### Install Granian with Extra Dependencies Source: https://github.com/emmett-framework/granian/blob/master/README.md Example of installing Granian with specific extra dependencies like 'pname' and 'uvloop'. Combine extras as needed for your project. ```bash $ pip install granian[pname,uvloop] ``` -------------------------------- ### ASGI Application Example Source: https://github.com/emmett-framework/granian/blob/master/README.md A basic ASGI application that responds with 'Hello, world!'. Ensure your application is defined in a Python file (e.g., main.py) and accessible. ```python async def app(scope, receive, send): assert scope['type'] == 'http' await send({ 'type': 'http.response.start', 'status': 200, 'headers': [ [b'content-type', b'text/plain'], ], }) await send({ 'type': 'http.response.body', 'body': b'Hello, world!', }) ``` -------------------------------- ### RSGI Application Example Source: https://github.com/emmett-framework/granian/blob/master/README.md A simple RSGI application that sends a 'Hello, world!' response. RSGI is an alternative interface supported by Granian. ```python async def app(scope, proto): assert scope.proto == 'http' proto.response_str( status=200, headers=( ('content-type', 'text/plain') ), body="Hello, world!" ) ``` -------------------------------- ### WSGI Application Example Source: https://github.com/emmett-framework/granian/blob/master/README.md A standard WSGI application that returns a 'Hello, world!' response. This is compatible with traditional Python web frameworks. ```python def app(environ, start_response): start_response('200 OK', [('content-type', 'text/plain')]) return [b"Hello, world!"] ``` -------------------------------- ### Initialize Embeddable Granian Server Source: https://github.com/emmett-framework/granian/blob/master/README.md Import and initialize the embeddable Granian server with your ASGI application. This setup is for projects requiring custom process management. ```python from granian.server.embed import Server server = Server(my_app, interface="asgi") async def my_main(): await server.serve() ``` -------------------------------- ### Custom AsyncIO Event Loop Initialization Source: https://github.com/emmett-framework/granian/blob/master/README.md Customize the default AsyncIO event loop initialization policy by overwriting the 'auto' policy. This example shows how to set the WindowsSelectorEventLoopPolicy. ```python import asyncio from granian import Granian, loops @loops.register('auto') def build_loop(): asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) return asyncio.new_event_loop() Granian(...).serve() ``` -------------------------------- ### Register Granian Lifecycle Hooks Source: https://github.com/emmett-framework/granian/blob/master/README.md Register callable functions to be executed during specific Granian lifecycle phases like startup, shutdown, or reload. This example shows how to register a reload hook. ```python from granian import Granian def my_hook(): print("hello from reload!") server = Granian(...) server.on_reload(my_hook) ``` -------------------------------- ### Display Granian Help and Options Source: https://github.com/emmett-framework/granian/blob/master/README.md Use the `--help` command to view all available options for Granian and their default values. This is useful for understanding the server's configuration capabilities. ```bash granian --help ``` -------------------------------- ### Build Development Environment Source: https://github.com/emmett-framework/granian/blob/master/CONTRIBUTING.md Initialize the development environment and build Granian. This command sets up the necessary tools for development. ```bash $ make build-dev ``` -------------------------------- ### Configure Multiple Static File Routes and Mounts Source: https://github.com/emmett-framework/granian/blob/master/README.md Use `--static-path-route` and `--static-path-mount` to serve multiple static file locations. Ensure the number of routes and mounts are equal. ```bash granian \ --static-path-route /static \ --static-path-mount assets/static \ --static-path-route /media \ --static-path-mount assets/media \ package:app ``` -------------------------------- ### Serve ASGI Application with Granian CLI Source: https://github.com/emmett-framework/granian/blob/master/README.md Command to serve a defined ASGI application using the Granian CLI. Replace 'main:app' with your application's module and variable name. ```bash $ granian --interface asgi main:app ``` -------------------------------- ### RSGI Application Initialization Source: https://github.com/emmett-framework/granian/blob/master/docs/spec/RSGI.md An RSGI application demonstrating the use of the `__rsgi_init__` method for synchronous and asynchronous initialization tasks during server startup. ```python class App: def __rsgi_init__(self, loop): some_sync_init_task() loop.run_until_complete(some_async_init_task()) async def __rsgi__(self, scope, protocol): # RSGI protocol handling ``` -------------------------------- ### Run Basic Test Suite Source: https://github.com/emmett-framework/granian/blob/master/CONTRIBUTING.md Execute the basic test suite for the current environment. CI will run the full suite upon pull request submission. ```bash $ make build-dev $ make test ``` -------------------------------- ### Serve WSGI Application with Granian CLI Source: https://github.com/emmett-framework/granian/blob/master/README.md Command to serve a defined WSGI application using the Granian CLI. Use '--interface wsgi' to specify the WSGI interface. ```bash $ granian --interface wsgi main:app ``` -------------------------------- ### Serve RSGI Application with Granian CLI Source: https://github.com/emmett-framework/granian/blob/master/README.md Command to serve a defined RSGI application using the Granian CLI. Specify the interface as 'rsgi'. ```bash $ granian --interface rsgi main:app ``` -------------------------------- ### Format and Lint Code Source: https://github.com/emmett-framework/granian/blob/master/CONTRIBUTING.md Apply code formatting and run linters on your changes. These commands ensure code consistency and quality. ```bash $ make format $ make lint ``` -------------------------------- ### Configure Git User Information Source: https://github.com/emmett-framework/granian/blob/master/CONTRIBUTING.md Set your global Git username and email. This is necessary for committing changes. ```bash $ git config --global user.name 'your name' $ git config --global user.email 'your email' ``` -------------------------------- ### Manage Embeddable Granian Server Lifecycle Source: https://github.com/emmett-framework/granian/blob/master/README.md Manage the lifecycle of the embeddable Granian server by spawning its serve task and interacting with its `stop` method. This allows for custom control within your application's event loop. ```python async def my_main(): server_task = asyncio.create_task(server.serve()) await my_logic() server.stop() await server_task ``` -------------------------------- ### Serve Specific File for Directory Listings Source: https://github.com/emmett-framework/granian/blob/master/README.md Use `--static-path-dir-to-file` to rewrite directory requests to a specific file, such as `index.html`. This behavior is enabled for all defined static paths. ```bash granian \ --static-path-route /docs \ --static-path-mount generated/docs \ --static-path-dir-to-file index.html \ package:app ``` -------------------------------- ### Clone Granian Fork Source: https://github.com/emmett-framework/granian/blob/master/CONTRIBUTING.md Clone your forked Granian repository locally. Replace 'your-username' with your GitHub username. ```bash $ git clone https://github.com/your-username/granian $ cd granian ``` -------------------------------- ### Wrap ASGI and WSGI Apps with Proxy Headers Source: https://github.com/emmett-framework/granian/blob/master/README.md Use these wrappers to modify the request scope based on proxy-forwarded headers like X-Forwarded-For and X-Forwarded-Proto. Ensure the proxy host is listed in `trusted_hosts` for security. ```python from granian.utils.proxies import wrap_asgi_with_proxy_headers, wrap_wsgi_with_proxy_headers async def my_asgi_app(scope, receive, send): ... def my_wsgi_app(environ, start_response): ... my_asgi_app = wrap_asgi_with_proxy_headers(my_asgi_app, trusted_hosts="1.2.3.4") my_wsgi_app = wrap_wsgi_with_proxy_headers(my_wsgi_app, trusted_hosts="1.2.3.4") ``` -------------------------------- ### Create Feature Branch Source: https://github.com/emmett-framework/granian/blob/master/CONTRIBUTING.md Create a new branch for your feature development, typically using the issue number and a brief description. ```bash $ git fetch origin $ git checkout -b 123-add-some-feature origin/master ``` -------------------------------- ### RSGI Application with ASGI Compatibility Source: https://github.com/emmett-framework/granian/blob/master/docs/spec/RSGI.md An RSGI application that also supports the ASGI protocol by implementing both `__call__` and `__rsgi__` methods. ```python class App: async def __call__(self, scope, receive, send): # ASGI protocol handling async def __rsgi__(self, scope, protocol): # RSGI protocol handling ``` -------------------------------- ### Transport Object Methods for Websockets Source: https://github.com/emmett-framework/granian/blob/master/docs/spec/RSGI.md Details the methods available on the transport object returned by `accept`. These include `receive` for incoming messages and `send_bytes`/`send_str` for outgoing messages. ```python coroutine receive() -> message coroutine send_bytes(bytes) coroutine send_str(str) ``` -------------------------------- ### HTTP Protocol Interface Methods Source: https://github.com/emmett-framework/granian/blob/master/docs/spec/RSGI.md Defines the awaitable methods for receiving request bodies and sending responses in the HTTP protocol. ```python coroutine __call__() -> body asynciterator __aiter__() -> body chunks coroutine client_disconnect() function response_empty(status, headers) function response_str(status, headers, body) function response_bytes(status, headers, body) function response_file(status, headers, file) function response_file_range(status, headers, file, start, end) function response_stream(status, headers) -> transport ``` -------------------------------- ### RSGI Application Cleanup Source: https://github.com/emmett-framework/granian/blob/master/docs/spec/RSGI.md An RSGI application demonstrating the use of the `__rsgi_del__` method for synchronous and asynchronous cleanup tasks during server shutdown. ```python class App: def __rsgi_del__(self, loop): some_sync_cleanup_task() loop.run_until_complete(some_async_cleanup_task()) async def __rsgi__(self, scope, protocol): # RSGI protocol handling ``` -------------------------------- ### Websocket Protocol Interface Methods Source: https://github.com/emmett-framework/granian/blob/master/docs/spec/RSGI.md Defines the core `accept` and `close` methods for the Websocket protocol interface. `accept` returns a transport object, and `close` takes a status code. ```python coroutine accept() -> transport function close(status) ``` -------------------------------- ### Websocket Protocol Interface Source: https://github.com/emmett-framework/granian/blob/master/docs/spec/RSGI.md The Websocket protocol object provides methods for applications to interact with websocket connections. This includes accepting new connections and closing existing ones. ```APIDOC ## Websocket Protocol Interface ### Description Provides methods for applications to manage websocket connections. ### Methods - `accept()`: An awaitable method that accepts an incoming websocket connection and returns a transport object. - `close(status)`: A method to close the websocket connection with a given status. ### Transport Object Methods - `receive()`: An awaitable method that returns a single incoming websocket message. - `send_bytes(bytes)`: An awaitable method to send outgoing messages as bytes. - `send_str(str)`: An awaitable method to send outgoing messages as strings. ### Incoming Message Format Incoming websocket messages are objects of the form `WebsocketMessage`: ```python class WebsocketMessage: kind: int data: Optional[Union[bytes, str]] ``` Where `kind` can be: - `0`: Websocket closed by client - `1`: Bytes message - `2`: String message ``` -------------------------------- ### RSGI Application Callable Source: https://github.com/emmett-framework/granian/blob/master/docs/spec/RSGI.md Defines the signature for an RSGI application. It must be an async callable that accepts a connection scope and a protocol object for communication. ```python coroutine application(scope, protocol) ``` -------------------------------- ### Stream Transport Methods Source: https://github.com/emmett-framework/granian/blob/master/docs/spec/RSGI.md Provides methods for sending data over a stream transport in the RSGI protocol. ```python coroutine send_bytes(bytes) coroutine send_str(str) ``` -------------------------------- ### HTTP Connection Scope Definition Source: https://github.com/emmett-framework/granian/blob/master/docs/spec/RSGI.md Defines the structure of the scope object for HTTP connections in RSGI, detailing attributes like protocol version, server/client addresses, and request details. ```python class Scope: proto: Literal['http'] = 'http' rsgi_version: str http_version: str server: str client: str scheme: str method: str path: str query_string: str headers: Mapping[str, str] authority: Optional[str] ``` -------------------------------- ### Websocket Incoming Message Structure Source: https://github.com/emmett-framework/granian/blob/master/docs/spec/RSGI.md Defines the structure of incoming Websocket messages in RSGI. The `WebsocketMessage` class includes a `kind` and `data` field. ```python class WebsocketMessage: kind: int data: Optional[Union[bytes, str]] ``` -------------------------------- ### WebSocket Scope Definition Source: https://github.com/emmett-framework/granian/blob/master/docs/spec/RSGI.md Defines the structure of the scope object for WebSocket connections in RSGI. ```python class Scope: proto: Literal['ws'] = 'ws' rsgi_version: str http_version: str server: str client: str scheme: str method: str path: str query_string: str headers: Mapping[str, str] authority: Optional[str] ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.