function download_generated_file
Flask route handler that downloads generated files from a user's session directory, with security checks and support for nested analysis subdirectories.
/tf/active/vicechatdev/full_smartstat/app.py
1695 - 1735
moderate
Purpose
This function serves as a Flask endpoint to securely download files generated during analysis sessions. It searches for files in the session directory, prioritizing the most recent analysis subdirectory, and includes path traversal protection to prevent unauthorized file access. It handles nested paths and provides appropriate error responses for missing or inaccessible files.
Source Code
def download_generated_file(session_id, filename):
"""Download generated file from session"""
try:
session_dir = Path(app_config.OUTPUT_DIR) / session_id
# Try to find the file in analysis subdirectories first
file_path = None
# Check analysis subdirectories
analysis_dirs = [d for d in session_dir.iterdir() if d.is_dir() and d.name.startswith('analysis_')]
if analysis_dirs:
# Use the most recent analysis directory
latest_analysis_dir = max(analysis_dirs, key=lambda d: d.stat().st_mtime)
potential_path = latest_analysis_dir / filename
if potential_path.exists() and potential_path.is_file():
file_path = potential_path
# Fallback to direct session directory
if not file_path:
potential_path = session_dir / filename
if potential_path.exists() and potential_path.is_file():
file_path = potential_path
# Handle nested paths (analysis_hash/filename)
if not file_path and '/' in filename:
potential_path = session_dir / filename
if potential_path.exists() and potential_path.is_file():
file_path = potential_path
if not file_path:
return jsonify({'error': 'File not found'}), 404
# Security check: ensure file is within session directory
if not str(file_path.resolve()).startswith(str(session_dir.resolve())):
return jsonify({'error': 'Access denied'}), 403
return send_file(file_path, as_attachment=True, download_name=file_path.name)
except Exception as e:
logger.error(f"Error downloading file {filename} for session {session_id}: {str(e)}")
return jsonify({'error': str(e)}), 500
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
session_id |
- | - | positional_or_keyword |
filename |
- | - | positional_or_keyword |
Parameter Details
session_id: Unique identifier for the user's session, used to locate the session-specific output directory. Expected to be a string that forms a valid directory name.
filename: Name or relative path of the file to download. Can be a simple filename or a nested path like 'analysis_hash/filename'. The path component allows Flask to capture slashes in the URL path.
Return Value
Returns a Flask Response object. On success (200), returns the file as an attachment using send_file(). On file not found (404), returns a JSON object with an 'error' key. On access denied (403), returns a JSON object indicating permission denial. On server error (500), returns a JSON object with the exception message.
Dependencies
flaskpathliblogging
Required Imports
from flask import jsonify
from flask import send_file
from pathlib import Path
import logging
Usage Example
# Flask application setup
from flask import Flask, jsonify, send_file
from pathlib import Path
import logging
app = Flask(__name__)
logger = logging.getLogger(__name__)
class AppConfig:
OUTPUT_DIR = '/path/to/output'
app_config = AppConfig()
@app.route('/download/<session_id>/<path:filename>')
def download_generated_file(session_id, filename):
# Function implementation here
pass
# Client usage - make HTTP GET request:
# GET /download/abc123/report.csv
# GET /download/abc123/analysis_xyz/visualization.png
# Or using requests library:
import requests
response = requests.get('http://localhost:5000/download/abc123/report.csv')
if response.status_code == 200:
with open('downloaded_file.csv', 'wb') as f:
f.write(response.content)
Best Practices
- Always validate that the resolved file path is within the session directory to prevent path traversal attacks
- Use Path.resolve() to normalize paths before security checks
- Prioritize the most recent analysis directory when multiple analysis subdirectories exist
- Return appropriate HTTP status codes (404 for not found, 403 for access denied, 500 for server errors)
- Log errors with sufficient context (session_id and filename) for debugging
- Use send_file with as_attachment=True to force download rather than inline display
- Ensure OUTPUT_DIR is properly configured and has appropriate file system permissions
- Consider implementing rate limiting to prevent abuse of the download endpoint
- The filename parameter uses <path:filename> converter to allow slashes in the URL path
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
function serve_generated_file 82.2% similar
-
function download_file 80.9% similar
-
function smartstat_download_script 71.2% similar
-
function export_report 68.2% similar
-
function serve_plot 67.7% similar