Skip to content

Commit 5badb8c

Browse files
committed
Initialize the app
0 parents  commit 5badb8c

11 files changed

Lines changed: 210 additions & 0 deletions

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
env
2+
__pycache__
3+
4+
.env

Project/.github/workflows/ci.yml

Whitespace-only changes.

Project/.gitignore

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

Project/Dockerfile

Whitespace-only changes.

Project/README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# 📝 FastAPI Todo API
2+
3+
A simple FastAPI-based Todo application with SQLite + Docker support.
4+
5+
---
6+
7+
## 🚀 Features
8+
9+
- ✅ REST API with FastAPI
10+
- 🗃️ SQLite database using SQLModel
11+
- 🐳 Dockerized for easy deployment
12+
- 🔄 GitHub Actions CI for linting and build test
13+
14+
---
15+
16+
## 📦 Tech Stack
17+
18+
- FastAPI
19+
- SQLModel
20+
- SQLite
21+
- Docker
22+
- GitHub Actions
23+
24+
---
25+
26+
## 🛠️ Setup Locally
27+
28+
```bash
29+
git clone https://github.com/YOUR_USERNAME/fastapi-todo.git
30+
cd fastapi-todo
31+
python -m venv venv
32+
source venv/bin/activate
33+
pip install -r requirements.txt
34+
uvicorn app.main:app --reload

Project/app/database.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from sqlmodel import SQLModel, create_engine
2+
3+
#! SQLite file name
4+
sqlite_file_name = "database.db"
5+
DATABASE_URL = f"sqlite:///{sqlite_file_name}"
6+
7+
8+
#! Create engine
9+
engine = create_engine(DATABASE_URL, echo=True)
10+
11+
12+
#! Initialize DB
13+
def create_db_and_table():
14+
SQLModel.metadata.create_all(engine)

Project/app/main.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
from contextlib import asynccontextmanager
2+
from fastapi import FastAPI, HTTPException
3+
from database import create_db_and_table, engine
4+
from models import Todo
5+
from sqlmodel import Session, select
6+
from typing import List
7+
import logging
8+
9+
#! Setup basic logging
10+
logging.basicConfig(level=logging.INFO)
11+
12+
13+
@asynccontextmanager
14+
async def lifespan(app: FastAPI):
15+
logging.info("🚀 Starting up... Creating database tables.")
16+
create_db_and_table()
17+
18+
yield
19+
20+
#! Shutdown login (cleanup)
21+
logging.info("🛑 Shutting down... Cleaning up resources")
22+
23+
24+
app = FastAPI(lifespan=lifespan)
25+
26+
27+
#! Create Todo list
28+
@app.post("/todo/", response_model=Todo)
29+
def create_todo(todo: Todo):
30+
with Session(engine) as session:
31+
session.add(todo)
32+
session.commit()
33+
session.refresh(todo)
34+
return todo
35+
36+
37+
#! Get all todos
38+
@app.get("/todo/", response_model=List[Todo])
39+
def get_all_todos():
40+
with Session(engine) as session:
41+
todos = session.exec(select(Todo)).all()
42+
return todos
43+
44+
45+
#! Get todo by id
46+
@app.get("/todo/{todo_id}/", response_model=Todo)
47+
def get_todo(todo_id: int):
48+
with Session(engine) as session:
49+
todo = session.get(Todo, todo_id)
50+
if not todo:
51+
raise HTTPException(status_code=404, detail="Todo not found")
52+
return todo

Project/app/models.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from sqlmodel import SQLModel, Field
2+
from typing import Optional
3+
4+
5+
#! Create Model
6+
class Todo(SQLModel, table=True):
7+
id: Optional[int] = Field(default=None, primary_key=True)
8+
title: str
9+
completed: bool = False

Project/requirements.txt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
annotated-types==0.7.0
2+
anyio==4.9.0
3+
certifi==2025.4.26
4+
click==8.1.8
5+
colorama==0.4.6
6+
dnspython==2.7.0
7+
email_validator==2.2.0
8+
fastapi==0.115.12
9+
fastapi-cli==0.0.7
10+
greenlet==3.2.1
11+
h11==0.16.0
12+
httpcore==1.0.9
13+
httptools==0.6.4
14+
httpx==0.28.1
15+
idna==3.10
16+
Jinja2==3.1.6
17+
markdown-it-py==3.0.0
18+
MarkupSafe==3.0.2
19+
mdurl==0.1.2
20+
pydantic==2.11.4
21+
pydantic_core==2.33.2
22+
Pygments==2.19.1
23+
python-dotenv==1.1.0
24+
python-multipart==0.0.20
25+
PyYAML==6.0.2
26+
rich==14.0.0
27+
rich-toolkit==0.14.5
28+
shellingham==1.5.4
29+
sniffio==1.3.1
30+
SQLAlchemy==2.0.40
31+
sqlmodel==0.0.24
32+
starlette==0.46.2
33+
typer==0.15.3
34+
typing-inspection==0.4.0
35+
typing_extensions==4.13.2
36+
uvicorn==0.34.2
37+
watchfiles==1.0.5
38+
websockets==15.0.1

main.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from fastapi import FastAPI
2+
3+
app = FastAPI()
4+
5+
6+
#! Root Path
7+
@app.get("/")
8+
async def root():
9+
return {"message": "Hello Genius"}
10+
11+
12+
#! Path parameter - Integer
13+
@app.get("/items/{item_id}")
14+
async def readItem(item_id: int):
15+
return {"Item ID ": item_id}
16+
17+
18+
#! Path parameter - String
19+
@app.get("/items_name/{item_name}")
20+
async def readItemName(item_name: str):
21+
return {"Item Name ": item_name}
22+
23+
#! Query Parameters

0 commit comments

Comments
 (0)