Gymawy commited on
Commit
a0dfbc9
·
1 Parent(s): a9d5d0b

Running The App

Browse files
Files changed (6) hide show
  1. .env +4 -0
  2. README.md +11 -11
  3. __pycache__/main.cpython-312.pyc +0 -0
  4. app.py +107 -0
  5. requirements.txt +5 -0
  6. static/index.html +127 -0
.env ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ GOOGLE_API_KEY=AIzaSyCzkwTikgJrpB-7ViBlDSmcXJq-GyrfNm4
2
+
3
+
4
+
README.md CHANGED
@@ -1,12 +1,12 @@
1
- ---
2
- title: Inbody
3
- emoji: ⚡
4
- colorFrom: red
5
- colorTo: pink
6
- sdk: gradio
7
- sdk_version: 5.33.2
8
- app_file: app.py
9
- pinned: false
10
- ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
1
+ # InBody Fitness Analysis AI
 
 
 
 
 
 
 
 
 
2
 
3
+ This is a FastAPI-powered app using LangChain + Gemini to generate:
4
+ - InBody report analysis
5
+ - Training plan
6
+ - Nutrition plan
7
+ - Weekly regime
8
+
9
+ Frontend: HTML/JS
10
+ Backend: FastAPI with LangChain & Google Gemini
11
+
12
+ Hosted on Hugging Face Spaces 🎯
__pycache__/main.cpython-312.pyc ADDED
Binary file (3.98 kB). View file
 
app.py ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, Request
2
+ from fastapi.responses import HTMLResponse
3
+ from pydantic import BaseModel
4
+ from langchain.chains import LLMChain
5
+ from langchain.prompts import PromptTemplate
6
+ from langchain_google_genai import ChatGoogleGenerativeAI
7
+ import uvicorn
8
+ import os
9
+ from dotenv import load_dotenv
10
+
11
+ load_dotenv()
12
+
13
+ app = FastAPI()
14
+
15
+ # Serve HTML form at /inbody
16
+ @app.get("/inbody", response_class=HTMLResponse)
17
+ async def serve_ui():
18
+ with open("static/index.html", "r", encoding="utf-8") as f:
19
+ return f.read()
20
+
21
+ # Input data schema
22
+ class InBodyRequest(BaseModel):
23
+ name: str
24
+ age: int
25
+ sex: str
26
+ report: str
27
+
28
+ # Prompt chains
29
+ analyze_prompt = PromptTemplate.from_template("""
30
+ You are a world-class certified fitness and health coach with deep expertise in human physiology, sports science, and nutrition.
31
+
32
+ Name: {name}
33
+ Age: {age}
34
+ Sex: {sex}
35
+
36
+ InBody Report:
37
+ {report}
38
+
39
+ Based on the above, provide a professional analysis:
40
+ - Identify key strengths and weaknesses.
41
+ - Highlight red flags or areas of concern.
42
+ - Use precise, expert language and back your insights with reasoning.
43
+ """)
44
+
45
+ analyze_chain = LLMChain(
46
+ llm=ChatGoogleGenerativeAI(model="gemini-2.0-flash", temperature=0.5),
47
+ prompt=analyze_prompt,
48
+ output_key="analysis"
49
+ )
50
+
51
+ training_prompt = PromptTemplate.from_template("""
52
+ Based on this analysis: {analysis}
53
+ Design a weekly training plan that includes cardio, strength training, and flexibility to improve body composition and overall fitness.
54
+ """)
55
+
56
+ training_chain = LLMChain(
57
+ llm=ChatGoogleGenerativeAI(model="gemini-2.0-flash", temperature=0.7),
58
+ prompt=training_prompt,
59
+ output_key="training_plan"
60
+ )
61
+
62
+ nutrition_prompt = PromptTemplate.from_template("""
63
+ Based on the following analysis: {analysis}
64
+ And this training plan: {training_plan}
65
+ Generate a personalized nutritional plan to reduce body fat, support muscle growth, and optimize recovery. Include macro goals and sample meals.
66
+ """)
67
+
68
+ nutrition_chain = LLMChain(
69
+ llm=ChatGoogleGenerativeAI(model="gemini-2.0-flash", temperature=0.7),
70
+ prompt=nutrition_prompt,
71
+ output_key="nutrition_plan"
72
+ )
73
+
74
+ regime_prompt = PromptTemplate.from_template("""
75
+ Combine this training plan: {training_plan}
76
+ And this nutrition plan: {nutrition_plan}
77
+ Into a clear daily/weekly schedule. Include timing suggestions and when to eat, train, and rest for optimal results.
78
+ """)
79
+
80
+ regime_chain = LLMChain(
81
+ llm=ChatGoogleGenerativeAI(model="gemini-2.0-flash", temperature=0.6),
82
+ prompt=regime_prompt,
83
+ output_key="regime"
84
+ )
85
+
86
+ # Combine all chains
87
+ total_chain = analyze_chain | training_chain | nutrition_chain | regime_chain
88
+
89
+ # POST endpoint for form submission
90
+ @app.post("/inbody")
91
+ def process_inbody(input: InBodyRequest):
92
+ result = total_chain.invoke({
93
+ "name": input.name,
94
+ "age": input.age,
95
+ "sex": input.sex,
96
+ "report": input.report
97
+ })
98
+ return {
99
+ "analysis": result["analysis"],
100
+ "training_plan": result["training_plan"],
101
+ "nutrition_plan": result["nutrition_plan"],
102
+ "regime": result["regime"]
103
+ }
104
+
105
+ # 🚀 Hugging Face Spaces entry point
106
+ def start():
107
+ uvicorn.run("app:app", host="0.0.0.0", port=7860, reload=False)
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ langchain
4
+ python-dotenv
5
+ langchain-google-genai
static/index.html ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>InBody Analysis</title>
6
+ <style>
7
+ body {
8
+ font-family: Arial, sans-serif;
9
+ padding: 40px;
10
+ max-width: 700px;
11
+ margin: auto;
12
+ background-color: #f4f4f4;
13
+ }
14
+ label {
15
+ display: block;
16
+ margin-top: 10px;
17
+ }
18
+ textarea, input, select {
19
+ width: 100%;
20
+ padding: 8px;
21
+ margin-top: 5px;
22
+ }
23
+ button {
24
+ margin-top: 20px;
25
+ padding: 10px 20px;
26
+ font-size: 16px;
27
+ }
28
+ .output {
29
+ margin-top: 30px;
30
+ padding: 20px;
31
+ background-color: white;
32
+ border-radius: 10px;
33
+ }
34
+ .loader {
35
+ border: 4px solid #f3f3f3;
36
+ border-top: 4px solid #3498db;
37
+ border-radius: 50%;
38
+ width: 18px;
39
+ height: 18px;
40
+ animation: spin 1s linear infinite;
41
+ display: inline-block;
42
+ vertical-align: middle;
43
+ margin-right: 8px;
44
+ }
45
+ @keyframes spin {
46
+ 0% { transform: rotate(0deg); }
47
+ 100% { transform: rotate(360deg); }
48
+ }
49
+ </style>
50
+ </head>
51
+ <body>
52
+
53
+ <h2>InBody AI Analysis</h2>
54
+
55
+ <label for="name">Name:</label>
56
+ <input id="name" type="text" placeholder="Enter your name" required>
57
+
58
+ <label for="age">Age:</label>
59
+ <input id="age" type="number" placeholder="Enter your age" required>
60
+
61
+ <label for="sex">Sex:</label>
62
+ <select id="sex">
63
+ <option value="male">Male</option>
64
+ <option value="female">Female</option>
65
+ </select>
66
+
67
+ <label for="report">InBody Report:</label>
68
+ <textarea id="report" rows="6" placeholder="Enter raw InBody report..."></textarea>
69
+
70
+ <button id="analyze-btn">Analyze</button>
71
+
72
+ <!-- Loading animation -->
73
+ <div id="loading" style="display: none; margin-top: 20px; font-weight: bold; color: blue;">
74
+ <span class="loader"></span> Processing your InBody report...
75
+ </div>
76
+
77
+ <!-- Output -->
78
+ <div class="output">
79
+ <h3>🧠 Analysis:</h3>
80
+ <p id="analysis"></p>
81
+
82
+ <h3>💪 Training Plan:</h3>
83
+ <p id="training"></p>
84
+
85
+ <h3>🥗 Nutrition Plan:</h3>
86
+ <p id="nutrition"></p>
87
+
88
+ <h3>📅 Weekly Regime:</h3>
89
+ <p id="regime"></p>
90
+ </div>
91
+
92
+ <script>
93
+ document.getElementById("analyze-btn").addEventListener("click", async () => {
94
+ const name = document.getElementById("name").value;
95
+ const age = parseInt(document.getElementById("age").value);
96
+ const sex = document.getElementById("sex").value;
97
+ const report = document.getElementById("report").value;
98
+
99
+ const loadingDiv = document.getElementById("loading");
100
+ loadingDiv.style.display = "block";
101
+
102
+ try {
103
+ const response = await fetch("http://localhost:8000/inbody", {
104
+ method: "POST",
105
+ headers: {
106
+ "Content-Type": "application/json"
107
+ },
108
+ body: JSON.stringify({ name, age, sex, report })
109
+ });
110
+
111
+ const result = await response.json();
112
+
113
+ document.getElementById("analysis").textContent = result.analysis;
114
+ document.getElementById("training").textContent = result.training_plan;
115
+ document.getElementById("nutrition").textContent = result.nutrition_plan;
116
+ document.getElementById("regime").textContent = result.regime;
117
+ } catch (error) {
118
+ alert("Something went wrong. Please check your backend.");
119
+ console.error(error);
120
+ } finally {
121
+ loadingDiv.style.display = "none";
122
+ }
123
+ });
124
+ </script>
125
+
126
+ </body>
127
+ </html>