ADD feature to allow donwload of source file with src endpoint

This commit is contained in:
CaffeineFueled 2025-06-24 00:55:40 +02:00
parent 36eed976f2
commit ade138ae05
2 changed files with 43 additions and 9 deletions

View file

@ -2,6 +2,10 @@
A simple FastAPI application that automatically exposes CSV and JSON files as API endpoints.
# TODO
- [x] show source format as well
- [ ] allow upload of static files (with password)
## Features
- Automatically creates API endpoints for CSV and JSON files in the `source` directory
@ -40,11 +44,14 @@ The API will be available at: http://localhost:8000
## API Endpoints
- `GET /` - Welcome message
- `GET /api/{filename}` - Access data from files in the source directory
- `GET /api/{filename}` - Access parsed data from files in the source directory
- `GET /api/{filename}/src` - Download the original source file
Example:
- `GET /api/contacts` - Returns data from `source/contacts.csv`
- `GET /api/users` - Returns data from `source/users.json`
- `GET /api/contacts` - Returns parsed data from `source/contacts.csv` as JSON
- `GET /api/contacts/src` - Downloads the original `contacts.csv` file
- `GET /api/users` - Returns parsed data from `source/users.json`
- `GET /api/users/src` - Downloads the original `users.json` file
## Sample Responses
@ -126,13 +133,26 @@ contacts_data = response.json()
contacts_df = pd.DataFrame(contacts_data)
print(contacts_df)
# Example 3: Extract specific information
# Example 3: Download original source files
# Download the original CSV file
csv_response = requests.get(f"{API_BASE_URL}/api/contacts/src")
with open('downloaded_contacts.csv', 'wb') as f:
f.write(csv_response.content)
print("Downloaded contacts.csv")
# Download the original JSON file
json_response = requests.get(f"{API_BASE_URL}/api/users/src")
with open('downloaded_users.json', 'wb') as f:
f.write(json_response.content)
print("Downloaded users.json")
# Example 4: Extract specific information
contacts_response = requests.get(f"{API_BASE_URL}/api/contacts")
contacts = contacts_response.json()
locations = [contact['location'] for contact in contacts]
print(f"Available locations: {locations}")
# Example 4: Filtering data
# Example 5: Filtering data
users_response = requests.get(f"{API_BASE_URL}/api/users")
users_data = users_response.json()
filtered_users = [user for user in users_data.get('users', [])
@ -149,6 +169,9 @@ Output:
0 dortmund achim
1 madrid santos
Downloaded contacts.csv
Downloaded users.json
Available locations: ['dortmund', 'madrid']
Filtered users: [{'name': 'John', 'email': 'john@example.com'}]
@ -212,4 +235,4 @@ podman stop static2api
docker rm static2api
# or
podman rm static2api
```
```

17
main.py
View file

@ -1,5 +1,5 @@
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from fastapi.responses import JSONResponse, FileResponse
from fastapi.middleware.cors import CORSMiddleware
import os
import csv
@ -47,6 +47,7 @@ def register_api_endpoints():
if file_path.is_file():
endpoint_name = file_path.stem
route = f"/api/{endpoint_name}"
src_route = f"/api/{endpoint_name}/src"
# Skip if route already exists
if any(route == route_info.path for route_info in app.routes):
@ -64,8 +65,13 @@ def register_api_endpoints():
content={"error": f"Failed to load CSV: {str(e)}"}
)
# Add the route
# Create a closure for serving the original file
async def get_csv_src(request: Request, file_path=file_path):
return FileResponse(file_path, media_type='text/csv', filename=file_path.name)
# Add the routes
app.add_api_route(route, get_csv_data, methods=["GET"])
app.add_api_route(src_route, get_csv_src, methods=["GET"])
elif file_path.suffix.lower() == '.json':
# Create a closure to capture the current file_path
@ -79,8 +85,13 @@ def register_api_endpoints():
content={"error": f"Failed to load JSON: {str(e)}"}
)
# Add the route
# Create a closure for serving the original file
async def get_json_src(request: Request, file_path=file_path):
return FileResponse(file_path, media_type='application/json', filename=file_path.name)
# Add the routes
app.add_api_route(route, get_json_data, methods=["GET"])
app.add_api_route(src_route, get_json_src, methods=["GET"])
@app.middleware("http")
async def check_for_new_files(request: Request, call_next):