Skip to main content
Glama
main.py6.09 kB
""" FastAPI Complete API Template Production-ready FastAPI application with authentication, CRUD, and best practices. """ from fastapi import FastAPI, HTTPException, Depends, status from fastapi.middleware.cors import CORSMiddleware from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from pydantic import BaseModel, EmailStr, Field from typing import Optional, List from datetime import datetime, timedelta import hashlib import secrets # ============================================ # Models # ============================================ class UserCreate(BaseModel): email: EmailStr name: str = Field(..., min_length=2, max_length=50) password: str = Field(..., min_length=8) class UserResponse(BaseModel): id: int email: str name: str created_at: datetime class Config: from_attributes = True class UserUpdate(BaseModel): name: Optional[str] = Field(None, min_length=2, max_length=50) email: Optional[EmailStr] = None class Token(BaseModel): access_token: str token_type: str = "bearer" class LoginRequest(BaseModel): email: EmailStr password: str # ============================================ # Database (In-Memory for Demo) # ============================================ class Database: def __init__(self): self.users: dict[int, dict] = {} self.tokens: dict[str, int] = {} # token -> user_id self.next_id = 1 def create_user(self, data: UserCreate) -> dict: user = { "id": self.next_id, "email": data.email, "name": data.name, "password_hash": hashlib.sha256(data.password.encode()).hexdigest(), "created_at": datetime.utcnow() } self.users[self.next_id] = user self.next_id += 1 return user def get_user(self, user_id: int) -> Optional[dict]: return self.users.get(user_id) def get_user_by_email(self, email: str) -> Optional[dict]: for user in self.users.values(): if user["email"] == email: return user return None def get_all_users(self) -> List[dict]: return list(self.users.values()) def update_user(self, user_id: int, data: UserUpdate) -> Optional[dict]: user = self.users.get(user_id) if not user: return None if data.name: user["name"] = data.name if data.email: user["email"] = data.email return user def delete_user(self, user_id: int) -> bool: if user_id in self.users: del self.users[user_id] return True return False def create_token(self, user_id: int) -> str: token = secrets.token_urlsafe(32) self.tokens[token] = user_id return token def verify_token(self, token: str) -> Optional[int]: return self.tokens.get(token) db = Database() # ============================================ # Auth # ============================================ security = HTTPBearer() async def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)) -> dict: token = credentials.credentials user_id = db.verify_token(token) if not user_id: raise HTTPException(status_code=401, detail="Invalid token") user = db.get_user(user_id) if not user: raise HTTPException(status_code=401, detail="User not found") return user # ============================================ # App Setup # ============================================ app = FastAPI( title="Code-MCP API Template", description="Production-ready FastAPI template", version="1.0.0" ) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # ============================================ # Routes # ============================================ @app.get("/health") async def health_check(): return {"status": "healthy", "timestamp": datetime.utcnow().isoformat()} @app.post("/auth/register", response_model=UserResponse, status_code=status.HTTP_201_CREATED) async def register(data: UserCreate): if db.get_user_by_email(data.email): raise HTTPException(status_code=400, detail="Email already registered") user = db.create_user(data) return user @app.post("/auth/login", response_model=Token) async def login(data: LoginRequest): user = db.get_user_by_email(data.email) if not user: raise HTTPException(status_code=401, detail="Invalid credentials") password_hash = hashlib.sha256(data.password.encode()).hexdigest() if user["password_hash"] != password_hash: raise HTTPException(status_code=401, detail="Invalid credentials") token = db.create_token(user["id"]) return {"access_token": token} @app.get("/users", response_model=List[UserResponse]) async def get_users(current_user: dict = Depends(get_current_user)): return db.get_all_users() @app.get("/users/{user_id}", response_model=UserResponse) async def get_user(user_id: int, current_user: dict = Depends(get_current_user)): user = db.get_user(user_id) if not user: raise HTTPException(status_code=404, detail="User not found") return user @app.put("/users/{user_id}", response_model=UserResponse) async def update_user(user_id: int, data: UserUpdate, current_user: dict = Depends(get_current_user)): user = db.update_user(user_id, data) if not user: raise HTTPException(status_code=404, detail="User not found") return user @app.delete("/users/{user_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_user(user_id: int, current_user: dict = Depends(get_current_user)): if not db.delete_user(user_id): raise HTTPException(status_code=404, detail="User not found") # ============================================ # Run # ============================================ if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/millsydotdev/Code-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server