# FastAPI JWT Harmony ๐ต
[](https://www.python.org/downloads/)
[](https://fastapi.tiangolo.com/)
[](https://pypi.org/project/fastapi-jwt-harmony/)
[](https://opensource.org/licenses/MIT)
[](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[](https://www.python.org/downloads/)\n[](https://fastapi.tiangolo.com/)\n[](https://pypi.org/project/fastapi-jwt-harmony/)\n[](https://opensource.org/licenses/MIT)\n[](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"
}