Skip to content

Commit 5e88f0a

Browse files
Implement User and Task Management Endpoints with FastAPI and SQLAlchemy (#1)
* assignment Signed-off-by: vignesh261201 <[email protected]> * Docker setup done Signed-off-by: vignesh261201 <[email protected]> * Removed the unwanted files Signed-off-by: vignesh261201 <[email protected]> --------- Signed-off-by: vignesh261201 <[email protected]>
1 parent 0e8720d commit 5e88f0a

File tree

12 files changed

+1083
-0
lines changed

12 files changed

+1083
-0
lines changed

Dockerfile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Use an official Python runtime as a parent image
2+
FROM python:3.11-slim
3+
4+
# Set the working directory
5+
WORKDIR /app
6+
7+
# Copy the requirements file
8+
COPY requirements.txt .
9+
10+
# Install dependencies
11+
RUN pip install --no-cache-dir -r requirements.txt
12+
13+
# Copy the application code
14+
COPY . .
15+
16+
# Expose the port FastAPI runs on
17+
EXPOSE 8000
18+
19+
# Command to run the application
20+
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]

docker-compose.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
services:
2+
app:
3+
build: .
4+
ports:
5+
- "8000:8000"
6+
volumes:
7+
- .:/app
8+
command: uvicorn main:app --host 0.0.0.0 --port 8000 --reload
9+
db:
10+
image: postgres:15.9
11+
environment:
12+
POSTGRES_USER: postgres
13+
POSTGRES_PASSWORD: password
14+
POSTGRES_DB: task_management
15+
ports:
16+
- "5432:5432"

main.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
from fastapi import FastAPI, Depends, HTTPException
2+
from sqlalchemy.orm import Session
3+
from typing import List, Optional
4+
from project import models, schemas, database
5+
6+
models.Base.metadata.create_all(bind=database.engine)
7+
8+
app = FastAPI()
9+
10+
11+
def get_db():
12+
db = database.SessionLocal()
13+
try:
14+
yield db
15+
finally:
16+
db.close()
17+
18+
19+
@app.post("/users/", response_model=schemas.User)
20+
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
21+
db_user = models.User(name=user.name, email=user.email)
22+
db.add(db_user)
23+
db.commit()
24+
db.refresh(db_user)
25+
return db_user
26+
27+
28+
@app.get("/users/{user_id}/", response_model=schemas.User)
29+
def get_user(user_id: int, db: Session = Depends(get_db)):
30+
user = db.query(models.User).filter(models.User.id == user_id).first()
31+
if not user:
32+
raise HTTPException(status_code=404, detail="User not found")
33+
return user
34+
35+
36+
@app.get("/users/", response_model=List[schemas.User])
37+
def list_users(db: Session = Depends(get_db)):
38+
return db.query(models.User).all()
39+
40+
41+
@app.post("/tasks/", response_model=schemas.Task)
42+
def create_task(task: schemas.TaskCreate, db: Session = Depends(get_db)):
43+
db_task = models.Task(**task.dict())
44+
db.add(db_task)
45+
db.commit()
46+
db.refresh(db_task)
47+
return db_task
48+
49+
50+
@app.get("/tasks/{task_id}/", response_model=schemas.Task)
51+
def get_task(task_id: int, db: Session = Depends(get_db)):
52+
task = db.query(models.Task).filter(models.Task.id == task_id).first()
53+
if not task:
54+
raise HTTPException(status_code=404, detail="Task not found")
55+
return task
56+
57+
58+
@app.get("/tasks/", response_model=List[schemas.Task])
59+
def list_tasks(user_id: Optional[int] = None, db: Session = Depends(get_db)):
60+
query = db.query(models.Task)
61+
if user_id:
62+
query = query.filter(models.Task.user_id == user_id)
63+
return query.all()
64+
65+
66+
@app.put("/tasks/{task_id}/", response_model=schemas.Task)
67+
def update_task(task_id: int, task: schemas.TaskUpdate, db: Session = Depends(get_db)):
68+
db_task = db.query(models.Task).filter(models.Task.id == task_id).first()
69+
if not db_task:
70+
raise HTTPException(status_code=404, detail="Task not found")
71+
72+
for key, value in task.dict(exclude_unset=True).items():
73+
setattr(db_task, key, value)
74+
75+
db.commit()
76+
db.refresh(db_task)
77+
return db_task
78+
79+
80+
@app.delete("/tasks/{task_id}/", response_model=schemas.Task)
81+
def delete_task(task_id: int, db: Session = Depends(get_db)):
82+
db_task = db.query(models.Task).filter(models.Task.id == task_id).first()
83+
if not db_task:
84+
raise HTTPException(status_code=404, detail="Task not found")
85+
86+
db.delete(db_task)
87+
db.commit()
88+
return db_task

poetry.lock

Lines changed: 761 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

project/__init__.py

Whitespace-only changes.

project/database.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from sqlalchemy import create_engine
2+
from sqlalchemy.orm import sessionmaker
3+
4+
SQLALCHEMY_DATABASE_URL = "sqlite:///./database.db"
5+
6+
engine = create_engine(
7+
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
8+
)
9+
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

project/models.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from sqlalchemy import Column, Integer, String, ForeignKey, DateTime
2+
from sqlalchemy.orm import relationship
3+
from sqlalchemy.ext.declarative import declarative_base
4+
5+
Base = declarative_base()
6+
7+
8+
class User(Base):
9+
__tablename__ = "users"
10+
11+
id = Column(Integer, primary_key=True, index=True)
12+
name = Column(String, index=True)
13+
email = Column(String, unique=True, index=True)
14+
15+
tasks = relationship("Task", back_populates="user")
16+
17+
18+
class Task(Base):
19+
__tablename__ = "tasks"
20+
21+
id = Column(Integer, primary_key=True, index=True)
22+
title = Column(String, index=True)
23+
description = Column(String, nullable=True)
24+
due_date = Column(DateTime, nullable=True)
25+
status = Column(String, default="pending")
26+
user_id = Column(Integer, ForeignKey("users.id"))
27+
28+
user = relationship("User", back_populates="tasks")

project/schemas.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from pydantic import BaseModel
2+
from typing import Optional
3+
from datetime import datetime
4+
5+
6+
class UserBase(BaseModel):
7+
name: str
8+
email: str
9+
10+
11+
class UserCreate(UserBase):
12+
pass
13+
14+
15+
class User(UserBase):
16+
id: int
17+
18+
class Config:
19+
from_attributes = True
20+
21+
22+
class TaskBase(BaseModel):
23+
title: str
24+
description: Optional[str] = None
25+
due_date: Optional[datetime] = None
26+
status: Optional[str] = "pending"
27+
user_id: int
28+
29+
30+
class TaskCreate(TaskBase):
31+
pass
32+
33+
34+
class TaskUpdate(BaseModel):
35+
title: Optional[str] = None
36+
description: Optional[str] = None
37+
due_date: Optional[datetime] = None
38+
status: Optional[str] = None
39+
40+
41+
class Task(TaskBase):
42+
id: int
43+
44+
class Config:
45+
from_attributes = True

pyproject.toml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[tool.poetry]
2+
name = "task management"
3+
version = "0.1.0"
4+
description = ""
5+
authors = ["Vigneshwaran Selvaraj <[email protected]>"]
6+
readme = "README.md"
7+
8+
[tool.poetry.dependencies]
9+
python = "^3.9"
10+
fastapi = "^0.115.5"
11+
sqlalchemy = "^2.0.36"
12+
uvicorn = "^0.32.0"
13+
pydantic = "^2.9.2"
14+
pytest = "^8.3.3"
15+
httpx = "^0.27.2"
16+
17+
18+
[tool.poetry.group.dev.dependencies]
19+
flake8 = "^7.1.1"
20+
black = "^24.10.0"
21+
isort = "^5.13.2"
22+
23+
[build-system]
24+
requires = ["poetry-core"]
25+
build-backend = "poetry.core.masonry.api"

requirements.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pywin32==306; platform_system == "Windows"
2+
pydantic==2.8.2
3+
uvicorn==0.23.1
4+
fastapi==0.103.1
5+
python-dateutil==2.9.0
6+
sqlalchemy==2.0.36

0 commit comments

Comments
 (0)