diff --git a/fastapi-mongo/Dockerfile b/fastapi-mongo/Dockerfile new file mode 100644 index 0000000..5bef015 --- /dev/null +++ b/fastapi-mongo/Dockerfile @@ -0,0 +1,12 @@ +FROM python:3.10-slim + +WORKDIR /app + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY main.py . + +EXPOSE 8000 + +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/fastapi-mongo/README.md b/fastapi-mongo/README.md new file mode 100644 index 0000000..4458655 --- /dev/null +++ b/fastapi-mongo/README.md @@ -0,0 +1,13 @@ +# FastAPI + MongoDB Sample App + +This sample demonstrates a simple Student Management API using FastAPI and MongoDB. + +## Features + +- Create, Read, Update, Delete (CRUD) operations for students +- Async MongoDB access using Motor +- Ready for Keploy API test recording + +## Running Locally + +1. **Start MongoDB** (Docker example): diff --git a/fastapi-mongo/__pycache__/main.cpython-313.pyc b/fastapi-mongo/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000..b3151c5 Binary files /dev/null and b/fastapi-mongo/__pycache__/main.cpython-313.pyc differ diff --git a/fastapi-mongo/main.py b/fastapi-mongo/main.py new file mode 100644 index 0000000..166cc21 --- /dev/null +++ b/fastapi-mongo/main.py @@ -0,0 +1,67 @@ +from fastapi import FastAPI, HTTPException +from pydantic import BaseModel, Field +from typing import List +from motor.motor_asyncio import AsyncIOMotorClient +from bson import ObjectId + +app = FastAPI(title="Student Management API (FastAPI + MongoDB)") + +# MongoDB connection +MONGO_DETAILS = "mongodb://localhost:27017" +client = AsyncIOMotorClient(MONGO_DETAILS) +db = client.students_db +collection = db.students + +class Student(BaseModel): + id: str = Field(default_factory=str, alias="_id") + name: str + age: int + + class Config: + allow_population_by_field_name = True + arbitrary_types_allowed = True + json_encoders = {ObjectId: str} + +@app.post("/students", response_model=Student) +async def create_student(student: Student): + student_dict = student.dict(by_alias=True) + student_dict.pop("id", None) + result = await collection.insert_one(student_dict) + student_dict["_id"] = str(result.inserted_id) + return Student(**student_dict) + +@app.get("/students", response_model=List[Student]) +async def get_students(): + students = [] + async for doc in collection.find(): + doc["_id"] = str(doc["_id"]) + students.append(Student(**doc)) + return students + +@app.get("/students/{student_id}", response_model=Student) +async def get_student(student_id: str): + student = await collection.find_one({"_id": ObjectId(student_id)}) + if student: + student["_id"] = str(student["_id"]) + return Student(**student) + raise HTTPException(status_code=404, detail="Student not found") + +@app.put("/students/{student_id}", response_model=Student) +async def update_student(student_id: str, student: Student): + student_dict = student.dict(by_alias=True) + student_dict.pop("id", None) + result = await collection.update_one( + {"_id": ObjectId(student_id)}, {"$set": student_dict} + ) + if result.modified_count == 1: + updated = await collection.find_one({"_id": ObjectId(student_id)}) + updated["_id"] = str(updated["_id"]) + return Student(**updated) + raise HTTPException(status_code=404, detail="Student not found") + +@app.delete("/students/{student_id}") +async def delete_student(student_id: str): + result = await collection.delete_one({"_id": ObjectId(student_id)}) + if result.deleted_count == 1: + return {"message": "Student deleted"} + raise HTTPException(status_code=404, detail="Student not found") diff --git a/fastapi-mongo/requirements.txt b/fastapi-mongo/requirements.txt new file mode 100644 index 0000000..9c9a39a --- /dev/null +++ b/fastapi-mongo/requirements.txt @@ -0,0 +1,4 @@ +fastapi +uvicorn +motor +pydantic