ADD feature to allow donwload of source file with src endpoint
This commit is contained in:
parent
36eed976f2
commit
ade138ae05
2 changed files with 43 additions and 9 deletions
33
README.md
33
README.md
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
A simple FastAPI application that automatically exposes CSV and JSON files as API endpoints.
|
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
|
## Features
|
||||||
|
|
||||||
- Automatically creates API endpoints for CSV and JSON files in the `source` directory
|
- 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
|
## API Endpoints
|
||||||
|
|
||||||
- `GET /` - Welcome message
|
- `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:
|
Example:
|
||||||
- `GET /api/contacts` - Returns data from `source/contacts.csv`
|
- `GET /api/contacts` - Returns parsed data from `source/contacts.csv` as JSON
|
||||||
- `GET /api/users` - Returns data from `source/users.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
|
## Sample Responses
|
||||||
|
|
||||||
|
@ -126,13 +133,26 @@ contacts_data = response.json()
|
||||||
contacts_df = pd.DataFrame(contacts_data)
|
contacts_df = pd.DataFrame(contacts_data)
|
||||||
print(contacts_df)
|
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_response = requests.get(f"{API_BASE_URL}/api/contacts")
|
||||||
contacts = contacts_response.json()
|
contacts = contacts_response.json()
|
||||||
locations = [contact['location'] for contact in contacts]
|
locations = [contact['location'] for contact in contacts]
|
||||||
print(f"Available locations: {locations}")
|
print(f"Available locations: {locations}")
|
||||||
|
|
||||||
# Example 4: Filtering data
|
# Example 5: Filtering data
|
||||||
users_response = requests.get(f"{API_BASE_URL}/api/users")
|
users_response = requests.get(f"{API_BASE_URL}/api/users")
|
||||||
users_data = users_response.json()
|
users_data = users_response.json()
|
||||||
filtered_users = [user for user in users_data.get('users', [])
|
filtered_users = [user for user in users_data.get('users', [])
|
||||||
|
@ -149,6 +169,9 @@ Output:
|
||||||
0 dortmund achim
|
0 dortmund achim
|
||||||
1 madrid santos
|
1 madrid santos
|
||||||
|
|
||||||
|
Downloaded contacts.csv
|
||||||
|
Downloaded users.json
|
||||||
|
|
||||||
Available locations: ['dortmund', 'madrid']
|
Available locations: ['dortmund', 'madrid']
|
||||||
|
|
||||||
Filtered users: [{'name': 'John', 'email': 'john@example.com'}]
|
Filtered users: [{'name': 'John', 'email': 'john@example.com'}]
|
||||||
|
|
17
main.py
17
main.py
|
@ -1,5 +1,5 @@
|
||||||
from fastapi import FastAPI, Request
|
from fastapi import FastAPI, Request
|
||||||
from fastapi.responses import JSONResponse
|
from fastapi.responses import JSONResponse, FileResponse
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
import os
|
import os
|
||||||
import csv
|
import csv
|
||||||
|
@ -47,6 +47,7 @@ def register_api_endpoints():
|
||||||
if file_path.is_file():
|
if file_path.is_file():
|
||||||
endpoint_name = file_path.stem
|
endpoint_name = file_path.stem
|
||||||
route = f"/api/{endpoint_name}"
|
route = f"/api/{endpoint_name}"
|
||||||
|
src_route = f"/api/{endpoint_name}/src"
|
||||||
|
|
||||||
# Skip if route already exists
|
# Skip if route already exists
|
||||||
if any(route == route_info.path for route_info in app.routes):
|
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)}"}
|
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(route, get_csv_data, methods=["GET"])
|
||||||
|
app.add_api_route(src_route, get_csv_src, methods=["GET"])
|
||||||
|
|
||||||
elif file_path.suffix.lower() == '.json':
|
elif file_path.suffix.lower() == '.json':
|
||||||
# Create a closure to capture the current file_path
|
# 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)}"}
|
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(route, get_json_data, methods=["GET"])
|
||||||
|
app.add_api_route(src_route, get_json_src, methods=["GET"])
|
||||||
|
|
||||||
@app.middleware("http")
|
@app.middleware("http")
|
||||||
async def check_for_new_files(request: Request, call_next):
|
async def check_for_new_files(request: Request, call_next):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue