### Basic Authentication Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/authentication.md This snippet demonstrates the basic setup for authentication middleware with a custom backend. Ensure `AuthenticationMiddleware` is installed and configured with a suitable backend. ```python from lilya.authentication import AuthenticationMiddleware from lilya.requests import Request from lilya.responses import PlainTextResponse from lilya.routing import Path async def homepage(request: Request): return PlainTextResponse(f"Hello, {request.user.display_name}") app = Lilya( routes=[ Path("/", homepage) ], middleware=[ AuthenticationMiddleware(backend=MyCustomBackend()) ] ) ``` -------------------------------- ### Complete Application Graph Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/introspection.md A comprehensive example demonstrating the setup of a Lilya application with global middleware, route-level middleware and permissions, includes with child apps, and a WebSocket route. It also shows how to print explanations and export the graph. ```python from lilya.apps import Lilya, ChildLilya from lilya.routing import Path, Include, WebSocketPath from lilya.middleware.base import DefineMiddleware from lilya.permissions.base import DefinePermission from lilya.protocols.permissions import PermissionProtocol # Middlewares class GlobalMW: ... class RouteMW1: ... class RouteMW2: ... class IncMW: ... # Permissions class Allow(PermissionProtocol): ... class Deny(PermissionProtocol): ... class IncAllow(PermissionProtocol): ... async def handler(): return "Hello" async def ws_handler(ws): await ws.accept() await ws.close() async def inner(): return "child" child = ChildLilya(routes=[Path("/inner", inner)]) app = Lilya( middleware=[GlobalMW], routes=[ Path("/users/{id}", handler, middleware=[DefineMiddleware(RouteMW1), DefineMiddleware(RouteMW2)], permissions=[Allow, Deny]), Include("/inc", app=child, middleware=[DefineMiddleware(IncMW)], permissions=[DefinePermission(IncAllow)]), WebSocketPath("/ws", ws_handler), ], ) g = app.graph print(g.explain("/users/{id}")) print(g.to_json()) ``` -------------------------------- ### Start Development Server with Auto Discovery Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/directives/discovery.md Run the development server using auto discovery. Ensure Palfrey is installed (`pip install palfrey`). ```shell $ lilya runserver ``` -------------------------------- ### End-to-End OpenTelemetry Setup with Lilya Middleware Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/opentelemetry.md Complete example demonstrating Lilya application setup with OpenTelemetryMiddleware and initial tracing configuration. This setup automatically instruments requests. ```python from lilya.apps import Lilya from lilya.routing import Path from lilya.responses import PlainText from lilya.middleware import DefineMiddleware from lilya.contrib.opentelemetry import OpenTelemetryMiddleware from lilya.contrib.opentelemetry.instrumentation import setup_tracing from lilya.contrib.opentelemetry.config import OpenTelemetryConfig setup_tracing(OpenTelemetryConfig( service_name="payments", exporter="otlp", otlp_endpoint="http://otel-collector:4317", # gRPC otlp_insecure=True, )) async def health(_): return PlainText("ok") app = Lilya( routes=[Path("/health", health)], middleware=[DefineMiddleware(OpenTelemetryMiddleware)], ) ``` -------------------------------- ### Create app.py for Security Setup Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/security/introduction.md This Python code sets up a basic application with security configurations using Lilya. It's intended to be the starting point for implementing authentication flows. ```python from lilya.apps import Lilya from lilya.routing import Path from lilya.security.authentication import BasicAuth, OAuth2PasswordBearer class User: def __init__(self, username: str, email: str = None, name: str = None): self.username = username self.email = email self.name = name async def get_current_user(token: str = OAuth2PasswordBearer(tokenUrl="token")) -> User: # In a real application, you would verify the token here # and retrieve the user associated with it. # For this example, we'll just return a dummy user. return User(username=token, email="test@example.com", name="Test User") async def read_users_me(current_user: User): return current_user app = Lilya( routes=[ Path("/users/me", endpoint=read_users_me, methods=["GET"]), ], authentication=OAuth2PasswordBearer(tokenUrl="token"), ) ``` -------------------------------- ### Basic Lilya Application Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/index.md A fundamental example of a Lilya application setup. This snippet illustrates the basic structure for creating an ASGI application with Lilya. ```python from lilya.applications import Lilya from lilya.routing import Path app = Lilya() @app.route(Path("/")) def homepage(): return {"message": "Hello World"} ``` -------------------------------- ### Basic AIClient Prompt Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/ai.md Shows a simple way to use the `AIClient` to get a direct response to a prompt. The result's text content is then printed. ```python result = await client.prompt( "Write a short release note for the latest deployment.", ) print(result.text) ``` -------------------------------- ### Basic Relay Setup Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/proxy/relay.md Configure a Relay instance to proxy traffic to an internal authentication service. This example shows how to set the target URL, upstream prefix, and optionally rewrite cookie domains. ```python from lilya.apps import Lilya from lilya.routing import Include from lilya.contrib.proxy.relay import Relay proxy = Relay( target_base_url="http://auth-service:8000", # internal service base URL upstream_prefix="/", # map "/auth/" -> "/" upstream preserve_host=False, # set Host to auth-service # Optional: drop the Domain attribute from Set-Cookie so it binds to current host rewrite_set_cookie_domain=lambda _original: "", max_retries=2, retry_backoff_factor=0.2, ) # The Main Lilya application app = Lilya( routes=[ Include("/auth", app=proxy), # Everything under /auth/** is proxied ], on_startup=[proxy.startup], # start shared HTTP client (pool) on_shutdown=[proxy.shutdown], # close it cleanly ) ``` -------------------------------- ### Basic Security Setup Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/security/interaction.md This snippet shows the initial setup where a security system provides a token string to the path operation function. ```python from fastapi import FastAPI, Depends from lilya.security.authorization import Security from lilya.security.oauth2 import OAuth2PasswordBearer app = FastAPI() class User: def __init__(self, username: str, email: str): self.username = username self.email = email async def get_current_user(token: str = Depends(OAuth2PasswordBearer(tokenUrl="token"))): return User(username=token, email=f"{token}@example.com") @app.get("/users/me") async def read_users_me( current_user: User = Depends(get_current_user) ): return current_user ``` -------------------------------- ### Quick Permission Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/permissions.md A concise example illustrating the basic structure of a permission class that can be quickly implemented. ```python from lilya.permissions import DefinePermission from lilya.exceptions import PermissionDenied class IsAdmin(DefinePermission): async def __call__(self, scope, receive, call_next): # Replace with your actual admin check logic if scope.get("state", {}).get("user_role") != "admin": raise PermissionDenied("User is not an admin") return await call_next(scope, receive, call_next) ``` -------------------------------- ### AsynczConfig Implementation Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/schedulers/config.md Example of how the AsynczConfig is implemented, showcasing specific configurations for the Asyncz scheduler. ```python from lilya.contrib.schedulers.config import SchedulerConfig class AsynczConfig(SchedulerConfig): def __init__(self, **kwargs): super().__init__(**kwargs) self.asyncz_kwargs = kwargs async def start(self): # Start the Asyncz scheduler with provided arguments pass async def shutdown(self): # Shutdown the Asyncz scheduler pass ``` -------------------------------- ### Start Development Server with --app Flag Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/directives/discovery.md Start the development server by explicitly specifying the application using the `--app` flag. ```shell $ lilya --app src.main:app runserver ``` -------------------------------- ### OpenID Connect Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/security/available-security.md This Python snippet demonstrates how to integrate OpenID Connect for user authentication and authorization within an application. It requires proper setup of an identity provider and client configuration. ```python from lilya.apps import Lilya from lilya.routing import Path from lilya.requests import Request from lilya.responses import JSONResponse async def homepage(request: Request): return JSONResponse({"message": "Welcome to the homepage"}) app = Lilya( routes=[ Path("/", endpoint=homepage), ] ) # Example of how to use OIDC with Lilya (conceptual) # This part is illustrative and would require a specific OIDC library integration. # async def login_with_oidc(request: Request): # # Redirect user to the OIDC provider's login page # # After successful login, the provider redirects back with an ID token # # The ID token is then validated and user information is extracted # pass # async def callback_from_oidc(request: Request): # # Handle the callback from the OIDC provider # # Validate the ID token and establish user session # pass ``` -------------------------------- ### Login Controller Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/templates.md Implement a login controller inheriting from `TemplateController` to handle GET and POST requests, including CSRF protection. ```python class LoginController(TemplateController): template_name = "login.html" csrf_enabled = True csrf_token_form_name = "csrf_token" async def get(self, request: Request) -> HTML: return await self.render_template(request) async def post(self, request: Request) -> HTML: # Get the form form = await request.form() # Do things and return ... # Return your HTML response ``` -------------------------------- ### Live Notifications with SSE Channels Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/sse.md Example of implementing live notifications where clients subscribe to a channel and the server pushes alerts. This setup is ideal for real-time user alerts. ```python from lilya.apps import Lilya from lilya.contrib.sse.channels import sse_manager app = Lilya() @app.get("/notify") async def notify(): ch = await sse_manager.get_or_create("user_notifications") await ch.broadcast({"event": "alert", "data": "You have a new message"}) return {"status": "notified"} ``` -------------------------------- ### Start Development Server with LILYA_DEFAULT_APP Environment Variable Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/directives/discovery.md Configure the `LILYA_DEFAULT_APP` environment variable and then start the development server. ```shell $ export LILYA_DEFAULT_APP=src.main:app $ lilya runserver ``` -------------------------------- ### Quick Middleware Sample Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/middleware.md A simple example demonstrating the structure of a middleware that can be used with Lilya. ```python from lilya.middleware import DefineMiddleware from lilya.apps import Lilya class HelloWorldMiddleware: def __init__(self): pass async def __call__(self, scope, receive, send): await send({ "type": "http.response.start", "status": 200, "headers": [ ["content-type", "application/json"], ], }) await send({ "type": "http.response.body", "body": b"{\"message\": \"Hello, world!\"}", }) app = Lilya( routes=[ # ... your routes ], middleware=[ DefineMiddleware(HelloWorldMiddleware), ], ) ``` -------------------------------- ### Install Asyncz Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/schedulers/scheduler.md Install the asyncz package to enable Lilya's scheduler functionality. ```shell pip install asyncz ``` -------------------------------- ### Lilya Application Entry Point Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/directives/discovery.md This is a basic example of a `main.py` file that initializes a Lilya application. ```python from lilya import Lilya app = Lilya() @app.route("/", methods=["GET"]) def homepage(): return {"message": "Hello, world!"} @app.route("/items/{item_id}", methods=["GET"]) def get_item(item_id: str): return {"item_id": item_id} ``` -------------------------------- ### Header-Based Authentication Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/parameters.md An example showing how to use a header parameter for authentication. ```APIDOC ## Header-Based Auth ### Description An example showing how to use a header parameter for authentication. ### Handler ```python async def get_user( token: str = Header(value="Authorization", required=True) ) -> dict: return {"user": validate_token(token)} ``` ### Request Example ```http GET /profile Authorization: Bearer TOKEN123 ``` ``` -------------------------------- ### Setup and Injection Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/ai.md Functions for setting up the AI client within the application and injecting it into handlers. ```APIDOC ## setup_ai() ### Description Registers the AI client with the application state and lifecycle. ### Method `setup_ai(...)` ### Parameters None explicitly documented for this method signature. ``` ```APIDOC ## AI ### Description Injects the configured AI client into Lilya handlers. ### Method `AI` ### Parameters None explicitly documented for this method signature. ``` -------------------------------- ### Install OpenTelemetry Packages Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/opentelemetry.md Install the necessary OpenTelemetry SDK, API, and exporter packages. The console exporter is included with the SDK if console output is preferred over OTLP. ```bash pip install opentelemetry-sdk opentelemetry-api opentelemetry-exporter-otlp # Optional, if you want console output instead of OTLP: pip install opentelemetry-sdk # (Console exporter ships with SDK) ``` -------------------------------- ### Basic OAuth2 Setup with Scopes Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/security/advanced/oauth2-scopes.md This snippet shows the initial setup for an OAuth2 security scheme, defining 'me' and 'items' scopes with their descriptions. These scopes will be visible in the API documentation for authorization. ```python from lilya.contrib.security.oauth2 import OAuth2 oauth2_scheme = OAuth2( scopes={"me": "read your profile", "items": "read items"} ) ``` -------------------------------- ### Installing Lilya (Pre-0.19.6) Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/release-notes.md Illustrates the installation command for Lilya before version 0.19.6, when all packages were included by default. ```shell $ pip install lilya ``` -------------------------------- ### Combined Parameters Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/parameters.md An example demonstrating how to combine Query, Header, Cookie parameters with request body and dependencies. ```APIDOC ## Combined Query, Header, Cookie, Body, Dependency ### Description An example demonstrating how to combine Query, Header, Cookie parameters with request body and dependencies. ### Handler ```python from lilya.params import Query, Header, Cookie from lilya.dependencies import Provide from pydantic import BaseModel class User(BaseModel): name: str age: int class Service: def show(self): return "ok" async def handle( user: User, # from JSON body q: str = Query(alias="q", default="none"), token: str = Header(value="X-TOKEN", required=True), session: str = Cookie(value="csrftoken"), svc: Service = Provide(Service) # injected dependency ): return { "user": user.model_dump(), "q": q, "token": token, "session": session, "svc": svc.show(), } ``` ### Request Example ```http GET /?q=hello Headers: X-TOKEN: tok Cookies: csrftoken=sess Body: {"name": "tiago", "age": 35} ``` ``` -------------------------------- ### Install Lilya with Standard Extras Source: https://github.com/dymmond/lilya/blob/main/README.md Install Lilya along with its client for scaffolding and other tools. This provides additional utilities for project management. ```shell pip install lilya[standard] ``` -------------------------------- ### Minimal TrustedHostMiddleware Setup Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/middleware/trustedhost.md Configure TrustedHostMiddleware with allowed hosts and enable www redirection. This is a basic setup for strict host header validation. ```python from lilya.apps import Lilya from lilya.middleware import DefineMiddleware from lilya.middleware.trustedhost import TrustedHostMiddleware app = Lilya( middleware=[ DefineMiddleware( TrustedHostMiddleware, allowed_hosts=["example.com", "*.example.com"], www_redirect=True, ) ] ) ``` -------------------------------- ### CSRF Middleware Example (Headers) Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/middleware.md A minimal example demonstrating CSRF protection using headers. ```python #!/usr/bin/env python from lilya.middleware import CSRFMiddleware from lilya.requests import Request from lilya.responses import PlainTextResponse from lilya.routing import Path def homepage(request: Request): return PlainTextResponse("Hello, world!") middleware = [ CSRFMiddleware( secret="your-long-unique-secret", httponly=False, secure=True, samesite="lax", ) ] routes = [ Path("/", endpoint=homepage), ] ``` -------------------------------- ### Basic Query Injection Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/parameters.md An example demonstrating how to inject a query parameter into a handler function. ```APIDOC ## Basic Query Injection ### Description An example demonstrating how to inject a query parameter into a handler function. ### Handler ```python async def search_books(query: str = Query()) -> dict: return {"query": query} ``` ### Request Example ```http GET /search?query=python ``` ``` -------------------------------- ### Install httpx Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/proxy/relay.md Before working with Relay, ensure httpx is installed as it's used by Lilya to create the Relay object. ```shell pip install httpx ``` -------------------------------- ### Serve Built Documentation Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contributing.md After building all documentation, use this command to serve the combined output. This is a simple server for previewing translated sites. ```shell $ hatch run docs:dev Warning: this is a very simple server. For development, use mkdocs serve instead. This is here only to preview a site with translations already built. Make sure you run the build-all command first. Serving at: http://127.0.0.1:8000 ``` -------------------------------- ### Install All Lilya Features Source: https://github.com/dymmond/lilya/blob/main/README.md Install Lilya with all available extras, including support for specific middlewares and advanced functionalities. ```shell pip install lilya[all] ``` -------------------------------- ### Include and Application Instance Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/routing.md Demonstrates how to use `Include` to manage application instances and routes, simplifying large configurations. ```python from lilya.routing import Include routes = [ Include(path="/api/v1", app=api_v1_app), Include(path="/admin", app=admin_app) ] ``` ```python from lilya.app import Lilya from lilya.routing import Include api_v1_app = Lilya() admin_app = Lilya() routes = [ Include(path="/api/v1", app=api_v1_app), Include(path="/admin", app=admin_app) ] app = Lilya(routes=routes) ``` -------------------------------- ### Complete Lilya Example with Thread Pool Tuning Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/threadpool.md This example demonstrates setting a custom thread pool size at startup and scheduling a blocking background task. The `compute_endpoint` would also run blocking code in a thread. ```python from lilya.apps import Lilya from lilya.background import Tasks from lilya.responses import JSONResponse import anyio.to_thread import time app = Lilya() # ↑→ Increase thread pool size before the app handles any requests limiter = anyio.to_thread.current_default_thread_limiter() limiter.total_tokens = 80 # bump from 40 to 80 def blocking_task(name: str, delay: float) -> None: """Simulate a long-running, blocking operation.""" time.sleep(delay) print(f"Task {name} completed in {delay}s") @app.get("/compute/{item_id}") def compute_endpoint(item_id: int): # runs in a thread so the event loop won't block result = heavy_computation(item_id) # Assuming heavy_computation is defined elsewhere return {"item_id": item_id, "result": result} @app.get("/start-background") async def start_background(): background_tasks = Tasks(as_group=True) # schedule blocking_task in a thread pool background_tasks.add_task(blocking_task, name="BG1", delay=5) return JSONResponse({"status": "Background task scheduled!"}, background=background_tasks) ``` -------------------------------- ### Basic Handler Example with @openapi Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/openapi.md This example demonstrates the basic usage of the @openapi decorator to attach metadata to a handler, which is then used to generate OpenAPI documentation. ```APIDOC ## GET /hello ### Description A simple endpoint that returns a greeting. ### Method GET ### Endpoint /hello ### Response #### Success Response (200) - **message** (string) - A greeting message. ### Request Example (No request body for this example) ### Response Example ```json { "message": "Hello, World!" } ``` ``` -------------------------------- ### Static Password Authentication Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/authentication.md This example shows how to implement authentication using static username and password pairs without a full user management system. It's suitable for simpler use cases where user data is not stored persistently. ```python from lilya.authentication import AuthenticationMiddleware from lilya.requests import Request from lilya.responses import PlainTextResponse from lilya.routing import Path async def homepage(request: Request): return PlainTextResponse(f"Hello, {request.user.display_name}") app = Lilya( routes=[ Path("/", homepage) ], middleware=[ AuthenticationMiddleware(backend=StaticPasswordBackend(users={"admin": "password"})) ] ) ``` -------------------------------- ### Install Passlib with Bcrypt Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/security/oauth-jwt.md Install the PassLib library with Bcrypt support for secure password hashing. PassLib supports various hashing algorithms and can be configured to read passwords hashed by other frameworks. ```shell $ pip install passlib[bcrypt] ``` -------------------------------- ### Manually Serve MkDocs Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contributing.md Navigate to the language-specific documentation directory and run 'mkdocs serve' to preview changes live. ```console $ cd docs/es/ $ mkdocs serve --dev-addr 8000 ``` -------------------------------- ### YAMLResponse example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/responses.md Used to return data in YAML format. Requires the PyYAML library to be installed. Automatically sets the media type to 'application/x-yaml'. ```python from lilya.responses import YAMLResponse @app.get("/yaml") def yaml_example(): return YAMLResponse(content={ "framework": "Lilya", "version": 1.0, }) ``` -------------------------------- ### WebSocket Proxy Setup Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/proxy/relay.md Install the 'websockets' library to enable WebSocket proxying. Mount the Relay proxy to a specific route in your Lilya application. ```shell pip install websockets ``` ```python proxy = Relay("http://chat-service.local") app = Lilya(routes=[Include("/ws", app=proxy)]) ``` -------------------------------- ### Dockerfile Instructions Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/docker.md This snippet shows essential Dockerfile instructions for setting up a Python application with Nginx and Supervisor. It covers base image selection, dependency installation, and service startup. ```dockerfile CMD ["/usr/bin/supervisord"] ``` -------------------------------- ### Directive Placement Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/directives/custom-directives.md Illustrates the directory structure for custom directives, emphasizing the 'directives/operations' package. ```shell . ├── Taskfile.yaml └── myproject ├── __init__.py ├── apps │ ├── accounts │ │ ├── directives │ │ │ ├── __init__.py │ │ │ └── operations │ │ │   ├── createsuperuser.py │ │ │   └── __init__.py │ ├── payroll │ │   ├── directives │ │   │   ├── __init__.py │ │   │   └── operations │ │   │   ├── run_payroll.py │ │   │   └── __init__.py │ ├── products │ │   ├── directives │ │   │   ├── __init__.py │ │   │   └── operations │ │   │   ├── createproduct.py │ │   │   └── __init__.py ├── configs │   ├── __init__.py │   ├── development │   │   ├── __init__.py │   │   └── settings.py │   ├── settings.py │   └── testing │   ├── __init__.py │   └── settings.py ├── directives │   ├── __init__.py │   └── operations │   ├── db_shell.py │   └── __init__.py ├── main.py ├── serve.py ├── tests │   ├── __init__.py │   └── test_app.py └── urls.py ``` -------------------------------- ### Basic SSE Channel Setup and Usage Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/sse.md Demonstrates creating an SSE channel, streaming events to clients, and broadcasting messages. Open `/events` in a browser and call `/send` in another tab to see the message arrive. ```python from lilya.apps import Lilya from lilya.routing import Path from lilya.contrib.security.signed_urls import SignedURLGenerator from lilya.contrib.sse.channels import SSEChannel, sse_manager from lilya.responses import EventStreamResponse # Create or get a named SSE channel notifications = SSEChannel("notifications") async def events(): # Stream messages to connected clients async def stream(): async for event in notifications.listen(heartbeat_interval=10): yield event return EventStreamResponse(stream()) async def send(): # Broadcast to all connected clients await notifications.broadcast({"event": "notice", "data": "Hello, world!"}) return {"sent": True} app = Lilya(routes=[ Path("/events", events), Path("/send", send), ]) ``` -------------------------------- ### Decorator-based Routing with Lilya Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/routing.md Provides examples of defining routes using decorators like `get`, `route`, and `websocket` on a Lilya application instance. ```python from lilya.apps import Lilya app = Lilya() @app.get("/users/{user_id:int}") async def get_user(user_id: int): return {"user_id": user_id} @app.route("/users", methods=["POST"]) async def create_user(request): return {"ok": True} @app.websocket("/ws") async def ws(websocket): await websocket.accept() await websocket.send_text("connected") await websocket.close() ``` -------------------------------- ### Python App Setup for OpenTelemetry Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/opentelemetry.md Basic Python setup for OpenTelemetry tracing using Lilya's instrumentation. Ensure OTEL_ENDPOINT is correctly configured, typically via environment variables. ```python import os from lilya.contrib.opentelemetry.instrumentation import setup_tracing from lilya.contrib.opentelemetry.config import OpenTelemetryConfig setup_tracing(OpenTelemetryConfig( service_name="checkout", exporter="otlp", otlp_endpoint=os.getenv("OTEL_ENDPOINT", "http://localhost:4317"), )) ``` -------------------------------- ### Configure Tracing at Startup (Default) Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/opentelemetry.md Use the default OpenTelemetry configuration to set up tracing. This option sends traces to the default OTLP endpoint (http://localhost:4317). ```python # app.py from lilya.contrib.opentelemetry.instrumentation import setup_tracing from lilya.contrib.opentelemetry.config import OpenTelemetryConfig # Option A: default config → OTLP to http://localhost:4317 setup_tracing() ``` -------------------------------- ### Lilya Application Setup with CQRS Routes Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/cqrs.md Defines a Lilya application with routes for the create_user (POST /users) and get_user (GET /users/{user_id}) endpoints. ```python from lilya.apps import Lilya from lilya.routing import Path app = Lilya( routes=[ Path("/users", create_user, methods=["POST"]), Path("/users/{user_id}", get_user), ] ) ``` -------------------------------- ### Simple HTTP Basic Auth Setup Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/security/advanced/basic-auth.md Import `HTTPBasic` and `HTTPBasicCredentials`, create a security scheme, and apply it to your path operation. The dependency will return an `HTTPBasicCredentials` object. ```python from esmerald import Esmerald, Gateway, HTTPBasic, HTTPBasicCredentials app = Esmerald() @app.get("/", security=HTTPBasic()) def main(credentials: HTTPBasicCredentials): return { "username": credentials.username, "password": credentials.password, } ``` -------------------------------- ### Serve Documentation for a Specific Language Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contributing.md Use this command to run the live server for documentation in a specific language, such as Spanish ('es'). ```shell $ hatch run docs:serve_lang es ``` -------------------------------- ### Switch AI Provider to Groq Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/ai.md Demonstrates how to switch the AI provider to Groq without modifying handler code. Only the startup wiring needs to be updated. ```python from lilya.contrib.ai import AIClient, GroqConfig, GroqProvider provider = GroqProvider(GroqConfig(api_key="...")) client = AIClient(provider, default_model="llama-3.3-70b-versatile") setup_ai(app, client=client) ``` -------------------------------- ### Install Lilya Source: https://github.com/dymmond/lilya/blob/main/README.md Install the core Lilya toolkit using pip. This is the base installation for the framework. ```shell pip install lilya ``` -------------------------------- ### Build All Documentation Sites Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contributing.md Execute this command to build all independent MkDocs sites for each language, combining them into a final output. ```shell $ hatch run docs:build ``` -------------------------------- ### Install PTPython Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/directives/shell.md Install PTPython to use as an alternative shell. Alternatively, install Lilya with the ptpython extra. ```shell $ pip install ptpython ``` ```shell $ pip install lilya[ptpyton] ``` -------------------------------- ### Basic Usage Examples Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/shortcuts/abort.md Demonstrates various ways to use the `abort()` shortcut, including raising simple errors, adding custom messages, returning JSON, and including custom headers. ```APIDOC ## Basic Usage ### Raise a simple error ```python from lilya.apps import Lilya from lilya.contrib.responses.shortcuts import abort from lilya.routing import Path async def not_found(): abort(404) # immediately stop execution app = Lilya(routes=[Path("/item", not_found)]) ``` **Result:** ```http HTTP/1.1 404 Not Found Content-Type: text/plain; charset=utf-8 Not Found ``` ### Add a custom message ```python async def forbidden(request): abort(403, "You cannot access this resource.") ``` **Result:** ```http HTTP/1.1 403 Forbidden Content-Type: text/plain; charset=utf-8 You cannot access this resource. ``` ### Return structured JSON errors ```python async def invalid(request): abort(400, {"error": "Invalid input", "field": "email"}) ``` **Result:** ```http HTTP/1.1 400 Bad Request Content-Type: application/json {"error": "Invalid input", "field": "email"} ``` ### Add custom headers ```python async def blocked(request): abort(403, "Access denied", headers={"X-Reason": "Policy Restriction"}) ``` **Result:** ```http HTTP/1.1 403 Forbidden X-Reason: Policy Restriction Content-Type: text/plain; charset=utf-8 Access denied ``` ``` -------------------------------- ### Install IPython Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/directives/shell.md Install IPython to use with Lilya's shell. Alternatively, install Lilya with the ipython extra. ```shell $ pip install ipython ``` ```shell $ pip install lilya[ipython] ``` -------------------------------- ### HTTP Controller with Initialization Parameters Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/controllers.md Example of using `with_init` to pass initialization parameters to an HTTP Controller. ```python from lilya.apps import Lilya from lilya.controllers import Controller from lilya.responses import JSONResponse class MyController(Controller): def __init__(self, config_value: str): self.config_value = config_value async def get(self, request): return JSONResponse({'config': self.config_value}) app = Lilya() app.add_controller(MyController.with_init(config_value='my_config')) ``` -------------------------------- ### Install Lilya Test Suite Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/test-client.md Install the Lilya testing suite to use the test client. This command installs Lilya with testing dependencies. ```shell pip install Lilya[test] ``` -------------------------------- ### Example StreamingResponse Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/responses.md Example usage of the StreamingResponse class. ```python from lilya.responses import StreamingResponse app = [...] ``` -------------------------------- ### Example RedirectResponse Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/responses.md Example usage of the RedirectResponse class. ```python from lilya.responses import RedirectResponse app = [...] ``` -------------------------------- ### Serve Documentation Manually with MkDocs Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contributing.md Manually serves the documentation using MkDocs from the English documentation directory. Assumes you are in the root project directory. ```shell $ cd docs/en/ ``` ```shell $ mkdocs serve --dev-addr 8000 ``` -------------------------------- ### Example JSONResponse Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/responses.md Example usage of the JSONResponse class. ```python from lilya.responses import JSONResponse app = [...] ``` -------------------------------- ### Install PyJWT Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/security/oauth-jwt.md Install the PyJWT library to work with JSON Web Tokens. For digital signature algorithms like RSA or ECDSA, install with the `crypto` extra. ```shell $ pip install pyjwt ``` ```shell $ pip install pyjwt[crypto] ``` -------------------------------- ### Basic JSONResponse Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/responses.md Example of creating a JSONResponse with a dictionary payload. ```python from lilya.responses import JSONResponse @app.route("/json") def get_json(): return JSONResponse({"message": "Hello, World!"}) ``` -------------------------------- ### Example FileResponse Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/responses.md Example usage of the FileResponse class for streaming a file. ```python from lilya.responses import FileResponse app = [...] ``` -------------------------------- ### Serve Documentation Locally Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contributing.md Builds the documentation site and watches for changes, live-reloading the site. Serves the documentation on http://localhost:8000 by default. ```shell $ hatch run docs:serve ``` -------------------------------- ### Example Ok Response Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/responses.md Example usage of the Ok response class. ```python from lilya.responses import Ok app = [...] ``` -------------------------------- ### Quick Overview of `abort()` Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/shortcuts/abort.md Demonstrates the basic usage of the `abort()` shortcut to immediately stop request execution with a 404 error. ```python from lilya.contrib.responses.shortcuts import abort async def endpoint(): abort(404) # immediately stop execution ``` -------------------------------- ### Example PlainText Response Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/responses.md Example usage of the PlainText response class. ```python from lilya.responses import PlainText app = [...] ``` -------------------------------- ### Example Error Response Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/responses.md Example usage of the Error response class. ```python from lilya.responses import Error app = [...] ``` -------------------------------- ### Example XMLResponse Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/responses.md Example usage of the XMLResponse class to return XML data. ```python from lilya.responses import XMLResponse app = [...] ``` -------------------------------- ### Initialize Hatch Environments Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contributing.md Create and initialize the necessary Hatch environments for development, testing, and documentation. ```shell cd lilya hatch env create hatch env create test hatch env create docs ``` -------------------------------- ### Example CSVResponse Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/responses.md Example usage of the CSVResponse class to return CSV data. ```python from lilya.responses import CSVResponse app = [...] ``` -------------------------------- ### Define Startup and Shutdown Handlers Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/lifespan.md Use `on_startup` and `on_shutdown` parameters to define functions that run once before the application starts and once after it shuts down. This is useful for managing resources like database connections. ```python from lilya import Lilya from lilya.routing import Path async def connect_to_db(): print("Connecting to database...") # Simulate database connection await asyncio.sleep(1) print("Database connected") async def disconnect_db(): print("Disconnecting from database...") # Simulate database disconnection await asyncio.sleep(1) print("Database disconnected") app = Lilya( routes=[ Path("/", endpoint=lambda: "Hello World") ], on_startup=[connect_to_db], on_shutdown=[disconnect_db] ) ``` -------------------------------- ### Project Structure Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/directives/discovery.md This is an example of a typical project structure that Lilya can auto-discover. ```shell . ├── Taskfile.yaml └── src ├── __init__.py ├── apps │ ├── accounts │ │ ├── directives │ │ │ ├── __init__.py │ │ │ └── operations │ │ │   └── __init__.py ├── configs │ ├── __init__.py │ ├── development │ │ ├── __init__.py │ │ └── settings.py │ ├── settings.py │ └── testing │ ├── __init__.py │ └── settings.py ├── main.py ├── tests │ ├── __init__.py │ └── test_app.py └── urls.py ``` -------------------------------- ### Cookie-Based Session Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/parameters.md An example illustrating the use of a cookie parameter for session management. ```APIDOC ## Cookie-Based Session ### Description An example illustrating the use of a cookie parameter for session management. ### Handler ```python async def dashboard( session_id: str = Cookie(value="sessionid", required=True) ) -> dict: return {"session": load_session(session_id)} ``` ### Request Example ```http GET /dashboard Cookie: sessionid=abc123 ``` ``` -------------------------------- ### WebSocket Controller with Initialization Parameters Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/controllers.md Example of using `with_init` to pass initialization parameters to a WebSocket Controller. ```python from lilya.controllers import WebSocketController from lilya.websockets import WebSocket class MyWebSocketController(WebSocketController): def __init__(self, db_connection_string: str): self.db_connection_string = db_connection_string async def on_connect(self, websocket: WebSocket, **kwargs): await websocket.accept() await websocket.send_json({'message': f'Connected with DB: {self.db_connection_string}'}) async def on_receive(self, websocket: WebSocket, data): await websocket.send_json({'message': f'Received: {data}'}) async def on_disconnect(self, websocket: WebSocket, close_code: int): await websocket.close(code=close_code) app = Lilya() app.add_websocket_controller(MyWebSocketController.with_init(db_connection_string='postgresql://user:password@host:port/database')) ``` -------------------------------- ### CronTrigger Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/schedulers/handler.md Example demonstrating the usage of CronTrigger with various parameters to schedule a task. ```python from datetime import datetime from asyncz.schedulers import AsynczScheduler from asyncz.triggers import CronTrigger def my_task(): print("I am called by the scheduler") scheduler = AsynczScheduler() scheduler.add_task( my_task, trigger=CronTrigger(year=2023, month=12, day=15, hour=14, minute=30, second=0), name="my_task", ) scheduler.start() ``` -------------------------------- ### Install Lilya with CLI support Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/lilya-cli.md Install the Lilya package with the necessary dependencies for the CLI functionality. ```shell $ pip install lilya[cli] ``` -------------------------------- ### Full Application AI Setup and Endpoint Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/ai.md Demonstrates setting up a shared AIClient with an OpenAI provider and integrating it into a Lilya application. This centralizes AI functionality for use across multiple routes. ```python from lilya.apps import Lilya from lilya.contrib.ai import AI, AIClient, ChatMessage, OpenAIConfig, OpenAIProvider, setup_ai provider = OpenAIProvider( OpenAIConfig( api_key="your-openai-key", timeout=20.0, ) ) client = AIClient( provider, default_model="gpt-4o-mini", default_system_prompt="You are a helpful assistant for Lilya applications.", ) app = Lilya() setup_ai(app, client=client) @app.post("/summarize", dependencies={"ai": AI}) async def summarize(ai: AI): result = await ai.chat( [ ChatMessage.user( "Summarize the following incident in three bullets: " "API latency increased after deployment. Error rate stayed low. " "A cache misconfiguration caused most of the slowdown." ) ] ) return { "provider": result.provider, "model": result.model, "text": result.text, } ``` -------------------------------- ### Setup AI Client with OpenAI Provider Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/ai.md Configure and set up the AI client with an OpenAI provider. This involves creating an `AIClient` instance with provider configuration and then using `setup_ai` to attach it to the Lilya app. ```python from lilya.apps import Lilya from lilya.contrib.ai import AIClient, OpenAIConfig, OpenAIProvider, setup_ai provider = OpenAIProvider(OpenAIConfig(api_key="...")) client = AIClient(provider, default_model="gpt-4o-mini") app = Lilya() setup_ai(app, client=client) ``` -------------------------------- ### Basic Lilya App Setup Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/logging.md Initialize a Lilya application. This is the default behavior if no specific logging configuration is provided. ```python from lilya.apps import Lilya app = Lilya() ``` -------------------------------- ### Route Priority Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/routing.md Demonstrates how to define routes with different priorities. More specific routes should be listed before general ones to ensure correct matching. ```python from lilya.apps import Lilya from lilya.routing import Path app = Lilya() @app.route("/users/{user_id}") def get_user(request): return JSONResponse({"user_id": request.path_params.get("user_id")}) @app.route("/users/me") def get_me(request): return JSONResponse({"user_id": "me"}) @app.route("/users/me/profile") def get_me_profile(request): return JSONResponse({"user_id": "me", "profile": True}) ``` -------------------------------- ### Full-Featured OpenAPI Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contrib/openapi.md Demonstrates combining various routing and parameter features for comprehensive OpenAPI generation. Pay attention to how path and query parameters are handled for different routes, especially when parameters are omitted due to route structure. ```python from lilya.apps import Lilya from lilya.routing import Path, Include from lilya.responses import OpenAPIResponse from pydantic import BaseModel class User(BaseModel): user_id: int name: str def list_user_items(user_id: int): return {"user_id": user_id, "items": ["item1", "item2"]} def get_profile(user_id: int): return {"user_id": user_id, "name": "John Doe"} def get_extra_info(user_id: int): return {"user_id": user_id, "extra": "some_extra_info"} routes = [ Path( "/users/{user_id}/items", methods=["GET"], handler=list_user_items, responses={ 200: OpenAPIResponse(model=dict, description="List of user items") }, ), Path( "/account/profile", methods=["GET"], handler=get_profile, responses={ 200: OpenAPIResponse(model=User, description="User profile") }, ), Include( "/users", routes=[ Path( "/extra/{user_id}/extra-info", methods=["GET"], handler=get_extra_info, responses={ 200: OpenAPIResponse(model=dict, description="Extra user info") }, ) ], ), ] app = Lilya(routes=routes) ``` -------------------------------- ### Variable Expansion Example Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/environments.md Demonstrates how to reference other environment variables within .env or YAML files using $VAR or ${VAR|default} syntax. ```python loader = EnvironLoader(env_file=".env") print(loader["LOG_PATH"]) # /var/log/myapp ``` -------------------------------- ### Install Hatch Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/contributing.md Install Hatch, a tool used for Lilya's development, testing, and release cycles. ```shell pip install hatch ``` -------------------------------- ### Basic Lilya Application Setup Source: https://github.com/dymmond/lilya/blob/main/README.md A simple ASGI application using Lilya with dynamic routing. It defines routes for a welcome message, a user-specific greeting, and a user greeting accessed via path parameters. ```python from lilya.apps import Lilya from lilya.requests import Request from lilya.responses import Ok from lilya.routing import Path async def welcome(): return Ok({"message": "Welcome to Lilya"}) async def user(user: str): return Ok({"message": f"Welcome to Lilya, {user}"}) async def user_in_request(request: Request): user = request.path_params["user"] return Ok({"message": f"Welcome to Lilya, {user}"}) app = Lilya( routes=[ Path("/{user}", user), Path("/in-request/{user}", user_in_request), Path("/", welcome), ] ) ``` -------------------------------- ### Register User and Send Confirmation Email Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/tasks.md Example of registering a user and sending a confirmation email as a background task. ```python from lilya.background import Task def send_email_notification(email: str, message: str): # Simulate sending an email print(f"Sending email to {email}: {message}") def write_in_file(message: str): # Simulate writing to a file print(f"Writing to file: {message}") @app.route("/register", methods=["POST"]) def register_user(request: Request): # Assume user data is in request.json() user_data = request.json() email = user_data.get("email") username = user_data.get("username") # Register user in the system (simulated) print(f"Registering user: {username} with email: {email}") # Attach background tasks to the response response = JSONResponse({"message": "User registered successfully"}) response.add_task(Task(send_email_notification, email=email, message="Welcome!")) response.add_task(Task(write_in_file, message=f"User {username} registered.")) return response ``` -------------------------------- ### Get Help for a Directive Source: https://github.com/dymmond/lilya/blob/main/docs/en/docs/directives/directives.md To get help for any Lilya directive, append the --help flag to the command. ```shell $ lilya runserver --help ```