Spaces:
Runtime error
Runtime error
PrabhuKiranKonda
commited on
Commit
•
cb7f5fc
1
Parent(s):
749e816
added project files and dockerfile
Browse files- Dockerfile +10 -0
- __pycache__/__init__.cpython-39.pyc +0 -0
- __pycache__/app.cpython-39.pyc +0 -0
- __pycache__/database.cpython-39.pyc +0 -0
- app.py +10 -0
- database.py +66 -0
- models/__pycache__/schema.cpython-39.pyc +0 -0
- models/schema.py +98 -0
- requirements.txt +5 -0
- routes/__pycache__/__init__.cpython-39.pyc +0 -0
- routes/__pycache__/student_routes.cpython-39.pyc +0 -0
- routes/student_routes.py +59 -0
Dockerfile
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FROM python:3.9-slim
|
2 |
+
WORKDIR /app
|
3 |
+
COPY requirements.txt ./requirements.txt
|
4 |
+
# Install uvicorn
|
5 |
+
RUN pip install uvicorn
|
6 |
+
# Install dependencies
|
7 |
+
RUN pip install -r requirements.txt
|
8 |
+
COPY . /app
|
9 |
+
ENTRYPOINT ["uvicorn", "app:app"]
|
10 |
+
CMD ["--host", "0.0.0.0", "--port", "7860"]
|
__pycache__/__init__.cpython-39.pyc
ADDED
Binary file (162 Bytes). View file
|
|
__pycache__/app.cpython-39.pyc
ADDED
Binary file (539 Bytes). View file
|
|
__pycache__/database.cpython-39.pyc
ADDED
Binary file (1.92 kB). View file
|
|
app.py
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import FastAPI
|
2 |
+
from routes.student_routes import router as StudentRouter
|
3 |
+
|
4 |
+
app = FastAPI(title="FastAPI and MongoDB")
|
5 |
+
app.include_router(StudentRouter, tags=["Student"], prefix="/student")
|
6 |
+
|
7 |
+
|
8 |
+
@app.get("/", tags=["Root"])
|
9 |
+
async def root():
|
10 |
+
return {"message": "FastAPI and MongoDB"}
|
database.py
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import motor.motor_asyncio
|
2 |
+
import os
|
3 |
+
from bson.objectid import ObjectId
|
4 |
+
|
5 |
+
MONGO_DETAILS = os.getenv("MONGO_DETAILS")
|
6 |
+
|
7 |
+
client = motor.motor_asyncio.AsyncIOMotorClient(MONGO_DETAILS)
|
8 |
+
|
9 |
+
database = client.fastapi_students
|
10 |
+
|
11 |
+
students_collection = database.get_collection("students")
|
12 |
+
|
13 |
+
|
14 |
+
# helpers
|
15 |
+
def student_helper(student) -> dict:
|
16 |
+
return {
|
17 |
+
"id": str(student["_id"]),
|
18 |
+
"name": student["name"],
|
19 |
+
"email": student["email"],
|
20 |
+
"password": student["password"],
|
21 |
+
"year": student["year"],
|
22 |
+
"branch": student["branch"],
|
23 |
+
"division": student["division"],
|
24 |
+
"pin": student["pin"],
|
25 |
+
"gpa": student["gpa"],
|
26 |
+
"phone": student["phone"],
|
27 |
+
"address": student["address"],
|
28 |
+
}
|
29 |
+
|
30 |
+
# Retrieve all students present in the database
|
31 |
+
|
32 |
+
|
33 |
+
async def get_all():
|
34 |
+
students = []
|
35 |
+
async for student in students_collection.find():
|
36 |
+
students.append(student_helper(student))
|
37 |
+
return students
|
38 |
+
|
39 |
+
|
40 |
+
async def add(student_data: dict) -> dict:
|
41 |
+
student = await students_collection.insert_one(student_data)
|
42 |
+
new_student = await students_collection.find_one({"_id": student.inserted_id})
|
43 |
+
return student_helper(new_student)
|
44 |
+
|
45 |
+
|
46 |
+
async def get(PIN: str) -> dict:
|
47 |
+
student = await students_collection.find_one({"pin": PIN})
|
48 |
+
if student:
|
49 |
+
return student_helper(student)
|
50 |
+
|
51 |
+
async def update(PIN: str, updated_data: dict) -> dict:
|
52 |
+
if not updated_data:
|
53 |
+
return False
|
54 |
+
student = await students_collection.find_one({"pin": PIN})
|
55 |
+
if student:
|
56 |
+
students_collection.update_one({"pin": PIN}, {"$set": updated_data})
|
57 |
+
return True
|
58 |
+
return False
|
59 |
+
|
60 |
+
|
61 |
+
async def delete(PIN: str):
|
62 |
+
student = await students_collection.find_one({"pin": PIN})
|
63 |
+
if student:
|
64 |
+
await students_collection.delete_one({"pin": PIN})
|
65 |
+
return True
|
66 |
+
return False
|
models/__pycache__/schema.cpython-39.pyc
ADDED
Binary file (3.25 kB). View file
|
|
models/schema.py
ADDED
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import Optional
|
2 |
+
from pydantic import BaseModel, Field, EmailStr
|
3 |
+
|
4 |
+
|
5 |
+
class StudentSchema(BaseModel):
|
6 |
+
name: str = Field(..., example="John Doe",
|
7 |
+
description="Name of the student")
|
8 |
+
email: EmailStr = Field(..., example="johndoe@gmail.com",
|
9 |
+
description="Email of the student")
|
10 |
+
password: str = Field(..., example="JohnDoe123",
|
11 |
+
description="Password of the student")
|
12 |
+
year: int = Field(..., gt=0, lt=5, example=1, description="Year of study")
|
13 |
+
branch: str = Field(..., min_length=3,
|
14 |
+
example="CSE or Computer Science and Engineering", description="Branch of study")
|
15 |
+
division: str = Field(..., min_length=1, max_length=1,
|
16 |
+
example="A", description="Division of study")
|
17 |
+
pin: str = Field(..., min_length=10, max_length=10,
|
18 |
+
example="20KJ1A0501", description="PIN of the student")
|
19 |
+
gpa: Optional[float] = Field(
|
20 |
+
None, gt=0, lt=10, example=9.0, description="GPA of the student")
|
21 |
+
phone: int = Field(..., gt=1000000000, lt=9999999999,
|
22 |
+
example=1234567890, description="Phone number of the student")
|
23 |
+
address: str = Field(..., min_length=3, max_length=100,
|
24 |
+
example="123, 1st cross, 1st main, City, State, Country - 123456", description="Address of the student")
|
25 |
+
|
26 |
+
class Config:
|
27 |
+
schema_extra = {
|
28 |
+
"Example": {
|
29 |
+
"name": "John Doe",
|
30 |
+
"email": "Johndoe@example.com",
|
31 |
+
"password": "JohnDoe123",
|
32 |
+
"year": 1,
|
33 |
+
"branch": "CSE",
|
34 |
+
"division": "A",
|
35 |
+
"pin": "20KJ1A0501",
|
36 |
+
"gpa": 9.0,
|
37 |
+
"phone": 1234567890,
|
38 |
+
"address": """
|
39 |
+
123, 1st cross, 1st main,
|
40 |
+
City, State, Country - 123456""",
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
|
45 |
+
class StudentUpdateSchema(BaseModel):
|
46 |
+
name: Optional[str] = Field(
|
47 |
+
None, example="John Doe", description="Name of the student")
|
48 |
+
email: Optional[EmailStr] = Field(
|
49 |
+
None, example="johndoe@example.com", description="Email")
|
50 |
+
password: Optional[str] = Field(
|
51 |
+
None, example="JohnDoe123", description="Password")
|
52 |
+
year: Optional[int] = Field(
|
53 |
+
None, gt=0, lt=5, example=1, description="Year of study")
|
54 |
+
branch: Optional[str] = Field(
|
55 |
+
None, min_length=3, example="CSE or Computer Science and Engineering", description="Branch of study")
|
56 |
+
division: Optional[str] = Field(
|
57 |
+
None, min_length=1, max_length=1, example="A", description="Division of study")
|
58 |
+
pin: Optional[str] = Field(None, min_length=10, max_length=10,
|
59 |
+
example="20KJ1A0501", description="PIN of the student")
|
60 |
+
gpa: Optional[float] = Field(
|
61 |
+
None, gt=0, lt=10, example=9.0, description="GPA of the student")
|
62 |
+
|
63 |
+
phone: Optional[int] = Field(None, gt=1000000000, lt=9999999999,
|
64 |
+
example=1234567890, description="Phone number of the student")
|
65 |
+
|
66 |
+
address: Optional[str] = Field(None, min_length=3, max_length=100,
|
67 |
+
example="123, 1st cross, 1st main, City, State, Country - 123456",
|
68 |
+
description="Address of the student")
|
69 |
+
|
70 |
+
class Config:
|
71 |
+
schema_extra = {
|
72 |
+
"Example": {
|
73 |
+
"name": "John Doe",
|
74 |
+
"email": "Johndoe@example.com",
|
75 |
+
"password": "JohnDoe123",
|
76 |
+
"year": 1,
|
77 |
+
"branch": "CSE",
|
78 |
+
"division": "A",
|
79 |
+
"pin": "20KJ1A0501",
|
80 |
+
"gpa": 9.0,
|
81 |
+
"phone": 1234567890,
|
82 |
+
"address": """
|
83 |
+
123, 1st cross, 1st main,
|
84 |
+
City, State, Country - 123456""",
|
85 |
+
}
|
86 |
+
}
|
87 |
+
|
88 |
+
|
89 |
+
def ResponseModel(data, message):
|
90 |
+
return {
|
91 |
+
"data": [data],
|
92 |
+
"code": 200,
|
93 |
+
"message": message,
|
94 |
+
}
|
95 |
+
|
96 |
+
|
97 |
+
def ErrorResponseModel(error, code, message):
|
98 |
+
return {"error": error, "code": code, "message": message}
|
requirements.txt
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
fastapi==0.96.0
|
2 |
+
motor==2.5.1
|
3 |
+
pydantic==1.10.2
|
4 |
+
pydantic[email]
|
5 |
+
pymongo==3.13.0
|
routes/__pycache__/__init__.cpython-39.pyc
ADDED
Binary file (171 Bytes). View file
|
|
routes/__pycache__/student_routes.cpython-39.pyc
ADDED
Binary file (2.51 kB). View file
|
|
routes/student_routes.py
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import APIRouter, Body, status
|
2 |
+
from fastapi.encoders import jsonable_encoder
|
3 |
+
from models.schema import (
|
4 |
+
StudentSchema,
|
5 |
+
StudentUpdateSchema,
|
6 |
+
ResponseModel,
|
7 |
+
ErrorResponseModel,
|
8 |
+
)
|
9 |
+
|
10 |
+
from database import *
|
11 |
+
|
12 |
+
router = APIRouter()
|
13 |
+
|
14 |
+
|
15 |
+
@router.post("/", response_description="Student data added into the database")
|
16 |
+
async def add_student_data(student: StudentSchema = Body(...)):
|
17 |
+
student = jsonable_encoder(student)
|
18 |
+
|
19 |
+
if get_student_data(student["pin"]):
|
20 |
+
return ErrorResponseModel("Student Exist", 404, f"Student with PIN: {student['pin']} already exists.")
|
21 |
+
|
22 |
+
new_student = await add(student)
|
23 |
+
return ResponseModel(new_student, "Student added successfully.")
|
24 |
+
|
25 |
+
|
26 |
+
@router.get("/all", response_description="Students Data Retrieved")
|
27 |
+
async def get_all_students():
|
28 |
+
students = await get_all()
|
29 |
+
if len(students) < 1:
|
30 |
+
return ErrorResponseModel("Empty Database", 404, "No Students data found")
|
31 |
+
|
32 |
+
if students:
|
33 |
+
return ResponseModel(students, "Retrieved all students data")
|
34 |
+
ErrorResponseModel("An Error Occurred", 404, "No Students database found")
|
35 |
+
|
36 |
+
|
37 |
+
@router.get("/{pin}", response_description="Student data retrieved")
|
38 |
+
async def get_student_data(pin):
|
39 |
+
student = await get(pin)
|
40 |
+
if student:
|
41 |
+
return ResponseModel(student, "Student data retrieved successfully")
|
42 |
+
return ErrorResponseModel("An error occurred.", 404, "Student doesn't exist.")
|
43 |
+
|
44 |
+
|
45 |
+
@router.put("/{pin}")
|
46 |
+
async def update_student_data(pin: str, data: StudentUpdateSchema = Body(...)):
|
47 |
+
data = {k: v for k, v in data.dict().items() if v is not None}
|
48 |
+
updated_student = await update(pin, data)
|
49 |
+
if updated_student:
|
50 |
+
return ResponseModel(updated_student, f"{pin} data updated")
|
51 |
+
return ErrorResponseModel("An Error occurred", 404, "Cannot update the data. Maybe pin doesn't exist")
|
52 |
+
|
53 |
+
|
54 |
+
@router.delete("/delete/{pin}", response_description="Delete student from database")
|
55 |
+
async def delete_student(pin: str):
|
56 |
+
student = await delete(pin)
|
57 |
+
if student:
|
58 |
+
return ResponseModel(f"Student with {pin} removed from the database", "Operation Success")
|
59 |
+
return ErrorResponseModel("An Error occurred", 404, f"student with PIN {pin} does not exist")
|