miracle-ema commited on
Commit
ad6a61c
·
verified ·
1 Parent(s): 3dbfd7a

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +138 -0
app.py ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, File, UploadFile, HTTPException, Form
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from fastapi.responses import HTMLResponse
4
+ from fastapi.staticfiles import StaticFiles
5
+ import pandas as pd
6
+ import matplotlib.pyplot as plt
7
+ import seaborn as sns
8
+ import os
9
+ import logging
10
+ from huggingface_hub import InferenceClient
11
+ from dotenv import load_dotenv
12
+ import hashlib
13
+ import textwrap
14
+
15
+ # Set up logging
16
+ logging.basicConfig(level=logging.INFO)
17
+ logger = logging.getLogger(__name__)
18
+
19
+ # Load environment variables (adjust path if needed)
20
+ load_dotenv("../.env") # Assuming .env is in project/
21
+
22
+ app = FastAPI()
23
+
24
+ app.add_middleware(
25
+ CORSMiddleware,
26
+ allow_origins=["*"],
27
+ allow_credentials=True,
28
+ allow_methods=["*"],
29
+ allow_headers=["*"],
30
+ )
31
+
32
+ app.mount("/static", StaticFiles(directory="static"), name="static")
33
+
34
+
35
+ API_TOKEN = os.getenv("HF_TOKEN")
36
+ if not API_TOKEN:
37
+ raise ValueError("HUGGINGFACE_API_TOKEN environment variable not set.")
38
+
39
+ #the model is use here using the huggingface inference client
40
+ MODEL_NAME = "bigcode/starcoder"
41
+ client = InferenceClient(model=MODEL_NAME, token=API_TOKEN) #for the Api token -->create it in the huggingface account in settings copy it and then create a secret in the space an name it HF_TOKEN and pass it in the value
42
+
43
+ #for using the model with transformers(its a big model)
44
+ # from transformers import pipeline
45
+ # generator = pipeline("text-generation", model=MODEL_NAME, token=API_TOKEN)
46
+
47
+ UPLOAD_DIR = "uploads"
48
+ os.makedirs(UPLOAD_DIR, exist_ok=True)
49
+
50
+ IMAGES_DIR = os.path.join("static", "images")
51
+ os.makedirs(IMAGES_DIR, exist_ok=True)
52
+
53
+ @app.post("/upload/")
54
+ async def upload_file(file: UploadFile = File(...)):
55
+ if not file.filename.endswith(".xlsx"):
56
+ raise HTTPException(status_code=400, detail="File must be an Excel file (.xlsx)")
57
+
58
+ file_path = os.path.join(UPLOAD_DIR, file.filename)
59
+ with open(file_path, "wb") as buffer:
60
+ buffer.write(await file.read())
61
+
62
+ logger.info(f"File uploaded: {file.filename}")
63
+ return {"filename": file.filename}
64
+
65
+ @app.post("/generate-visualization/")
66
+ async def generate_visualization(prompt: str = Form(...), filename: str = Form(...)):
67
+ file_path = os.path.join(UPLOAD_DIR, filename)
68
+
69
+ if not os.path.exists(file_path):
70
+ raise HTTPException(status_code=404, detail="File not found on server.")
71
+
72
+ try:
73
+ df = pd.read_excel(file_path)
74
+ if df.empty:
75
+ raise ValueError("Excel file is empty.")
76
+ except Exception as e:
77
+ raise HTTPException(status_code=400, detail=f"Error reading Excel file: {str(e)}")
78
+
79
+ input_text = f"""
80
+ Given the DataFrame 'df =pd.read_excel({filename})' with columns {', '.join(df.columns)} and preview:
81
+ {df.head().to_string()}
82
+ Write Python code to: {prompt}
83
+ - Use ONLY 'df' (no external data loading like pd.read_csv).
84
+ - Use pandas (pd), matplotlib.pyplot (plt), or seaborn (sns).
85
+ - Include axis labels and a title.
86
+ - Output ONLY executable code (no comments, functions, print, or triple quotes).
87
+ """
88
+
89
+ try:
90
+ generated_code = client.text_generation(input_text, max_new_tokens=500)
91
+ logger.info(f"Generated code:\n{generated_code}")
92
+ except Exception as e:
93
+ raise HTTPException(status_code=500, detail=f"Error querying model: {str(e)}")
94
+
95
+ if not generated_code.strip():
96
+ raise HTTPException(status_code=500, detail="No code generated by the AI model.")
97
+
98
+ generated_code = generated_code.strip()
99
+ if generated_code.startswith('"""') or generated_code.startswith("'''"):
100
+ generated_code = generated_code.split('"""')[1] if '"""' in generated_code else generated_code.split("'''")[1]
101
+ if generated_code.endswith('"""') or generated_code.endswith("'''"):
102
+ generated_code = generated_code.rsplit('"""')[0] if '"""' in generated_code else generated_code.rsplit("'''")[0]
103
+ generated_code = generated_code.strip()
104
+
105
+
106
+ lines = generated_code.splitlines()
107
+ executable_code = "\n".join(
108
+ line.strip() for line in lines
109
+ if line.strip() and not line.strip().startswith(('#', 'def', 'class', '"""', "'''"))
110
+ and not any(kw in line for kw in ["pd.read_csv", "pd.read_excel", "http", "raise", "print"])
111
+ ).strip()
112
+
113
+ executable_code = executable_code.replace("plt.show()", "").strip()
114
+
115
+ logger.info(f"Executable code:\n{executable_code}")
116
+
117
+ plot_hash = hashlib.md5(f"{filename}_{prompt}".encode()).hexdigest()[:8]
118
+ plot_filename = f"plot_{plot_hash}.png"
119
+ plot_path = os.path.join(IMAGES_DIR, plot_filename)
120
+
121
+ try:
122
+ exec_globals = {"pd": pd, "plt": plt, "sns": sns, "df": df}
123
+ exec(executable_code, exec_globals)
124
+ plt.savefig(plot_path, bbox_inches="tight")
125
+ plt.close()
126
+ except Exception as e:
127
+ logger.error(f"Error executing code:\n{executable_code}\nException: {str(e)}")
128
+ raise HTTPException(status_code=500, detail=f"Error executing code: {str(e)}")
129
+
130
+ if not os.path.exists(plot_path):
131
+ raise HTTPException(status_code=500, detail="Plot file was not created.")
132
+
133
+ return {"plot_url": f"/static/images/{plot_filename}", "generated_code": generated_code}
134
+
135
+ @app.get("/")
136
+ async def serve_frontend():
137
+ with open("static/index.html", "r") as f:
138
+ return HTMLResponse(content=f.read())