Spaces:
Running
Running
fix app
Browse files
app.py
CHANGED
@@ -99,24 +99,6 @@ def create_interface():
|
|
99 |
commit_message="Initial upload: export.xml"
|
100 |
)
|
101 |
|
102 |
-
# Parse the XML file and create SQLite database
|
103 |
-
with tempfile.TemporaryDirectory() as temp_dir:
|
104 |
-
db_path = os.path.join(temp_dir, "health_data.db")
|
105 |
-
|
106 |
-
# Parse the XML file
|
107 |
-
parser = AppleHealthParser(db_path=db_path)
|
108 |
-
parser.parse_file(file_path)
|
109 |
-
|
110 |
-
# Upload the SQLite database (second commit)
|
111 |
-
api.upload_file(
|
112 |
-
path_or_fileobj=db_path,
|
113 |
-
path_in_repo="health_data.db",
|
114 |
-
repo_id=dataset_repo_id,
|
115 |
-
repo_type="dataset",
|
116 |
-
token=token,
|
117 |
-
commit_message="Add parsed SQLite database"
|
118 |
-
)
|
119 |
-
|
120 |
# Create README for dataset
|
121 |
dataset_readme = f"""# Apple Health Data
|
122 |
|
@@ -150,121 +132,11 @@ This dataset is private and contains personal health information. Do not share a
|
|
150 |
token=token
|
151 |
)
|
152 |
|
153 |
-
#
|
154 |
-
|
155 |
-
|
156 |
-
import sqlite3
|
157 |
-
import pandas as pd
|
158 |
-
from datetime import datetime
|
159 |
-
import json
|
160 |
-
|
161 |
-
# Download the health data
|
162 |
-
DATA_REPO = "{dataset_repo_id}"
|
163 |
-
|
164 |
-
def get_db_connection(token=None):
|
165 |
-
"""Get a connection to the SQLite database."""
|
166 |
-
# Download the health_data.db file from the dataset
|
167 |
-
db_path = hf_hub_download(
|
168 |
-
repo_id=DATA_REPO,
|
169 |
-
filename="health_data.db",
|
170 |
-
repo_type="dataset",
|
171 |
-
token=token
|
172 |
-
)
|
173 |
-
return sqlite3.connect(db_path)
|
174 |
-
|
175 |
-
def execute_sql_query(sql_query, hf_token=None):
|
176 |
-
"""Execute any SQL query on the Apple Health SQLite database.
|
177 |
-
|
178 |
-
Args:
|
179 |
-
sql_query (str): The SQL query to execute
|
180 |
-
hf_token (str): Hugging Face token for accessing private dataset
|
181 |
-
|
182 |
-
Returns:
|
183 |
-
str: JSON formatted results or error message
|
184 |
-
"""
|
185 |
-
if not sql_query or not sql_query.strip():
|
186 |
-
return "Error: Empty SQL query provided"
|
187 |
-
|
188 |
-
try:
|
189 |
-
conn = get_db_connection(token=hf_token)
|
190 |
-
|
191 |
-
# Execute the query
|
192 |
-
result = pd.read_sql_query(sql_query, conn)
|
193 |
-
conn.close()
|
194 |
-
|
195 |
-
# Convert to JSON
|
196 |
-
return json.dumps(result.to_dict('records'), indent=2)
|
197 |
-
|
198 |
-
except Exception as e:
|
199 |
-
return f"Error executing SQL query: {{str(e)}}"
|
200 |
-
|
201 |
-
# MCP Server Interface
|
202 |
-
with gr.Blocks(title="Apple Health MCP Server") as demo:
|
203 |
-
gr.Markdown("# Apple Health MCP Server")
|
204 |
-
gr.Markdown(f"This is an MCP server for querying Apple Health data from dataset: `{{DATA_REPO}}`")
|
205 |
-
|
206 |
-
with gr.Tab("SQL Query Interface"):
|
207 |
-
gr.Markdown("### Execute SQL Queries")
|
208 |
-
gr.Markdown("Enter any SQL query to execute against your Apple Health SQLite database.")
|
209 |
-
|
210 |
-
hf_token_input = gr.Textbox(
|
211 |
-
label="Hugging Face Token",
|
212 |
-
placeholder="hf_...",
|
213 |
-
type="password",
|
214 |
-
info="Your HF token to access the private dataset. Get it from https://huggingface.co/settings/tokens"
|
215 |
-
)
|
216 |
-
|
217 |
-
sql_input = gr.Textbox(
|
218 |
-
label="SQL Query",
|
219 |
-
placeholder="SELECT * FROM records LIMIT 10;",
|
220 |
-
lines=5,
|
221 |
-
info="Enter your SQL query here. Available tables: records, workouts"
|
222 |
-
)
|
223 |
-
|
224 |
-
query_btn = gr.Button("Execute Query", variant="primary")
|
225 |
-
output = gr.Code(language="json", label="Query Results")
|
226 |
-
|
227 |
-
query_btn.click(
|
228 |
-
fn=execute_sql_query,
|
229 |
-
inputs=[sql_input, hf_token_input],
|
230 |
-
outputs=output
|
231 |
-
)
|
232 |
-
|
233 |
-
with gr.Tab("MCP Endpoint"):
|
234 |
-
gr.Markdown("""
|
235 |
-
## MCP Server Endpoint
|
236 |
-
|
237 |
-
This space can be used as an MCP server with the following configuration:
|
238 |
-
|
239 |
-
```json
|
240 |
-
{{
|
241 |
-
"mcpServers": {{
|
242 |
-
"apple-health": {{
|
243 |
-
"command": "npx",
|
244 |
-
"args": [
|
245 |
-
"mcp-remote",
|
246 |
-
"https://huggingface.co/spaces/{space_repo_id}/gradio_api/mcp/sse",
|
247 |
-
"--header",
|
248 |
-
"Authorization:${{AUTH_HEADER}}"
|
249 |
-
],
|
250 |
-
"env": {{
|
251 |
-
"AUTH_HEADER": "Bearer YOUR_HF_TOKEN_HERE"
|
252 |
-
}}
|
253 |
-
}}
|
254 |
-
}}
|
255 |
-
}}
|
256 |
-
```
|
257 |
-
|
258 |
-
**Setup Instructions:**
|
259 |
-
1. Replace `YOUR_HF_TOKEN_HERE` with your actual Hugging Face token
|
260 |
-
2. Add this configuration to your Claude Desktop config file
|
261 |
-
3. Claude will be able to query your Apple Health data using SQL
|
262 |
-
""")
|
263 |
-
|
264 |
-
if __name__ == "__main__":
|
265 |
-
demo.launch(mcp_server=True)
|
266 |
-
'''
|
267 |
|
|
|
268 |
api.upload_file(
|
269 |
path_or_fileobj=mcp_app_content.encode(),
|
270 |
path_in_repo="app.py",
|
@@ -273,10 +145,46 @@ if __name__ == "__main__":
|
|
273 |
token=token
|
274 |
)
|
275 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
276 |
# Create requirements.txt for the space
|
277 |
requirements_content = """gradio>=5.34.0
|
278 |
huggingface-hub>=0.20.0
|
279 |
pandas>=2.0.0
|
|
|
|
|
|
|
280 |
"""
|
281 |
|
282 |
api.upload_file(
|
@@ -287,6 +195,22 @@ pandas>=2.0.0
|
|
287 |
token=token
|
288 |
)
|
289 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
290 |
return f"""✅ Successfully created Apple Health Landing Zone!
|
291 |
|
292 |
**Private Dataset:** [{dataset_repo_id}]({dataset_url})
|
@@ -296,8 +220,11 @@ pandas>=2.0.0
|
|
296 |
**MCP Server Space:** [{space_repo_id}]({space_url})
|
297 |
- Query interface for your health data using SQLite
|
298 |
- MCP endpoint configuration included
|
|
|
|
|
299 |
|
300 |
-
Both repositories are private and only accessible by you.
|
|
|
301 |
|
302 |
except Exception as e:
|
303 |
return f"❌ Error creating landing zone: {str(e)}"
|
|
|
99 |
commit_message="Initial upload: export.xml"
|
100 |
)
|
101 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
# Create README for dataset
|
103 |
dataset_readme = f"""# Apple Health Data
|
104 |
|
|
|
132 |
token=token
|
133 |
)
|
134 |
|
135 |
+
# Read MCP server code from mcp_server.py
|
136 |
+
with open('mcp_server.py', 'r') as f:
|
137 |
+
mcp_app_content = f.read()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
|
139 |
+
# Upload the MCP server app.py
|
140 |
api.upload_file(
|
141 |
path_or_fileobj=mcp_app_content.encode(),
|
142 |
path_in_repo="app.py",
|
|
|
145 |
token=token
|
146 |
)
|
147 |
|
148 |
+
# Upload parser dependencies for auto-parsing functionality
|
149 |
+
api.upload_file(
|
150 |
+
path_or_fileobj="src/parser/parser.py",
|
151 |
+
path_in_repo="src/parser/parser.py",
|
152 |
+
repo_id=space_repo_id,
|
153 |
+
repo_type="space",
|
154 |
+
token=token
|
155 |
+
)
|
156 |
+
|
157 |
+
api.upload_file(
|
158 |
+
path_or_fileobj="src/parser/models.py",
|
159 |
+
path_in_repo="src/parser/models.py",
|
160 |
+
repo_id=space_repo_id,
|
161 |
+
repo_type="space",
|
162 |
+
token=token
|
163 |
+
)
|
164 |
+
|
165 |
+
api.upload_file(
|
166 |
+
path_or_fileobj="src/parser/__init__.py",
|
167 |
+
path_in_repo="src/parser/__init__.py",
|
168 |
+
repo_id=space_repo_id,
|
169 |
+
repo_type="space",
|
170 |
+
token=token
|
171 |
+
)
|
172 |
+
|
173 |
+
api.upload_file(
|
174 |
+
path_or_fileobj="src/__init__.py",
|
175 |
+
path_in_repo="src/__init__.py",
|
176 |
+
repo_id=space_repo_id,
|
177 |
+
repo_type="space",
|
178 |
+
token=token
|
179 |
+
)
|
180 |
+
|
181 |
# Create requirements.txt for the space
|
182 |
requirements_content = """gradio>=5.34.0
|
183 |
huggingface-hub>=0.20.0
|
184 |
pandas>=2.0.0
|
185 |
+
lxml>=4.9.0
|
186 |
+
sqlmodel>=0.0.8
|
187 |
+
tqdm>=4.64.0
|
188 |
"""
|
189 |
|
190 |
api.upload_file(
|
|
|
195 |
token=token
|
196 |
)
|
197 |
|
198 |
+
# Create space variables for the dataset repo ID
|
199 |
+
api.add_space_variable(
|
200 |
+
repo_id=space_repo_id,
|
201 |
+
key="DATA_REPO",
|
202 |
+
value=dataset_repo_id,
|
203 |
+
token=token
|
204 |
+
)
|
205 |
+
|
206 |
+
# Add the token as a secret for dataset access
|
207 |
+
api.add_space_secret(
|
208 |
+
repo_id=space_repo_id,
|
209 |
+
key="HF_TOKEN",
|
210 |
+
value=token,
|
211 |
+
token=token
|
212 |
+
)
|
213 |
+
|
214 |
return f"""✅ Successfully created Apple Health Landing Zone!
|
215 |
|
216 |
**Private Dataset:** [{dataset_repo_id}]({dataset_url})
|
|
|
220 |
**MCP Server Space:** [{space_repo_id}]({space_url})
|
221 |
- Query interface for your health data using SQLite
|
222 |
- MCP endpoint configuration included
|
223 |
+
- Environment variables automatically configured
|
224 |
+
- Fine-grained access token created for secure dataset access
|
225 |
|
226 |
+
Both repositories are private and only accessible by you.
|
227 |
+
The MCP server uses a dedicated token with limited permissions for enhanced security."""
|
228 |
|
229 |
except Exception as e:
|
230 |
return f"❌ Error creating landing zone: {str(e)}"
|