use flask cors

This commit is contained in:
Matteo Rosati
2026-01-16 10:18:06 +01:00
parent 686e4ff477
commit fdaf72f103
4 changed files with 43 additions and 35 deletions

45
app.py
View File

@@ -4,6 +4,7 @@ from datetime import datetime
from zoneinfo import ZoneInfo from zoneinfo import ZoneInfo
from functools import wraps from functools import wraps
from flask import Flask, request, jsonify, Response from flask import Flask, request, jsonify, Response
from flask_cors import CORS
from ingress import IngressAPI from ingress import IngressAPI
from models import EventType, Plext from models import EventType, Plext
from pymongo import MongoClient from pymongo import MongoClient
@@ -22,6 +23,7 @@ logging.basicConfig(
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
app = Flask(__name__) app = Flask(__name__)
CORS(app)
def check_basic_auth(username: str, password: str) -> bool: def check_basic_auth(username: str, password: str) -> bool:
@@ -155,7 +157,7 @@ def plext_to_dict(plext: Plext) -> dict:
} }
@app.route("/plexts/from-db", methods=["GET", "OPTIONS"]) @app.route("/plexts/from-db", methods=["GET"])
@basic_auth_required @basic_auth_required
def get_plexts_from_db(): def get_plexts_from_db():
""" """
@@ -171,17 +173,6 @@ def get_plexts_from_db():
Returns: Returns:
JSON response with list of plexts (without _id field), limited by the limit parameter JSON response with list of plexts (without _id field), limited by the limit parameter
""" """
# CORS headers
cors_headers = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
}
# Handle OPTIONS preflight request
if request.method == "OPTIONS":
return "", 200, cors_headers
try: try:
# Parse query parameters # Parse query parameters
player_name = request.args.get("player_name") player_name = request.args.get("player_name")
@@ -194,38 +185,22 @@ def get_plexts_from_db():
try: try:
timestamp_from = int(timestamp_from) timestamp_from = int(timestamp_from)
except ValueError: except ValueError:
return ( return jsonify({"error": "timestamp_from must be an integer"}), 400
jsonify({"error": "timestamp_from must be an integer"}),
400,
cors_headers,
)
if timestamp_to is not None: if timestamp_to is not None:
try: try:
timestamp_to = int(timestamp_to) timestamp_to = int(timestamp_to)
except ValueError: except ValueError:
return ( return jsonify({"error": "timestamp_to must be an integer"}), 400
jsonify({"error": "timestamp_to must be an integer"}),
400,
cors_headers,
)
# Validate and convert limit parameter to integer if provided, otherwise default to 100 # Validate and convert limit parameter to integer if provided, otherwise default to 100
if limit_param is not None: if limit_param is not None:
try: try:
limit = int(limit_param) limit = int(limit_param)
if limit <= 0: if limit <= 0:
return ( return jsonify({"error": "limit must be a positive integer"}), 400
jsonify({"error": "limit must be a positive integer"}),
400,
cors_headers,
)
except ValueError: except ValueError:
return ( return jsonify({"error": "limit must be an integer"}), 400
jsonify({"error": "limit must be an integer"}),
400,
cors_headers,
)
else: else:
limit = 100 limit = 100
@@ -266,17 +241,17 @@ def get_plexts_from_db():
# Convert cursor to list # Convert cursor to list
plexts = list(cursor) plexts = list(cursor)
return jsonify({"count": len(plexts), "plexts": plexts}), 200, cors_headers return jsonify({"count": len(plexts), "plexts": plexts}), 200
except PyMongoError as e: except PyMongoError as e:
logger.error(f"MongoDB error: {e}") logger.error(f"MongoDB error: {e}")
return jsonify({"error": "Database error"}), 500, cors_headers return jsonify({"error": "Database error"}), 500
finally: finally:
client.close() client.close()
except Exception as e: except Exception as e:
logger.exception("Unexpected error in get_plexts_from_db") logger.exception("Unexpected error in get_plexts_from_db")
return jsonify({"error": "An error occurred"}), 500, cors_headers return jsonify({"error": "An error occurred"}), 500
@app.route("/plexts/from-api", methods=["GET"]) @app.route("/plexts/from-api", methods=["GET"])

View File

@@ -12,4 +12,5 @@ dependencies = [
"pymongo>=4.10.0", "pymongo>=4.10.0",
"apscheduler>=3.10.0", "apscheduler>=3.10.0",
"ipython>=9.9.0", "ipython>=9.9.0",
"flask-cors>=6.0.2",
] ]

View File

@@ -1,19 +1,36 @@
apscheduler==3.11.2 apscheduler==3.11.2
asttokens==3.0.1
blinker==1.9.0 blinker==1.9.0
certifi==2026.1.4 certifi==2026.1.4
charset-normalizer==3.4.4 charset-normalizer==3.4.4
click==8.3.1 click==8.3.1
decorator==5.2.1
dnspython==2.8.0 dnspython==2.8.0
executing==2.2.1
flask==3.1.2 flask==3.1.2
flask-cors==6.0.2
gunicorn==23.0.0 gunicorn==23.0.0
idna==3.11 idna==3.11
ipython==9.9.0
ipython-pygments-lexers==1.1.1
itsdangerous==2.2.0 itsdangerous==2.2.0
jedi==0.19.2
jinja2==3.1.6 jinja2==3.1.6
markupsafe==3.0.3 markupsafe==3.0.3
matplotlib-inline==0.2.1
packaging==25.0 packaging==25.0
parso==0.8.5
pexpect==4.9.0
prompt-toolkit==3.0.52
ptyprocess==0.7.0
pure-eval==0.2.3
pygments==2.19.2
pymongo==4.16.0 pymongo==4.16.0
python-dotenv==1.2.1 python-dotenv==1.2.1
requests==2.32.5 requests==2.32.5
stack-data==0.6.3
traitlets==5.14.3
tzlocal==5.3.1 tzlocal==5.3.1
urllib3==2.6.3 urllib3==2.6.3
wcwidth==0.2.14
werkzeug==3.1.5 werkzeug==3.1.5

15
uv.lock generated
View File

@@ -147,6 +147,19 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/ec/f9/7f9263c5695f4bd0023734af91bedb2ff8209e8de6ead162f35d8dc762fd/flask-3.1.2-py3-none-any.whl", hash = "sha256:ca1d8112ec8a6158cc29ea4858963350011b5c846a414cdb7a954aa9e967d03c", size = 103308, upload-time = "2025-08-19T21:03:19.499Z" }, { url = "https://files.pythonhosted.org/packages/ec/f9/7f9263c5695f4bd0023734af91bedb2ff8209e8de6ead162f35d8dc762fd/flask-3.1.2-py3-none-any.whl", hash = "sha256:ca1d8112ec8a6158cc29ea4858963350011b5c846a414cdb7a954aa9e967d03c", size = 103308, upload-time = "2025-08-19T21:03:19.499Z" },
] ]
[[package]]
name = "flask-cors"
version = "6.0.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "flask" },
{ name = "werkzeug" },
]
sdist = { url = "https://files.pythonhosted.org/packages/70/74/0fc0fa68d62f21daef41017dafab19ef4b36551521260987eb3a5394c7ba/flask_cors-6.0.2.tar.gz", hash = "sha256:6e118f3698249ae33e429760db98ce032a8bf9913638d085ca0f4c5534ad2423", size = 13472, upload-time = "2025-12-12T20:31:42.861Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/4f/af/72ad54402e599152de6d067324c46fe6a4f531c7c65baf7e96c63db55eaf/flask_cors-6.0.2-py3-none-any.whl", hash = "sha256:e57544d415dfd7da89a9564e1e3a9e515042df76e12130641ca6f3f2f03b699a", size = 13257, upload-time = "2025-12-12T20:31:41.3Z" },
]
[[package]] [[package]]
name = "gunicorn" name = "gunicorn"
version = "23.0.0" version = "23.0.0"
@@ -175,6 +188,7 @@ source = { virtual = "." }
dependencies = [ dependencies = [
{ name = "apscheduler" }, { name = "apscheduler" },
{ name = "flask" }, { name = "flask" },
{ name = "flask-cors" },
{ name = "gunicorn" }, { name = "gunicorn" },
{ name = "ipython" }, { name = "ipython" },
{ name = "pymongo" }, { name = "pymongo" },
@@ -186,6 +200,7 @@ dependencies = [
requires-dist = [ requires-dist = [
{ name = "apscheduler", specifier = ">=3.10.0" }, { name = "apscheduler", specifier = ">=3.10.0" },
{ name = "flask", specifier = ">=3.1.2" }, { name = "flask", specifier = ">=3.1.2" },
{ name = "flask-cors", specifier = ">=6.0.2" },
{ name = "gunicorn", specifier = ">=23.0.0" }, { name = "gunicorn", specifier = ">=23.0.0" },
{ name = "ipython", specifier = ">=9.9.0" }, { name = "ipython", specifier = ">=9.9.0" },
{ name = "pymongo", specifier = ">=4.10.0" }, { name = "pymongo", specifier = ">=4.10.0" },