Spaces:
Running
Running
Pulastya B commited on
Commit ·
94bbef1
1
Parent(s): 16616fb
Fixed the File Path Issues
Browse files- src/api/app.py +33 -9
- src/orchestrator.py +18 -4
- src/tools/plotly_visualizations.py +7 -2
src/api/app.py
CHANGED
|
@@ -833,19 +833,43 @@ async def general_exception_handler(request, exc):
|
|
| 833 |
async def serve_output_files(file_path: str):
|
| 834 |
"""
|
| 835 |
Serve generated output files (reports, plots, models, etc.).
|
|
|
|
| 836 |
"""
|
| 837 |
-
|
| 838 |
-
|
| 839 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 840 |
raise HTTPException(status_code=404, detail=f"File not found: {file_path}")
|
| 841 |
|
| 842 |
-
if not output_path.is_file():
|
| 843 |
-
raise HTTPException(status_code=400, detail="Path is not a file")
|
| 844 |
-
|
| 845 |
# Security: prevent directory traversal
|
| 846 |
-
|
| 847 |
-
|
| 848 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 849 |
raise HTTPException(status_code=403, detail="Access denied")
|
| 850 |
|
| 851 |
# Determine media type based on file extension
|
|
|
|
| 833 |
async def serve_output_files(file_path: str):
|
| 834 |
"""
|
| 835 |
Serve generated output files (reports, plots, models, etc.).
|
| 836 |
+
Checks multiple locations: ./outputs, /tmp/data_science_agent/outputs, and /tmp/data_science_agent.
|
| 837 |
"""
|
| 838 |
+
# Locations to check (in order of priority)
|
| 839 |
+
search_paths = [
|
| 840 |
+
Path("./outputs") / file_path, # Local development
|
| 841 |
+
Path("/tmp/data_science_agent/outputs") / file_path, # Production with subdirs
|
| 842 |
+
Path("/tmp/data_science_agent") / file_path, # Production flat
|
| 843 |
+
Path("/tmp/data_science_agent/outputs") / Path(file_path).name, # Production filename only
|
| 844 |
+
]
|
| 845 |
+
|
| 846 |
+
output_path = None
|
| 847 |
+
for path in search_paths:
|
| 848 |
+
if path.exists() and path.is_file():
|
| 849 |
+
output_path = path
|
| 850 |
+
break
|
| 851 |
+
|
| 852 |
+
if output_path is None:
|
| 853 |
raise HTTPException(status_code=404, detail=f"File not found: {file_path}")
|
| 854 |
|
|
|
|
|
|
|
|
|
|
| 855 |
# Security: prevent directory traversal
|
| 856 |
+
resolved_path = output_path.resolve()
|
| 857 |
+
allowed_bases = [
|
| 858 |
+
Path("./outputs").resolve(),
|
| 859 |
+
Path("/tmp/data_science_agent").resolve()
|
| 860 |
+
]
|
| 861 |
+
|
| 862 |
+
# Check if path is within allowed directories
|
| 863 |
+
is_allowed = False
|
| 864 |
+
for base in allowed_bases:
|
| 865 |
+
try:
|
| 866 |
+
resolved_path.relative_to(base)
|
| 867 |
+
is_allowed = True
|
| 868 |
+
break
|
| 869 |
+
except ValueError:
|
| 870 |
+
continue
|
| 871 |
+
|
| 872 |
+
if not is_allowed:
|
| 873 |
raise HTTPException(status_code=403, detail="Access denied")
|
| 874 |
|
| 875 |
# Determine media type based on file extension
|
src/orchestrator.py
CHANGED
|
@@ -344,11 +344,25 @@ class DataScienceCopilot:
|
|
| 344 |
self.specialist_agents = self._initialize_specialist_agents()
|
| 345 |
self.active_agent = "Orchestrator" # Track which agent is working
|
| 346 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 347 |
# Ensure output directories exist
|
| 348 |
-
|
| 349 |
-
|
| 350 |
-
|
| 351 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 352 |
|
| 353 |
def _build_tool_functions_map(self) -> Dict[str, callable]:
|
| 354 |
"""Build mapping of tool names to their functions - All 75 tools."""
|
|
|
|
| 344 |
self.specialist_agents = self._initialize_specialist_agents()
|
| 345 |
self.active_agent = "Orchestrator" # Track which agent is working
|
| 346 |
|
| 347 |
+
# Determine output directory based on environment
|
| 348 |
+
# In production (HuggingFace/Cloud Run), use /tmp for ephemeral storage
|
| 349 |
+
if os.path.exists("/tmp") and os.access("/tmp", os.W_OK):
|
| 350 |
+
self.output_base = Path("/tmp/data_science_agent/outputs")
|
| 351 |
+
else:
|
| 352 |
+
self.output_base = Path("./outputs")
|
| 353 |
+
|
| 354 |
+
# Set environment variable for tools to use
|
| 355 |
+
os.environ["DS_AGENT_OUTPUT_DIR"] = str(self.output_base)
|
| 356 |
+
|
| 357 |
# Ensure output directories exist
|
| 358 |
+
self.output_base.mkdir(parents=True, exist_ok=True)
|
| 359 |
+
(self.output_base / "models").mkdir(exist_ok=True)
|
| 360 |
+
(self.output_base / "reports").mkdir(exist_ok=True)
|
| 361 |
+
(self.output_base / "data").mkdir(exist_ok=True)
|
| 362 |
+
(self.output_base / "plots").mkdir(exist_ok=True)
|
| 363 |
+
(self.output_base / "plots" / "interactive").mkdir(exist_ok=True)
|
| 364 |
+
|
| 365 |
+
print(f"📁 Output directory: {self.output_base}")
|
| 366 |
|
| 367 |
def _build_tool_functions_map(self) -> Dict[str, callable]:
|
| 368 |
"""Build mapping of tool names to their functions - All 75 tools."""
|
src/tools/plotly_visualizations.py
CHANGED
|
@@ -170,18 +170,23 @@ def generate_interactive_histogram(
|
|
| 170 |
|
| 171 |
def generate_interactive_correlation_heatmap(
|
| 172 |
file_path: str,
|
| 173 |
-
output_path: str =
|
| 174 |
) -> Dict[str, Any]:
|
| 175 |
"""
|
| 176 |
Create interactive correlation heatmap with Plotly.
|
| 177 |
|
| 178 |
Args:
|
| 179 |
file_path: Path to dataset
|
| 180 |
-
output_path: Path to save HTML file
|
| 181 |
|
| 182 |
Returns:
|
| 183 |
Dictionary with plot info
|
| 184 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 185 |
# Validation
|
| 186 |
validate_file_exists(file_path)
|
| 187 |
validate_file_format(file_path)
|
|
|
|
| 170 |
|
| 171 |
def generate_interactive_correlation_heatmap(
|
| 172 |
file_path: str,
|
| 173 |
+
output_path: str = None
|
| 174 |
) -> Dict[str, Any]:
|
| 175 |
"""
|
| 176 |
Create interactive correlation heatmap with Plotly.
|
| 177 |
|
| 178 |
Args:
|
| 179 |
file_path: Path to dataset
|
| 180 |
+
output_path: Path to save HTML file (auto-determined if None)
|
| 181 |
|
| 182 |
Returns:
|
| 183 |
Dictionary with plot info
|
| 184 |
"""
|
| 185 |
+
# Auto-determine output path based on environment
|
| 186 |
+
if output_path is None:
|
| 187 |
+
output_base = os.getenv("DS_AGENT_OUTPUT_DIR", "./outputs")
|
| 188 |
+
output_path = f"{output_base}/plots/interactive/correlation_heatmap.html"
|
| 189 |
+
|
| 190 |
# Validation
|
| 191 |
validate_file_exists(file_path)
|
| 192 |
validate_file_format(file_path)
|