Name | getserving JSON |
Version |
0.1.1a8
JSON |
| download |
home_page | None |
Summary | A powerful, dependency-injection-driven ASGI web framework for Python with first-class support for configuration management, type-safe routing, and extensible middleware. |
upload_time | 2025-09-19 22:35:41 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.13 |
license | MIT License Copyright (c) 2025 Zechariah Zimmerman Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
keywords |
api
asgi
framework
http
web
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# Serving: The Extensible Python Web Framework 🚀
> [!WARNING]
> Serving is currently in alpha and is NOT recommended for production use. APIs are subject to change.
Serving is a small ASGI web framework built on Starlette with first‑class dependency injection (Bevy), YAML configuration, typed routing, forms with CSRF, and themed error pages.
## ✨ Highlights
- ASGI/Starlette core with a minimal surface area
- Dependency Injection via Bevy (request‑scoped container)
- YAML configuration with typed `ConfigModel`s (including collections)
- Lightweight routing decorator; return‑type‑based responses
- Forms + CSRF with Jinja2 templates
- Themed error pages with dev‑mode details
- Simple CLI wrapper around Uvicorn
- Pluggable sessions with DI‑friendly access
- Static asset mount in dev compatible with `url_for('static', ...)`
## 🚀 Quick Start
### Install
```bash
pip install getserving[server]
```
### Minimal App
1) Router module
```python
# myapp/web.py
from serving.router import Router
from serving.types import PlainText, JSON, Jinja2
from serving.injectors import QueryParam
from serving import redirect
app = Router()
@app.route("/")
async def index() -> Jinja2:
return "home.html", {"message": "Hello from Serving"}
@app.route("/hello")
async def hello(name: QueryParam[str] = "world") -> PlainText:
return f"Hello, {name}!"
@app.route("/redirect")
async def go_home() -> PlainText:
redirect("/")
return "This will not be sent"
```
2) Template
```html
<!-- templates/home.html -->
<h1>{{ message }}</h1>
```
3) Configuration
```yaml
# serving.dev.yaml
environment: dev
auth:
credential_provider: myapp.auth:MyProvider
config:
csrf_secret: change-me-long-random-string
templates:
directory: templates
static:
mount: /static
directory: static
# In dev, assets are served by default; in other envs default is false.
# Explicitly enable serving in non-dev if desired:
# serve: true
routers:
- entrypoint: myapp.web:app
routes:
- path: "/"
- path: "/hello"
- path: "/redirect"
```
4) Run
```bash
serv -e dev --reload
```
Your app will be available at http://127.0.0.1:8000.
## 🗝️ Sessions
Serving supports pluggable session providers and a dict‑like `Session` mapping bound to each request.
Configure a provider in YAML:
```yaml
# serving.dev.yaml (add alongside `auth`/`routers`)
session:
session_provider: serving.session:InMemorySessionProvider
session_type: serving.session:Session # optional
config: {}
```
Use the session in routes:
```python
from serving.session import Session
from serving.injectors import SessionParam
@app.route("/whoami")
async def whoami(sess: Session) -> JSON:
return {"user": sess.get("user_id")}
@app.route("/feature")
async def feature(beta: SessionParam[bool] = False) -> JSON:
# Uses parameter name as key; default applies if key is missing
return {"beta": beta}
```
See the full guide: [Sessions](docs/sessions.md)
## 🧭 Return Types
- `PlainText` → PlainTextResponse
- `JSON` → JSONResponse
- `HTML` → HTMLResponse
- `Jinja2` → TemplateResponse (tuple of `template_name`, `context_dict`)
- Returning a Starlette `Response` is passed through as‑is
## 🔐 Authentication & Permissions
Configure an auth provider in YAML (`auth.credential_provider`). Serving calls `has_credentials(permissions)` before invoking a route; if denied, a themed 401 page is rendered. See [Authentication](docs/authentication.md) for the `CredentialProvider` protocol and examples.
## 🧾 Forms & CSRF
Use `serving.forms.Form` with Jinja2. When CSRF is enabled (default), templates must call `{{ csrf() }}`; invalid tokens are rejected by `CSRFMiddleware`. See [Forms & CSRF](docs/forms.md).
## 🎨 Error Pages & Theming
Customize error templates via the `theming` section in YAML. Dev mode can include extra details (stack traces, missing path). See [Error Handling & Theming](docs/error-handling.md).
## 🧰 CLI
```bash
serv [-d DIR] [-e ENV] [uvicorn options...]
```
- `-d, --working-directory DIR` — where your `serving.{env}.yaml` lives
- `-e, --env ENV` — choose environment (e.g., `dev`, `prod`)
- All other flags are passed to Uvicorn (e.g., `--reload`, `--host`, `--port`)
## 📚 Documentation
See the [docs/](docs/README.md) directory for detailed guides and references:
- [Getting Started](docs/getting-started.md) — install and minimal setup
- [Configuration](docs/configuration.md) — YAML layout, templates, theming, routers, auth
- [Routing](docs/routing.md) — router decorator, params, permissions
- [Dependency Injection](docs/dependency-injection.md) — Bevy DI and `ConfigModel`s
- [Forms & CSRF](docs/forms.md) — forms + CSRF
- [Error Handling](docs/error-handling.md) — exceptions and theming
- [Authentication](docs/authentication.md) — provider protocol and configuration
- [Middleware](docs/middleware.md) — default middleware stack
- [Response Helpers](docs/response.md) — `set_header`, `redirect`, etc.
- [CLI](docs/cli.md) — CLI flags and examples
- [Testing](docs/testing.md) — testing patterns
Also see the [demo/blog](demo/blog/README.md) demo for a runnable example.
## 🤝 Contributing
Contributions are welcome! Bug reports, feature suggestions, docs, and tests are appreciated. Please open an issue or pull request.
## 📄 License
MIT — see [LICENSE](LICENSE).
Raw data
{
"_id": null,
"home_page": null,
"name": "getserving",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.13",
"maintainer_email": "Zechariah Zimmerman <zzimmerman@8ly.com>",
"keywords": "api, asgi, framework, http, web",
"author": null,
"author_email": "Zechariah Zimmerman <zzimmerman@8ly.com>",
"download_url": "https://files.pythonhosted.org/packages/52/32/ab7fcf109b24b3ed02e0449c9b6790d73af8a792fd8af43379a4a486408a/getserving-0.1.1a8.tar.gz",
"platform": null,
"description": "# Serving: The Extensible Python Web Framework \ud83d\ude80\n\n> [!WARNING]\n> Serving is currently in alpha and is NOT recommended for production use. APIs are subject to change.\n\nServing is a small ASGI web framework built on Starlette with first\u2011class dependency injection (Bevy), YAML configuration, typed routing, forms with CSRF, and themed error pages.\n\n## \u2728 Highlights\n\n- ASGI/Starlette core with a minimal surface area\n- Dependency Injection via Bevy (request\u2011scoped container)\n- YAML configuration with typed `ConfigModel`s (including collections)\n- Lightweight routing decorator; return\u2011type\u2011based responses\n- Forms + CSRF with Jinja2 templates\n- Themed error pages with dev\u2011mode details\n- Simple CLI wrapper around Uvicorn\n- Pluggable sessions with DI\u2011friendly access\n- Static asset mount in dev compatible with `url_for('static', ...)`\n\n## \ud83d\ude80 Quick Start\n\n### Install\n\n```bash\npip install getserving[server]\n```\n\n### Minimal App\n\n1) Router module\n\n```python\n# myapp/web.py\nfrom serving.router import Router\nfrom serving.types import PlainText, JSON, Jinja2\nfrom serving.injectors import QueryParam\nfrom serving import redirect\n\napp = Router()\n\n@app.route(\"/\")\nasync def index() -> Jinja2:\n return \"home.html\", {\"message\": \"Hello from Serving\"}\n\n@app.route(\"/hello\")\nasync def hello(name: QueryParam[str] = \"world\") -> PlainText:\n return f\"Hello, {name}!\"\n\n@app.route(\"/redirect\")\nasync def go_home() -> PlainText:\n redirect(\"/\")\n return \"This will not be sent\"\n```\n\n2) Template\n\n```html\n<!-- templates/home.html -->\n<h1>{{ message }}</h1>\n```\n\n3) Configuration\n\n```yaml\n# serving.dev.yaml\nenvironment: dev\n\nauth:\n credential_provider: myapp.auth:MyProvider\n config:\n csrf_secret: change-me-long-random-string\n\ntemplates:\n directory: templates\n\nstatic:\n mount: /static\n directory: static\n # In dev, assets are served by default; in other envs default is false.\n # Explicitly enable serving in non-dev if desired:\n # serve: true\n\nrouters:\n - entrypoint: myapp.web:app\n routes:\n - path: \"/\"\n - path: \"/hello\"\n - path: \"/redirect\"\n```\n\n4) Run\n\n```bash\nserv -e dev --reload\n```\n\nYour app will be available at http://127.0.0.1:8000.\n\n## \ud83d\udddd\ufe0f Sessions\n\nServing supports pluggable session providers and a dict\u2011like `Session` mapping bound to each request.\n\nConfigure a provider in YAML:\n\n```yaml\n# serving.dev.yaml (add alongside `auth`/`routers`)\nsession:\n session_provider: serving.session:InMemorySessionProvider\n session_type: serving.session:Session # optional\n config: {}\n```\n\nUse the session in routes:\n\n```python\nfrom serving.session import Session\nfrom serving.injectors import SessionParam\n\n@app.route(\"/whoami\")\nasync def whoami(sess: Session) -> JSON:\n return {\"user\": sess.get(\"user_id\")}\n\n@app.route(\"/feature\")\nasync def feature(beta: SessionParam[bool] = False) -> JSON:\n # Uses parameter name as key; default applies if key is missing\n return {\"beta\": beta}\n```\n\nSee the full guide: [Sessions](docs/sessions.md)\n\n## \ud83e\udded Return Types\n\n- `PlainText` \u2192 PlainTextResponse\n- `JSON` \u2192 JSONResponse\n- `HTML` \u2192 HTMLResponse\n- `Jinja2` \u2192 TemplateResponse (tuple of `template_name`, `context_dict`)\n- Returning a Starlette `Response` is passed through as\u2011is\n\n## \ud83d\udd10 Authentication & Permissions\n\nConfigure an auth provider in YAML (`auth.credential_provider`). Serving calls `has_credentials(permissions)` before invoking a route; if denied, a themed 401 page is rendered. See [Authentication](docs/authentication.md) for the `CredentialProvider` protocol and examples.\n\n## \ud83e\uddfe Forms & CSRF\n\nUse `serving.forms.Form` with Jinja2. When CSRF is enabled (default), templates must call `{{ csrf() }}`; invalid tokens are rejected by `CSRFMiddleware`. See [Forms & CSRF](docs/forms.md).\n\n## \ud83c\udfa8 Error Pages & Theming\n\nCustomize error templates via the `theming` section in YAML. Dev mode can include extra details (stack traces, missing path). See [Error Handling & Theming](docs/error-handling.md).\n\n## \ud83e\uddf0 CLI\n\n```bash\nserv [-d DIR] [-e ENV] [uvicorn options...]\n```\n\n- `-d, --working-directory DIR` \u2014 where your `serving.{env}.yaml` lives\n- `-e, --env ENV` \u2014 choose environment (e.g., `dev`, `prod`)\n- All other flags are passed to Uvicorn (e.g., `--reload`, `--host`, `--port`)\n\n## \ud83d\udcda Documentation\n\nSee the [docs/](docs/README.md) directory for detailed guides and references:\n\n- [Getting Started](docs/getting-started.md) \u2014 install and minimal setup\n- [Configuration](docs/configuration.md) \u2014 YAML layout, templates, theming, routers, auth\n- [Routing](docs/routing.md) \u2014 router decorator, params, permissions\n- [Dependency Injection](docs/dependency-injection.md) \u2014 Bevy DI and `ConfigModel`s\n- [Forms & CSRF](docs/forms.md) \u2014 forms + CSRF\n- [Error Handling](docs/error-handling.md) \u2014 exceptions and theming\n- [Authentication](docs/authentication.md) \u2014 provider protocol and configuration\n- [Middleware](docs/middleware.md) \u2014 default middleware stack\n- [Response Helpers](docs/response.md) \u2014 `set_header`, `redirect`, etc.\n- [CLI](docs/cli.md) \u2014 CLI flags and examples\n- [Testing](docs/testing.md) \u2014 testing patterns\n\nAlso see the [demo/blog](demo/blog/README.md) demo for a runnable example.\n\n## \ud83e\udd1d Contributing\n\nContributions are welcome! Bug reports, feature suggestions, docs, and tests are appreciated. Please open an issue or pull request.\n\n## \ud83d\udcc4 License\n\nMIT \u2014 see [LICENSE](LICENSE).\n",
"bugtrack_url": null,
"license": "MIT License Copyright (c) 2025 Zechariah Zimmerman Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
"summary": "A powerful, dependency-injection-driven ASGI web framework for Python with first-class support for configuration management, type-safe routing, and extensible middleware.",
"version": "0.1.1a8",
"project_urls": {
"Changelog": "https://github.com/ZechCodes/Serving/blob/main/CHANGELOG.md",
"Documentation": "https://github.com/ZechCodes/Serving/tree/main/docs",
"Homepage": "https://github.com/ZechCodes/Serving",
"Issues": "https://github.com/ZechCodes/Serving/issues",
"Repository": "https://github.com/ZechCodes/Serving"
},
"split_keywords": [
"api",
" asgi",
" framework",
" http",
" web"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "57d06e566b05b9849e7f36fabe1072ef484ded47a3e351dcaa6767826f80bd04",
"md5": "0b4a30e0afd759837cadbf33e88eebce",
"sha256": "a0af155ceeabb8f3dab023c1b84ec0366f7707f9b41b31526421023977f003de"
},
"downloads": -1,
"filename": "getserving-0.1.1a8-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0b4a30e0afd759837cadbf33e88eebce",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.13",
"size": 30508,
"upload_time": "2025-09-19T22:35:40",
"upload_time_iso_8601": "2025-09-19T22:35:40.468083Z",
"url": "https://files.pythonhosted.org/packages/57/d0/6e566b05b9849e7f36fabe1072ef484ded47a3e351dcaa6767826f80bd04/getserving-0.1.1a8-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "5232ab7fcf109b24b3ed02e0449c9b6790d73af8a792fd8af43379a4a486408a",
"md5": "f5cca3443f9dab617ea547596f21fb77",
"sha256": "baa0244587b79cc0c1f52549a48185b1a063f94841673f7cd96de7de15f58d6c"
},
"downloads": -1,
"filename": "getserving-0.1.1a8.tar.gz",
"has_sig": false,
"md5_digest": "f5cca3443f9dab617ea547596f21fb77",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.13",
"size": 66895,
"upload_time": "2025-09-19T22:35:41",
"upload_time_iso_8601": "2025-09-19T22:35:41.783409Z",
"url": "https://files.pythonhosted.org/packages/52/32/ab7fcf109b24b3ed02e0449c9b6790d73af8a792fd8af43379a4a486408a/getserving-0.1.1a8.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-19 22:35:41",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "ZechCodes",
"github_project": "Serving",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "getserving"
}