AmbitiousPotato's picture
Update app.py
efeb261 verified
Raw
History Blame Contribute Delete
6.85 kB
import os
import io
import json
import base64
from fastapi import FastAPI, File, UploadFile, Form, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
import uvicorn
from PIL import Image
from openai import AsyncOpenAI
from dotenv import load_dotenv
load_dotenv()
app = FastAPI()
ALLOWED_ORIGINS = [
"http://localhost:3000",
"https://food-analayser.vercel.app/"
]
app.add_middleware(
CORSMiddleware,
allow_origins=ALLOWED_ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
hackclubapi = os.getenv("OPENAI_API_KEY")
client = AsyncOpenAI(
base_url="https://ai.hackclub.com/proxy/v1",
api_key=hackclubapi
)
class TextRequest(BaseModel):
ingredients: str
api_key: str = "shiggaapi"
@app.get("/")
def lobster():
return {"message": "Lobster says its workin"}
@app.post("/analyzetext")
async def barcodetext(request: TextRequest):
prompt = f"""
You are an expert food scientist and nutritionist. Analyze the following list of ingredients: {request.ingredients}.
1. Extract and standardize the ingredients.
2. Provide a short, easy to understand health summary for eg.(is it healthy, protein rich, ultra processed, etc.?).
3. Identify any potential allergens, harmful additives or hidden sugars.
4. Identify any potential health benefits.
5. Give it a health score from 1 to 10 (dont include /10 in text).
Format your response as a JSON object with the following structure:
{{
"ingredientsList": ["list of ingredients"],
"healthsum": "short health summary",
"issuesList": ["list of potential issues"]
"benefitsList": ["list of health benefits"]
"healthScore": "health score"
}}
Return only the JSON object without any additional text or explanations.
"""
try:
response = await client.chat.completions.create(
model="google/gemini-2.5-flash",
messages=[{"role": "user", "content": prompt}],
response_format={"type": "json_object"}
)
responcetxt = response.choices[0].message.content.strip()
if responcetxt.startswith("```json"):
responcetxt = responcetxt[7:-3]
elif responcetxt.startswith("```"):
responcetxt = responcetxt[3:-3]
return json.loads(responcetxt)
except Exception as e:
print(f"Error: {e}, trying claude")
try:
response = await client.chat.completions.create(
model="anthropic/claude-opus-4.8-fast",
messages=[{"role": "user", "content": prompt}]
)
responcetxt = response.choices[0].message.content.strip()
if responcetxt.startswith("```json"):
responcetxt = responcetxt[7:-3]
elif responcetxt.startswith("```"):
responcetxt = responcetxt[3:-3]
return json.loads(responcetxt)
except Exception as e2:
print(f"Fallback Error: {e2}")
raise HTTPException(status_code=500, detail="An error occurred while analyzing the ingredients.")
@app.post("/analyze")
async def analyzefood(image: UploadFile = File(...), api_key: str = Form(...)):
prompt = """
You are an expert food scientist and nutritionist. look at this food label and
1. Extract the ingredients.
2. Provide a short, easy to understand health summary for eg.(is it healthy, protein rich, ultra processed, etc.?).
3. Identify any potential allergens, harmful additives or hidden sugars.
4. Identify any potential health benefits.
5. Give it a health score from 1 to 10 (dont include /10 in text).
Format your response as a JSON object with the following structure:
{
"ingredientsList": ["list of ingredients"],
"healthsum": "short health summary",
"issuesList": ["list of potential issues"]
"benefitsList": ["list of health benefits"]
"healthScore": "health score"
}
Return only the JSON object without any additional text or explanations.
"""
try:
imagebites = await image.read()
img = Image.open(io.BytesIO(imagebites))
if not img:
raise ValueError("empty file")
if img.mode != 'RGB':
img = img.convert('RGB')
img.thumbnail((1024, 1024))
buffer = io.BytesIO()
img.save(buffer, format="JPEG", quality=85)
img64 = base64.b64encode(buffer.getvalue()).decode('utf-8')
except Exception as e:
print(f"Image Processing Error: {e}")
try:
response = await client.chat.completions.create(
model="google/gemini-3.1-flash-lite",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": prompt},
{
"type": "image_url",
"image_url": {
"url": f"data:image/jpeg;base64,{img64}"
}
}
]
}
],
)
responcetxt = response.choices[0].message.content.strip()
if responcetxt.startswith("```json"):
responcetxt = responcetxt[7:-3]
elif responcetxt.startswith("```"):
responcetxt = responcetxt[3:-3]
return json.loads(responcetxt)
except Exception as error:
print(f"Image Analysis Error: {error}, trying different model")
try:
response = await client.chat.completions.create(
model="perceptron/perceptron-mk1",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": prompt},
{
"type": "image_url",
"image_url": {
"url": f"data:image/jpeg;base64,{img64}"
}
}
]
}
],
)
responcetxt = response.choices[0].message.content.strip()
if responcetxt.startswith("```json"):
responcetxt = responcetxt[7:-3]
elif responcetxt.startswith("```"):
responcetxt = responcetxt[3:-3]
return json.loads(responcetxt)
except Exception as e3:
print(f"Image Analysis Error: {e3}")
if __name__ == "__main__":
uvicorn.run(app, host="127.0.0.1", port=7860)