fastapi-jwt-harmony


Namefastapi-jwt-harmony JSON
Version 0.1.2 PyPI version JSON
download
home_pageNone
SummaryFastAPI JWT authentication library with Pydantic integration - bringing harmony to your auth flow
upload_time2025-07-14 17:28:04
maintainerNone
docs_urlNone
authorNone
requires_python>=3.11
licenseNone
keywords authentication fastapi fastapi-jwt harmony jwt pydantic
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # FastAPI JWT Harmony ๐ŸŽต

[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
[![FastAPI](https://img.shields.io/badge/FastAPI-0.68+-green.svg)](https://fastapi.tiangolo.com/)
[![PyPI version](https://img.shields.io/pypi/v/fastapi-jwt-harmony.svg)](https://pypi.org/project/fastapi-jwt-harmony/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Code Quality](https://img.shields.io/badge/code%20quality-A+-green.svg)](https://github.com/astral-sh/ruff)

A modern, type-safe JWT authentication library for FastAPI with **Pydantic integration** - bringing harmony to your auth flow! ๐ŸŽถ

## ๐Ÿ”‘ Key Features

- ๐Ÿ”’ **Type-safe JWT authentication** with full Pydantic model support
- ๐Ÿš€ **FastAPI dependency injection** - automatic JWT validation
- ๐Ÿ“ **Multiple token locations** - headers, cookies, or both
- ๐Ÿ›ก๏ธ **CSRF protection** for cookie-based authentication
- ๐ŸŒ **WebSocket support** with dedicated authentication methods
- ๐Ÿ‘ค **User claims as Pydantic models** - strongly typed user data
- ๐Ÿšซ **Token denylist/blacklist** support for logout functionality
- ๐Ÿ” **Asymmetric algorithms** support (RS256, ES256, etc.)
- โœ… **100% test coverage** with comprehensive test suite

## ๐Ÿš€ Quick Start

### Installation

```bash
pip install fastapi-jwt-harmony
```

For asymmetric algorithm support:
```bash
pip install fastapi-jwt-harmony[asymmetric]
```

### Basic Example

```python
from fastapi import FastAPI, Depends
from pydantic import BaseModel
from fastapi_jwt_harmony import JWTHarmony, JWTHarmonyDep

app = FastAPI()

# Define your user model
class User(BaseModel):
    id: str
    username: str
    email: str

# Configure JWT (simple way with dict)
JWTHarmony.configure(
    User,
    {
        "authjwt_secret_key": "your-secret-key",  # pragma: allowlist secret
        "authjwt_token_location": {"headers", "cookies"}  # Support both
    }
)

# Or use JWTHarmonyConfig for advanced configuration
# from fastapi_jwt_harmony import JWTHarmonyConfig
# JWTHarmony.configure(
#     User,
#     JWTHarmonyConfig(
#         authjwt_secret_key="your-secret-key",  # pragma: allowlist secret
#         authjwt_token_location={"headers", "cookies"}
#     )
# )

@app.post("/login")
def login(Authorize: JWTHarmony[User] = Depends()):
    # Authenticate user (your logic here)
    user = User(id="123", username="john", email="john@example.com")

    # Create tokens
    access_token = Authorize.create_access_token(user_claims=user)
    refresh_token = Authorize.create_refresh_token(user_claims=user)

    # Set cookies (optional)
    Authorize.set_access_cookies(access_token)
    Authorize.set_refresh_cookies(refresh_token)

    return {"access_token": access_token}

@app.get("/protected")
def protected_route(Authorize: JWTHarmony[User] = Depends(JWTHarmonyDep)):
    # JWT automatically validated by JWTHarmonyDep
    current_user = Authorize.user_claims  # Typed User model!
    return {"user": current_user, "message": f"Hello {current_user.username}!"}
```

## ๐Ÿ“ฆ Dependencies Overview

FastAPI JWT Harmony provides several dependency types for different authentication needs:

```python
from fastapi_jwt_harmony import (
    JWTHarmonyDep,      # Requires valid access token
    JWTHarmonyOptional, # Optional JWT validation
    JWTHarmonyRefresh,  # Requires valid refresh token
    JWTHarmonyFresh,    # Requires fresh access token
    JWTHarmonyBare,     # No automatic validation
)

@app.get("/public")
def public_endpoint(Authorize: JWTHarmony[User] = Depends(JWTHarmonyOptional)):
    if Authorize.user_claims:
        return {"message": f"Hello {Authorize.user_claims.username}!"}
    return {"message": "Hello anonymous user!"}

@app.post("/sensitive-action")
def sensitive_action(Authorize: JWTHarmony[User] = Depends(JWTHarmonyFresh)):
    # Requires fresh token (just logged in)
    return {"message": "Sensitive action performed"}
```

## ๐Ÿช Cookie Authentication

Enable secure cookie-based authentication with CSRF protection:

```python
from fastapi import Response

JWTHarmony.configure(
    User,
    {
        "authjwt_secret_key": "your-secret-key",  # pragma: allowlist secret
        "authjwt_token_location": {"cookies"},
        "authjwt_cookie_csrf_protect": True,
        "authjwt_cookie_secure": True,  # HTTPS only
        "authjwt_cookie_samesite": "strict"
    }
)

@app.post("/login")
def login(response: Response, Authorize: JWTHarmony[User] = Depends()):
    user = User(id="123", username="john", email="john@example.com")
    access_token = Authorize.create_access_token(user_claims=user)

    # Set secure cookies
    Authorize.set_access_cookies(access_token, response)
    return {"message": "Logged in successfully"}

@app.post("/logout")
def logout(response: Response, Authorize: JWTHarmony[User] = Depends(JWTHarmonyDep)):
    Authorize.unset_jwt_cookies(response)
    return {"message": "Logged out successfully"}
```

## ๐ŸŒ WebSocket Authentication

Authenticate WebSocket connections with dedicated methods:

```python
from fastapi import WebSocket, Query
from fastapi_jwt_harmony import JWTHarmonyWS, JWTHarmonyWebSocket

@app.websocket("/ws")
async def websocket_endpoint(
    websocket: WebSocket,
    token: str = Query(...),
    Authorize: JWTHarmonyWS = Depends(JWTHarmonyWebSocket)
):
    await websocket.accept()
    try:
        # Validate JWT token
        Authorize.jwt_required(token)
        user = Authorize.user_claims

        await websocket.send_text(f"Hello {user.username}!")
    except Exception as e:
        await websocket.send_text(f"Authentication failed: {str(e)}")
        await websocket.close()
```

## ๐Ÿšซ Token Denylist (Logout)

Implement secure logout with token blacklisting:

```python
# In-memory denylist (use Redis in production)
denylist = set()

def check_if_token_revoked(jwt_payload: dict) -> bool:
    jti = jwt_payload.get("jti")
    return jti in denylist

# Configure with denylist callback
JWTHarmony.configure(
    User,
    {
        "authjwt_secret_key": "your-secret-key",  # pragma: allowlist secret
        "authjwt_denylist_enabled": True,
        "authjwt_denylist_token_checks": {"access", "refresh"}
    },
    denylist_callback=check_if_token_revoked
)

@app.post("/logout")
def logout(Authorize: JWTHarmony[User] = Depends(JWTHarmonyDep)):
    jti = Authorize.get_jti()
    denylist.add(jti)  # Add to denylist
    return {"message": "Successfully logged out"}
```

## โš™๏ธ Configuration Options

Comprehensive configuration with sensible defaults:

```python
from datetime import timedelta

JWTHarmonyConfig(
    # Core settings
    authjwt_secret_key="your-secret-key",           # Required for HS256  # pragma: allowlist secret
    authjwt_algorithm="HS256",                      # JWT algorithm
    authjwt_token_location={"headers"},             # Where to look for tokens

    # Token expiration
    authjwt_access_token_expires=timedelta(minutes=15),
    authjwt_refresh_token_expires=timedelta(days=30),

    # Headers
    authjwt_header_name="Authorization",
    authjwt_header_type="Bearer",

    # Cookies
    authjwt_cookie_secure=False,                    # Set True for HTTPS
    authjwt_cookie_csrf_protect=True,               # CSRF protection
    authjwt_cookie_samesite="strict",

    # Asymmetric keys (for RS256, ES256, etc.)
    authjwt_private_key=None,                       # For signing
    authjwt_public_key=None,                        # For verification

    # Denylist
    authjwt_denylist_enabled=False,
    authjwt_denylist_token_checks={"access", "refresh"},

    # Validation
    authjwt_decode_leeway=0,                        # Clock skew tolerance
    authjwt_decode_audience=None,                   # Expected audience
    authjwt_decode_issuer=None,                     # Expected issuer
)
```

## ๐Ÿ” Asymmetric Algorithms

Support for RS256, ES256, and other asymmetric algorithms:

```python
# Generate keys (example)
private_key = """-----BEGIN PRIVATE KEY-----  # pragma: allowlist secret
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7...
-----END PRIVATE KEY-----"""  # pragma: allowlist secret

public_key = """-----BEGIN PUBLIC KEY-----  # pragma: allowlist secret
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu7...
-----END PUBLIC KEY-----"""  # pragma: allowlist secret

JWTHarmony.configure(
    User,
    JWTHarmonyConfig(
        authjwt_algorithm="RS256",
        authjwt_private_key=private_key,  # For signing tokens  # pragma: allowlist secret
        authjwt_public_key=public_key,    # For verifying tokens  # pragma: allowlist secret
    )
)
```

## ๐Ÿงช Testing

Run the comprehensive test suite:

```bash
# Install development dependencies
uv sync --dev

# Run tests
uv run pytest

# Run with coverage
uv run pytest --cov=fastapi_jwt_harmony
```

## ๐Ÿ› ๏ธ Development

```bash
# Clone the repository
git clone https://github.com/ivolnistov/fastapi-jwt-harmony.git
cd fastapi-jwt-harmony

# Install with development dependencies
uv sync --dev

# Run tests
uv run pytest

# Run linting
uv run ruff check src/
uv run mypy src/fastapi_jwt_harmony
uv run pylint src/fastapi_jwt_harmony
```

## ๐Ÿ“Š Project Status

- โœ… **111 tests passing** - Comprehensive test coverage
- โœ… **Type-safe** - Full mypy compatibility
- โœ… **Modern Python** - Supports Python 3.11+
- โœ… **Production ready** - Used in production applications

## ๐Ÿค Contributing

Contributions are welcome! Please:

1. Fork the repository
2. Create a feature branch
3. Add tests for new functionality
4. Ensure all tests pass
5. Submit a pull request

## ๐Ÿ“„ License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## ๐Ÿ™ Acknowledgments

- **FastAPI** for the amazing web framework
- **Pydantic** for data validation and settings management
- **PyJWT** for JWT implementation
- **Original fastapi-jwt-auth** for inspiration

---

**Made with โค๏ธ for the FastAPI community**

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "fastapi-jwt-harmony",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.11",
    "maintainer_email": "Ilya Volnistov <i.volnistov@gaijin.team>",
    "keywords": "authentication, fastapi, fastapi-jwt, harmony, jwt, pydantic",
    "author": null,
    "author_email": "Ilya Volnistov <i.volnistov@gaijin.team>",
    "download_url": "https://files.pythonhosted.org/packages/9a/5f/e2cc9b17c18246ca5c368616029e619b03fc260ee322c132f081812452b9/fastapi_jwt_harmony-0.1.2.tar.gz",
    "platform": null,
    "description": "# FastAPI JWT Harmony \ud83c\udfb5\n\n[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)\n[![FastAPI](https://img.shields.io/badge/FastAPI-0.68+-green.svg)](https://fastapi.tiangolo.com/)\n[![PyPI version](https://img.shields.io/pypi/v/fastapi-jwt-harmony.svg)](https://pypi.org/project/fastapi-jwt-harmony/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Code Quality](https://img.shields.io/badge/code%20quality-A+-green.svg)](https://github.com/astral-sh/ruff)\n\nA modern, type-safe JWT authentication library for FastAPI with **Pydantic integration** - bringing harmony to your auth flow! \ud83c\udfb6\n\n## \ud83d\udd11 Key Features\n\n- \ud83d\udd12 **Type-safe JWT authentication** with full Pydantic model support\n- \ud83d\ude80 **FastAPI dependency injection** - automatic JWT validation\n- \ud83d\udccd **Multiple token locations** - headers, cookies, or both\n- \ud83d\udee1\ufe0f **CSRF protection** for cookie-based authentication\n- \ud83c\udf10 **WebSocket support** with dedicated authentication methods\n- \ud83d\udc64 **User claims as Pydantic models** - strongly typed user data\n- \ud83d\udeab **Token denylist/blacklist** support for logout functionality\n- \ud83d\udd10 **Asymmetric algorithms** support (RS256, ES256, etc.)\n- \u2705 **100% test coverage** with comprehensive test suite\n\n## \ud83d\ude80 Quick Start\n\n### Installation\n\n```bash\npip install fastapi-jwt-harmony\n```\n\nFor asymmetric algorithm support:\n```bash\npip install fastapi-jwt-harmony[asymmetric]\n```\n\n### Basic Example\n\n```python\nfrom fastapi import FastAPI, Depends\nfrom pydantic import BaseModel\nfrom fastapi_jwt_harmony import JWTHarmony, JWTHarmonyDep\n\napp = FastAPI()\n\n# Define your user model\nclass User(BaseModel):\n    id: str\n    username: str\n    email: str\n\n# Configure JWT (simple way with dict)\nJWTHarmony.configure(\n    User,\n    {\n        \"authjwt_secret_key\": \"your-secret-key\",  # pragma: allowlist secret\n        \"authjwt_token_location\": {\"headers\", \"cookies\"}  # Support both\n    }\n)\n\n# Or use JWTHarmonyConfig for advanced configuration\n# from fastapi_jwt_harmony import JWTHarmonyConfig\n# JWTHarmony.configure(\n#     User,\n#     JWTHarmonyConfig(\n#         authjwt_secret_key=\"your-secret-key\",  # pragma: allowlist secret\n#         authjwt_token_location={\"headers\", \"cookies\"}\n#     )\n# )\n\n@app.post(\"/login\")\ndef login(Authorize: JWTHarmony[User] = Depends()):\n    # Authenticate user (your logic here)\n    user = User(id=\"123\", username=\"john\", email=\"john@example.com\")\n\n    # Create tokens\n    access_token = Authorize.create_access_token(user_claims=user)\n    refresh_token = Authorize.create_refresh_token(user_claims=user)\n\n    # Set cookies (optional)\n    Authorize.set_access_cookies(access_token)\n    Authorize.set_refresh_cookies(refresh_token)\n\n    return {\"access_token\": access_token}\n\n@app.get(\"/protected\")\ndef protected_route(Authorize: JWTHarmony[User] = Depends(JWTHarmonyDep)):\n    # JWT automatically validated by JWTHarmonyDep\n    current_user = Authorize.user_claims  # Typed User model!\n    return {\"user\": current_user, \"message\": f\"Hello {current_user.username}!\"}\n```\n\n## \ud83d\udce6 Dependencies Overview\n\nFastAPI JWT Harmony provides several dependency types for different authentication needs:\n\n```python\nfrom fastapi_jwt_harmony import (\n    JWTHarmonyDep,      # Requires valid access token\n    JWTHarmonyOptional, # Optional JWT validation\n    JWTHarmonyRefresh,  # Requires valid refresh token\n    JWTHarmonyFresh,    # Requires fresh access token\n    JWTHarmonyBare,     # No automatic validation\n)\n\n@app.get(\"/public\")\ndef public_endpoint(Authorize: JWTHarmony[User] = Depends(JWTHarmonyOptional)):\n    if Authorize.user_claims:\n        return {\"message\": f\"Hello {Authorize.user_claims.username}!\"}\n    return {\"message\": \"Hello anonymous user!\"}\n\n@app.post(\"/sensitive-action\")\ndef sensitive_action(Authorize: JWTHarmony[User] = Depends(JWTHarmonyFresh)):\n    # Requires fresh token (just logged in)\n    return {\"message\": \"Sensitive action performed\"}\n```\n\n## \ud83c\udf6a Cookie Authentication\n\nEnable secure cookie-based authentication with CSRF protection:\n\n```python\nfrom fastapi import Response\n\nJWTHarmony.configure(\n    User,\n    {\n        \"authjwt_secret_key\": \"your-secret-key\",  # pragma: allowlist secret\n        \"authjwt_token_location\": {\"cookies\"},\n        \"authjwt_cookie_csrf_protect\": True,\n        \"authjwt_cookie_secure\": True,  # HTTPS only\n        \"authjwt_cookie_samesite\": \"strict\"\n    }\n)\n\n@app.post(\"/login\")\ndef login(response: Response, Authorize: JWTHarmony[User] = Depends()):\n    user = User(id=\"123\", username=\"john\", email=\"john@example.com\")\n    access_token = Authorize.create_access_token(user_claims=user)\n\n    # Set secure cookies\n    Authorize.set_access_cookies(access_token, response)\n    return {\"message\": \"Logged in successfully\"}\n\n@app.post(\"/logout\")\ndef logout(response: Response, Authorize: JWTHarmony[User] = Depends(JWTHarmonyDep)):\n    Authorize.unset_jwt_cookies(response)\n    return {\"message\": \"Logged out successfully\"}\n```\n\n## \ud83c\udf10 WebSocket Authentication\n\nAuthenticate WebSocket connections with dedicated methods:\n\n```python\nfrom fastapi import WebSocket, Query\nfrom fastapi_jwt_harmony import JWTHarmonyWS, JWTHarmonyWebSocket\n\n@app.websocket(\"/ws\")\nasync def websocket_endpoint(\n    websocket: WebSocket,\n    token: str = Query(...),\n    Authorize: JWTHarmonyWS = Depends(JWTHarmonyWebSocket)\n):\n    await websocket.accept()\n    try:\n        # Validate JWT token\n        Authorize.jwt_required(token)\n        user = Authorize.user_claims\n\n        await websocket.send_text(f\"Hello {user.username}!\")\n    except Exception as e:\n        await websocket.send_text(f\"Authentication failed: {str(e)}\")\n        await websocket.close()\n```\n\n## \ud83d\udeab Token Denylist (Logout)\n\nImplement secure logout with token blacklisting:\n\n```python\n# In-memory denylist (use Redis in production)\ndenylist = set()\n\ndef check_if_token_revoked(jwt_payload: dict) -> bool:\n    jti = jwt_payload.get(\"jti\")\n    return jti in denylist\n\n# Configure with denylist callback\nJWTHarmony.configure(\n    User,\n    {\n        \"authjwt_secret_key\": \"your-secret-key\",  # pragma: allowlist secret\n        \"authjwt_denylist_enabled\": True,\n        \"authjwt_denylist_token_checks\": {\"access\", \"refresh\"}\n    },\n    denylist_callback=check_if_token_revoked\n)\n\n@app.post(\"/logout\")\ndef logout(Authorize: JWTHarmony[User] = Depends(JWTHarmonyDep)):\n    jti = Authorize.get_jti()\n    denylist.add(jti)  # Add to denylist\n    return {\"message\": \"Successfully logged out\"}\n```\n\n## \u2699\ufe0f Configuration Options\n\nComprehensive configuration with sensible defaults:\n\n```python\nfrom datetime import timedelta\n\nJWTHarmonyConfig(\n    # Core settings\n    authjwt_secret_key=\"your-secret-key\",           # Required for HS256  # pragma: allowlist secret\n    authjwt_algorithm=\"HS256\",                      # JWT algorithm\n    authjwt_token_location={\"headers\"},             # Where to look for tokens\n\n    # Token expiration\n    authjwt_access_token_expires=timedelta(minutes=15),\n    authjwt_refresh_token_expires=timedelta(days=30),\n\n    # Headers\n    authjwt_header_name=\"Authorization\",\n    authjwt_header_type=\"Bearer\",\n\n    # Cookies\n    authjwt_cookie_secure=False,                    # Set True for HTTPS\n    authjwt_cookie_csrf_protect=True,               # CSRF protection\n    authjwt_cookie_samesite=\"strict\",\n\n    # Asymmetric keys (for RS256, ES256, etc.)\n    authjwt_private_key=None,                       # For signing\n    authjwt_public_key=None,                        # For verification\n\n    # Denylist\n    authjwt_denylist_enabled=False,\n    authjwt_denylist_token_checks={\"access\", \"refresh\"},\n\n    # Validation\n    authjwt_decode_leeway=0,                        # Clock skew tolerance\n    authjwt_decode_audience=None,                   # Expected audience\n    authjwt_decode_issuer=None,                     # Expected issuer\n)\n```\n\n## \ud83d\udd10 Asymmetric Algorithms\n\nSupport for RS256, ES256, and other asymmetric algorithms:\n\n```python\n# Generate keys (example)\nprivate_key = \"\"\"-----BEGIN PRIVATE KEY-----  # pragma: allowlist secret\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7...\n-----END PRIVATE KEY-----\"\"\"  # pragma: allowlist secret\n\npublic_key = \"\"\"-----BEGIN PUBLIC KEY-----  # pragma: allowlist secret\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu7...\n-----END PUBLIC KEY-----\"\"\"  # pragma: allowlist secret\n\nJWTHarmony.configure(\n    User,\n    JWTHarmonyConfig(\n        authjwt_algorithm=\"RS256\",\n        authjwt_private_key=private_key,  # For signing tokens  # pragma: allowlist secret\n        authjwt_public_key=public_key,    # For verifying tokens  # pragma: allowlist secret\n    )\n)\n```\n\n## \ud83e\uddea Testing\n\nRun the comprehensive test suite:\n\n```bash\n# Install development dependencies\nuv sync --dev\n\n# Run tests\nuv run pytest\n\n# Run with coverage\nuv run pytest --cov=fastapi_jwt_harmony\n```\n\n## \ud83d\udee0\ufe0f Development\n\n```bash\n# Clone the repository\ngit clone https://github.com/ivolnistov/fastapi-jwt-harmony.git\ncd fastapi-jwt-harmony\n\n# Install with development dependencies\nuv sync --dev\n\n# Run tests\nuv run pytest\n\n# Run linting\nuv run ruff check src/\nuv run mypy src/fastapi_jwt_harmony\nuv run pylint src/fastapi_jwt_harmony\n```\n\n## \ud83d\udcca Project Status\n\n- \u2705 **111 tests passing** - Comprehensive test coverage\n- \u2705 **Type-safe** - Full mypy compatibility\n- \u2705 **Modern Python** - Supports Python 3.11+\n- \u2705 **Production ready** - Used in production applications\n\n## \ud83e\udd1d Contributing\n\nContributions are welcome! Please:\n\n1. Fork the repository\n2. Create a feature branch\n3. Add tests for new functionality\n4. Ensure all tests pass\n5. Submit a pull request\n\n## \ud83d\udcc4 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## \ud83d\ude4f Acknowledgments\n\n- **FastAPI** for the amazing web framework\n- **Pydantic** for data validation and settings management\n- **PyJWT** for JWT implementation\n- **Original fastapi-jwt-auth** for inspiration\n\n---\n\n**Made with \u2764\ufe0f for the FastAPI community**\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "FastAPI JWT authentication library with Pydantic integration - bringing harmony to your auth flow",
    "version": "0.1.2",
    "project_urls": {
        "Bug Tracker": "https://github.com/fastapi-jwt-harmony/fastapi-jwt-harmony/issues",
        "Changelog": "https://github.com/fastapi-jwt-harmony/fastapi-jwt-harmony/blob/main/CHANGELOG.md",
        "Documentation": "https://github.com/fastapi-jwt-harmony/fastapi-jwt-harmony/blob/main/docs/README.md",
        "Homepage": "https://github.com/fastapi-jwt-harmony/fastapi-jwt-harmony",
        "Repository": "https://github.com/fastapi-jwt-harmony/fastapi-jwt-harmony"
    },
    "split_keywords": [
        "authentication",
        " fastapi",
        " fastapi-jwt",
        " harmony",
        " jwt",
        " pydantic"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b8fed8165f2e5265ed63275832061708e921fb95ddaee329bb55d8683f300fe5",
                "md5": "62aa1fbc91016f5246375412c138bd1b",
                "sha256": "9409496058bd1f800c1bcc11c0e55c8f5c4a5d159fa42bb4ab16cbd3026199fe"
            },
            "downloads": -1,
            "filename": "fastapi_jwt_harmony-0.1.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "62aa1fbc91016f5246375412c138bd1b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.11",
            "size": 23345,
            "upload_time": "2025-07-14T17:28:03",
            "upload_time_iso_8601": "2025-07-14T17:28:03.295644Z",
            "url": "https://files.pythonhosted.org/packages/b8/fe/d8165f2e5265ed63275832061708e921fb95ddaee329bb55d8683f300fe5/fastapi_jwt_harmony-0.1.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "9a5fe2cc9b17c18246ca5c368616029e619b03fc260ee322c132f081812452b9",
                "md5": "5b32a4d993d620643ef667396693d14f",
                "sha256": "78dc3797049b46fe3a6227c5cd1d8f1c7ba0d9125e02f64264c9a617ae0327c8"
            },
            "downloads": -1,
            "filename": "fastapi_jwt_harmony-0.1.2.tar.gz",
            "has_sig": false,
            "md5_digest": "5b32a4d993d620643ef667396693d14f",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.11",
            "size": 46170,
            "upload_time": "2025-07-14T17:28:04",
            "upload_time_iso_8601": "2025-07-14T17:28:04.728963Z",
            "url": "https://files.pythonhosted.org/packages/9a/5f/e2cc9b17c18246ca5c368616029e619b03fc260ee322c132f081812452b9/fastapi_jwt_harmony-0.1.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-14 17:28:04",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "fastapi-jwt-harmony",
    "github_project": "fastapi-jwt-harmony",
    "github_not_found": true,
    "lcname": "fastapi-jwt-harmony"
}
        
Elapsed time: 1.88873s