Components¶
Route Components¶
Route parameters are detected based on each route’s template. Each
parameter is coerced to the appropriate type before the handler is
called. If a value can’t be coerced, then a 400 Bad Request
response is returned:
def hello(name: str, age: int) -> None:
...
Route("/hello/{name}/{age}", hello)
Request Components¶
Request
gives you access to the current request:
def index(request: Request) -> None:
print(request.path)
QueryString
gives you access to the full query string:
def index(query: QueryString) -> None:
print(query)
QueryParams
gives you access to all the query parameters in the
request:
def index(params: QueryParams) -> None:
print(params.get("some_param"))
print(params.get_all("some_param"))
QueryParam
gives you access to an individual query parameter in the
current request:
def index(some_param: QueryParam) -> None:
print(some_param)
This returns a 400 Bad Request
response if some_param
is
missing from the request. You may mark query params as optional to
avoid that:
def index(some_param: Optional[QueryParam]) -> None:
print(some_param)
Headers
gives you access to all the headers in the current request:
def index(headers: Headers) -> None:
print(headers.get("some-header"))
Header
gives you access to an individual header from the current
request:
def index(content_type: Header) -> None:
print(content_type)
This returns a 400 Bad Request
response if the content-type
header is missing from the request. You may mark query params as
optional to avoid that:
def index(content_type: Optional[Header]) -> None:
print(content_type)
Cookies
gives you access to all the cookies in the current request:
def index(cookies: Cookies) -> None:
print(headers.get("some-cookie"))
RequestInput
gives you access to the request body as a binary
file-like object:
def index(content_length: Header, body_file: RequestInput) -> None:
print(body_file.read(int(content_length)))
RequestBody
gives you access to the request body as bytestring:
def index(body: RequestBody) -> None:
print(body)
RequestData
gives you access to the parsed request body:
def index(data: RequestData) -> None:
print(data)
Settings Components¶
molten declares a Settings
class that 3rd party component libraries
may build components for or use internally. This is useful because
components – both 3rd party and 1st party – can depend on the
existence of a shared settings object regardless of how those settings
are loaded.
Two settings components are provided by the library.
from molten import Settings, SettingsComponent
def handle(settings: Settings) -> None:
...
app = App(
components=[SettingsComponent(Settings({"example": 42}))],
routes=[Route("/", handle)],
)
from molten import Settings
from molten.contrib.toml_settings import TOMLSettingsComponent
def handle(settings: Settings) -> None:
...
app = App(
components=[TOMLSettingsComponent("settings.toml")],
routes=[Route("/", handle)],
)
Special Components¶
The current application object can be requested by annotating
parameters with BaseApp
:
def index(app: BaseApp) -> str:
return app.reverse_uri("other")
Sometimes it may be useful for functions to gain access to the current
dependency resolver instance. Any parameter whose annotation is
DependencyResolver
will have the current resolver injected into it:
def index(resolver: DependencyResolver) -> None:
...
Certain components may require access to the current parameter being
resolved. In that case, they can annotate a dependency with
inspect.Parameter
:
def resolve(self, parameter: Parameter) -> Something:
return Something(parameter.name)
This is how the route parameter component is implemented under the hood.