Initial commit from template
This commit is contained in:
commit
7ea01dc243
35
.gitignore
vendored
Normal file
35
.gitignore
vendored
Normal 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
9
core/auth.py
Normal 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
11
core/database.py
Normal 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
|
||||||
|
}
|
||||||
|
}
|
18
core/router.py
Normal file
18
core/router.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
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"):
|
||||||
|
# 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 and include it directly
|
||||||
|
if hasattr(module, "router"):
|
||||||
|
router.include_router(module.router)
|
||||||
|
|
||||||
|
return router
|
11
endpoints/health.get.py
Normal file
11
endpoints/health.get.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
from fastapi import APIRouter
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
@router.get("/health")
|
||||||
|
async def health_check():
|
||||||
|
"""Health check endpoint"""
|
||||||
|
return {
|
||||||
|
"status": "ok",
|
||||||
|
"message": "Service is healthy"
|
||||||
|
}
|
25
endpoints/login.post.py
Normal file
25
endpoints/login.post.py
Normal 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
33
endpoints/signup.post.py
Normal 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"
|
||||||
|
]
|
||||||
|
}
|
19
main.py
Normal file
19
main.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
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": "FastAPI App Running",
|
||||||
|
"endpoints": {
|
||||||
|
"health": "/health (GET)",
|
||||||
|
"login": "/login (POST)",
|
||||||
|
"signup": "/signup (POST)"
|
||||||
|
}
|
||||||
|
}
|
5
requirements.txt
Normal file
5
requirements.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
fastapi>=0.68.0
|
||||||
|
uvicorn[standard]
|
||||||
|
python-multipart
|
||||||
|
python-jose[cryptography]
|
||||||
|
passlib[bcrypt]
|
Loading…
x
Reference in New Issue
Block a user