Cristobal299's picture
Upload app.py with huggingface_hub
e849906 verified
Raw
History Blame Contribute Delete
6.34 kB
# -*- coding: utf-8 -*-
import os
import sqlite3
import json
import requests
from flask import Flask, request, jsonify, g
app = Flask(__name__)
@app.after_request
def add_cors_headers(response):
response.headers['Access-Control-Allow-Origin'] = '*'
response.headers['Access-Control-Allow-Methods'] = 'GET,POST,PUT,DELETE,OPTIONS'
response.headers['Access-Control-Allow-Headers'] = 'Content-Type,Authorization'
return response
# ----------------------------------------------------------------------
# Database utilities (unchanged)
# ----------------------------------------------------------------------
DATABASE = os.path.join(os.path.dirname(__file__), "tasks.db")
def get_db():
db = getattr(g, "_database", None)
if db is None:
db = g._database = sqlite3.connect(DATABASE, check_same_thread=False)
db.row_factory = sqlite3.Row
return db
def init_db():
conn = sqlite3.connect(DATABASE)
cursor = conn.cursor()
cursor.execute(
"""
CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
completed INTEGER NOT NULL DEFAULT 0
)
"""
)
conn.commit()
conn.close()
@app.teardown_appcontext
def close_connection(exception):
db = getattr(g, "_database", None)
if db is not None:
db.close()
# ----------------------------------------------------------------------
# Existing task endpoints (unchanged)
# ----------------------------------------------------------------------
@app.route("/tasks", methods=["GET"])
def list_tasks():
db = get_db()
cursor = db.execute("SELECT id, title, completed FROM tasks")
tasks = [
{"id": row["id"], "title": row["title"], "completed": bool(row["completed"])}
for row in cursor.fetchall()
]
return jsonify(tasks)
@app.route("/tasks", methods=["POST"])
def create_task():
data = request.get_json()
title = data.get("title")
if not title:
return jsonify({"error": "title is required"}), 400
db = get_db()
cursor = db.execute(
"INSERT INTO tasks (title, completed) VALUES (?, ?)",
(title, 0),
)
db.commit()
task_id = cursor.lastrowid
return jsonify({"id": task_id, "title": title, "completed": False}), 201
@app.route("/tasks/<int:task_id>", methods=["PUT"])
def update_task(task_id):
data = request.get_json()
title = data.get("title")
completed = data.get("completed")
if title is None and completed is None:
return jsonify({"error": "nothing to update"}), 400
db = get_db()
if title is not None:
db.execute("UPDATE tasks SET title = ? WHERE id = ?", (title, task_id))
if completed is not None:
db.execute(
"UPDATE tasks SET completed = ? WHERE id = ?",
(1 if completed else 0, task_id),
)
db.commit()
return jsonify({"id": task_id, "title": title, "completed": completed})
@app.route("/tasks/<int:task_id>", methods=["DELETE"])
def delete_task(task_id):
db = get_db()
db.execute("DELETE FROM tasks WHERE id = ?", (task_id,))
db.commit()
return "", 204
# ----------------------------------------------------------------------
# Health endpoints (unchanged)
# ----------------------------------------------------------------------
@app.route("/", methods=["GET"])
@app.route("/test", methods=["GET"])
def index():
return "Task API is running."
@app.route("/ping", methods=["GET"])
def ping():
return "pong", 200
# ----------------------------------------------------------------------
# New: Generic API connector
# ----------------------------------------------------------------------
@app.route("/api/connector", methods=["GET", "POST"])
def api_connector():
"""
Expects a JSON payload with the following fields:
{
"url": "https://example.com/endpoint",
"method": "GET|POST|PUT|DELETE|PATCH",
"headers": {"Authorization": "Bearer ...", ...}, # optional
"params": {"q": "search"}, # optional, for query string
"json": {"key": "value"} # optional, for JSON body
}
The endpoint forwards the request to the target API and returns
the raw response (status code, headers and JSON body if possible).
"""
payload = request.get_json()
if not payload:
return jsonify({"error": "invalid json payload"}), 400
url = payload.get("url")
# placeholder replacement removed
method = payload.get("method", "GET").upper()
headers = payload.get("headers", {})
params = payload.get("params", {})
json_body = payload.get("json", None)
if not url:
return jsonify({"error": "url is required"}), 400
# Optional: inject a default API key from environment if not provided
default_key = os.environ.get("DEFAULT_API_KEY")
if default_key and "Authorization" not in headers:
headers["Authorization"] = f"Bearer {default_key}"
try:
response = requests.request(
method=method,
url=url,
headers=headers,
params=params,
json=json_body,
timeout=30
)
# Do not raise for HTTP errors; return the response as is
except requests.RequestException as e:
return jsonify({"error": "request failed", "details": str(e)}), 502
# Try to parse JSON, fallback to raw text
try:
resp_content = response.json()
except ValueError:
resp_content = response.text
result = {
"status_code": response.status_code,
"headers": dict(response.headers),
"content": resp_content
}
return jsonify(result), response.status_code
# ----------------------------------------------------------------------
# Error handling (unchanged)
# ----------------------------------------------------------------------
@app.errorhandler(404)
def not_found(e):
return jsonify({"error": "not found"}), 404
# ----------------------------------------------------------------------
# Main entry point (unchanged)
# ----------------------------------------------------------------------
if __name__ == "__main__":
if not os.path.isfile(DATABASE):
init_db()
app.run(host="0.0.0.0", port=7860)