mirror of
https://github.com/ghndrx/file-transformer-s3.git
synced 2026-02-10 06:45:05 +00:00
Initial commit: File Transformer S3 project with React dashboard and Knative functions
This commit is contained in:
30
api-gateway/Dockerfile
Normal file
30
api-gateway/Dockerfile
Normal file
@@ -0,0 +1,30 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
gcc \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy requirements and install Python dependencies
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy application code
|
||||
COPY app.py .
|
||||
|
||||
# Create non-root user
|
||||
RUN useradd --create-home --shell /bin/bash app && chown -R app:app /app
|
||||
USER app
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8080
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
|
||||
CMD curl -f http://localhost:8080/health || exit 1
|
||||
|
||||
# Run the application
|
||||
CMD ["gunicorn", "--bind", "0.0.0.0:8080", "--workers", "4", "--timeout", "300", "app:app"]
|
||||
165
api-gateway/app.py
Normal file
165
api-gateway/app.py
Normal file
@@ -0,0 +1,165 @@
|
||||
import os
|
||||
import requests
|
||||
from flask import Flask, request, jsonify
|
||||
from flask_cors import CORS
|
||||
import logging
|
||||
|
||||
app = Flask(__name__)
|
||||
CORS(app)
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Function service URLs
|
||||
UPLOAD_SERVICE_URL = os.getenv('UPLOAD_SERVICE_URL', 'http://function-upload:5000')
|
||||
TRANSFORM_SERVICE_URL = os.getenv('TRANSFORM_SERVICE_URL', 'http://function-transform:5000')
|
||||
DOWNLOAD_SERVICE_URL = os.getenv('DOWNLOAD_SERVICE_URL', 'http://function-download:5000')
|
||||
METADATA_SERVICE_URL = os.getenv('METADATA_SERVICE_URL', 'http://function-metadata:5000')
|
||||
|
||||
@app.route('/health', methods=['GET'])
|
||||
def health_check():
|
||||
"""Health check endpoint."""
|
||||
return jsonify({'status': 'healthy', 'service': 'api-gateway'})
|
||||
|
||||
@app.route('/files/upload', methods=['POST'])
|
||||
def upload_file():
|
||||
"""Route file upload requests to upload service."""
|
||||
try:
|
||||
response = requests.post(
|
||||
f"{UPLOAD_SERVICE_URL}/upload",
|
||||
files=request.files,
|
||||
data=request.form,
|
||||
timeout=300
|
||||
)
|
||||
return jsonify(response.json()), response.status_code
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Upload service error: {e}")
|
||||
return jsonify({'error': 'Upload service unavailable'}), 503
|
||||
|
||||
@app.route('/files/<file_id>/transform', methods=['POST'])
|
||||
def transform_file(file_id):
|
||||
"""Route transformation requests to transform service."""
|
||||
try:
|
||||
response = requests.post(
|
||||
f"{TRANSFORM_SERVICE_URL}/transform/{file_id}",
|
||||
json=request.get_json(),
|
||||
timeout=300
|
||||
)
|
||||
return jsonify(response.json()), response.status_code
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Transform service error: {e}")
|
||||
return jsonify({'error': 'Transform service unavailable'}), 503
|
||||
|
||||
@app.route('/files/<file_id>/download', methods=['GET'])
|
||||
def download_file(file_id):
|
||||
"""Route download requests to download service."""
|
||||
try:
|
||||
response = requests.get(
|
||||
f"{DOWNLOAD_SERVICE_URL}/download/{file_id}",
|
||||
timeout=300
|
||||
)
|
||||
return response.content, response.status_code, response.headers.items()
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Download service error: {e}")
|
||||
return jsonify({'error': 'Download service unavailable'}), 503
|
||||
|
||||
@app.route('/files/<file_id>/metadata', methods=['GET'])
|
||||
def get_file_metadata(file_id):
|
||||
"""Route metadata requests to metadata service."""
|
||||
try:
|
||||
response = requests.get(
|
||||
f"{METADATA_SERVICE_URL}/files/{file_id}/metadata",
|
||||
timeout=30
|
||||
)
|
||||
return jsonify(response.json()), response.status_code
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Metadata service error: {e}")
|
||||
return jsonify({'error': 'Metadata service unavailable'}), 503
|
||||
|
||||
@app.route('/files/<file_id>/metadata', methods=['PUT'])
|
||||
def update_file_metadata(file_id):
|
||||
"""Route metadata update requests to metadata service."""
|
||||
try:
|
||||
response = requests.put(
|
||||
f"{METADATA_SERVICE_URL}/files/{file_id}/metadata",
|
||||
json=request.get_json(),
|
||||
timeout=30
|
||||
)
|
||||
return jsonify(response.json()), response.status_code
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Metadata service error: {e}")
|
||||
return jsonify({'error': 'Metadata service unavailable'}), 503
|
||||
|
||||
@app.route('/files', methods=['GET'])
|
||||
def get_files():
|
||||
"""Route file listing requests to metadata service."""
|
||||
try:
|
||||
response = requests.get(
|
||||
f"{METADATA_SERVICE_URL}/files",
|
||||
params=request.args,
|
||||
timeout=30
|
||||
)
|
||||
return jsonify(response.json()), response.status_code
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Metadata service error: {e}")
|
||||
return jsonify({'error': 'Metadata service unavailable'}), 503
|
||||
|
||||
@app.route('/transformations', methods=['GET'])
|
||||
def get_transformations():
|
||||
"""Route transformation listing requests to metadata service."""
|
||||
try:
|
||||
response = requests.get(
|
||||
f"{METADATA_SERVICE_URL}/transformations",
|
||||
params=request.args,
|
||||
timeout=30
|
||||
)
|
||||
return jsonify(response.json()), response.status_code
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Metadata service error: {e}")
|
||||
return jsonify({'error': 'Metadata service unavailable'}), 503
|
||||
|
||||
@app.route('/dashboard/stats', methods=['GET'])
|
||||
def get_dashboard_stats():
|
||||
"""Route dashboard stats requests to metadata service."""
|
||||
try:
|
||||
response = requests.get(
|
||||
f"{METADATA_SERVICE_URL}/stats",
|
||||
timeout=30
|
||||
)
|
||||
return jsonify(response.json()), response.status_code
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Metadata service error: {e}")
|
||||
return jsonify({'error': 'Metadata service unavailable'}), 503
|
||||
|
||||
@app.route('/buckets', methods=['GET'])
|
||||
def get_buckets():
|
||||
"""Route bucket requests to metadata service."""
|
||||
try:
|
||||
response = requests.get(
|
||||
f"{METADATA_SERVICE_URL}/buckets",
|
||||
timeout=30
|
||||
)
|
||||
return jsonify(response.json()), response.status_code
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Metadata service error: {e}")
|
||||
return jsonify({'error': 'Metadata service unavailable'}), 503
|
||||
|
||||
# Auth endpoints (placeholder for now)
|
||||
@app.route('/auth/login', methods=['POST'])
|
||||
def login():
|
||||
"""Placeholder login endpoint."""
|
||||
return jsonify({'token': 'dummy-token', 'user': {'id': 1, 'username': 'admin'}}), 200
|
||||
|
||||
@app.route('/auth/logout', methods=['POST'])
|
||||
def logout():
|
||||
"""Placeholder logout endpoint."""
|
||||
return jsonify({'message': 'Logged out successfully'}), 200
|
||||
|
||||
@app.route('/auth/profile', methods=['GET'])
|
||||
def get_profile():
|
||||
"""Placeholder profile endpoint."""
|
||||
return jsonify({'id': 1, 'username': 'admin', 'email': 'admin@example.com'}), 200
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', port=8080, debug=False)
|
||||
11
api-gateway/requirements.txt
Normal file
11
api-gateway/requirements.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
# Core dependencies
|
||||
flask==2.3.3
|
||||
flask-cors==4.0.0
|
||||
gunicorn==21.2.0
|
||||
python-dotenv==1.0.0
|
||||
|
||||
# HTTP requests
|
||||
requests==2.31.0
|
||||
|
||||
# Logging
|
||||
structlog==23.1.0
|
||||
Reference in New Issue
Block a user