Team Ai
Apppublic

Cristobal299/flask-sqlite-api

sourceHugging Faceupdated 4mo agoView on Hugging Face
0likes
app.py190 linesDownload Raw Back to root
1# -*- coding: utf-8 -*-2import os3import sqlite34import json5import requests6from flask import Flask, request, jsonify, g7 8app = Flask(__name__)9 10@app.after_request11def add_cors_headers(response):12    response.headers['Access-Control-Allow-Origin'] = '*'13    response.headers['Access-Control-Allow-Methods'] = 'GET,POST,PUT,DELETE,OPTIONS'14    response.headers['Access-Control-Allow-Headers'] = 'Content-Type,Authorization'15    return response16 17# ----------------------------------------------------------------------18# Database utilities (unchanged)19# ----------------------------------------------------------------------20DATABASE = os.path.join(os.path.dirname(__file__), "tasks.db")21 22def get_db():23    db = getattr(g, "_database", None)24    if db is None:25        db = g._database = sqlite3.connect(DATABASE, check_same_thread=False)26        db.row_factory = sqlite3.Row27    return db28 29def init_db():30    conn = sqlite3.connect(DATABASE)31    cursor = conn.cursor()32    cursor.execute(33        """34        CREATE TABLE IF NOT EXISTS tasks (35            id INTEGER PRIMARY KEY AUTOINCREMENT,36            title TEXT NOT NULL,37            completed INTEGER NOT NULL DEFAULT 038        )39        """40    )41    conn.commit()42    conn.close()43 44@app.teardown_appcontext45def close_connection(exception):46    db = getattr(g, "_database", None)47    if db is not None:48        db.close()49 50# ----------------------------------------------------------------------51# Existing task endpoints (unchanged)52# ----------------------------------------------------------------------53@app.route("/tasks", methods=["GET"])54def list_tasks():55    db = get_db()56    cursor = db.execute("SELECT id, title, completed FROM tasks")57    tasks = [58        {"id": row["id"], "title": row["title"], "completed": bool(row["completed"])}59        for row in cursor.fetchall()60    ]61    return jsonify(tasks)62 63@app.route("/tasks", methods=["POST"])64def create_task():65    data = request.get_json()66    title = data.get("title")67    if not title:68        return jsonify({"error": "title is required"}), 40069    db = get_db()70    cursor = db.execute(71        "INSERT INTO tasks (title, completed) VALUES (?, ?)",72        (title, 0),73    )74    db.commit()75    task_id = cursor.lastrowid76    return jsonify({"id": task_id, "title": title, "completed": False}), 20177 78@app.route("/tasks/<int:task_id>", methods=["PUT"])79def update_task(task_id):80    data = request.get_json()81    title = data.get("title")82    completed = data.get("completed")83    if title is None and completed is None:84        return jsonify({"error": "nothing to update"}), 40085    db = get_db()86    if title is not None:87        db.execute("UPDATE tasks SET title = ? WHERE id = ?", (title, task_id))88    if completed is not None:89        db.execute(90            "UPDATE tasks SET completed = ? WHERE id = ?",91            (1 if completed else 0, task_id),92        )93    db.commit()94    return jsonify({"id": task_id, "title": title, "completed": completed})95 96@app.route("/tasks/<int:task_id>", methods=["DELETE"])97def delete_task(task_id):98    db = get_db()99    db.execute("DELETE FROM tasks WHERE id = ?", (task_id,))100    db.commit()101    return "", 204102 103# ----------------------------------------------------------------------104# Health endpoints (unchanged)105# ----------------------------------------------------------------------106@app.route("/", methods=["GET"])107@app.route("/test", methods=["GET"])108def index():109    return "Task API is running."110 111@app.route("/ping", methods=["GET"])112def ping():113    return "pong", 200114 115# ----------------------------------------------------------------------116# New: Generic API connector117# ----------------------------------------------------------------------118@app.route("/api/connector", methods=["GET", "POST"])119def api_connector():120    """121    Expects a JSON payload with the following fields:122    {123        "url": "https://example.com/endpoint",124        "method": "GET|POST|PUT|DELETE|PATCH",125        "headers": {"Authorization": "Bearer ...", ...},   # optional126        "params": {"q": "search"},                         # optional, for query string127        "json": {"key": "value"}                          # optional, for JSON body128    }129    The endpoint forwards the request to the target API and returns130    the raw response (status code, headers and JSON body if possible).131    """132    payload = request.get_json()133    if not payload:134        return jsonify({"error": "invalid json payload"}), 400135 136    url = payload.get("url")137    # placeholder replacement removed138    method = payload.get("method", "GET").upper()139    headers = payload.get("headers", {})140    params = payload.get("params", {})141    json_body = payload.get("json", None)142 143    if not url:144        return jsonify({"error": "url is required"}), 400145 146    # Optional: inject a default API key from environment if not provided147    default_key = os.environ.get("DEFAULT_API_KEY")148    if default_key and "Authorization" not in headers:149        headers["Authorization"] = f"Bearer {default_key}"150 151    try:152        response = requests.request(153            method=method,154            url=url,155            headers=headers,156            params=params,157            json=json_body,158            timeout=30159        )160        # Do not raise for HTTP errors; return the response as is161    except requests.RequestException as e:162        return jsonify({"error": "request failed", "details": str(e)}), 502163 164    # Try to parse JSON, fallback to raw text165    try:166        resp_content = response.json()167    except ValueError:168        resp_content = response.text169 170    result = {171        "status_code": response.status_code,172        "headers": dict(response.headers),173        "content": resp_content174    }175    return jsonify(result), response.status_code176 177# ----------------------------------------------------------------------178# Error handling (unchanged)179# ----------------------------------------------------------------------180@app.errorhandler(404)181def not_found(e):182    return jsonify({"error": "not found"}), 404183 184# ----------------------------------------------------------------------185# Main entry point (unchanged)186# ----------------------------------------------------------------------187if __name__ == "__main__":188    if not os.path.isfile(DATABASE):189        init_db()190    app.run(host="0.0.0.0", port=7860)