Context¶
The Context
is a beauty of an object unique to Lilya. The context
is a parameter that
can be used inside the function handlers and provides additional information
that you might need for any particular reason.
Very similar approach to Request in terms of implementation but not the same.
In fact, a context
contains also the request and information about the handler itself.
Importing is as simple as:
from lilya.context import Context
The Context
class¶
You can see the context
as the request context
of a given handler. This also means, when
a function handler (view) is declared all the information passed to it
is automatically accessible via context.handler
parameter.
from lilya.context import Context
from lilya.responses import make_response
def home(context: Context):
"""
Accessing the context object.
"""
return make_response(content=None, status_code=204)
The context
also provides access to the request
object as well as the
application settings and other functions.
This means, if you want to pass a request
and context
you actually only need the context
directly as the request is already available inside but you can still pass both anyway.
Example
from lilya.apps import Lilya
from lilya.context import Context
from lilya.routing import Path
def read_context(context: Context, id: str):
host = context.request.client.host
context_data = context.get_context_data()
context.add_to_context("name", "Lilya")
context_data = context.get_context_data()
context_data.update({
"host": host, "user_id": id
})
return context_data
app = Lilya(
routes=[
Path("/users/{id}", read_request)
]
)
The context
becomes especially valuable when you need to retrieve handler
information that is
unavailable after the handler's instantiation. For instance, it proves useful when accessing
context.settings
to retrieve application settings, offering a versatile approach to accessing them.
Attributes¶
Handler¶
The function handler that is responsible for the request.
from lilya.context import Context
from lilya.responses import Response
def home(context: Context):
handler = context.handler
return Response("Ok")
Request¶
The request being used for the scope of the handler.
from lilya.context import Context
from lilya.responses import Response
def home(context: Context):
request = context.request
return Response("Ok")
User¶
The user allocated in the request.
from lilya.context import Context
from lilya.responses import Response
def home(context: Context):
user = context.user
return Response("Ok")
User¶
The user allocated to the request.
from lilya.context import Context
from lilya.responses import Response
def home(context: Context):
user = context.user
return Response("Ok")
Settings¶
The settings being used by the Lilya application.
This can be the global settings or if a settings_module
was provided, returns that
same settings.
from lilya.context import Context
from lilya.responses import Response
def home(context: Context):
settings = context.settings
return Response("Ok")
Scope¶
The scope of the application handler.
from lilya.context import Context
from lilya.responses import Response
def home(context: Context):
scope = context.scope
return Response("Ok")
Application¶
The Lilya application.
from lilya.context import Context
from lilya.responses import Response
def home(context: Context):
app = context.app
return Response("Ok")
Methods¶
The context
provides also different functions to manipulate the object.
get_context_data¶
The context of the application. This can be particularly useful when working with templates.
from lilya.context import Context
from lilya.responses import Response
def home(context: Context):
context = context.get_context_data()
return Response("Ok")
add_to_context¶
Adding values into the current context.
from lilya.context import Context
from lilya.responses import Response
def home(context: Context):
context.add_to_context("call", "ok")
return Response("Ok")
path_for¶
Retrives the path of a specific handler.
from lilya.context import Context
from lilya.responses import Response
def home(context: Context):
url = context.path_for("/home")
return Response(url)
The G
object¶
This object is a pretty cool one, it is what allows you to have a global request context across the lifecycle.
Imagine the following. You have a deceorator that validates a login and wants to store arbitrary data inside a request global context to be used later on and once the request is closed, then its cleared.
This is where the G
object comes to play. Imagine the g
of Flask, same principle.
This object is globally used and on each request it will be "reset", meaning, it only lives in the request context of the call.
from lilya.apps import Lilya
from lilya.context import g
from lilya.middleware import DefineMiddleware
from lilya.middleware.global_context import GlobalContextMiddleware
from lilya.routing import Path
def populate_g():
g.name = "Lilya"
g.age = 25
async def show_g():
return g.store
app = Lilya(
routes=[Path("/show", show_g)]
)
populate_g()
This of course is a very simple example and probably not like how you would like to use but it
explains how to use the g
. After every request, the g
is cleared.
Imagine now you want to use it in a decorator
.
import functools
from lilya.apps import Lilya
from lilya.context import g
from lilya.middleware import DefineMiddleware
from lilya.middleware.global_context import GlobalContextMiddleware
from lilya.routing import Path
def user_check(func):
@functools.wraps(func)
async def wrapper(*args, **kwargs):
if not hasattr(g, "user"):
g.user = "not logged in"
return await func(*args, **kwargs)
return wrapper
@user_check
async def show_g():
return g.store
app = Lilya(
routes=[Path("/show", show_g)]
)
This example is closer to the reality of the use of a g
like validating a login against anything
in your APIs.
The RequestContext
object¶
This is a very useful object that acts a lazyy loader of the request object without the need of explicitly declaring it inside an handler.
Danger
When using the request_context
object, you must install the RequestContextMiddleware
or an ImproperlyConfigured
exception is raised.
from lilya.apps import Lilya
from lilya.context import request_context
from lilya.middleware import DefineMiddleware
from lilya.middleware.request_context import RequestContextMiddleware
from lilya.routing import Path
async def show_request_context():
return {"url": str(request_context.url)}
app = Lilya(routes=[
Path('/show', show_request_context)
],
middleware=[DefineMiddleware(RequestContextMiddleware)],
)