MCPcopy Create free account
hub / github.com/emmett-framework/granian

github.com/emmett-framework/granian @v2.7.9

Chat with this repo
repository ↗ · DeepWiki ↗ · release v2.7.9 ↗ · + Follow
807 symbols 2,002 edges 87 files 1 documented · 0% 3 cross-repo links updated 14d agov2.7.9 · 2026-07-03★ 5,49041 open issues

Browse by type

Functions 638 Types & classes 135 Endpoints 34
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

granian

The Rust HTTP server for Python


Granian is a Rust HTTP server for Python applications built on top of Hyper and Tokio.

Rationale

The main reasons behind Granian design are:

  • Have a single, correct HTTP implementation, supporting versions 1, 2 (and eventually 3)
  • Provide a single package for several platforms
  • Avoid the usual Gunicorn + uvicorn + http-tools dependency composition on unix systems
  • Provide stable performance when compared to existing alternatives

Adopting Granian would thus be a good choice when:

  • wanting a modern, single dependency to serve both ASGI and WSGI applications
  • looking for the most performant way to serve your Python application under HTTP/2
  • you need great concurrency capabilities, especially with websockets
  • you care about throughput more than everything else

On the other hand, Granian won't be the ideal option if:

  • you want a pure Python solution
  • you need advanced debugging features
  • your application relies on trio or gevent
  • you're looking for ASGI extensions not (yet) implemented

Features

  • Supports ASGI/3, RSGI and WSGI interface applications
  • HTTP/1 and HTTP/2 protocols
  • HTTPS and mTLS
  • Websockets
  • Direct static files serving
  • ASGI pathsend extension

Quickstart

You can install Granian using pip:

$ pip install granian

ASGI

Create an application in your main.py:

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!',
    })

and serve it using Granian CLI:

$ granian --interface asgi main:app

RSGI

Create an application your main.py:

async def app(scope, proto):
    assert scope.proto == 'http'

    proto.response_str(
        status=200,
        headers=[
            ('content-type', 'text/plain')
        ],
        body="Hello, world!"
    )

and serve it using Granian CLI:

$ granian --interface rsgi main:app

WSGI

Create an application your main.py:

def app(environ, start_response):
    start_response('200 OK', [('content-type', 'text/plain')])
    return [b"Hello, world!"]

and serve it using Granian CLI:

$ granian --interface wsgi main:app

Extra dependencies

Mind that Granian also provides several extra dependencies you might be interested into, in particular:

  • dotenv (allows to load environment files)
  • pname (allows to customize processes' names)
  • reload (adds reload on changes functionality)
  • rloop
  • uvloop
  • winloop

You can combine the above extras to suit your needs, eg:

$ pip install granian[pname,uvloop]

For further information, check the options below.

Options

You can check all the options provided by Granian with the --help command:

``` $ granian --help Usage: granian [OPTIONS] APP

APP Application target to serve. [required]

Options: --host TEXT Host address to bind to [env var: GRANIAN_HOST; default: (127.0.0.1)] --port INTEGER Port to bind to. [env var: GRANIAN_PORT; default: 8000] --uds PATH Unix Domain Socket to bind to. [env var: GRANIAN_UDS] --uds-permissions OCTAL INTEGER Unix Domain Socket file permissions [env var: GRANIAN_UDS_PERMISSIONS] --interface [asgi|asginl|rsgi|wsgi] Application interface type [env var: GRANIAN_INTERFACE; default: (rsgi)] --http [auto|1|2] HTTP version [env var: GRANIAN_HTTP; default: (auto)] --ws / --no-ws Enable websockets handling [env var: GRANIAN_WEBSOCKETS; default: (enabled)] --workers INTEGER RANGE Number of worker processes [env var: GRANIAN_WORKERS; default: 1; x>=1] --blocking-threads INTEGER RANGE Number of blocking threads (per worker) [env var: GRANIAN_BLOCKING_THREADS; x>=1] --blocking-threads-idle-timeout DURATION The maximum amount of time in seconds (or a human-readable duration) an idle blocking thread will be kept alive [env var: GRANIAN_BLOCKING_THREADS_IDLE_TIMEOUT; default: 30; 5<=x<=600] --runtime-threads INTEGER RANGE Number of runtime threads (per worker) [env var: GRANIAN_RUNTIME_THREADS; default: 1; x>=1] --runtime-blocking-threads INTEGER RANGE Number of runtime I/O blocking threads (per worker) [env var: GRANIAN_RUNTIME_BLOCKING_THREADS; x>=1] --runtime-mode [auto|mt|st] Runtime mode to use (single/multi threaded) [env var: GRANIAN_RUNTIME_MODE; default: (auto)] --loop [auto|asyncio|rloop|uvloop|winloop] Event loop implementation [env var: GRANIAN_LOOP; default: (auto)] --task-impl [asyncio|rust] Async task implementation to use [env var: GRANIAN_TASK_IMPL; default: (asyncio)] --backlog INTEGER RANGE Maximum number of connections to hold in backlog (globally) [env var: GRANIAN_BACKLOG; default: 1024; x>=128] --backpressure INTEGER RANGE Maximum number of requests to process concurrently (per worker) [env var: GRANIAN_BACKPRESSURE; default: (backlog/workers); x>=1] --http1-buffer-size INTEGER RANGE Sets the maximum buffer size for HTTP/1 connections [env var: GRANIAN_HTTP1_BUFFER_SIZE; default: 417792; x>=8192] --http1-header-read-timeout INTEGER RANGE Sets a timeout (in milliseconds) to read headers [env var: GRANIAN_HTTP1_HEADER_READ_TIMEOUT; default: 30000; 1<=x<=60000] --http1-keep-alive / --no-http1-keep-alive Enables or disables HTTP/1 keep-alive [env var: GRANIAN_HTTP1_KEEP_ALIVE; default: (enabled)] --http1-pipeline-flush / --no-http1-pipeline-flush Aggregates HTTP/1 flushes to better support pipelined responses (experimental) [env var: GRANIAN_HTTP1_PIPELINE_FLUSH; default: (disabled)] --http2-adaptive-window / --no-http2-adaptive-window Sets whether to use an adaptive flow control for HTTP2 [env var: GRANIAN_HTTP2_ADAPTIVE_WINDOW; default: (disabled)] --http2-initial-connection-window-size INTEGER RANGE Sets the max connection-level flow control for HTTP2 [env var: GRANIAN_HTTP2_INITIAL_C ONNECTION_WINDOW_SIZE; default: 1048576; x>=1024] --http2-initial-stream-window-size INTEGER RANGE Sets the SETTINGS_INITIAL_WINDOW_SIZE option for HTTP2 stream-level flow control [env var: GRANIAN_HTTP2_INITIAL_STREAM_WINDOW_SIZE; default: 1048576; x>=1024] --http2-keep-alive-interval INTEGER RANGE Sets an interval (in milliseconds) for HTTP2 Ping frames should be sent to keep a connection alive [env var: GRANIAN_HTTP2_KEEP_ALIVE_INTERVAL; 1<=x<=60000] --http2-keep-alive-timeout DURATION Sets a timeout (in seconds or a human- readable duration) for receiving an acknowledgement of the HTTP2 keep-alive ping [env var: GRANIAN_HTTP2_KEEP_ALIVE_TIMEOUT; default: 20; x>=1] --http2-max-concurrent-streams INTEGER RANGE Sets the SETTINGS_MAX_CONCURRENT_STREAMS option for HTTP2 connections [env var: GRANIAN_HTTP2_MAX_CONCURRENT_STREAMS; default: 200; x>=10] --http2-max-frame-size INTEGER RANGE Sets the maximum frame size to use for HTTP2 [env var: GRANIAN_HTTP2_MAX_FRAME_SIZE; default: 16384; x>=1024] --http2-max-headers-size INTEGER RANGE Sets the max size of received header frames [env var: GRANIAN_HTTP2_MAX_HEADERS_SIZE; default: 16777216; x>=1] --http2-max-send-buffer-size INTEGER RANGE Set the maximum write buffer size for each HTTP/2 stream [env var: GRANIAN_HTTP2_MAX_SEND_BUFFER_SIZE; default: 409600; x>=1024] --log / --no-log Enable logging [env var: GRANIAN_LOG_ENABLED; default: (enabled)] --log-level [critical|error|warning|warn|info|debug|notset] Log level [env var: GRANIAN_LOG_LEVEL; default: (info)] --log-config FILE Logging configuration file (json) [env var: GRANIAN_LOG_CONFIG] --access-log / --no-access-log Enable access log [env var: GRANIAN_LOG_ACCESS_ENABLED; default: (disabled)] --access-log-fmt TEXT Access log format [env var: GRANIAN_LOG_ACCESS_FMT] --ssl-certificate FILE SSL certificate file [env var: GRANIAN_SSL_CERTIFICATE] --ssl-keyfile FILE SSL key file (PKCS#8 format only) [env var: GRANIAN_SSL_KEYFILE] --ssl-keyfile-password TEXT SSL key password [env var: GRANIAN_SSL_KEYFILE_PASSWORD] --ssl-protocol-min [tls1.2|tls1.3] Set the minimum supported protocol for SSL connections. [env var: GRANIAN_SSL_PROTOCOL_MIN; default: (tls1.3)] --ssl-ca FILE Root SSL cerificate file for client verification [env var: GRANIAN_SSL_CA] --ssl-crl FILE SSL CRL file(s) [env var: GRANIAN_SSL_CRL] --ssl-client-verify / --no-ssl-client-verify Verify clients SSL certificates [env var: GRANIAN_SSL_CLIENT_VERIFY; default: (disabled)] --url-path-prefix TEXT URL path prefix the app is mounted on [env var: GRANIAN_URL_PATH_PREFIX] --respawn-failed-workers / --no-respawn-failed-workers Enable workers respawn on unexpected exit [env var: GRANIAN_RESPAWN_FAILED_WORKERS; default: (disabled)] --respawn-interval FLOAT The number of seconds to sleep between workers respawn [env var: GRANIAN_RESPAWN_INTERVAL; default: 3.5] --rss-sample-interval DURATION The sample rate in seconds (or a human- readable duration) for the resource monitor [env var: GRANIAN_RSS_SAMPLE_INTERVAL; default: 30; 1<=x<=300] --rss-samples INTEGER RANGE The number of consecutive samples to consider a worker over resource limit [env var: GRANIAN_RSS_SAMPLES; default: 1; x>=1] --workers-lifetime DURATION The maximum

Extension points exported contracts — how you extend this code

browse all types & interfaces →

Core symbols most depended-on inside this repo

browse all functions →

Shape

Method 331
Function 307
Class 118
Route 34
Enum 11
Interface 6

Languages

Python58%
Rust42%

Modules by API surface

granian/server/common.py46 symbols
src/workers.rs36 symbols
src/callbacks.rs35 symbols
granian/server/embed.py33 symbols
granian/server/mp.py26 symbols
src/metrics.rs25 symbols
src/runtime.rs24 symbols
granian/server/mt.py24 symbols
src/rsgi/types.rs23 symbols
granian/_futures.py23 symbols
src/rsgi/io.rs22 symbols
granian/rsgi.py22 symbols

For agents

$ claude mcp add granian \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page