Metadata-Version: 2.4
Name: blunt
Version: 0.0.4
Summary: Lightweight ASGI framework for Python
Author-email: White NEFOR <n7for8572@gmail.com>
License: BSD-2-Clause
Project-URL: Homepage, https://github.com/ndugram/blunt
Project-URL: Documentation, https://ndugram.github.io/blunt
Project-URL: Repository, https://github.com/ndugram/blunt
Project-URL: Issues, https://github.com/ndugram/blunt/issues
Keywords: asgi,framework,web,http,async
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: anyio>=4.13.0
Requires-Dist: jinja2>=3.0.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: uvicorn>=0.42.0
Provides-Extra: dev
Requires-Dist: pydantic>=2.0.0; extra == "dev"
Requires-Dist: jinja2>=3.0.0; extra == "dev"
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
Requires-Dist: httpx>=0.24.0; extra == "dev"
Dynamic: license-file

<p align="center">
    <picture>
        <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/ndugram/blunt/main/docs/img/blunt_dark.svg" width="420px">
        <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/ndugram/blunt/main/docs/img/blunt.svg" width="420px">
        <img alt="blunt-logo" src="https://raw.githubusercontent.com/ndugram/blunt/main/docs/img/blunt.svg">
    </picture>
</p>
<p align="center">
    <em>✨ The little ASGI framework that shines. ✨</em>
</p>

---

[![Package version](https://badge.fury.io/py/blunt.svg)](https://pypi.python.org/pypi/blunt)
[![Supported Python Version](https://img.shields.io/pypi/pyversions/blunt.svg?color=%2334D058)](https://pypi.org/project/blunt)

---

**Documentation**: <a href="https://ndugram.github.io/blunt/" target="_blank">https://ndugram.github.io/blunt</a>
**Source Code**: <a href="https://github.com/ndugram/blunt" target="_blank">https://github.com/ndugram/blunt</a>

---

# Blunt

Blunt is a lightweight [ASGI][asgi] framework/toolkit, which is ideal for building async web services in Python.

It is production-ready, and gives you the following:

* A lightweight, low-complexity HTTP web framework.
* Auto-generated API documentation (Swagger UI & ReDoc).
* Middleware support (CORS, Timing, and more).
* Static files and template rendering.
* Path parameters and query string handling.
* Type hints and clean API.
* Few hard dependencies.
* Compatible with `asyncio` backends.

## Installation

```shell
$ pip install blunt
```

You'll also want to install an ASGI server, such as [uvicorn](https://www.uvicorn.org/):

```shell
$ pip install uvicorn
```

## Example

```python title="main.py"
from blunt import Blunt, Route
from blunt.responses import JSONResponse


async def homepage(request):
    return JSONResponse({'hello': 'world'})


routes = [
    Route("/", endpoint=homepage)
]

app = Blunt(debug=True, routes=routes)
```

Then run the application using Uvicorn:

```shell
$ uvicorn main:app
```

## Auto Documentation

Once running, visit:

* `/docs` — Swagger UI
* `/redoc` — ReDoc
* `/openapi.json` — OpenAPI schema

## Dependencies

Blunt requires `anyio`, and the following are optional:

* [`pydantic`][pydantic] - Required for data validation and response models.
* [`jinja2`][jinja2] - Required if you want to use templates.

## Framework or Toolkit

Blunt is designed to be used either as a complete framework, or as an ASGI toolkit. You can use any of its components independently.

```python
from blunt.responses import PlainTextResponse


async def app(scope, receive, send):
    assert scope['type'] == 'http'
    response = PlainTextResponse('Hello, world!')
    await response(scope, receive, send)
```

Run the `app` application in `example.py`:

```shell
$ uvicorn example:app
INFO: Started server process [11509]
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```

Run uvicorn with `--reload` to enable auto-reloading on code changes.

---

<p align="center"><i>Blunt is <a href="https://github.com/ndugram/blunt/blob/main/LICENSE">BSD licensed</a> code.<br/>Designed & crafted with care.</i></br>&mdash; ⭐️ &mdash;</p>

[asgi]: https://asgi.readthedocs.io/en/latest/
[pydantic]: https://docs.pydantic.dev/
[jinja2]: https://jinja.palletsprojects.com/
