Skip to content

Commit b4d3ab7

Browse files
serving ML model
1 parent 1054ab9 commit b4d3ab7

File tree

16 files changed

+3578
-226
lines changed

16 files changed

+3578
-226
lines changed

fastapi_intro/.gitignore

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
# .gitignore for Python projects
2-
.venv/
1+
/.venv/
32
/__pycache__/
43
*.pyc
5-
uv.lock
4+
uv.lock

fastapi_intro/FastApi/app.py

Lines changed: 178 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,185 @@
1-
# Import FastAPI class from fastapi package
2-
from fastapi import FastAPI
1+
# Import necessary modules from FastAPI, Pydantic, and standard libraries
2+
from fastapi import FastAPI, Path, HTTPException, Query
3+
from fastapi.responses import JSONResponse
4+
from pydantic import BaseModel, Field, computed_field
5+
from typing import Annotated, Literal, Optional
6+
import json
37
import uvicorn
4-
# Create FastAPI app instance with metadata
5-
app = FastAPI(
6-
title="FastAPI", # Title of the API
7-
description="A FastAPI project managed with uv", # Description of the API
8-
version="1.0.0" # Version of the API
9-
)
10-
11-
# Root endpoint: returns a welcome message
8+
9+
# Initialize the FastAPI app
10+
app = FastAPI()
11+
12+
# --------- Pydantic Models ---------
13+
class Patient(BaseModel):
14+
"""
15+
Schema for patient information.
16+
Includes fields for ID, name, city, age, gender, height, weight, and computed properties for BMI and health verdict.
17+
"""
18+
id: Annotated[str, Field(..., description='ID of the patient', examples=['P001'])]
19+
name: Annotated[str, Field(..., description='Name of the patient')]
20+
city: Annotated[str, Field(..., description='City where the patient is living')]
21+
age: Annotated[int, Field(..., gt=0, lt=120, description='Age of the patient')]
22+
gender: Annotated[Literal['male', 'female', 'others'], Field(..., description='Gender of the patient')]
23+
height: Annotated[float, Field(..., gt=0, description='Height of the patient in meters')]
24+
weight: Annotated[float, Field(..., gt=0, description='Weight of the patient in kilograms')]
25+
26+
@computed_field
27+
@property
28+
def bmi(self) -> float:
29+
"""
30+
Calculate Body Mass Index (BMI).
31+
BMI = weight (kg) / (height (m))^2
32+
"""
33+
return round(self.weight / (self.height ** 2), 2)
34+
35+
@computed_field
36+
@property
37+
def verdict(self) -> str:
38+
"""
39+
Provide a health verdict based on BMI.
40+
"""
41+
if self.bmi < 18.5:
42+
return 'Underweight'
43+
elif self.bmi < 25:
44+
return 'Normal'
45+
elif self.bmi < 30:
46+
return 'Overweight'
47+
return 'Obese'
48+
49+
class PatientUpdate(BaseModel):
50+
"""
51+
Schema for updating patient information.
52+
Allows partial updates with optional fields.
53+
"""
54+
name: Annotated[Optional[str], Field(default=None)]
55+
city: Annotated[Optional[str], Field(default=None)]
56+
age: Annotated[Optional[int], Field(default=None, gt=0, lt=120)]
57+
gender: Annotated[Optional[Literal['male', 'female', 'others']], Field(default=None)]
58+
height: Annotated[Optional[float], Field(default=None, gt=0)]
59+
weight: Annotated[Optional[float], Field(default=None, gt=0)]
60+
61+
# --------- Utility Functions ---------
62+
def load_data() -> dict:
63+
"""
64+
Load patient data from a JSON file.
65+
"""
66+
with open('patients.json', 'r') as f:
67+
return json.load(f)
68+
69+
def save_data(data: dict) -> None:
70+
"""
71+
Save patient data to a JSON file.
72+
"""
73+
with open('patients.json', 'w') as f:
74+
json.dump(data, f)
75+
76+
# --------- API Routes ---------
1277
@app.get("/")
13-
def read_root():
14-
return {"message": "Welcome to FastAPI with uv!"}
78+
def hello():
79+
"""
80+
Root endpoint: Welcome message for the API.
81+
"""
82+
return {'message': 'Patient Management System API'}
1583

16-
# Endpoint 1: Greets the user by name
17-
@app.get("/hello")
18-
def greet_user(name: str):
19-
return {"message": f"Hello, {name}!"}
84+
@app.get('/about')
85+
def about():
86+
"""
87+
About endpoint: Provides information about the API.
88+
"""
89+
return {'message': 'A fully functional API to manage your patient records'}
2090

21-
# Endpoint 2: Returns the square of a given number
22-
@app.get("/square/{number}")
23-
def square_number(number: int):
24-
return {"number": number, "square": number * number}
91+
@app.get('/view')
92+
def view():
93+
"""
94+
View all patients in the database.
95+
"""
96+
return load_data()
2597

98+
@app.get('/patient/{patient_id}')
99+
def view_patient(patient_id: str = Path(..., description='ID of the patient in the DB', example='P001')):
100+
"""
101+
View details of a specific patient by ID.
102+
"""
103+
data = load_data()
104+
if patient_id in data:
105+
return data[patient_id]
106+
raise HTTPException(status_code=404, detail='Patient not found')
26107

27-
# Endpoint to get the length of the text
28-
if __name__ == "__main__":
108+
@app.get('/sort')
109+
def sort_patients(
110+
sort_by: str = Query(..., description='Sort on the basis of height, weight, or BMI'),
111+
order: str = Query('asc', description='Sort in ascending or descending order')
112+
):
113+
"""
114+
Sort patients by a specified field and order.
115+
"""
116+
valid_fields = ['height', 'weight', 'bmi']
117+
if sort_by not in valid_fields:
118+
raise HTTPException(status_code=400, detail=f'Invalid field. Select from {valid_fields}')
119+
if order not in ['asc', 'desc']:
120+
raise HTTPException(status_code=400, detail='Invalid order. Select between asc and desc')
121+
122+
data = load_data()
123+
sorted_list = sorted(
124+
data.values(),
125+
key=lambda x: x.get(sort_by, 0),
126+
reverse=(order == 'desc')
127+
)
128+
return sorted_list
29129

30-
# Run the FastAPI app using uvicorn server
31-
uvicorn.run(app, host="127.0.0.1", port=8000, reload=True)
130+
@app.post('/create')
131+
def create_patient(patient: Patient):
132+
"""
133+
Create a new patient record.
134+
"""
135+
data = load_data()
136+
if patient.id in data:
137+
raise HTTPException(status_code=400, detail='Patient already exists')
138+
139+
data[patient.id] = patient.model_dump(exclude=['id'])
140+
save_data(data)
141+
return JSONResponse(status_code=201, content={'message': 'Patient created successfully'})
142+
143+
@app.put('/edit/{patient_id}')
144+
def update_patient(patient_id: str, patient_update: PatientUpdate):
145+
"""
146+
Update an existing patient's information.
147+
"""
148+
data = load_data()
149+
if patient_id not in data:
150+
raise HTTPException(status_code=404, detail='Patient not found')
151+
152+
existing_patient_info = data[patient_id]
153+
updated_patient_info = patient_update.model_dump(exclude_unset=True)
154+
155+
for key, value in updated_patient_info.items():
156+
existing_patient_info[key] = value
157+
158+
existing_patient_info['id'] = patient_id
159+
patient_pydantic_obj = Patient(**existing_patient_info)
160+
existing_patient_info = patient_pydantic_obj.model_dump(exclude=['id'])
161+
162+
data[patient_id] = existing_patient_info
163+
save_data(data)
164+
return JSONResponse(status_code=200, content={'message': 'Patient updated successfully'})
165+
166+
@app.delete('/delete/{patient_id}')
167+
def delete_patient(patient_id: str):
168+
"""
169+
Delete a patient record by ID.
170+
"""
171+
data = load_data()
172+
if patient_id not in data:
173+
raise HTTPException(status_code=404, detail='Patient not found')
174+
175+
del data[patient_id]
176+
save_data(data)
177+
return JSONResponse(status_code=200, content={'message': 'Patient deleted successfully'})
178+
179+
# --------- Run the App ---------
180+
if __name__ == "__main__":
181+
"""
182+
Run the FastAPI app using uvicorn.
183+
"""
184+
uvicorn.run(app, host="127.0.0.1", port=8000, reload=True)
185+
# To run the app, use the command: uvicorn app:app --reload

fastapi_intro/FastApi/get_methed.py

Lines changed: 0 additions & 69 deletions
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"P002": {"name": "Ravi Mehta", "city": "Mumbai", "age": 35, "gender": "male", "height": 1.75, "weight": 85, "bmi": 27.76, "verdict": "Overweight"}, "P003": {"name": "Sneha Kulkarni", "city": "Pune", "age": 22, "gender": "female", "height": 1.6, "weight": 45, "bmi": 17.58, "verdict": "Underweight"}, "P005": {"name": "Neha Sinha", "city": "Kolkata", "age": 30, "gender": "female", "height": 1.55, "weight": 75, "bmi": 31.22, "verdict": "Obese"}, "P006": {"name": "suresh", "city": "umerkot", "age": 20, "gender": "Male", "height": 5.5, "weight": 90.0, "bmi": 2.98, "verdict": "under"}, "P007": {"name": "kumar", "city": "karachi", "age": 70, "gender": "Male", "height": 7.0, "weight": 90.0, "bmi": 1.84, "verdict": "Underweight"}, "P008": {"name": "RK BEEKHANO", "city": "NEW Chhor", "age": 15, "gender": "Male", "height": 6.0, "weight": 34.0, "bmi": 0.94, "verdict": "Underweight"}}

fastapi_intro/FastApi/put_methed.py

Whitespace-only changes.

0 commit comments

Comments
 (0)