File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ env
2+ __pycache__
3+
4+ .env
Original file line number Diff line number Diff line change 1+ venv
Original file line number Diff line number Diff line change 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
Original file line number Diff line number Diff line change 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 )
Original file line number Diff line number Diff line change 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
Original file line number Diff line number Diff line change 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
Original file line number Diff line number Diff line change 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
Original file line number Diff line number Diff line change 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
You can’t perform that action at this time.
0 commit comments