{"id":2523,"library":"granian","title":"Granian","description":"Granian is a high-performance HTTP server for Python applications, implemented in Rust and built upon the Hyper crate. It supports ASGI/3, RSGI, and WSGI interfaces, offering robust handling for HTTP/1, HTTP/2, and Websockets. The project aims to provide a single, performant dependency solution, avoiding the typical Gunicorn + Uvicorn + http-tools stack. It is actively maintained with regular patch and minor releases, compatible with Python 3.10 and above.","status":"active","version":"2.7.3","language":"en","source_language":"en","source_url":"https://github.com/emmett-framework/granian","tags":["http server","asgi","wsgi","rust","performance","websockets"],"install":[{"cmd":"pip install granian","lang":"bash","label":"Install Granian"}],"dependencies":[{"reason":"Used for the command-line interface (CLI) to run applications.","package":"click","optional":false}],"imports":[{"note":"This import is for embedding Granian programmatically within an application for advanced lifecycle management. It is currently considered experimental and only supports async protocols (ASGI/RSGI), not WSGI. Most users will interact with Granian via its command-line interface directly.","symbol":"Server","correct":"from granian.server.embed import Server"}],"quickstart":{"code":"# main.py\nasync def app(scope, receive, send):\n    assert scope['type'] == 'http'\n    await send({\n        'type': 'http.response.start',\n        'status': 200,\n        'headers': [\n            [b'content-type', b'text/plain'],\n        ],\n    })\n    await send({\n        'type': 'http.response.body',\n        'body': b'Hello, world!',\n    })\n\n# To run from your terminal (assuming main.py is in current directory):\n# granian --interface asgi main:app --port 8000","lang":"python","description":"Create an ASGI application in a file (e.g., `main.py`), then serve it using the `granian` command-line interface. This example starts Granian on `127.0.0.1:8000` serving the ASGI application `app` from `main.py`."},"warnings":[{"fix":"Upgrade Python to 3.10+.","message":"Granian dropped support for Python 3.9 and PyPy 3.9/3.10 starting from v2.6.0. Users on these versions must upgrade their Python environment to Python 3.10 or newer.","severity":"breaking","affected_versions":">=2.6.0"},{"fix":"Upgrade Granian to v2.7.1 or newer to ensure proper websocket disconnect event handling.","message":"Prior to v2.7.1, ASGI applications, particularly those using Django channels, might not reliably receive `websocket.disconnect` events after a server-initiated close, potentially leading to connection hangs.","severity":"gotcha","affected_versions":"<2.7.1"},{"fix":"Upgrade Granian to v2.7.1 or newer to resolve the thread panic issue.","message":"Versions prior to v2.7.1 could experience an occasional runtime thread panic (`Cannot drop pointer into Python heap without the thread being attached`) during websocket cleanup on shutdown.","severity":"gotcha","affected_versions":"<2.7.1"},{"fix":"Upgrade Granian to v2.5.6 or newer to ensure correct `PATH_INFO` handling.","message":"On WSGI applications, versions prior to v2.5.6 could have incorrect `PATH_INFO` values in the `environ` dictionary when the `--url-path-prefix` option was used. This could lead to incorrect routing or resource access.","severity":"gotcha","affected_versions":"<2.5.6"},{"fix":"Upgrade Granian to v2.5.5 or newer if experiencing startup issues on Python 3.14 with `forkserver`.","message":"On Unix systems, Granian v2.5.5 addressed an issue preventing startup on Python 3.14 when using the `forkserver` multiprocessing start method, by falling back to `spawn`.","severity":"gotcha","affected_versions":"<2.5.5"}],"env_vars":null,"last_verified":"2026-04-10T00:00:00.000Z","next_check":"2026-07-09T00:00:00.000Z"}