Initial commit from template

This commit is contained in:
Obi.M 2025-03-13 14:13:06 +01:00
commit d5fddb8fd2
8 changed files with 171 additions and 0 deletions

35
.gitignore vendored Normal file
View File

@ -0,0 +1,35 @@
# Python
__pycache__/
*.py[cod]
*$py.class
# Environment
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Logs
*.log
# Local development
.settings/
.vscode/
# Database
*.db
*.sqlite
# Temporary files
*.tmp
*.temp
# Security
secrets.json
credentials.json
# IDE specific
.idea/

9
core/auth.py Normal file
View File

@ -0,0 +1,9 @@
from fastapi import Depends, HTTPException
from core.database import fake_users_db
async def get_current_user_dummy(username: str = "demo"):
"""Demo auth dependency"""
user = fake_users_db.get(username)
if not user:
raise HTTPException(status_code=404, detail="User not found")
return user

11
core/database.py Normal file
View File

@ -0,0 +1,11 @@
from typing import Dict, Any
# Demo database
fake_users_db: Dict[str, Dict[str, Any]] = {
"demo": {
"id": "7b0a5c28-32aa-4e39-975f-88c8a029a5e2",
"email": "demo@example.com",
"password": "password",
"disabled": False
}
}

35
core/router.py Normal file
View File

@ -0,0 +1,35 @@
import importlib.util
from pathlib import Path
from fastapi import APIRouter
def load_endpoints(base_path: Path = Path("endpoints")) -> APIRouter:
router = APIRouter()
for file_path in base_path.glob("**/*.*.py"):
# Parse path components
relative_path = file_path.relative_to(base_path)
path_parts = list(relative_path.parts)
# Extract HTTP method from filename
filename = path_parts[-1]
name_parts = filename.split(".")
if len(name_parts) < 3 or name_parts[-1] != "py":
continue # Skip invalid formats
method = name_parts[-2].upper()
endpoint_name = ".".join(name_parts[:-2])
# Build URL path
url_path = "/" + "/".join(path_parts[:-1] + [endpoint_name])
url_path = url_path.replace("[", "{").replace("]", "}") # Convert path params
# Load the module
spec = importlib.util.spec_from_file_location("", file_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
# Find the router in the module
if hasattr(module, "router"):
router.include_router(module.router, prefix=url_path)
return router

25
endpoints/login.post.py Normal file
View File

@ -0,0 +1,25 @@
from fastapi import APIRouter, Depends, HTTPException
from core.auth import get_current_user_dummy
from core.database import fake_users_db
router = APIRouter()
@router.post("/login")
async def login_demo(
username: str = "demo",
password: str = "password"
):
"""Demo login endpoint"""
user = fake_users_db.get(username)
if not user or user["password"] != password:
raise HTTPException(status_code=400, detail="Invalid credentials")
return {
"message": "Login successful (demo)",
"user": username,
"token": "dummy_jwt_token_123",
"features": {
"rate_limit": 100,
"expires_in": 3600
}
}

33
endpoints/signup.post.py Normal file
View File

@ -0,0 +1,33 @@
from fastapi import APIRouter, HTTPException
from core.database import fake_users_db
import uuid
router = APIRouter()
@router.post("/signup")
async def signup_demo(
username: str = "new_user",
email: str = "user@example.com",
password: str = "securepassword123"
):
"""Demo signup endpoint"""
if username in fake_users_db:
raise HTTPException(status_code=400, detail="Username already exists")
user_id = str(uuid.uuid4())
fake_users_db[username] = {
"id": user_id,
"email": email,
"password": password,
"disabled": False
}
return {
"message": "User created successfully",
"user_id": user_id,
"username": username,
"next_steps": [
"Verify your email (demo)",
"Complete profile setup"
]
}

18
main.py Normal file
View File

@ -0,0 +1,18 @@
from fastapi import FastAPI
from pathlib import Path
from core.router import load_endpoints
app = FastAPI(title="API Starter Template")
# Load all endpoints
app.include_router(load_endpoints(Path("endpoints")))
@app.get("/")
def root():
return {
"message": "API Server Running",
"endpoints": {
"login": "/auth/login (POST)",
"signup": "/auth/signup (POST)"
}
}

5
requirements.txt Normal file
View File

@ -0,0 +1,5 @@
fastapi>=0.68.0
uvicorn[standard]
python-multipart
python-jose[cryptography]
passlib[bcrypt]