{"id":25896328,"url":"https://github.com/patx/micropie","last_synced_at":"2026-01-28T01:12:09.786Z","repository":{"id":273159663,"uuid":"918862197","full_name":"patx/micropie","owner":"patx","description":"MicroPie is an ultra-micro ASGI Python web framework that gets out of your way.","archived":false,"fork":false,"pushed_at":"2026-01-12T01:02:51.000Z","size":5086,"stargazers_count":220,"open_issues_count":0,"forks_count":6,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-12T05:47:42.151Z","etag":null,"topics":["api","asgi","asgi-framework","asgi-middleware","asgi-toolkit","asyncio","cherrypy","framework","http","jinja2","json","microframework","multipart-formdata","python","python-web-framework","rest","session-management","uvicorn","web","websockets"],"latest_commit_sha":null,"homepage":"https://patx.github.io/micropie","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/patx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-01-19T03:51:39.000Z","updated_at":"2026-01-12T01:02:54.000Z","dependencies_parsed_at":"2025-01-19T04:30:12.405Z","dependency_job_id":"899aa8e0-dcd7-435d-9311-4b1a7288a3d2","html_url":"https://github.com/patx/micropie","commit_stats":null,"previous_names":["patx/micropie"],"tags_count":45,"template":false,"template_full_name":null,"purl":"pkg:github/patx/micropie","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patx%2Fmicropie","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patx%2Fmicropie/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patx%2Fmicropie/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patx%2Fmicropie/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/patx","download_url":"https://codeload.github.com/patx/micropie/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patx%2Fmicropie/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28831237,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T23:29:49.665Z","status":"ssl_error","status_checked_at":"2026-01-27T23:25:58.379Z","response_time":168,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","asgi","asgi-framework","asgi-middleware","asgi-toolkit","asyncio","cherrypy","framework","http","jinja2","json","microframework","multipart-formdata","python","python-web-framework","rest","session-management","uvicorn","web","websockets"],"created_at":"2025-03-02T23:00:46.278Z","updated_at":"2026-01-28T01:12:09.780Z","avatar_url":"https://github.com/patx.png","language":"Python","funding_links":[],"categories":["Micro-frameworks"],"sub_categories":["Async"],"readme":"[![Logo](https://patx.github.io/micropie/logo.png)](https://patx.github.io/micropie)\n\n[![License](https://img.shields.io/github/license/patx/micropie)](LICENSE)\n[![PyPI](https://img.shields.io/pypi/v/micropie)](https://pypi.org/project/micropie/)\n[![PyPI Downloads](https://static.pepy.tech/badge/micropie)](https://pepy.tech/projects/micropie)\n\n## **Introduction**\n**MicroPie** is a fast, lightweight, modern Python web framework built on ASGI for asynchronous web applications. Designed for flexibility and simplicity, it enables high-concurrency web apps with built-in WebSockets, session management, middleware, lifecycle event handling, and optional template rendering. Extensible for integration with ASGI-compatible tools like [python-socketio](https://python-socketio.readthedocs.io/en/stable/server.html#running-as-an-asgi-application) and [ServeStatic](https://archmonger.github.io/ServeStatic/latest/asgi/), it’s inspired by CherryPy and licensed under the BSD 3-Clause License.\n\n### **Key Features**\n- 📬 **Routing:** Automatic mapping of URLs to functions with support for dynamic and query parameters.\n- 🔑 **Sessions:** Simple, pluggable session management using cookies.\n- 🎨 **Templates:** Jinja2, if installed, for rendering dynamic HTML pages.\n- 🚧 **Middleware:** Support for custom request middleware enabling functions like rate limiting, authentication, logging, and more.\n- 💨 **Real-Time Communication:** Built-in WebSocket support for real-time, bidirectional communication.\n- ☀️ **ASGI-Powered:** Built with asynchronous support for modern web servers like Uvicorn, Hypercorn, and Daphne, enabling high concurrency.\n- ☁️ **Lightweight Design:** Only optional dependencies for flexibility and faster development/deployment.\n- 👶 **Lifecycle Events:** ASGI lifespan event handling for startup and shutdown tasks (e.g., database initialization).\n- 🏁 **Competitive Performance:** Check out how MicroPie compares to other popular ASGI frameworks below!\n\n### **Useful Links**\n- **Homepage**: [patx.github.io/micropie](https://patx.github.io/micropie)\n- **Official Documentation**: [micropie.readthedocs.io](https://micropie.readthedocs.io/)\n- **PyPI Page**: [pypi.org/project/MicroPie](https://pypi.org/project/MicroPie/)\n- **GitHub Project**: [github.com/patx/micropie](https://github.com/patx/micropie)\n- **File Issue/Request**: [github.com/patx/micropie/issues](https://github.com/patx/micropie/issues)\n- **Example Applications**: [github.com/patx/micropie/tree/main/examples](https://github.com/patx/micropie/tree/main/examples)\n- **Introduction Lightning Talk**: [Introduction to MicroPie on YouTube](https://www.youtube.com/watch?v=BzkscTLy1So)\n\n### Latest Release Notes\nView the latest release notes [here](https://github.com/patx/micropie/blob/main/docs/release_notes.md). It is useful to check release notes each time a new version of MicroPie is published. Any breaking changes (rare, but do happen) also appear here.\n\n## **Installing MicroPie**\n\n### **Installation**\nInstall MicroPie with **standard** optional dependencies via pip:\n```bash\npip install micropie[standard]\n```\nThis will install MicroPie along with `jinja2` for template rendering and `multipart` for parsing multipart form data.\n\nIf you would like to install **all** optional dependencies (everything from `standard` plus `orjson` and `uvicorn`) you can run:\n```bash\npip install micropie[all]\n```\n\n### **Minimal Setup**\nYou can also install MicroPie without ANY dependencies via pip:\n```bash\npip install micropie\n```\nFor an ultra-minimalistic approach, download the standalone script (development version):\n\n[micropie.py](https://raw.githubusercontent.com/patx/micropie/refs/heads/main/micropie.py)\n\nPlace it in your project directory, and you are good to go. Note that `jinja2` must be installed separately to use the `_render_template` method and/or `multipart` for handling file data (the `_parse_multipart` method), but this *is* optional and you can use MicroPie without them. To install the optional dependencies use:\n```bash\npip install jinja2 multipart\n```\n\nBy default MicroPie will use the `json` library from Python's standard library. If you need faster performance you can use `orjson`. MicroPie *will* use `orjson` *if installed* by default. If it is not installed, MicroPie will fallback to `json`. This means with or without `orjson` installed MicroPie will still handle JSON requests/responses the same. To install `orjson` and take advantage of its performance, use:\n```bash\npip install orjson\n```\n\n### **Install an ASGI Web Server**\nIn order to test and deploy your apps you will need an ASGI web server like Uvicorn, Hypercorn, or Daphne.\n\nIf you installed `micropie[all]` Uvicorn *should* be ready to use. If you didn't install all of MicroPie's optional dependencies, use:\n```bash\npip install uvicorn\n```\n\n## **Getting Started**\n\n### **Create Your First ASGI App**\n\nSave the following as `app.py`:\n```python\nfrom micropie import App\n\nclass MyApp(App):\n    async def index(self):\n        return \"Welcome to MicroPie ASGI.\"\n\napp = MyApp()\n```\nRun the server with:\n```bash\nuvicorn app:app\n```\nAccess your app at [http://127.0.0.1:8000](http://127.0.0.1:8000).\n\n## **Core Features**\n\n### **Route Handlers**\n\nMicroPie's route handlers map URLs to methods in your `App` subclass, handling HTTP requests with flexible parameter mapping and response formats.\n\n#### **Key Points**\n- **Automatic Mapping**: URLs map to method names (e.g., `/greet` → `greet`, `/` → `index`).\n- **Private Methods**: Methods starting with `_` (e.g., `_private_method`) are private and inaccessible via URLs, returning 404. **Security Note**: Use `_` for sensitive methods to prevent external access.\n- **Parameters**: Automatically populated from:\n  - Path segments (e.g., `/greet/Alice` → `name=\"Alice\"`).\n  - Query strings (e.g., `?name=Alice`).\n  - Form data (POST/PUT/PATCH).\n  - Session data (`self.request.session`).\n  - File uploads (`self.request.files`).\n  - Default values in method signatures.\n- **HTTP Methods**: Handlers support all methods (GET, POST, etc.). Check `self.request.method` to handle specific methods.\n- **Responses**:\n  - String, bytes, or JSON-serializable object.\n  - Tuple: `(status_code, body)` or `(status_code, body, headers)`.\n  - Sync/async generator for streaming.\n\n#### **Advanced Usage**\n- **Custom Routing**: Use middleware for explicit routing (see [examples/middleware](https://github.com/patx/micropie/tree/main/examples/middleware) and [examples/explicit_routing](https://github.com/patx/micropie/tree/main/examples/explicit_routing)).\n- **Errors**: Auto-handled 404/400; customize via middleware.\n- **Dynamic Params**: Use `*args` for multiple path parameters.\n\n#### **Flexible HTTP Routing for GET Requests**\nMicroPie automatically maps URLs to methods within your `App` class. Routes can be defined as either synchronous or asynchronous functions, offering good flexibility.\n\nFor GET requests, pass data through query strings or URL path segments, automatically mapped to method arguments.\n```python\nclass MyApp(App):\n    async def greet(self, name=\"Guest\"):\n        return f\"Hello, {name}!\"\n\n    async def hello(self):\n        name = self.request.query_params.get(\"name\", [None])[0]\n        return f\"Hello {name}!\"\n```\n**Access:**\n- [http://127.0.0.1:8000/greet?name=Alice](http://127.0.0.1:8000/greet?name=Alice) returns `Hello, Alice!`, same as [http://127.0.0.1:8000/greet/Alice](http://127.0.0.1:8000/greet/Alice) returns `Hello, Alice!`.\n- [http://127.0.0.1:8000/hello/Alice](http://127.0.0.1:8000/hello/Alice) returns a `500 Internal Server Error` because it is expecting [http://127.0.0.1:8000/hello?name=Alice](http://127.0.0.1:8000/hello?name=Alice), which returns `Hello Alice!`\n\n#### **Flexible HTTP POST Request Handling**\nMicroPie also supports handling form data submitted via HTTP POST requests. Form data is automatically mapped to method arguments. It is able to handle default values and raw/JSON POST data:\n```python\nclass MyApp(App):\n    async def submit_default_values(self, username=\"Anonymous\"):\n        return f\"Form submitted by: {username}\"\n\n    async def submit_catch_all(self):\n        username = self.request.body_params.get(\"username\", [\"Anonymous\"])[0]\n        return f\"Submitted by: {username}\"\n```\n\nBy default, MicroPie's route handlers can accept any request method, it's up to you how to handle any incoming requests! You can check the request method (and a number of other things specific to the current request state) in the handler with `self.request.method`. You can see how to handle POST JSON data at [examples/json_api](https://github.com/patx/micropie/tree/main/examples/json_api).\n\n### **Lifecycle Event Handling**\nMicroPie supports ASGI lifespan events, allowing you to register asynchronous handlers for application startup and shutdown. This is useful for tasks like initializing database connections or cleaning up resources.\n\n#### **Key Points**\n- **Startup Handlers**: Register async handlers to run during `lifespan.startup` using `app.startup_handlers.append(handler)`.\n- **Shutdown Handlers**: Register async handlers to run during `lifespan.shutdown` using `app.shutdown_handlers.append(handler)`.\n- **Error Handling**: Errors during startup or shutdown are caught and reported via `lifespan.startup.failed` or `lifespan.shutdown.failed` events.\n- **Use Cases**: Ideal for setting up database pools, external service connections, or logging systems on startup, and closing them on shutdown.\n\n#### **Example**\n```python\nfrom micropie import App\n\nasync def setup_db():\n    print(\"Setting up database...\")\n    # DB init code here\n    print(\"Database setup complete!\")\n\nasync def close_db():\n    print(\"Closing database...\")\n    # DB close code here\n    print(\"Database closed!\")\n\nclass MyApp(App):\n    async def index(self):\n        return \"Welcome to MicroPie ASGI.\"\n\napp = MyApp()\napp.startup_handlers.append(setup_db)\napp.shutdown_handlers.append(close_db)\n```\nOn startup, the `setup_db` method initializes the database connection. On shutdown (e.g., Ctrl+C), the `close_db` method closes it.\n\n### Real-Time Communication with WebSockets and Socket.IO\nMicroPie includes built-in support for WebSocket connections. WebSocket routes are defined in your App subclass using methods prefixed with `ws_`, mirroring the simplicity of MicroPie's HTTP routing. For example, a method named `ws_chat` handles WebSocket connections at `ws://\u003chost\u003e/chat`.\n\n#### MicroPie’s WebSocket support allows you to:\n- Define WebSocket handlers with the same intuitive automatic routing as HTTP (e.g., `/chat` maps to `ws_chat` method).\n- Access query parameters, path parameters, and session data in WebSocket handlers, consistent with HTTP requests.\n- Manage WebSocket connections using the WebSocket class, which provides methods like `accept`, `receive_text`, `send_text`, and `close`.\n\nCheck out a basic example:\n```python\nfrom micropie import App\n\nclass Root(App):\n    async def ws_echo(self, ws):\n        await ws.accept()\n        while True:\n            msg = await ws.receive_text()\n            await ws.send_text(f\"Echo: {msg}\")\n\napp = Root()\n```\n\n#### Use Socket.IO for Advanced Real-Time Features\nIf you want more advanced real-time features like automatic reconnection, broadcasting, or fallbacks (e.g., polling), you can integrate Socket.IO with your MicroPie app using Uvicorn as the server. See [examples/socketio](https://github.com/patx/micropie/tree/main/examples/socketio) for integration instructions and examples.\n\n### **Jinja2 Template Rendering**\nDynamic HTML generation is supported via Jinja2. This happens asynchronously using Python's `asyncio` library, so make sure to use `async` and `await` with this method.\n\n#### **`app.py`**\n```python\nclass MyApp(App):\n    async def index(self):\n        return await self._render_template(\"index.html\", title=\"Welcome\", message=\"Hello from MicroPie!\")\n```\n\n#### **`templates/index.html`**\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n\u003chead\u003e\n    \u003cmeta charset=\"UTF-8\"\u003e\n    \u003ctitle\u003e{{ title }}\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    \u003ch1\u003e{{ message }}\u003c/h1\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n### **Static File Serving**\nMicroPie does not natively support static files, if you need them, you can easily implement it in your application code or integrate dedicated libraries like **ServeStatic** or **Starlette’s StaticFiles** alongside Uvicorn to handle async static file serving. Check out [examples/static_content](https://github.com/patx/micropie/tree/main/examples/static_content) to see this in action.\n\n### **Streaming Responses**\nSupport for streaming responses makes it easy to send data in chunks.\n\n```python\nclass MyApp(App):\n    async def stream(self):\n        async def generator():\n            for i in range(1, 6):\n                yield f\"Chunk {i}\\n\"\n        return generator()\n```\n\n### **Sessions and Cookies**\nBuilt-in session handling simplifies state management:\n\n```python\nclass MyApp(App):\n    async def index(self):\n        if \"visits\" not in self.request.session:\n            self.request.session[\"visits\"] = 1\n        else:\n            self.request.session[\"visits\"] += 1\n        return f\"You have visited {self.request.session['visits']} times.\"\n```\n\nYou also can use the `SessionBackend` class to create your own session backend. You can see an example of this in [examples/sessions](https://github.com/patx/micropie/tree/main/examples/sessions).\n\n### **Middleware**\nMicroPie allows you to create pluggable middleware to hook into the request lifecycle. Take a look at a trivial example using `HttpMiddleware` to send console messages before and after the request is processed. Check out [examples/middleware](https://github.com/patx/micropie/tree/main/examples/middleware) to see more.\n```python\nfrom micropie import App, HttpMiddleware\n\nclass MiddlewareExample(HttpMiddleware):\n    async def before_request(self, request):\n        print(\"Hook before request\")\n\n    async def after_request(self, request, status_code, response_body, extra_headers):\n        print(\"Hook after request\")\n\nclass Root(App):\n    async def index(self):\n        print(\"Hello, World!\")\n        return \"Hello, World!\"\n\napp = Root()\napp.middlewares.append(MiddlewareExample())\n```\n\nMiddleware provides an easy and **reusable** way to extend the MicroPie framework. We can do things such as rate limiting, checking for max upload size in multipart requests, **explicit routing**, CSRF protection, and more.\n\nMicroPie apps can be deployed using any ASGI server. For example, using Uvicorn if our application is saved as `app.py` and our `App` subclass is assigned to the `app` variable we can run it with:\n```bash\nuvicorn app:app --workers 4 --port 8000\n```\n\n## **Learn by Examples**\nThe best way to get an idea of how MicroPie works is to see it in action! Check out the [examples folder](https://github.com/patx/micropie/tree/main/examples) for more advanced usage, including:\n- Template rendering\n- Custom HTTP request handling\n- File uploads\n- Serving static content\n- Session usage\n- JSON Requests and Responses\n- Socket.io Integration\n- Async Streaming\n- Middleware including explicit routing and more\n- Form handling and POST requests\n- WebSockets\n- Lifecycle event handling\n- URL shortener app ([live demo @ erd.sh](https://erd.sh/))\n- And more\n\n## **Comparisons**\n\n### **Features vs Other Popular Frameworks**\n| Feature             | MicroPie      | Flask        | CherryPy   | Bottle       | Django       | FastAPI         |\n|---------------------|---------------|--------------|------------|--------------|--------------|-----------------|\n| **Routing**         | Automatic     | Manual       | Automatic  | Manual       | Views        | Manual          |\n| **Template Engine** | Jinja2 (Opt.) | Jinja2       | Plugin     | SimpleTpl    | Django       | Jinja2          |\n| **Middleware**      | Yes           | Yes          | Yes        | Yes          | Yes          | Yes             |\n| **Session Handling**| Plugin        | Plugin       | Built-in   | Plugin       | Built-in     | Plugin          |\n| **Async Support**   | Yes           | No           | No         | No           | Yes          | Yes             |\n| **Built-in Server** | No            | No           | Yes        | Yes          | Yes          | No              |\n| **Lifecycle Events**| Yes           | No           | Yes        | No           | Yes          | Yes             |\n\n## Benchmark Results\n\nThe table below summarizes the performance of various ASGI frameworks based on a 15-second `wrk` test with 4 threads and 64 connections, measuring a simple \"hello world\" JSON response. [Learn More](https://gist.github.com/patx/39e846ed66bead3e42270ff193db35f8).\n\n| Framework  | Requests/sec | Avg Latency (ms) | Max Latency (ms) | Transfer/sec (MB) | Total Requests | Data Read (MB) |\n|------------|--------------|------------------|------------------|-------------------|----------------|----------------|\n| Starlette  | 21615.41     | 3.00             | 90.34            | 2.93              | 324374         | 43.93          |\n| MicroPie   | 18519.02     | 3.53             | 105.00           | 2.84              | 277960         | 42.68          |\n| FastAPI    | 8899.40      | 7.22             | 56.09            | 1.21              | 133542         | 18.08          |\n| Quart      | 8601.40      | 7.52             | 117.99           | 1.17              | 129089         | 17.60          |\n\n## **Suggestions or Feedback?**\nWe welcome suggestions, bug reports, and pull requests!\n- File issues or feature requests [here](https://github.com/patx/micropie/issues).\n- Security issues that should not be public, email `harrisonerd [at] gmail.com`.\n\n## **Rock Your Powered by MicroPie Badge**\n[![Powered by MicroPie](https://img.shields.io/badge/MicroPie-CC0000?style=for-the-badge\u0026logo=python\u0026logoColor=white)](https://patx.github.io/micropie)\n\nYou can add a Powered by MicroPie badge to your projects README using the following markdown:\n```\n[![Powered by MicroPie](https://img.shields.io/badge/MicroPie-CC0000?style=for-the-badge\u0026logo=python\u0026logoColor=white)](https://patx.github.io/micropie)\n```\n\n© 2025 Harrison Erd\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatx%2Fmicropie","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpatx%2Fmicropie","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatx%2Fmicropie/lists"}