Skip to content

Commit 21a7dfd

Browse files
committed
Merge branch '2025-project'
2 parents b760c07 + 5051b1d commit 21a7dfd

16 files changed

Lines changed: 666 additions & 0 deletions

File tree

2025/project/.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
db_user=your_db_user
2+
db_password=your_db_password

2025/project/.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.13

2025/project/Dockerfile

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
FROM python:3.13-slim-bookworm
2+
3+
RUN apt-get update && apt-get install --no-install-recommends -y \
4+
build-essential && \
5+
apt-get clean && rm -rf /var/lib/apt/lists/*
6+
7+
ADD https://astral.sh/uv/install.sh /install.sh
8+
RUN chmod -R 755 /install.sh && /install.sh && rm /install.sh
9+
10+
# Set up the UV environment path correctly
11+
ENV PATH="/root/.local/bin:${PATH}"
12+
13+
WORKDIR /app
14+
15+
COPY . .
16+
17+
RUN uv sync
18+
19+
ENV PATH="/app/.venv/bin:{$PATH}"
20+
21+
# Expose the specified port for FastAPI
22+
EXPOSE $PORT
23+
24+
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]

2025/project/README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
Starting the server:
2+
3+
uv run uvicorn app.main:app --reload
4+
5+
Example requests:
6+
7+
Here’s a set of simple curl examples you can use to interact with your FastAPI app once it’s running (default at http://localhost:8000):
8+
9+
1️⃣ Create a User
10+
11+
curl -X POST "http://localhost:8000/api/v1/users" \
12+
-H "Content-Type: application/json" \
13+
-d '{"name": "Ada Lovelace"}'
14+
15+
16+
2️⃣ Get All Users
17+
18+
curl -X GET "http://localhost:8000/api/v1/users"
19+
20+
21+
3️⃣ Get a User by ID
22+
23+
(Replace 1 with the actual ID from the create response)
24+
25+
curl -X GET "http://localhost:8000/api/v1/users/1"
26+
27+
28+
4️⃣ Update a User
29+
30+
curl -X PUT "http://localhost:8000/api/v1/users/1" \
31+
-H "Content-Type: application/json" \
32+
-d '{"name": "Grace Hopper"}'
33+
34+
35+
36+
37+
5️⃣ Delete a User
38+
39+
curl -X DELETE "http://localhost:8000/api/v1/users/1"

2025/project/app/api/v1/user.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from fastapi import APIRouter, Depends, HTTPException
2+
3+
from app.db.schema import SessionLocal
4+
from app.models.user import UserCreate, UserRead
5+
from app.services.user_service import UserService
6+
7+
router = APIRouter()
8+
9+
10+
def get_user_service() -> UserService:
11+
return UserService(session=SessionLocal())
12+
13+
14+
@router.get("/users", response_model=list[UserRead])
15+
def get_users(service: UserService = Depends(get_user_service)):
16+
return service.list_users()
17+
18+
19+
@router.post("/users", response_model=UserRead)
20+
def create_user(user: UserCreate, service: UserService = Depends(get_user_service)):
21+
return service.create_user(user.name)
22+
23+
24+
@router.get("/users/{user_id}", response_model=UserRead)
25+
def get_user(user_id: int, service: UserService = Depends(get_user_service)):
26+
user = service.get_user(user_id)
27+
if not user:
28+
raise HTTPException(status_code=404, detail="User not found")
29+
return user
30+
31+
32+
@router.put("/users/{user_id}", response_model=UserRead)
33+
def update_user(
34+
user_id: int, user: UserCreate, service: UserService = Depends(get_user_service)
35+
):
36+
updated = service.update_user(user_id, user.name)
37+
if not updated:
38+
raise HTTPException(status_code=404, detail="User not found")
39+
return updated
40+
41+
42+
@router.delete("/users/{user_id}")
43+
def delete_user(user_id: int, service: UserService = Depends(get_user_service)):
44+
success = service.delete_user(user_id)
45+
if not success:
46+
raise HTTPException(status_code=404, detail="User not found")
47+
return {"success": True}

2025/project/app/core/config.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from dotenv import load_dotenv
2+
from pydantic_settings import BaseSettings
3+
4+
load_dotenv()
5+
6+
7+
class Config(BaseSettings):
8+
app_name: str = "ScalableFastAPIProject"
9+
debug: bool = False
10+
db_user: str = ""
11+
db_password: str = ""
12+
db_name: str = "test.db"
13+
14+
@property
15+
def db_url(self):
16+
return f"sqlite:///./{self.db_name}"
17+
18+
19+
config = Config()

2025/project/app/core/logging.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import logging
2+
3+
def setup_logging():
4+
logging.basicConfig(
5+
level=logging.INFO,
6+
format="%(asctime)s %(levelname)s [%(name)s] %(message)s"
7+
)

2025/project/app/db/schema.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from sqlalchemy import String, create_engine
2+
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, sessionmaker
3+
4+
from app.core.config import config
5+
6+
engine = create_engine(config.db_url, connect_args={"check_same_thread": False})
7+
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
8+
9+
10+
class Base(DeclarativeBase):
11+
pass
12+
13+
14+
class User(Base):
15+
__tablename__ = "users"
16+
17+
id: Mapped[int] = mapped_column(primary_key=True)
18+
name: Mapped[str] = mapped_column(String, index=True)

2025/project/app/main.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from fastapi import FastAPI
2+
3+
from app.api.v1 import user
4+
from app.core.config import config
5+
from app.core.logging import setup_logging
6+
from app.db.schema import Base, engine
7+
8+
setup_logging()
9+
Base.metadata.create_all(bind=engine)
10+
11+
app = FastAPI(title=config.app_name)
12+
13+
14+
# Register routes
15+
app.include_router(user.router, prefix="/api/v1")

2025/project/app/models/user.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from pydantic import BaseModel
2+
3+
4+
class UserCreate(BaseModel):
5+
name: str
6+
7+
8+
class UserRead(BaseModel):
9+
id: int
10+
name: str

0 commit comments

Comments
 (0)