Updated to expose auth_app instead of app_route
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,5 @@
|
|||||||
|
**/UserDB
|
||||||
|
|
||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[codz]
|
*.py[codz]
|
||||||
|
|||||||
3
Makefile
3
Makefile
@@ -15,4 +15,5 @@ clean-build: clean-package
|
|||||||
find . -name "*.pyo" -exec rm -f {} +
|
find . -name "*.pyo" -exec rm -f {} +
|
||||||
|
|
||||||
# Alias to clean everything
|
# Alias to clean everything
|
||||||
clean: clean-build
|
clean: clean-build
|
||||||
|
find . -name "UserDB" -exec rm -f {} +
|
||||||
49
README.md
49
README.md
@@ -75,17 +75,18 @@ This example configures myauth to use MongoDB as its backend.
|
|||||||
```Python
|
```Python
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from myauth import create_app_router_for_mongoDB
|
|
||||||
|
from myauth import create_auth_app_for_mongodb
|
||||||
|
|
||||||
# 1. Initialize FastAPI app
|
# 1. Initialize FastAPI app
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
||||||
# 2. Configure repositories for MongoDB
|
# 2. Configure repositories for MongoDB
|
||||||
auth_router = create_app_router_for_mongoDB(mongodb_url="mongodb://localhost:27017",
|
auth_app = create_auth_app_for_mongodb(mongodb_url="mongodb://localhost:27017",
|
||||||
jwt_secret="THIS_NEEDS_TO_BE_CHANGED")
|
jwt_secret="THIS_NEEDS_TO_BE_CHANGED")
|
||||||
|
|
||||||
# 3. Include the authentication routes
|
# 3. Include the authentication routes
|
||||||
app.include_router(auth_router)
|
app.mount("/auth", auth_app)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
@app.get("/")
|
||||||
@@ -100,19 +101,20 @@ This example configures myauth to use PostgreSQL as its backend.
|
|||||||
```Python
|
```Python
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from myauth import create_app_router_for_postgreSQL
|
|
||||||
|
from myauth import create_auth_app_for_postgresql
|
||||||
|
|
||||||
# 1. Initialize FastAPI app
|
# 1. Initialize FastAPI app
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
||||||
# 2. Configure repositories for MongoDB
|
# 2. Configure repositories for PostgreSQL
|
||||||
auth_router = create_app_router_for_mongoDB(postgresql_url="mongodb://localhost:27017",
|
auth_app = create_auth_app_for_postgresql(postgresql_url="mongodb://localhost:27017",
|
||||||
username="admin",
|
username="admin",
|
||||||
password="password",
|
password="password",
|
||||||
jwt_secret="THIS_NEEDS_TO_BE_CHANGED")
|
jwt_secret="THIS_NEEDS_TO_BE_CHANGED")
|
||||||
|
|
||||||
# 3. Include the authentication routes
|
# 3. Include the authentication routes
|
||||||
app.include_router(auth_router)
|
app.mount("/auth", auth_app)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
@app.get("/")
|
||||||
@@ -127,16 +129,17 @@ This example configures myauth to use SQLite, which is ideal for development or
|
|||||||
```Python
|
```Python
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from myauth import create_app_router_for_sqlite
|
|
||||||
|
from myauth import create_auth_app_for_sqlite
|
||||||
|
|
||||||
# 1. Initialize FastAPI app
|
# 1. Initialize FastAPI app
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
||||||
# 2. Configure repositories for MongoDB
|
# 2. Configure repositories for MongoDB
|
||||||
auth_router = create_app_router_for_sqlite(db_path="./UserDB", jwt_secret="THIS_NEEDS_TO_BE_CHANGED")
|
auth_app = create_auth_app_for_sqlite(db_path="./UserDB", jwt_secret="THIS_NEEDS_TO_BE_CHANGED")
|
||||||
|
|
||||||
# 3. Include the authentication routes
|
# 3. Include the authentication routes
|
||||||
app.include_router(auth_router)
|
app.mount("/auth", auth_app)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
@app.get("/")
|
||||||
@@ -159,8 +162,9 @@ pip install "myauth[email]"
|
|||||||
```Python
|
```Python
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
|
from myauth import create_auth_app_for_sqlite
|
||||||
from myauth.emailing.smtp import SMTPEmailService
|
from myauth.emailing.smtp import SMTPEmailService
|
||||||
from myauth import create_app_router_for_sqlite
|
|
||||||
|
|
||||||
# 1. Initialize FastAPI app
|
# 1. Initialize FastAPI app
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
@@ -175,11 +179,11 @@ email_service = SMTPEmailService(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# 3. Configure repositories for MongoDB
|
# 3. Configure repositories for MongoDB
|
||||||
auth_router = create_app_router_for_sqlite(db_path="./UserDB", jwt_secret="THIS_NEEDS_TO_BE_CHANGED",
|
auth_app = create_auth_app_for_sqlite(db_path="./UserDB", jwt_secret="THIS_NEEDS_TO_BE_CHANGED",
|
||||||
email_service=email_service)
|
email_service=email_service)
|
||||||
|
|
||||||
# 4. Include the authentication routes
|
# 4. Include the authentication routes
|
||||||
app.include_router(auth_router)
|
app.mount("/auth", auth_app)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Option 2: Create a Custom Email Service
|
### Option 2: Create a Custom Email Service
|
||||||
@@ -189,8 +193,9 @@ If you use a third-party service (like AWS SES, Mailgun) that requires an API, y
|
|||||||
```Python
|
```Python
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
|
from myauth import create_auth_app_for_sqlite
|
||||||
from myauth.emailing.base import EmailService
|
from myauth.emailing.base import EmailService
|
||||||
from myauth import create_app_router_for_sqlite
|
|
||||||
|
|
||||||
# 1. Initialize FastAPI app
|
# 1. Initialize FastAPI app
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
@@ -220,11 +225,11 @@ class CustomEmailService(EmailService):
|
|||||||
email_service = CustomEmailService(api_key="YOUR_API_KEY_HERE")
|
email_service = CustomEmailService(api_key="YOUR_API_KEY_HERE")
|
||||||
|
|
||||||
# 3. Pass your custom service to AuthService
|
# 3. Pass your custom service to AuthService
|
||||||
auth_router = create_app_router_for_sqlite(db_path="./UserDB", jwt_secret="THIS_NEEDS_TO_BE_CHANGED",
|
auth_app = create_auth_app_for_sqlite(db_path="./UserDB", jwt_secret="THIS_NEEDS_TO_BE_CHANGED",
|
||||||
email_service=email_service)
|
email_service=email_service)
|
||||||
|
|
||||||
# 4. Include the authentication routes
|
# 4. Include the authentication routes
|
||||||
app.include_router(auth_router)
|
app.mount("/auth", auth_app)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "myauth"
|
name = "myauth"
|
||||||
version = "0.5.0"
|
version = "0.1.0"
|
||||||
description = "A reusable, modular authentication system for FastAPI applications with pluggable database backends."
|
description = "A reusable, modular authentication system for FastAPI applications with pluggable database backends."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
authors = [
|
authors = [
|
||||||
|
|||||||
22
src/main.py
Normal file
22
src/main.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import uvicorn
|
||||||
|
from fastapi import FastAPI
|
||||||
|
|
||||||
|
from myauth import create_auth_app_for_sqlite
|
||||||
|
|
||||||
|
# 1. Initialize FastAPI app
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
# 2. Configure repositories for MongoDB
|
||||||
|
auth_app = create_auth_app_for_sqlite(db_path="./UserDB", jwt_secret="THIS_NEEDS_TO_BE_CHANGED")
|
||||||
|
|
||||||
|
# 3. Include the authentication routes
|
||||||
|
app.mount("/auth", auth_app)
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/")
|
||||||
|
def read_root():
|
||||||
|
return {"message": "Application running with MyAuth (SQLite)"}
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
uvicorn.run(app, host="0.0.0.0", port=8000)
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
from .factory import create_sqlite_auth_service, create_app_router_for_sqlite
|
from .factory import create_sqlite_auth_service, create_auth_app_for_sqlite, create_auth_app_for_mongodb, \
|
||||||
|
create_auth_app_for_postgresql
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'create_sqlite_auth_service',
|
'create_sqlite_auth_service',
|
||||||
'create_app_router_for_sqlite',
|
'create_auth_app_for_sqlite',
|
||||||
|
'create_auth_app_for_mongodb',
|
||||||
|
'create_auth_app_for_postgresql'
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
from .routes import create_auth_router
|
from .routes import create_auth_app
|
||||||
|
|
||||||
__all__ = ["create_auth_router"]
|
__all__ = ["create_auth_app"]
|
||||||
@@ -7,7 +7,7 @@ operations. Routes are organized in an APIRouter with /auth prefix.
|
|||||||
|
|
||||||
from typing import Annotated
|
from typing import Annotated
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException, status
|
from fastapi import Depends, HTTPException, status, FastAPI
|
||||||
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
||||||
|
|
||||||
from ..core.auth import AuthService
|
from ..core.auth import AuthService
|
||||||
@@ -24,7 +24,7 @@ from ..models.user import UserCreate, UserResponse
|
|||||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/auth/login")
|
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/auth/login")
|
||||||
|
|
||||||
|
|
||||||
def create_auth_router(auth_service: AuthService) -> APIRouter:
|
def create_auth_app(auth_service: AuthService) -> FastAPI:
|
||||||
"""
|
"""
|
||||||
Create and configure the authentication router.
|
Create and configure the authentication router.
|
||||||
|
|
||||||
@@ -40,13 +40,13 @@ def create_auth_router(auth_service: AuthService) -> APIRouter:
|
|||||||
|
|
||||||
Example:
|
Example:
|
||||||
>>> from fastapi import FastAPI
|
>>> from fastapi import FastAPI
|
||||||
>>> from auth_module.api.routes import create_auth_router
|
>>> from myauth.api.routes import create_auth_app
|
||||||
>>>
|
>>>
|
||||||
>>> app = FastAPI()
|
>>> app = FastAPI()
|
||||||
>>> auth_router = create_auth_router(auth_service)
|
>>> auth_api = create_auth_app(auth_service)
|
||||||
>>> app.include_router(auth_router)
|
>>> app.mount(auth_api)
|
||||||
"""
|
"""
|
||||||
router = APIRouter(prefix="/auth", tags=["authentication"])
|
auth_app = FastAPI(prefix="/auth", tags=["authentication"])
|
||||||
|
|
||||||
def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]) -> UserResponse:
|
def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]) -> UserResponse:
|
||||||
"""
|
"""
|
||||||
@@ -65,7 +65,7 @@ def create_auth_router(auth_service: AuthService) -> APIRouter:
|
|||||||
HTTPException: 401 if token is invalid or expired.
|
HTTPException: 401 if token is invalid or expired.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
>>> @app.get("/protected")
|
>>> @auth_app.get("/protected")
|
||||||
>>> def protected_route(user: UserResponse = Depends(get_current_user)):
|
>>> def protected_route(user: UserResponse = Depends(get_current_user)):
|
||||||
>>> return {"user_id": user.id}
|
>>> return {"user_id": user.id}
|
||||||
"""
|
"""
|
||||||
@@ -86,7 +86,7 @@ def create_auth_router(auth_service: AuthService) -> APIRouter:
|
|||||||
detail=e.message
|
detail=e.message
|
||||||
)
|
)
|
||||||
|
|
||||||
@router.post(
|
@auth_app.post(
|
||||||
"/register",
|
"/register",
|
||||||
response_model=UserResponse,
|
response_model=UserResponse,
|
||||||
status_code=status.HTTP_201_CREATED,
|
status_code=status.HTTP_201_CREATED,
|
||||||
@@ -128,7 +128,7 @@ def create_auth_router(auth_service: AuthService) -> APIRouter:
|
|||||||
detail=e.message
|
detail=e.message
|
||||||
)
|
)
|
||||||
|
|
||||||
@router.post(
|
@auth_app.post(
|
||||||
"/login",
|
"/login",
|
||||||
response_model=AccessTokenResponse,
|
response_model=AccessTokenResponse,
|
||||||
summary="Login with email and password",
|
summary="Login with email and password",
|
||||||
@@ -163,7 +163,7 @@ def create_auth_router(auth_service: AuthService) -> APIRouter:
|
|||||||
detail=e.message
|
detail=e.message
|
||||||
)
|
)
|
||||||
|
|
||||||
@router.post(
|
@auth_app.post(
|
||||||
"/logout",
|
"/logout",
|
||||||
status_code=status.HTTP_204_NO_CONTENT,
|
status_code=status.HTTP_204_NO_CONTENT,
|
||||||
summary="Logout user",
|
summary="Logout user",
|
||||||
@@ -185,7 +185,7 @@ def create_auth_router(auth_service: AuthService) -> APIRouter:
|
|||||||
auth_service.logout(request.refresh_token)
|
auth_service.logout(request.refresh_token)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@router.post(
|
@auth_app.post(
|
||||||
"/refresh",
|
"/refresh",
|
||||||
response_model=AccessTokenResponse,
|
response_model=AccessTokenResponse,
|
||||||
summary="Refresh access token",
|
summary="Refresh access token",
|
||||||
@@ -217,7 +217,7 @@ def create_auth_router(auth_service: AuthService) -> APIRouter:
|
|||||||
detail=e.message
|
detail=e.message
|
||||||
)
|
)
|
||||||
|
|
||||||
@router.post(
|
@auth_app.post(
|
||||||
"/password-reset-request",
|
"/password-reset-request",
|
||||||
status_code=status.HTTP_200_OK,
|
status_code=status.HTTP_200_OK,
|
||||||
summary="Request password reset",
|
summary="Request password reset",
|
||||||
@@ -252,7 +252,7 @@ def create_auth_router(auth_service: AuthService) -> APIRouter:
|
|||||||
detail=e.message
|
detail=e.message
|
||||||
)
|
)
|
||||||
|
|
||||||
@router.post(
|
@auth_app.post(
|
||||||
"/password-reset",
|
"/password-reset",
|
||||||
status_code=status.HTTP_200_OK,
|
status_code=status.HTTP_200_OK,
|
||||||
summary="Reset password with token",
|
summary="Reset password with token",
|
||||||
@@ -284,7 +284,7 @@ def create_auth_router(auth_service: AuthService) -> APIRouter:
|
|||||||
detail=e.message
|
detail=e.message
|
||||||
)
|
)
|
||||||
|
|
||||||
@router.post(
|
@auth_app.post(
|
||||||
"/verify-email-request",
|
"/verify-email-request",
|
||||||
status_code=status.HTTP_200_OK,
|
status_code=status.HTTP_200_OK,
|
||||||
summary="Request email verification",
|
summary="Request email verification",
|
||||||
@@ -320,7 +320,7 @@ def create_auth_router(auth_service: AuthService) -> APIRouter:
|
|||||||
detail=e.message
|
detail=e.message
|
||||||
)
|
)
|
||||||
|
|
||||||
@router.get(
|
@auth_app.get(
|
||||||
"/verify-email",
|
"/verify-email",
|
||||||
status_code=status.HTTP_200_OK,
|
status_code=status.HTTP_200_OK,
|
||||||
summary="Verify email with token",
|
summary="Verify email with token",
|
||||||
@@ -352,7 +352,7 @@ def create_auth_router(auth_service: AuthService) -> APIRouter:
|
|||||||
detail=e.message
|
detail=e.message
|
||||||
)
|
)
|
||||||
|
|
||||||
@router.get(
|
@auth_app.get(
|
||||||
"/me",
|
"/me",
|
||||||
response_model=UserResponse,
|
response_model=UserResponse,
|
||||||
summary="Get current user",
|
summary="Get current user",
|
||||||
@@ -376,4 +376,4 @@ def create_auth_router(auth_service: AuthService) -> APIRouter:
|
|||||||
"""
|
"""
|
||||||
return current_user
|
return current_user
|
||||||
|
|
||||||
return router
|
return auth_app
|
||||||
|
|||||||
@@ -57,9 +57,9 @@ def create_sqlite_auth_service(db_path: str,
|
|||||||
return auth_service
|
return auth_service
|
||||||
|
|
||||||
|
|
||||||
def create_app_router_for_sqlite(db_path: str,
|
def create_auth_app_for_sqlite(db_path: str,
|
||||||
jwt_secret: str,
|
jwt_secret: str,
|
||||||
email_service: Optional[EmailService] = None):
|
email_service: Optional[EmailService] = None):
|
||||||
"""
|
"""
|
||||||
Creates an application router designed to use with an SQLite database backend.
|
Creates an application router designed to use with an SQLite database backend.
|
||||||
This function initializes an authentication service using the provided database
|
This function initializes an authentication service using the provided database
|
||||||
@@ -74,5 +74,17 @@ def create_app_router_for_sqlite(db_path: str,
|
|||||||
:return: An application router configured for handling authentication API routes.
|
:return: An application router configured for handling authentication API routes.
|
||||||
"""
|
"""
|
||||||
auth_service = create_sqlite_auth_service(db_path, jwt_secret, email_service)
|
auth_service = create_sqlite_auth_service(db_path, jwt_secret, email_service)
|
||||||
from .api.routes import create_auth_router
|
from .api.routes import create_auth_app
|
||||||
return create_auth_router(auth_service)
|
return create_auth_app(auth_service)
|
||||||
|
|
||||||
|
|
||||||
|
def create_auth_app_for_mongodb(mongodb_url="mongodb://localhost:27017",
|
||||||
|
jwt_secret="THIS_NEEDS_TO_BE_CHANGED"):
|
||||||
|
raise NotImplementedError("MongoDB support is not yet implemented.")
|
||||||
|
|
||||||
|
|
||||||
|
def create_auth_app_for_postgresql(postgresql_url="mongodb://localhost:27017",
|
||||||
|
username="admin",
|
||||||
|
password="password",
|
||||||
|
jwt_secret="THIS_NEEDS_TO_BE_CHANGED"):
|
||||||
|
raise NotImplementedError("PostgreSQL support is not yet implemented.")
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import pytest
|
|||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
|
|
||||||
from myauth.api.routes import create_auth_router
|
from myauth.api import create_auth_app
|
||||||
from myauth.core.auth import AuthService
|
from myauth.core.auth import AuthService
|
||||||
from myauth.exceptions import (
|
from myauth.exceptions import (
|
||||||
UserAlreadyExistsError,
|
UserAlreadyExistsError,
|
||||||
@@ -51,8 +51,8 @@ def test_app(mock_auth_service):
|
|||||||
FastAPI application configured for testing.
|
FastAPI application configured for testing.
|
||||||
"""
|
"""
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
auth_router = create_auth_router(mock_auth_service)
|
auth_app = create_auth_app(mock_auth_service)
|
||||||
app.include_router(auth_router)
|
app.mount("/auth", auth_app)
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user