Metadata-Version: 2.4
Name: quart-httpauth
Version: 0.0.1
Summary: Basic, Digest and Token HTTP authentication for Quart routes
Project-URL: Homepage, https://github.com/lymagics/quart_httpauth
Project-URL: Bug Tracker, https://github.com/lymagics/quart_httpauth/issues
Author: quart_httpauth contributors
License: MIT
License-File: LICENSE
Keywords: async,authentication,basic,bearer,digest,http,quart,token
Classifier: Environment :: Web Environment
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Security
Requires-Python: >=3.9
Requires-Dist: quart>=0.19
Provides-Extra: dev
Requires-Dist: black; extra == 'dev'
Requires-Dist: coverage; extra == 'dev'
Requires-Dist: hypercorn; extra == 'dev'
Requires-Dist: hypothesis; extra == 'dev'
Requires-Dist: language-tool-python; extra == 'dev'
Requires-Dist: mypy; extra == 'dev'
Requires-Dist: pyhamcrest; extra == 'dev'
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: pytest-asyncio; extra == 'dev'
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: pytest-fail-slow; extra == 'dev'
Requires-Dist: pytest-randomly; extra == 'dev'
Requires-Dist: pytest-repeat; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Provides-Extra: docs
Requires-Dist: furo; extra == 'docs'
Requires-Dist: sphinx; extra == 'docs'
Description-Content-Type: text/markdown

# quart-httpauth

Basic, Digest and Token (Bearer) HTTP authentication for [Quart](https://github.com/pallets/quart)
routes — an **async-native port of [Flask-HTTPAuth](https://github.com/miguelgrinberg/flask-httpauth)**.

The public API mirrors Flask-HTTPAuth: class names, constructor arguments,
decorator names, and callback contracts are preserved. Existing Flask-HTTPAuth
code transfers by switching `flask` imports to `quart` and `flask_httpauth` to
`quart_httpauth`. The one intentional change is that the request pipeline and
every callback are awaited — your verify/role/error callbacks may be written as
either `def` **or** `async def`.

## Installation

```
pip install quart-httpauth
```

The distribution name is `quart-httpauth`; the import name is `quart_httpauth`.

## Quickstart — Basic auth

```python
from quart import Quart
from quart_httpauth import HTTPBasicAuth
from werkzeug.security import check_password_hash, generate_password_hash

app = Quart(__name__)
auth = HTTPBasicAuth()

users = {
    "susan": generate_password_hash("hunter2"),
}


@auth.verify_password
async def verify_password(username, password):
    if username in users and check_password_hash(users[username], password):
        return username


@app.route("/")
@auth.login_required
async def index():
    return f"Hello, {auth.current_user()}!"
```

## Token (Bearer) auth

```python
from quart import Quart
from quart_httpauth import HTTPTokenAuth

app = Quart(__name__)
auth = HTTPTokenAuth(scheme="Bearer")

tokens = {"secret-token-1": "john"}


@auth.verify_token
async def verify_token(token):
    return tokens.get(token)


@app.route("/")
@auth.login_required
async def index():
    return f"Hello, {auth.current_user()}!"
```

A custom header works too: `HTTPTokenAuth(header="X-API-Key")` — there the entire
header value is treated as the token with no scheme prefix.

## Roles and optional auth

```python
@auth.get_user_roles
async def get_user_roles(user):
    return user.roles


@app.route("/admin")
@auth.login_required(role="admin")
async def admin():
    return "for admins only"


@app.route("/maybe")
@auth.login_required(optional=True)
async def maybe():
    user = auth.current_user()
    return f"Hello, {user or 'anonymous'}!"
```

## Multiple schemes on one route

```python
from quart_httpauth import HTTPBasicAuth, HTTPTokenAuth, MultiAuth

basic = HTTPBasicAuth()
token = HTTPTokenAuth()
multi = MultiAuth(basic, token)   # HTTPMultiAuth is an alias


@app.route("/")
@multi.login_required
async def index():
    return f"Hello, {multi.current_user()}!"
```

See [`examples/`](examples/) for runnable apps.

## Differences from Flask-HTTPAuth

- The deprecated `hash_password` callback, the `username()` accessor, and the
  legacy `get_password`-as-Basic-credential path are **not** ported. Use
  `verify_password` for Basic auth. `get_password` is retained for
  `HTTPDigestAuth`, where it is the primary, non-deprecated mechanism.
- The per-request user is stored on `g.quart_httpauth_user`.

## License

MIT. Ported from Flask-HTTPAuth (also MIT) by Miguel Grinberg.
