Spaces:
Running
Running
Prathamesh Sable
commited on
Commit
·
2c89b88
1
Parent(s):
3f55893
docs and bug fix
Browse files- main.py +27 -3
- requirements.txt +3 -0
- templates/api_docs.html +186 -0
main.py
CHANGED
|
@@ -1,17 +1,41 @@
|
|
| 1 |
-
from fastapi import FastAPI
|
|
|
|
|
|
|
|
|
|
| 2 |
from routers.auth import router as auth_router
|
| 3 |
from routers.analysis import router as analysis_router
|
| 4 |
from routers.history import router as history_router
|
| 5 |
from routers.product import router as product_router
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
|
| 7 |
app = FastAPI()
|
| 8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
app.include_router(analysis_router, prefix="/api/analyze")
|
| 10 |
app.include_router(auth_router, prefix="/api/auth")
|
| 11 |
app.include_router(product_router, prefix="/api/product")
|
| 12 |
app.include_router(history_router, prefix="/api/history")
|
| 13 |
|
|
|
|
|
|
|
| 14 |
# To run the FastAPI app, use the command: uvicorn main:app --reload
|
| 15 |
if __name__ == "__main__":
|
| 16 |
-
|
| 17 |
-
uvicorn.run(app, host="0.0.0.0", port=
|
|
|
|
| 1 |
+
from fastapi import FastAPI, Request
|
| 2 |
+
from fastapi.responses import HTMLResponse, RedirectResponse
|
| 3 |
+
from fastapi.templating import Jinja2Templates
|
| 4 |
+
from fastapi.staticfiles import StaticFiles
|
| 5 |
from routers.auth import router as auth_router
|
| 6 |
from routers.analysis import router as analysis_router
|
| 7 |
from routers.history import router as history_router
|
| 8 |
from routers.product import router as product_router
|
| 9 |
+
from dotenv import load_dotenv
|
| 10 |
+
import os
|
| 11 |
+
import uvicorn
|
| 12 |
+
from pathlib import Path
|
| 13 |
+
|
| 14 |
+
load_dotenv()
|
| 15 |
+
# Load environment variables from .env file
|
| 16 |
+
PORT = os.getenv("PORT", 8000)
|
| 17 |
+
|
| 18 |
+
# Define the templates directory
|
| 19 |
+
templates = Jinja2Templates(directory="templates")
|
| 20 |
|
| 21 |
app = FastAPI()
|
| 22 |
|
| 23 |
+
@app.get("/")
|
| 24 |
+
def read_root():
|
| 25 |
+
return RedirectResponse("/api")
|
| 26 |
+
|
| 27 |
+
@app.get("/api", response_class=HTMLResponse)
|
| 28 |
+
async def read_api(request: Request):
|
| 29 |
+
return templates.TemplateResponse("api_docs.html", {"request": request})
|
| 30 |
+
|
| 31 |
app.include_router(analysis_router, prefix="/api/analyze")
|
| 32 |
app.include_router(auth_router, prefix="/api/auth")
|
| 33 |
app.include_router(product_router, prefix="/api/product")
|
| 34 |
app.include_router(history_router, prefix="/api/history")
|
| 35 |
|
| 36 |
+
app.add_event_handler("startup", lambda: print("Starting up..."))
|
| 37 |
+
|
| 38 |
# To run the FastAPI app, use the command: uvicorn main:app --reload
|
| 39 |
if __name__ == "__main__":
|
| 40 |
+
# run using fastapi directly for development purposes
|
| 41 |
+
uvicorn.run(app, host="0.0.0.0", port=PORT)
|
requirements.txt
CHANGED
|
@@ -2,11 +2,14 @@
|
|
| 2 |
fastapi==0.115.12
|
| 3 |
uvicorn==0.34.0
|
| 4 |
python-multipart==0.0.20
|
|
|
|
| 5 |
|
| 6 |
# Database
|
| 7 |
sqlalchemy==2.0.40
|
| 8 |
alembic==1.15.2
|
| 9 |
psycopg2-binary==2.9.10
|
|
|
|
|
|
|
| 10 |
|
| 11 |
# Authentication
|
| 12 |
python-jose==3.3.0
|
|
|
|
| 2 |
fastapi==0.115.12
|
| 3 |
uvicorn==0.34.0
|
| 4 |
python-multipart==0.0.20
|
| 5 |
+
jinja2
|
| 6 |
|
| 7 |
# Database
|
| 8 |
sqlalchemy==2.0.40
|
| 9 |
alembic==1.15.2
|
| 10 |
psycopg2-binary==2.9.10
|
| 11 |
+
mysqlclient
|
| 12 |
+
pymysql
|
| 13 |
|
| 14 |
# Authentication
|
| 15 |
python-jose==3.3.0
|
templates/api_docs.html
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html>
|
| 3 |
+
|
| 4 |
+
<head>
|
| 5 |
+
<title>FoodAnalyzer API Documentation</title>
|
| 6 |
+
<style>
|
| 7 |
+
body {
|
| 8 |
+
font-family: Arial, sans-serif;
|
| 9 |
+
margin: 20px;
|
| 10 |
+
line-height: 1.6;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
h1,
|
| 14 |
+
h2,
|
| 15 |
+
h3 {
|
| 16 |
+
color: #333;
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
.endpoint {
|
| 20 |
+
margin-bottom: 15px;
|
| 21 |
+
border-left: 4px solid #ddd;
|
| 22 |
+
padding-left: 15px;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
.method {
|
| 26 |
+
font-weight: bold;
|
| 27 |
+
color: #0066cc;
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
code {
|
| 31 |
+
background: #f4f4f4;
|
| 32 |
+
padding: 2px 5px;
|
| 33 |
+
border-radius: 3px;
|
| 34 |
+
font-family: monospace;
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
pre {
|
| 38 |
+
background: #f9f9f9;
|
| 39 |
+
padding: 10px;
|
| 40 |
+
border-radius: 5px;
|
| 41 |
+
overflow-x: auto;
|
| 42 |
+
}
|
| 43 |
+
</style>
|
| 44 |
+
</head>
|
| 45 |
+
|
| 46 |
+
<body>
|
| 47 |
+
<h1>FoodAnalyzer API Documentation</h1>
|
| 48 |
+
|
| 49 |
+
<h2>Authentication Endpoints</h2>
|
| 50 |
+
<div class="endpoint">
|
| 51 |
+
<p><span class="method">POST</span> <a href="/api/auth/register">/api/auth/register</a></p>
|
| 52 |
+
<p>Register a new user in the system</p>
|
| 53 |
+
<p>Request body:</p>
|
| 54 |
+
<pre><code>{
|
| 55 |
+
"name": "John Doe",
|
| 56 |
+
"email": "john@example.com",
|
| 57 |
+
"password": "securepassword"
|
| 58 |
+
}</code></pre>
|
| 59 |
+
<p>Response:</p>
|
| 60 |
+
<pre><code>{
|
| 61 |
+
"access_token": "eyJhbGciOiJIUzI1NiIs...",
|
| 62 |
+
"token_type": "bearer"
|
| 63 |
+
}</code></pre>
|
| 64 |
+
</div>
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
<div class="endpoint">
|
| 68 |
+
<p><span class="method">POST</span> <a href="/api/auth/login">/api/auth/login</a></p>
|
| 69 |
+
<p>Login to get an access token (valid for 4 weeks)</p>
|
| 70 |
+
<p>Form data: username (email), password</p>
|
| 71 |
+
<p>Response:</p>
|
| 72 |
+
<pre><code>{
|
| 73 |
+
"access_token": "eyJhbGciOiJIUzI1NiIs...",
|
| 74 |
+
"token_type": "bearer"
|
| 75 |
+
}</code></pre>
|
| 76 |
+
</div>
|
| 77 |
+
|
| 78 |
+
<div class="endpoint">
|
| 79 |
+
<p><span class="method">GET</span> <a href="/api/auth/user">/api/auth/user</a></p>
|
| 80 |
+
<p>Get current authenticated user's information</p>
|
| 81 |
+
<p>Headers: Authorization: Bearer {token}</p>
|
| 82 |
+
<p>Response:</p>
|
| 83 |
+
<pre><code>{
|
| 84 |
+
"name": "John Doe",
|
| 85 |
+
"email": "john@example.com"
|
| 86 |
+
}</code></pre>
|
| 87 |
+
</div>
|
| 88 |
+
|
| 89 |
+
<div class="endpoint">
|
| 90 |
+
<p><span class="method">GET</span> <a href="/api/auth/user/email">/api/auth/user/email</a></p>
|
| 91 |
+
<p>Get user information by email</p>
|
| 92 |
+
<p>Query parameters: email</p>
|
| 93 |
+
</div>
|
| 94 |
+
|
| 95 |
+
<h2>Analysis Endpoints</h2>
|
| 96 |
+
<div class="endpoint">
|
| 97 |
+
<p><span class="method">POST</span> <a href="/api/analyze/process_image">/api/analyze/process_image</a></p>
|
| 98 |
+
<p>Upload and process an image using YOLO object detection</p>
|
| 99 |
+
<p>Form data: image (file)</p>
|
| 100 |
+
<p>Response:</p>
|
| 101 |
+
<pre><code>{
|
| 102 |
+
"message": "Product extracted successfully",
|
| 103 |
+
"product_image_name": "f7e5d4c3-b2a1-4f9e-8d7c-6e5f4d3a2b1c.jpg"
|
| 104 |
+
}</code></pre>
|
| 105 |
+
</div>
|
| 106 |
+
|
| 107 |
+
<div class="endpoint">
|
| 108 |
+
<p><span class="method">GET</span> <a
|
| 109 |
+
href="/api/analyze/get_image/{image_name}">/api/analyze/get_image/{image_name}</a></p>
|
| 110 |
+
<p>Retrieve a processed image by its name</p>
|
| 111 |
+
<p>Path parameters: image_name</p>
|
| 112 |
+
<p>Response: Image file (JPEG)</p>
|
| 113 |
+
</div>
|
| 114 |
+
|
| 115 |
+
<div class="endpoint">
|
| 116 |
+
<p><span class="method">POST</span> <a
|
| 117 |
+
href="/api/analyze/process_ingredient">/api/analyze/process_ingredient</a></p>
|
| 118 |
+
<p>Process a single ingredient and get detailed analysis</p>
|
| 119 |
+
<p>Request body:</p>
|
| 120 |
+
<pre><code>{
|
| 121 |
+
"name": "Monosodium Glutamate"
|
| 122 |
+
}</code></pre>
|
| 123 |
+
</div>
|
| 124 |
+
|
| 125 |
+
<div class="endpoint">
|
| 126 |
+
<p><span class="method">POST</span> <a
|
| 127 |
+
href="/api/analyze/process_product_ingredients">/api/analyze/process_product_ingredients</a></p>
|
| 128 |
+
<p>Process multiple ingredients of a product</p>
|
| 129 |
+
<p>Headers: Authorization: Bearer {token}</p>
|
| 130 |
+
<p>Request body:</p>
|
| 131 |
+
<pre><code>{
|
| 132 |
+
"ingredients": ["Sugar", "Salt", "Monosodium Glutamate"],
|
| 133 |
+
"user_id": 1
|
| 134 |
+
}</code></pre>
|
| 135 |
+
</div>
|
| 136 |
+
|
| 137 |
+
<h2>Product Endpoints</h2>
|
| 138 |
+
<div class="endpoint">
|
| 139 |
+
<p><span class="method">POST</span> <a href="/api/product/add">/api/product/add</a></p>
|
| 140 |
+
<p>Add a new product with ingredients and images</p>
|
| 141 |
+
<p>Request body:</p>
|
| 142 |
+
<pre><code>{
|
| 143 |
+
"name": "Maggi 2-Minute Noodles",
|
| 144 |
+
"image_names": ["maggi_front.jpg", "maggi_ingredients.jpg"],
|
| 145 |
+
"ingredients": [
|
| 146 |
+
"Wheat Flour",
|
| 147 |
+
"Palm Oil",
|
| 148 |
+
"Salt",
|
| 149 |
+
"Monosodium Glutamate"
|
| 150 |
+
],
|
| 151 |
+
"ingredients_count": 4,
|
| 152 |
+
"overall_safety_score": 6.5,
|
| 153 |
+
"suitable_diet_types": ["Vegetarian"],
|
| 154 |
+
"allergy_warnings": ["Contains Wheat (Gluten)"],
|
| 155 |
+
"usage_recommendations": "Consume in moderation",
|
| 156 |
+
"health_insights": [
|
| 157 |
+
"High sodium content may contribute to high blood pressure"
|
| 158 |
+
],
|
| 159 |
+
"ingredient_interactions": [
|
| 160 |
+
"No significant harmful interactions between ingredients"
|
| 161 |
+
],
|
| 162 |
+
"key_takeaway": "Convenient food option but should be consumed occasionally",
|
| 163 |
+
"user_id": 1,
|
| 164 |
+
"timestamp": "2025-04-27T15:30:00Z"
|
| 165 |
+
}</code></pre>
|
| 166 |
+
</div>
|
| 167 |
+
|
| 168 |
+
<h2>History Endpoints</h2>
|
| 169 |
+
<div class="endpoint">
|
| 170 |
+
<p><span class="method">POST</span> <a href="/api/history/scan">/api/history/scan</a></p>
|
| 171 |
+
<p>Record a new product scan in user history</p>
|
| 172 |
+
</div>
|
| 173 |
+
|
| 174 |
+
<div class="endpoint">
|
| 175 |
+
<p><span class="method">GET</span> <a href="/api/history/user/{user_id}">/api/history/user/{user_id}</a></p>
|
| 176 |
+
<p>Retrieve scan history for a specific user</p>
|
| 177 |
+
<p>Path parameters: user_id</p>
|
| 178 |
+
</div>
|
| 179 |
+
|
| 180 |
+
<h2>Authentication</h2>
|
| 181 |
+
<p>Protected endpoints require JWT token in Authorization header:</p>
|
| 182 |
+
<p><code>Authorization: Bearer eyJhbGciOiJIUzI1NiIs...</code></p>
|
| 183 |
+
<p>Tokens are valid for 4 weeks after login.</p>
|
| 184 |
+
</body>
|
| 185 |
+
|
| 186 |
+
</html>
|