### Run an AuthX Example Source: https://github.com/yezz123/authx/blob/main/examples/README.md Starts a specific AuthX example application. After running, you can access the API documentation at http://localhost:8000/docs. ```bash python example_name.py ``` -------------------------------- ### Complete AuthX Example with Aliases Source: https://github.com/yezz123/authx/blob/main/docs/dependencies/aliases.md A comprehensive example showcasing the setup of AuthX with custom configuration and the usage of various dependency aliases within FastAPI routes. ```python from fastapi import FastAPI from authx import AuthX, AuthXConfig app = FastAPI() config = AuthXConfig( JWT_SECRET_KEY="your-secret-key", JWT_TOKEN_LOCATION=["headers"], ) auth = AuthX(config=config) auth.handle_errors(app) @app.get("/login") def login(): return {"access_token": auth.create_access_token(uid="user123", fresh=True)} @app.get("/protected", dependencies=[auth.ACCESS_REQUIRED]) def protected(): return {"message": "Access granted"} @app.get("/me") def get_me(payload=auth.ACCESS_REQUIRED): return {"user_id": payload.sub} @app.post("/sensitive", dependencies=[auth.FRESH_REQUIRED]) def sensitive(): return {"message": "Sensitive operation complete"} ``` -------------------------------- ### AuthX Quick Start Example Source: https://github.com/yezz123/authx/blob/main/docs/get-started/installation.md A basic FastAPI application demonstrating AuthX for authentication and protected routes. Requires `uvicorn` to run. ```python from fastapi import FastAPI, Depends, HTTPException from authx import AuthX, AuthXConfig app = FastAPI() config = AuthXConfig( JWT_SECRET_KEY="your-secret-key", JWT_TOKEN_LOCATION=["headers"], ) auth = AuthX(config=config) auth.handle_errors(app) @app.post("/login") def login(username: str, password: str): if username == "test" and password == "test": return {"access_token": auth.create_access_token(uid=username)} raise HTTPException(401, detail="Invalid credentials") @app.get("/protected", dependencies=[Depends(auth.access_token_required)]) def protected(): return {"message": "Hello World"} ``` ```bash uvicorn main:app --reload ``` -------------------------------- ### Complete AuthX FastAPI Example Source: https://github.com/yezz123/authx/blob/main/docs/get-started/basic-usage.md A full example demonstrating AuthX setup, login endpoint, and a protected route. Ensure JWT_SECRET_KEY is set via environment variables in production. ```python from fastapi import FastAPI, Depends, HTTPException from authx import AuthX, AuthXConfig app = FastAPI() # Step 1: Configure AuthX config = AuthXConfig( JWT_SECRET_KEY="your-secret-key", # Required: use env variable in production JWT_TOKEN_LOCATION=["headers"], # Where to look for tokens ) # Step 2: Create AuthX instance auth = AuthX(config=config) # Step 3: Register error handlers (important!) auth.handle_errors(app) # Step 4: Create login endpoint @app.post("/login") def login(username: str, password: str): if username == "test" and password == "test": token = auth.create_access_token(uid=username) return {"access_token": token} raise HTTPException(401, detail="Invalid credentials") # Step 5: Protect your routes @app.get("/protected", dependencies=[Depends(auth.access_token_required)]) def protected(): return {"message": "Hello World"} ``` -------------------------------- ### Complete AuthX Setup with Scopes Source: https://github.com/yezz123/authx/blob/main/docs/get-started/scopes.md This example demonstrates a full AuthX integration with FastAPI, including user management, token creation, and scope-protected routes. ```python from typing import Annotated from fastapi import Depends, FastAPI, HTTPException from authx import AuthX, AuthXConfig, InsufficientScopeError from authx.schema import TokenPayload app = FastAPI() config = AuthXConfig(JWT_SECRET_KEY="secret") auth = AuthX(config=config) # User database with scopes USERS = { "admin": {"password": "admin", "scopes": ["admin:*"Май] "editor": {"password": "editor", "scopes": ["posts:read", "posts:write"]}, "viewer": {"password": "viewer", "scopes": ["posts:read"]}, } @app.post("/login") def login(username: str, password: str): user = USERS.get(username) if not user or user["password"] != password: raise HTTPException(401, "Invalid credentials") token = auth.create_access_token(uid=username, scopes=user["scopes"]) return {"access_token": token, "scopes": user["scopes"]} # Type aliases for common scope requirements AdminRequired = Annotated[TokenPayload, Depends(auth.scopes_required("admin:*"))] PostsRead = Annotated[TokenPayload, Depends(auth.scopes_required("posts:read"))] PostsWrite = Annotated[TokenPayload, Depends(auth.scopes_required("posts:write"))] @app.get("/posts") async def list_posts(payload: PostsRead): return {"posts": [...], "user": payload.sub} @app.post("/posts") async def create_post(payload: PostsWrite): return {"message": "Post created", "user": payload.sub} @app.get("/admin") async def admin_panel(payload: AdminRequired): return {"message": "Admin access granted", "user": payload.sub} ``` -------------------------------- ### Install Dependencies with uv Source: https://github.com/yezz123/authx/blob/main/examples/README.md Installs project dependencies using the uv package manager. This is typically the first step before running any examples. ```bash uv sync ``` -------------------------------- ### Run Full Working Example Source: https://github.com/yezz123/authx/blob/main/docs/get-started/scopes.md Execute the provided bash commands to set up and run the full working example. This includes navigating to the example directory and running the Python script. ```bash cd examples/examples python scopes.py ``` -------------------------------- ### Complete AuthX Example with Token Freshness Source: https://github.com/yezz123/authx/blob/main/docs/get-started/token.md This example demonstrates how to set up AuthX, handle login, token refresh, and protect routes with access token and fresh token requirements. ```python from fastapi import FastAPI, Depends, HTTPException from pydantic import BaseModel from authx import AuthX, AuthXConfig, TokenPayload app = FastAPI() config = AuthXConfig( JWT_SECRET_KEY="your-secret-key", JWT_TOKEN_LOCATION=["headers"], ) auth = AuthX(config=config) auth.handle_errors(app) class LoginRequest(BaseModel): username: str password: str @app.post("/login") def login(data: LoginRequest): """Login returns a FRESH access token and a refresh token.""" if data.username == "test" and data.password == "test": # fresh=True because user just entered credentials access_token = auth.create_access_token(uid=data.username, fresh=True) refresh_token = auth.create_refresh_token(uid=data.username) return { "access_token": access_token, "refresh_token": refresh_token, } raise HTTPException(401, detail="Invalid credentials") @app.post("/refresh") def refresh(payload: TokenPayload = Depends(auth.refresh_token_required)): """Refresh returns a NON-FRESH access token.""" # fresh=False because user didn't re-enter credentials access_token = auth.create_access_token(uid=payload.sub, fresh=False) return {"access_token": access_token} @app.get("/protected", dependencies=[Depends(auth.access_token_required)]) def protected(): """Any valid token works here.""" return {"message": "You have access"} @app.post("/change-password", dependencies=[Depends(auth.fresh_token_required)]) def change_password(): """Only FRESH tokens work here.""" return {"message": "Password changed"} ``` -------------------------------- ### Run Jinja2 Template Example Source: https://github.com/yezz123/authx/blob/main/docs/extra/templates.md Instructions to run a full working example of Jinja2 templates. This involves navigating to the example directory, running a Python script, and accessing the application via a web browser. ```bash cd examples/examples python jinja2_templates.py ``` -------------------------------- ### Complete User Serialization Example Source: https://github.com/yezz123/authx/blob/main/docs/callbacks/user.md This example demonstrates a full FastAPI application setup with AuthX for user authentication and serialization. It includes mock user data, login functionality, and a protected route to retrieve the current user's details. ```python from fastapi import FastAPI, Depends, HTTPException from pydantic import BaseModel from authx import AuthX, AuthXConfig app = FastAPI() config = AuthXConfig( JWT_SECRET_KEY="your-secret-key", JWT_TOKEN_LOCATION=["headers"], ) auth = AuthX(config=config) auth.handle_errors(app) # User model class User(BaseModel): email: str firstname: str lastname: str # Mock database USERS_DB = { "john@example.com": { "email": "john@example.com", "firstname": "John", "lastname": "Doe", "password": "secret123", } } # Define how to get user from token subject @auth.set_subject_getter def get_user_from_uid(uid: str) -> User: user_data = USERS_DB.get(uid) if user_data: return User(**{k: v for k, v in user_data.items() if k != "password"}) return None class LoginRequest(BaseModel): email: str password: str @app.post("/login") def login(data: LoginRequest): user = USERS_DB.get(data.email) if user and user["password"] == data.password: token = auth.create_access_token(uid=data.email) return {"access_token": token} raise HTTPException(401, detail="Invalid credentials") @app.get("/me") def get_me(user: User = Depends(auth.get_current_subject)): return {"user": user} ``` -------------------------------- ### Install AuthX with pip Source: https://github.com/yezz123/authx/blob/main/docs/get-started/installation.md Use pip to install the AuthX package. ```bash pip install authx ``` -------------------------------- ### AuthX FastAPI Quick Start Source: https://github.com/yezz123/authx/blob/main/README.md Basic setup for a FastAPI application using AuthX for JWT authentication. Includes login endpoint and a protected route. ```python from fastapi import FastAPI, Depends, HTTPException from authx import AuthX, AuthXConfig app = FastAPI() config = AuthXConfig( JWT_SECRET_KEY="your-secret-key", # Change this! JWT_TOKEN_LOCATION=["headers"], ) auth = AuthX(config=config) auth.handle_errors(app) @app.post("/login") def login(username: str, password: str): if username == "test" and password == "test": token = auth.create_access_token(uid=username) return {"access_token": token} raise HTTPException(401, detail="Invalid credentials") @app.get("/protected", dependencies=[Depends(auth.access_token_required)]) def protected(): return {"message": "Hello World"} ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/yezz123/authx/blob/main/docs/development/contributing.md Installs all necessary development dependencies for AuthX from the project's configuration. ```console $ uv sync ---> 100% ``` -------------------------------- ### Install authx_extra Package Source: https://github.com/yezz123/authx/blob/main/docs/extra/Metrics.md Command to install the authx_extra package, which includes the necessary metrics collection middleware. ```console $ pip install authx_extra ---> 100% ``` -------------------------------- ### Install authx_extra Dependency Source: https://github.com/yezz123/authx/blob/main/docs/api/internal/extra/memory.md Before using the Memory Cache, you need to install the 'authx_extra' package. This command installs the necessary dependencies. ```console $ pip install authx_extra ``` -------------------------------- ### Complete Token Blocklist Example Source: https://github.com/yezz123/authx/blob/main/docs/callbacks/token.md This example demonstrates a full implementation of a token blocklist using FastAPI and AuthX. It includes setting up the AuthX configuration, defining an in-memory blocklist, creating a callback to check token revocation, and implementing login, logout, and protected routes. ```python from typing import Optional from fastapi import FastAPI, Depends, HTTPException from authx import AuthX, AuthXConfig, RequestToken, TokenPayload app = FastAPI() config = AuthXConfig( JWT_SECRET_KEY="your-secret-key", JWT_TOKEN_LOCATION=["headers"], ) auth = AuthX(config=config) auth.handle_errors(app) # Simple in-memory blocklist (use Redis/database in production) BLOCKLIST: set[str] = set() @auth.set_callback_token_blocklist def is_token_revoked(token: str) -> bool: """Return True if token is revoked.""" return token in BLOCKLIST @app.post("/login") def login(username: str, password: str): if username == "test" and password == "test": token = auth.create_access_token(uid=username) return {"access_token": token} raise HTTPException(401, detail="Invalid credentials") @app.post("/logout", dependencies=[Depends(auth.access_token_required)]) async def logout(request): """Add current token to blocklist.""" token = await auth.get_access_token_from_request(request) BLOCKLIST.add(token.token) return {"message": "Logged out"} @app.get("/protected", dependencies=[Depends(auth.access_token_required)]) def protected(): return {"message": "Access granted"} ``` -------------------------------- ### Install authx_extra Source: https://github.com/yezz123/authx/blob/main/docs/api/extra/oauth2.md Install the necessary dependencies for the Oauth2 Middleware. ```console $ pip install authx_extra ``` -------------------------------- ### Install Test Dependencies Source: https://github.com/yezz123/authx/blob/main/docs/development/contributing.md Installs all necessary dependencies for testing AuthX, including development and testing extras. ```bash $ uv sync --group test --all-extras ``` -------------------------------- ### Install AuthX with uv Source: https://github.com/yezz123/authx/blob/main/docs/get-started/installation.md Use uv to add AuthX to your project dependencies. ```bash uv add authx ``` -------------------------------- ### Complete AuthX Example with Login and Payload Access Source: https://github.com/yezz123/authx/blob/main/docs/get-started/payload.md A full example demonstrating user login with custom data, token creation, and accessing user-specific information and roles from the token payload. Includes routes for login, retrieving user data, and an admin-only route. ```python from fastapi import FastAPI, Depends, HTTPException from pydantic import BaseModel from authx import AuthX, AuthXConfig, TokenPayload app = FastAPI() config = AuthXConfig( JWT_SECRET_KEY="your-secret-key", JWT_TOKEN_LOCATION=["headers"], ) auth = AuthX(config=config) auth.handle_errors(app) class LoginRequest(BaseModel): username: str password: str # Mock user database USERS = { "admin": {"password": "admin123", "role": "admin"}, "user": {"password": "user123", "role": "user"}, } @app.post("/login") def login(data: LoginRequest): user = USERS.get(data.username) if user and user["password"] == data.password: token = auth.create_access_token( uid=data.username, data={"role": user["role"]} ) return {"access_token": token} raise HTTPException(401, detail="Invalid credentials") @app.get("/me") def get_me(payload: TokenPayload = Depends(auth.access_token_required)): return { "username": payload.sub, "role": payload.extra_dict.get("role"), "expires_in": str(payload.time_until_expiry), } @app.get("/admin-only") def admin_only(payload: TokenPayload = Depends(auth.access_token_required)): if payload.extra_dict.get("role") != "admin": raise HTTPException(403, detail="Admin access required") return {"message": "Welcome, admin!"} ``` -------------------------------- ### Install AuthX Extra Features Source: https://github.com/yezz123/authx/blob/main/docs/get-started/installation.md Install the `authx-extra` package to enable additional features like Redis caching, profiling, and Prometheus metrics. ```bash pip install authx-extra ``` -------------------------------- ### Configure ProfilerMiddleware Options Source: https://github.com/yezz123/authx/blob/main/docs/extra/profiler.md This example shows how to configure the ProfilerMiddleware with specific options, such as the output type (HTML), whether to print profiling for each request, and the name of the HTML output file. ```python app.add_middleware(PyInstrumentProfilerMiddleware, profiler_output_type="html", is_print_each_request=False, html_file_name="profiling.html") ``` -------------------------------- ### Verify AuthX Installation Source: https://github.com/yezz123/authx/blob/main/docs/get-started/installation.md Check the installed AuthX version to confirm successful installation. ```python import authx print(authx.__version__) ``` -------------------------------- ### Complete AuthX Example with FastAPI Source: https://github.com/yezz123/authx/blob/main/docs/dependencies/injection.md A comprehensive example demonstrating public routes, login functionality, and protected API endpoints using AuthX and FastAPI, including Pydantic models and APIRouter. ```python from fastapi import FastAPI, APIRouter, Depends, HTTPException from pydantic import BaseModel from authx import AuthX, AuthXConfig, TokenPayload app = FastAPI() config = AuthXConfig( JWT_SECRET_KEY="your-secret-key", JWT_TOKEN_LOCATION=["headers"], ) auth = AuthX(config=config) auth.handle_errors(app) class LoginRequest(BaseModel): username: str password: str # Public routes @app.get("/") def home(): return {"message": "Welcome"} @app.post("/login") def login(data: LoginRequest): if data.username == "admin" and data.password == "admin": return {"access_token": auth.create_access_token(uid=data.username)} raise HTTPException(401, detail="Invalid credentials") # Protected router protected_router = APIRouter( prefix="/api", dependencies=[Depends(auth.access_token_required)] ) @protected_router.get("/me") def get_me(payload: TokenPayload = Depends(auth.access_token_required)): return {"user_id": payload.sub} @protected_router.get("/data") def get_data(): return {"data": [1, 2, 3]} app.include_router(protected_router) ``` -------------------------------- ### Install authx_extra for HTTP Cache Source: https://github.com/yezz123/authx/blob/main/docs/api/extra/cache.md Install the necessary dependencies to utilize the HTTP Cache functionality. This command should be run in your project's environment. ```console pip install authx_extra ``` -------------------------------- ### Complete FastAPI AuthX Example Source: https://github.com/yezz123/authx/blob/main/docs/extra/templates.md This snippet provides a full, runnable example of a FastAPI application integrated with AuthX. It covers setting up AuthX configuration, defining user authentication logic, handling login and logout routes, and protecting the dashboard route with authentication. It also demonstrates using Jinja2 templates for rendering login and dashboard pages. ```Python from fastapi import Depends, FastAPI, Form, Request, Response from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.templating import Jinja2Templates from authx import AuthX, AuthXConfig from authx.exceptions import AuthXException app = FastAPI() templates = Jinja2Templates(directory="templates") config = AuthXConfig( JWT_SECRET_KEY="secret", JWT_TOKEN_LOCATION=["cookies"], JWT_COOKIE_CSRF_PROTECT=True, JWT_CSRF_CHECK_FORM=True, ) auth = AuthX(config=config) # Simple user store USERS = {"admin": "password123"} class RedirectToLogin(Exception): pass @app.exception_handler(RedirectToLogin) async def handle_redirect(request, exc): return RedirectResponse("/login", status_code=303) async def require_auth(request: Request): try: token = await auth.get_access_token_from_request(request) return auth.verify_token(token, verify_csrf=False) except AuthXException: raise RedirectToLogin() @app.get("/login", response_class=HTMLResponse) async def login_page(request: Request): return templates.TemplateResponse("login.html", {"request": request}) @app.post("/login") async def login(username: str = Form(...), password: str = Form(...)): if USERS.get(username) != password: return RedirectResponse("/login?error=1", status_code=303) token = auth.create_access_token(uid=username) response = RedirectResponse("/dashboard", status_code=303) auth.set_access_cookies(token, response) return response @app.get("/dashboard", response_class=HTMLResponse) async def dashboard(request: Request, user=Depends(require_auth)): csrf = request.cookies.get("csrf_access_token", "") return templates.TemplateResponse( "dashboard.html", {"request": request, "user": user.sub, "csrf_token": csrf} ) @app.post("/logout") async def logout(): response = RedirectResponse("/login", status_code=303) auth.unset_cookies(response) return response ``` -------------------------------- ### Complete FastAPI Example with AuthX Source: https://github.com/yezz123/authx/blob/main/docs/dependencies/dependencies.md This example demonstrates how to integrate AuthX with FastAPI for various authentication flows, including route-level protection, dependency injection of token payloads, and handling optional tokens. ```python from fastapi import FastAPI, Depends, HTTPException from authx import AuthX, AuthXConfig, TokenPayload, RequestToken app = FastAPI() config = AuthXConfig( JWT_SECRET_KEY="your-secret-key", JWT_TOKEN_LOCATION=["headers"], ) auth = AuthX(config=config) auth.handle_errors(app) @app.post("/login") def login(username: str, password: str): if username == "test" and password == "test": return {"access_token": auth.create_access_token(uid=username, fresh=True)} raise HTTPException(401, detail="Invalid credentials") # Route level dependency - just protects the route @app.get("/protected", dependencies=[Depends(auth.access_token_required)]) def protected(): return {"message": "Access granted"} # Get payload in function @app.get("/me") def get_me(payload: TokenPayload = Depends(auth.access_token_required)): return {"user_id": payload.sub, "token_type": payload.type} # Fresh token for sensitive operations @app.post("/delete-account", dependencies=[Depends(auth.fresh_token_required)]) def delete_account(): return {"message": "Account deleted"} # Optional token - doesn't require authentication @app.get("/greeting") async def greeting(request): token = await auth.get_token_from_request(request, optional=True) if token: try: payload = auth.verify_token(token) return {"message": f"Hello, {payload.sub}!"} except Exception: pass return {"message": "Hello, guest!"} ``` -------------------------------- ### Install AuthX with Poetry Source: https://github.com/yezz123/authx/blob/main/docs/get-started/installation.md Use Poetry to add AuthX to your project dependencies. ```bash poetry add authx ``` -------------------------------- ### Install Pre-commit Hooks Source: https://github.com/yezz123/authx/blob/main/docs/development/contributing.md Installs the pre-commit Git hooks to enforce code formatting and linting checks before each commit. ```console $ pre-commit install ``` -------------------------------- ### Complete WebSocket Authentication Example Source: https://github.com/yezz123/authx/blob/main/docs/get-started/websocket.md This example demonstrates how to set up a FastAPI application with AuthX for WebSocket authentication. It includes a login endpoint to obtain a token and an authenticated WebSocket endpoint that verifies the token before accepting the connection. ```python from fastapi import FastAPI, Depends, HTTPException, WebSocket, WebSocketDisconnect from pydantic import BaseModel from authx import AuthX, AuthXConfig, TokenPayload app = FastAPI() config = AuthXConfig( JWT_SECRET_KEY="your-secret-key", JWT_TOKEN_LOCATION=["headers"], ) auth = AuthX(config=config) auth.handle_errors(app) class LoginRequest(BaseModel): username: str password: str @app.post("/login") def login(data: LoginRequest): """Get a token to use with WebSocket.""" if data.username == "test" and data.password == "test": token = auth.create_access_token(uid=data.username) return {"access_token": token} raise HTTPException(401, detail="Invalid credentials") @app.websocket("/ws") async def websocket_endpoint( websocket: WebSocket, payload: TokenPayload = Depends(auth._ws_auth_required), ): """Authenticated WebSocket endpoint.""" await websocket.accept() await websocket.send_json({"message": f"Hello, {payload.sub}!"}) try: while True: data = await websocket.receive_text() await websocket.send_json({"user": payload.sub, "echo": data}) except WebSocketDisconnect: pass ``` -------------------------------- ### Complete Session Management Example Source: https://github.com/yezz123/authx/blob/main/docs/get-started/sessions.md This example demonstrates how to integrate AuthX for session management in a FastAPI application. It includes endpoints for user login, creating tracked sessions, listing active sessions, revoking specific sessions, and revoking all sessions for a user. It utilizes an InMemorySessionStore for demonstration purposes. ```python from fastapi import FastAPI, HTTPException, Request from pydantic import BaseModel from authx import AuthX, AuthXConfig, SessionInfo from authx._internal._session import InMemorySessionStore app = FastAPI() config = AuthXConfig( JWT_SECRET_KEY="a]V&F*jk2s$5ghT!qR@pN8xLm3wY+bZ", JWT_TOKEN_LOCATION=["headers"], ) auth = AuthX(config=config) auth.handle_errors(app) auth.set_session_store(InMemorySessionStore()) class LoginRequest(BaseModel): username: str password: str @app.post("/login") async def login(data: LoginRequest, request: Request): """Login and create a tracked session.""" if data.username == "test" and data.password == "test": session = await auth.create_session(uid=data.username, request=request) token = auth.create_access_token( uid=data.username, data={"session_id": session.session_id}, ) return {"access_token": token, "session_id": session.session_id} raise HTTPException(401, detail="Invalid credentials") @app.get("/sessions") async def list_sessions(request: Request): """List all active sessions for the current user.""" token = await auth.get_access_token_from_request(request) payload = auth.verify_token(token) sessions = await auth.list_sessions(payload.sub) return {"sessions": [s.model_dump() for s in sessions]} @app.post("/sessions/{session_id}/revoke") async def revoke_session(session_id: str, request: Request): """Revoke a specific session.""" token = await auth.get_access_token_from_request(request) auth.verify_token(token) await auth.revoke_session(session_id) return {"message": "Session revoked"} @app.post("/sessions/revoke-all") async def revoke_all(request: Request): """Revoke all sessions for the current user.""" token = await auth.get_access_token_from_request(request) payload = auth.verify_token(token) await auth.revoke_all_sessions(payload.sub) return {"message": "All sessions revoked"} ``` -------------------------------- ### Running the FastAPI Application Source: https://github.com/yezz123/authx/blob/main/docs/get-started/basic-usage.md Command to start the FastAPI development server with hot reloading. ```bash uvicorn main:app --reload ``` -------------------------------- ### Complete AuthX Example with Bundle Source: https://github.com/yezz123/authx/blob/main/docs/dependencies/bundle.md A comprehensive FastAPI application demonstrating login, token refreshing, logout, and accessing a protected route using the AuthXDependency bundle for simplified cookie management. ```python from fastapi import FastAPI, HTTPException from pydantic import BaseModel from authx import AuthX, AuthXConfig, AuthXDependency app = FastAPI() config = AuthXConfig( JWT_SECRET_KEY="your-secret-key", JWT_TOKEN_LOCATION=["cookies"], JWT_COOKIE_SECURE=False, # Set True in production (HTTPS) ) auth = AuthX(config=config) auth.handle_errors(app) class LoginRequest(BaseModel): username: str password: str @app.post("/login") def login(data: LoginRequest, deps: AuthXDependency = auth.BUNDLE): if data.username == "test" and data.password == "test": tokens = deps.create_token_pair(uid=data.username) deps.set_access_cookies(tokens.access_token) deps.set_refresh_cookies(tokens.refresh_token) return {"message": "Logged in"} raise HTTPException(401, detail="Invalid credentials") @app.post("/refresh") def refresh(payload=auth.REFRESH_REQUIRED, deps: AuthXDependency = auth.BUNDLE): access_token = deps.create_access_token(uid=payload.sub) deps.set_access_cookies(access_token) return {"message": "Token refreshed"} @app.post("/logout", dependencies=[auth.ACCESS_REQUIRED]) def logout(deps: AuthXDependency = auth.BUNDLE): deps.unset_cookies() return {"message": "Logged out"} @app.get("/protected", dependencies=[auth.ACCESS_REQUIRED]) def protected(): return {"message": "Access granted"} ``` -------------------------------- ### Create Virtual Environment with uv Source: https://github.com/yezz123/authx/blob/main/docs/development/contributing.md Installs uv and creates a virtual environment named .venv. This isolates project dependencies. ```console pip install uv uv venv ``` -------------------------------- ### Setup Jinja2 Templates with FastAPI Source: https://github.com/yezz123/authx/blob/main/docs/extra/templates.md Initialize Jinja2 templating within a FastAPI application to render HTML templates. ```python from fastapi import FastAPI from fastapi.templating import Jinja2Templates app = FastAPI() templates = Jinja2Templates(directory="templates") ``` -------------------------------- ### Run AuthX Tests Source: https://github.com/yezz123/authx/blob/main/docs/development/contributing.md Executes the test suite for AuthX using a bash script. Ensure all dependencies are installed before running. ```bash $ bash scripts/test.sh ``` -------------------------------- ### Implement Redis Session Store Source: https://github.com/yezz123/authx/blob/main/docs/get-started/sessions.md Implement the `SessionStoreProtocol` using Redis for production environments. This example demonstrates basic CRUD operations and user-specific session management. ```python class RedisSessionStore: async def create(self, session: SessionInfo) -> None: await redis.set(f"session:{session.session_id}", session.model_dump_json()) async def get(self, session_id: str) -> SessionInfo | None: data = await redis.get(f"session:{session_id}") return SessionInfo.model_validate_json(data) if data else None async def update(self, session_id: str, **kwargs) -> None: session = await self.get(session_id) if session: for k, v in kwargs.items(): setattr(session, k, v) await redis.set(f"session:{session.session_id}", session.model_dump_json()) async def delete(self, session_id: str) -> None: await redis.delete(f"session:{session_id}") async def list_by_user(self, uid: str) -> list[SessionInfo]: # Implement with Redis sorted sets or secondary index ... async def delete_all_by_user(self, uid: str) -> None: for session in await self.list_by_user(uid): await self.delete(session.session_id) ``` -------------------------------- ### Complete Cookie Authentication Example Source: https://github.com/yezz123/authx/blob/main/docs/get-started/location.md Sets up FastAPI with AuthX to use HttpOnly cookies for authentication. Ensure JWT_COOKIE_SECURE is set to True in production environments. ```python from fastapi import FastAPI, Depends, HTTPException, Response from pydantic import BaseModel from authx import AuthX, AuthXConfig app = FastAPI() config = AuthXConfig( JWT_SECRET_KEY="your-secret-key", JWT_TOKEN_LOCATION=["cookies"], JWT_COOKIE_CSRF_PROTECT=True, # Enabled by default JWT_COOKIE_SECURE=False, # Set True in production (HTTPS) ) auth = AuthX(config=config) auth.handle_errors(app) class LoginRequest(BaseModel): username: str password: str @app.post("/login") def login(data: LoginRequest, response: Response): if data.username == "test" and data.password == "test": token = auth.create_access_token(uid=data.username) # IMPORTANT: Use set_access_cookies() - this sets BOTH the JWT cookie AND the CSRF cookie auth.set_access_cookies(token, response) return {"message": "Logged in"} raise HTTPException(401, detail="Invalid credentials") @app.post("/logout") def logout(response: Response): auth.unset_cookies(response) return {"message": "Logged out"} @app.get("/protected", dependencies=[Depends(auth.access_token_required)]) def protected(): return {"message": "Access granted"} ``` -------------------------------- ### Example cURL Request with Query Token Source: https://github.com/yezz123/authx/blob/main/docs/get-started/location.md Demonstrates how to send a request with a token in the query string using cURL. ```bash curl "http://localhost:8000/protected?token=" ``` -------------------------------- ### Implement Metrics in FastAPI Application Source: https://github.com/yezz123/authx/blob/main/docs/extra/Metrics.md Example of adding the MetricsMiddleware to a FastAPI application and exposing Prometheus metrics at the /metrics endpoint. ```python from fastapi import FastAPI from authx_extra.metrics import MetricsMiddleware, get_metrics app = FastAPI() app.add_middleware(MetricsMiddleware) app.add_route("/metrics", get_metrics) ``` -------------------------------- ### Complete Symmetric Key Rotation Example Source: https://github.com/yezz123/authx/blob/main/docs/get-started/key-rotation.md Demonstrates setting up AuthX with both a new and a previous secret key for symmetric JWT signing. This allows new tokens to be signed with the current key while older tokens signed with the previous key remain valid during the transition. ```python from fastapi import FastAPI, Depends, HTTPException from pydantic import BaseModel from authx import AuthX, AuthXConfig, TokenPayload app = FastAPI() config = AuthXConfig( JWT_SECRET_KEY="new-secret-key-2026", JWT_PREVIOUS_SECRET_KEY="old-secret-key-2025", # Still accepted during transition JWT_TOKEN_LOCATION=["headers"], ) auth = AuthX(config=config) auth.handle_errors(app) class LoginRequest(BaseModel): username: str password: str @app.post("/login") def login(data: LoginRequest): """New tokens are always signed with the current key.""" if data.username == "test" and data.password == "test": token = auth.create_access_token(uid=data.username) return {"access_token": token} raise HTTPException(401, detail="Invalid credentials") @app.get("/protected") def protected(payload: TokenPayload = Depends(auth.access_token_required)): """Accepts tokens signed with either the current or previous key.""" return {"user": payload.sub} ``` -------------------------------- ### Example cURL Request with JSON Token Source: https://github.com/yezz123/authx/blob/main/docs/get-started/location.md Shows how to send a request with a JSON Web Token using cURL. ```bash curl -X POST \ -H "Content-Type: application/json" \ -d '{"access_token": ""}' \ http://localhost:8000/protected ``` -------------------------------- ### Example JavaScript Fetch Request with JSON Token Source: https://github.com/yezz123/authx/blob/main/docs/get-started/location.md Demonstrates sending a request with a JSON Web Token using the JavaScript fetch API. ```javascript fetch("http://localhost:8000/protected", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ access_token: token }) }); ``` -------------------------------- ### User Serialization with SQLAlchemy Source: https://github.com/yezz123/authx/blob/main/docs/callbacks/user.md This example shows how to integrate AuthX with SQLAlchemy for user retrieval. It sets up a database, defines a user model, and implements the subject getter to query the database. ```python from fastapi import FastAPI, Depends, HTTPException from pydantic import BaseModel from sqlalchemy import create_engine, Column, String from sqlalchemy.orm import sessionmaker, declarative_base from authx import AuthX, AuthXConfig app = FastAPI() config = AuthXConfig( JWT_SECRET_KEY="your-secret-key", JWT_TOKEN_LOCATION=["headers"], ) auth = AuthX(config=config) auth.handle_errors(app) # Database setup Base = declarative_base() engine = create_engine("sqlite:///./users.db") SessionLocal = sessionmaker(bind=engine) class UserDB(Base): __tablename__ = "users" id = Column(String, primary_key=True) email = Column(String) password = Column(String) firstname = Column(String) lastname = Column(String) Base.metadata.create_all(bind=engine) class User(BaseModel): id: str email: str firstname: str lastname: str class Config: from_attributes = True @auth.set_subject_getter def get_user_from_uid(uid: str) -> User | None: with SessionLocal() as db: user = db.query(UserDB).filter(UserDB.id == uid).first() if user: return User.model_validate(user) return None @app.get("/me") def get_me(user: User = Depends(auth.get_current_subject)): if user is None: raise HTTPException(404, detail="User not found") return {"user": user} ``` -------------------------------- ### Testing AuthX Endpoints with cURL Source: https://github.com/yezz123/authx/blob/main/docs/get-started/payload.md Command-line examples using cURL to test the login endpoint, retrieve user information, and access an admin-only route. Demonstrates how to send POST requests with JSON data and include the Authorization header with a bearer token. ```bash # Login as admin curl -X POST -H "Content-Type: application/json" \ -d '{"username":"admin", "password":"admin123"}' \ http://localhost:8000/login # Get user info curl -H "Authorization: Bearer " http://localhost:8000/me # {"username": "admin", "role": "admin", "expires_in": "0:14:59.123456"} # Access admin route curl -H "Authorization: Bearer " http://localhost:8000/admin-only # {"message": "Welcome, admin!"} ``` -------------------------------- ### Complete FastAPI App with AuthX and Rate Limiting Source: https://github.com/yezz123/authx/blob/main/docs/get-started/rate-limiting.md A full example demonstrating AuthX configuration, token creation, and rate limiting on the login endpoint. The login route is limited to 5 attempts per 5 minutes. ```python from fastapi import FastAPI, Depends, HTTPException, Request from pydantic import BaseModel from authx import AuthX, AuthXConfig, RateLimiter app = FastAPI() config = AuthXConfig( JWT_SECRET_KEY="a]V&F*jk2s$5ghT!qR@pN8xLm3wY+bZ", JWT_TOKEN_LOCATION=["headers"], ) auth = AuthX(config=config) auth.handle_errors(app) login_limiter = RateLimiter(max_requests=5, window=300) class LoginRequest(BaseModel): username: str password: str @app.post("/login", dependencies=[Depends(login_limiter)]) def login(data: LoginRequest): """Login with rate limiting: 5 attempts per 5 minutes.""" if data.username == "test" and data.password == "test": token = auth.create_access_token(uid=data.username) return {"access_token": token} raise HTTPException(401, detail="Invalid credentials") @app.get("/protected") async def protected(request: Request): token = await auth.get_access_token_from_request(request) payload = auth.verify_token(token) return {"user": payload.sub} ``` -------------------------------- ### Connect WebSocket with Token via Query Parameter (Python) Source: https://github.com/yezz123/authx/blob/main/docs/get-started/websocket.md This Python example demonstrates connecting to a WebSocket endpoint using a token passed as a query parameter. Suitable for non-browser clients. ```python import asyncio import websockets async def main(): token = "eyJ..." async with websockets.connect(f"ws://localhost:8000/ws?token={token}") as ws: print(await ws.recv()) await ws.send("Hello server!") print(await ws.recv()) asyncio.run(main()) ``` -------------------------------- ### Complete FastAPI Refresh Token Implementation Source: https://github.com/yezz123/authx/blob/main/docs/get-started/refresh.md This example demonstrates a full implementation of login, protected routes, and token refresh using FastAPI and AuthX. It includes Pydantic models for requests and token handling. ```python from fastapi import FastAPI, Depends, HTTPException from pydantic import BaseModel from authx import AuthX, AuthXConfig, TokenPayload app = FastAPI() config = AuthXConfig( JWT_SECRET_KEY="your-secret-key", JWT_TOKEN_LOCATION=["headers"], ) auth = AuthX(config=config) auth.handle_errors(app) class LoginRequest(BaseModel): username: str password: str @app.post("/login") def login(data: LoginRequest): """Returns both access and refresh tokens.""" if data.username == "test" and data.password == "test": access_token = auth.create_access_token(uid=data.username) refresh_token = auth.create_refresh_token(uid=data.username) return { "access_token": access_token, "refresh_token": refresh_token, } raise HTTPException(401, detail="Invalid credentials") @app.post("/refresh") def refresh(payload: TokenPayload = Depends(auth.refresh_token_required)): """Exchange refresh token for new access token.""" access_token = auth.create_access_token(uid=payload.sub) return {"access_token": access_token} @app.get("/protected", dependencies=[Depends(auth.access_token_required)]) def protected(): """Requires valid access token.""" return {"message": "You have access"} ``` -------------------------------- ### Testing AuthX Endpoints with cURL Source: https://github.com/yezz123/authx/blob/main/docs/get-started/basic-usage.md Example cURL commands to test the login endpoint for obtaining a token and then using that token to access a protected resource. ```bash # Get a token curl -X POST "http://localhost:8000/login?username=test&password=test" ``` ```bash # Use the token curl -H "Authorization: Bearer " http://localhost:8000/protected ``` -------------------------------- ### Testing AuthX Endpoints with cURL Source: https://github.com/yezz123/authx/blob/main/docs/dependencies/bundle.md Provides command-line examples using cURL to test the login, protected route access, and logout functionalities of the FastAPI application, demonstrating cookie handling. ```bash # Login (sets cookies) curl -X POST -H "Content-Type: application/json" \ -d '{"username":"test", "password":"test"}' \ -c cookies.txt \ http://localhost:8000/login # Access protected route (uses cookies) curl -b cookies.txt http://localhost:8000/protected # Logout (clears cookies) curl -X POST -b cookies.txt -c cookies.txt http://localhost:8000/logout ``` -------------------------------- ### Router-Level Protection with AuthX Source: https://github.com/yezz123/authx/blob/main/docs/dependencies/injection.md Secure all routes within an `APIRouter` by specifying `Depends(auth.access_token_required)` in the router's dependencies. This example shows setup in `main.py` and `admin_router.py`. ```python # main.py from fastapi import FastAPI from authx import AuthX, AuthXConfig app = FastAPI() config = AuthXConfig( JWT_SECRET_KEY="your-secret-key", JWT_TOKEN_LOCATION=["headers"], ) auth = AuthX(config=config) auth.handle_errors(app) @app.get("/") def home(): return {"message": "Public"} @app.get("/login") def login(): return {"access_token": auth.create_access_token(uid="user")} ``` ```python # admin_router.py from fastapi import APIRouter, Depends from main import auth # All routes in this router require authentication router = APIRouter( prefix="/admin", dependencies=[Depends(auth.access_token_required)] ) @router.get("/dashboard") def dashboard(): return {"message": "Admin Dashboard"} @router.get("/users") def list_users(): return {"users": ["user1", "user2"]} ``` ```python # main.py (continued) from admin_router import router app.include_router(router) ``` -------------------------------- ### Build AuthX Documentation Source: https://github.com/yezz123/authx/blob/main/docs/development/contributing.md Use these commands to synchronize dependencies and build the AuthX documentation locally. Ensure your environment is set up as described previously. ```console uv sync --group docs --all-extras ``` ```bash bash scripts/docs_build.sh ``` -------------------------------- ### Loading AuthX Configuration After Instance Creation Source: https://github.com/yezz123/authx/blob/main/docs/get-started/basic-usage.md Alternatively, create an AuthX instance first and then load the configuration. ```python auth = AuthX() auth.load_config(config) ``` -------------------------------- ### Initialize FastAPI Application Source: https://github.com/yezz123/authx/blob/main/docs/extra/OAuth2.md Create an instance of the FastAPI application. ```python app = FastAPI() ``` -------------------------------- ### Render Login Page (GET) Source: https://github.com/yezz123/authx/blob/main/docs/extra/templates.md Define a GET endpoint to render the login page using Jinja2 templates. Handles optional error messages to display to the user. ```python @app.get("/login", response_class=HTMLResponse) async def login_page(request: Request, error: str = None): return templates.TemplateResponse( "login.html", {"request": request, "error": error} ) ``` -------------------------------- ### Creating an AuthX Instance Source: https://github.com/yezz123/authx/blob/main/docs/get-started/basic-usage.md Instantiate AuthX with a configuration object. ```python from authx import AuthX auth = AuthX(config=config) ``` -------------------------------- ### Get Optional Refresh Token using REFRESH_TOKEN Shortcut Source: https://github.com/yezz123/authx/blob/main/docs/dependencies/dependencies.md Use the `auth.REFRESH_TOKEN` property shortcut as a dependency to get an optional refresh token. The `RequestToken` object will be None if no token is present. ```python from authx import RequestToken # Get refresh token (optional) @app.post("/refresh-info") def refresh_info(token: RequestToken = auth.REFRESH_TOKEN): if token: return {"has_refresh": True} return {"has_refresh": False} ``` -------------------------------- ### Get Optional Access Token using ACCESS_TOKEN Shortcut Source: https://github.com/yezz123/authx/blob/main/docs/dependencies/dependencies.md Use the `auth.ACCESS_TOKEN` property shortcut as a dependency to get an optional access token. The `RequestToken` object will be None if no token is present. ```python from authx import RequestToken # Get access token (optional) @app.get("/info") def get_info(token: RequestToken = auth.ACCESS_TOKEN): if token: return {"token_location": token.location} return {"message": "No token"} ``` -------------------------------- ### Initialize AuthXConfig from Environment Source: https://github.com/yezz123/authx/blob/main/docs/get-started/key-rotation.md Shows how to initialize AuthXConfig without arguments, causing it to automatically load configuration values from environment variables. ```python config = AuthXConfig() # Reads from environment automatically ``` -------------------------------- ### MemoryIO Class Source: https://github.com/yezz123/authx/blob/main/docs/api/internal/extra/memory.md The MemoryIO class offers an in-memory cache. To use it, ensure you have installed the 'authx_extra' package. ```APIDOC ## MemoryIO !!! warning You need to install dependencies to use The Memory Cache. ```console $ pip install authx_extra ``` ::: authx_extra.extra._memory.MemoryIO ``` -------------------------------- ### Login with Bundle Source: https://github.com/yezz123/authx/blob/main/docs/dependencies/bundle.md Demonstrates how to log in a user and set access cookies using the AuthXDependency bundle, simplifying the process by not requiring explicit response object handling. ```python from fastapi import FastAPI from authx import AuthX, AuthXConfig, AuthXDependency app = FastAPI() config = AuthXConfig( JWT_SECRET_KEY="your-secret-key", JWT_TOKEN_LOCATION=["cookies"], JWT_COOKIE_SECURE=False, ) auth = AuthX(config=config) auth.handle_errors(app) @app.post("/login") def login(deps: AuthXDependency = auth.BUNDLE): token = deps.create_access_token(uid="user") deps.set_access_cookies(token) # No response object needed! return {"message": "Logged in"} ``` -------------------------------- ### Comparing Aliases vs. Direct Dependency Injection Source: https://github.com/yezz123/authx/blob/main/docs/dependencies/aliases.md Demonstrates the difference in code verbosity when using AuthX dependency aliases compared to direct dependency injection for access token requirements. ```python from fastapi import FastAPI, Depends from authx import AuthX, AuthXConfig app = FastAPI() auth = AuthX(config=AuthXConfig(JWT_SECRET_KEY="secret")) auth.handle_errors(app) @app.get("/", dependencies=[Depends(auth.access_token_required)]) def root(payload=Depends(auth.access_token_required)): return {"user": payload.sub} ``` ```python from fastapi import FastAPI from authx import AuthX, AuthXConfig app = FastAPI() auth = AuthX(config=AuthXConfig(JWT_SECRET_KEY="secret")) auth.handle_errors(app) @app.get("/", dependencies=[auth.ACCESS_REQUIRED]) def root(payload=auth.ACCESS_REQUIRED): return {"user": payload.sub} ``` -------------------------------- ### Getting the Token Payload Source: https://github.com/yezz123/authx/blob/main/docs/get-started/scopes.md Access the token payload, including user information and scopes, by using the `auth.scopes_required()` dependency and type-hinting the parameter with `TokenPayload`. ```APIDOC ### Getting the Token Payload If you need access to the token payload (to get user info or scopes): ```python from typing import Annotated from authx.schema import TokenPayload @app.get("/profile") async def get_profile( payload: Annotated[TokenPayload, Depends(auth.scopes_required("profile:read"))] ): return { "user": payload.sub, "scopes": payload.scopes, } ``` ``` -------------------------------- ### Deploy with Both Symmetric Keys Source: https://github.com/yezz123/authx/blob/main/docs/get-started/key-rotation.md Illustrates the configuration step for deploying AuthX with both the new and the previous symmetric secret keys during a key rotation. ```python config = AuthXConfig( JWT_SECRET_KEY=new_key, JWT_PREVIOUS_SECRET_KEY=old_key, ) ``` -------------------------------- ### Send JWT in Authorization Header (cURL) Source: https://github.com/yezz123/authx/blob/main/docs/get-started/location.md Example of sending a JWT token in the Authorization header using cURL. Ensure the token is prefixed with 'Bearer '. ```bash curl -H "Authorization: Bearer " http://localhost:8000/protected ```