Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:

strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]

steps:
- name: Checkout code
Expand All @@ -60,8 +60,6 @@ jobs:
- name: Install Poetry
uses: snok/install-poetry@v1
with:
# Keep Poetry pinned because the latest Poetry bootstrap dependencies can
# use Python 3.10-only APIs while this workflow still tests Python 3.9.
version: "2.2.1"
virtualenvs-create: true
virtualenvs-in-project: true
Expand Down
2 changes: 1 addition & 1 deletion .ruff.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
line-length = 100
target-version = "py39"
target-version = "py310"

[lint]
select = [
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

### 1. Install the SDK

_This library requires Python 3.9.2+._
_This library requires Python 3.10+._

```shell
pip install auth0-fastapi-api
Expand Down
10 changes: 5 additions & 5 deletions fastapi_plugin/fast_api_client.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Callable, Optional, Union
from collections.abc import Callable

from auth0_api_python.api_client import ApiClient, ApiClientOptions, BaseAuthError
from auth0_api_python.cache import CacheAdapter
Expand All @@ -15,17 +15,17 @@ class Auth0FastAPI:

def __init__(
self,
domain: Optional[str] = None,
domain: str | None = None,
audience: str = "",
domains: Optional[Union[list[str], Callable]] = None,
domains: list[str] | Callable | None = None,
client_id=None,
client_secret=None,
custom_fetch=None,
dpop_enabled=True,
dpop_required=False,
dpop_iat_leeway=30,
dpop_iat_offset=300,
cache_adapter: Optional[CacheAdapter] = None,
cache_adapter: CacheAdapter | None = None,
cache_ttl_seconds: int = 600,
cache_max_entries: int = 100):
"""
Expand Down Expand Up @@ -72,7 +72,7 @@ def __init__(

def require_auth(
self,
scopes: Optional[Union[str, list[str]]] = None
scopes: str | list[str] | None = None
):
"""
Returns an async FastAPI dependency that:
Expand Down
5 changes: 2 additions & 3 deletions fastapi_plugin/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from typing import Optional
from urllib.parse import urlparse, urlunparse

from fastapi import HTTPException, Request
Expand All @@ -8,7 +7,7 @@ def http_exception(
status_code: int,
error: str,
error_desc: str,
headers: Optional[dict[str, str]] = None
headers: dict[str, str] | None = None
) -> HTTPException:
"""
Construct an HTTPException with appropriate headers.
Expand Down Expand Up @@ -45,7 +44,7 @@ def _should_trust_proxy(request: Request) -> bool:
# If app.state doesn't exist or trust_proxy isn't set, don't trust
return False

def _parse_forwarded_host(forwarded_host: Optional[str]) -> Optional[str]:
def _parse_forwarded_host(forwarded_host: str | None) -> str | None:
"""
Parses X-Forwarded-Host header, handling multiple comma-separated values.

Expand Down
701 changes: 13 additions & 688 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ packages = [
]

[tool.poetry.dependencies]
python = "^3.9.2"
python = "^3.10"
fastapi = ">=0.115.11"
httpx = ">=0.28.1"
auth0-api-python = ">=1.0.0b10"
Expand Down
22 changes: 11 additions & 11 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import hashlib
import secrets
import time
from typing import Any, Optional, Union
from typing import Any

from authlib.jose import JsonWebKey, jwt

Expand Down Expand Up @@ -46,11 +46,11 @@
async def generate_token(
domain: str,
user_id: str,
audience: Optional[str] = None,
issuer: Union[str, bool, None] = None,
audience: str | None = None,
issuer: str | bool | None = None,
iat: bool = True,
exp: bool = True,
claims: Optional[dict[str, Any]] = None,
claims: dict[str, Any] | None = None,
expiration_time: int = 3600,
token_type: str = "bearer"
) -> str:
Expand Down Expand Up @@ -105,7 +105,7 @@ def base64url_encode(data: bytes) -> str:
"""Base64URL encode without padding."""
return base64.urlsafe_b64encode(data).decode('ascii').rstrip('=')

def sha256_hash(data: Union[str, bytes]) -> str:
def sha256_hash(data: str | bytes) -> str:
"""SHA256 hash and base64url encode."""
if isinstance(data, str):
data = data.encode('utf-8')
Expand All @@ -132,8 +132,8 @@ def calculate_jwk_thumbprint(jwk_dict: dict[str, Any]) -> str:
async def generate_dpop_proof(
http_method: str,
http_url: str,
access_token: Optional[str] = None,
nonce: Optional[str] = None,
access_token: str | None = None,
nonce: str | None = None,
iat_offset: int = 0
) -> str:
"""
Expand Down Expand Up @@ -193,13 +193,13 @@ async def generate_dpop_proof(
async def generate_dpop_bound_token(
domain: str,
user_id: str,
audience: Optional[str] = None,
issuer: Union[str, bool, None] = None,
audience: str | None = None,
issuer: str | bool | None = None,
iat: bool = True,
exp: bool = True,
claims: Optional[dict[str, Any]] = None,
claims: dict[str, Any] | None = None,
expiration_time: int = 3600,
cnf_jkt: Optional[str] = None
cnf_jkt: str | None = None
) -> str:
"""
Generate a DPoP-bound access token for testing.
Expand Down
Loading