from flask import Flask, request, jsonify, make_response import requests import json from urllib.parse import urlparse import logging # Configure basic logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # Initialize Flask app MyApp = Flask(__name__) MyApp.config['SECRET_KEY'] = 'your-secret-key-here' class ResourceRouter: def __init__(self): self.resource_mappings = { 'login': {'backend_url': 'http://linepe.de:5004/login', 'methods': ['POST']}, 'logout': {'backend_url': 'http://linepe.de:5004/logout', 'methods': ['POST']}, 'register': {'backend_url': 'http://linepe.de:5004/register', 'methods': ['POST']}, 'listing': {'backend_url': 'http://linepe.de:5005/listing', 'methods': ['GET', 'POST', 'PUT', 'DELETE']}, 'listings': {'backend_url': 'http://linepe.de:5005/listings', 'methods': ['GET', 'POST', 'PUT', 'DELETE']} } def get_backend_info(self, resource_path): """Get backend URL and allowed methods based on the resource path""" return self.resource_mappings.get(resource_path) def is_valid_request(self, resource_path, method): """Check if the request path and method are valid""" backend_info = self.get_backend_info(resource_path) if not backend_info: return False return method in backend_info['methods'] resource_router = ResourceRouter() def handle_backend_response(response): """Helper function to handle backend responses""" if not response.ok: logger.error(f"Backend request failed with status code {response.status_code}") # Check if the response has a valid Content-Type header for JSON if response.headers.get('Content-Type', '').startswith('application/json'): try: logger.error(f"Errormessage {response.json()}") except ValueError as e: logger.error(f"Failed to parse JSON response: {e}") else: # If the response isn't JSON, log the raw response content logger.error(f"Non-JSON response received: {response.text}") if not response.json(): return jsonify({"error": f"Failed to process request"}), 500 else: return response.json(), response.status_code try: data = response.json() return jsonify(data), response.status_code except json.JSONDecodeError: logger.error("Failed to decode backend response") return jsonify({"error": "Invalid response format"}), 500 @MyApp.route('/') def home(): """Health check endpoint""" return jsonify({'status': 'ok', 'message': 'API gateway is running'}) @MyApp.route('/', methods=['GET', 'POST', 'PUT', 'DELETE']) def generic_proxy(path): """Generic route handler for all API resources""" if "/" in path: route_parts = path.split('/') resource = route_parts[0] listing_id = route_parts[1] elif "?" in path: route_parts = path.split('?') resource = route_parts[0] else: resource = path if not resource_router.is_valid_request(resource, request.method): return jsonify({"error": "Invalid path or method"}), 405 backend_info = resource_router.get_backend_info(resource) backend_url = backend_info['backend_url'] # Extract all query parameters query_params = dict(request.args) try: data = {} if request.is_json and request.json: data.update(request.json) # Append listing_id to the URL if present in query parameters if "/" in path: backend_url += f"/{listing_id}" # Make the request to the backend service response = requests.request( method=request.method, url=backend_url, json=data, params=query_params, # Send all remaining query parameters as part of the request headers=request.headers ) return handle_backend_response(response) except Exception as e: logger.error(f"Error proxying request: {str(e)}") return jsonify({"error": str(e)}), 500 if __name__ == '__main__': MyApp.run(debug=True, port=5000)