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.

SettingsComponent:

from molten import Settings, SettingsComponent

def handle(settings: Settings) -> None:
    ...

app = App(
    components=[SettingsComponent(Settings({"example": 42}))],
    routes=[Route("/", handle)],
)

TOMLSettingsComponent:

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.