This commit is contained in:
2026-02-15 16:53:17 +01:00
parent 9efdef77ac
commit cde554c981
4 changed files with 110 additions and 67 deletions

19
.dockerignore Normal file
View File

@@ -0,0 +1,19 @@
__pycache__
*.pyc
*.pyo
*.pyd
.Python
.env
.venv
.git
.gitignore
*.sqlite3
*.db
analysis.py
db.py
pyproject.toml
README.md
run_speedtest.py
uv.lock
.dockerignore
.python-version

36
Dockerfile Normal file
View File

@@ -0,0 +1,36 @@
# Use a lightweight Python base image
FROM python:3.13-slim
# Set environment variables to prevent Python from writing pyc files
# and to flush stdout/stderr immediately (useful for docker logs)
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
# Set the working directory
WORKDIR /app
RUN apt-get update && \
apt-get install -y git && \
rm -rf /var/lib/apt/lists/*
# Install dependencies first (for better caching)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy the rest of the application code
COPY . .
# Create a directory for the database mount (optional but good for clarity)
RUN mkdir -p /data
# Default environment variable for the database path inside the container
ENV DB_PATH="/data/speedtest.db"
ENV PORT=5000
# Expose the port the app runs on
EXPOSE 5000
# Run using Gunicorn
# -b 0.0.0.0:5000: Bind to all interfaces on port 5000
# --access-logfile -: Log access to stdout
CMD ["gunicorn", "--workers", "1", "--bind", "0.0.0.0:5000", "--access-logfile", "-", "app:app"]

View File

@@ -1,67 +0,0 @@
import sqlite3
import os
from datetime import datetime
import pytz
import time
from config import DB_PATH
def get_conn() -> sqlite3.Connection:
uri = f"file:{os.path.abspath(DB_PATH)}?cache=shared"
conn = sqlite3.connect(uri, uri=True, check_same_thread=False)
conn.row_factory = sqlite3.Row
conn.execute("PRAGMA journal_mode=WAL;")
conn.execute("PRAGMA synchronous=NORMAL;")
conn.execute("PRAGMA temp_store=MEMORY;")
conn.execute("PRAGMA cache_size=-20000;") # ~20MB cache
return conn
CONN = get_conn()
# ---------------------- Utilities ----------------------
def ts_to_iso(ts: float | int | str) -> str:
try:
t = float(ts)
except Exception:
return str(ts)
return datetime.fromtimestamp(t, tz=pytz.timezone("Europe/Berlin")).isoformat()
# ---------------------- API Endpoints ----------------------
def api_series(q_from: float, q_to: float):
params = []
where = []
if q_from is not None:
where.append("timestamp >= ?")
params.append(q_from)
if q_to is not None:
where.append("timestamp <= ?")
params.append(q_to)
where_sql = ("WHERE " + " AND ".join(where)) if where else ""
sql = (
f"SELECT timestamp, down_90th, up_90th FROM speed_tests {where_sql} "
"ORDER BY timestamp ASC;"
)
rows = []
for i, r in enumerate(CONN.execute(sql, params)):
rows.append({
"t": float(r["timestamp"]),
"t_iso": ts_to_iso(r["timestamp"]),
"down_90th": None if r["down_90th"] is None else float(r["down_90th"]),
"up_90th": None if r["up_90th"] is None else float(r["up_90th"]),
})
return rows
rows = api_series(1756220400, time.time())
does_not_work = 0
for r in rows:
if r["down_90th"] is None or r["up_90th"] is None:
does_not_work += 1
print(f"Working percentage: {100 - (does_not_work / len(rows))*100}% ({does_not_work}/{len(rows)})")

55
requirements.txt Normal file
View File

@@ -0,0 +1,55 @@
# This file was autogenerated by uv via the following command:
# uv export --format requirements-txt -o requirements.txt --no-hashes
blinker==1.9.0
# via flask
certifi==2025.11.12
# via requests
charset-normalizer==3.4.4
# via requests
click==8.3.1
# via flask
cloudflarepycli @ git+https://github.com/cato447/cloudflarepycli@26477fb5511839648a774f1685426925b5b44311
# via speed-logger
colorama==0.4.6 ; sys_platform == 'win32'
# via click
flask==3.1.2
# via speed-logger
getmac==0.9.5
# via speed-logger
gunicorn==23.0.0
# via speed-logger
idna==3.11
# via requests
itsdangerous==2.2.0
# via flask
jinja2==3.1.6
# via flask
markupsafe==3.0.3
# via
# flask
# jinja2
# werkzeug
numpy==2.4.0
# via pandas
packaging==25.0
# via gunicorn
pandas==2.3.3
# via speed-logger
prometheus-client==0.23.1
# via speed-logger
python-dateutil==2.9.0.post0
# via pandas
pytz==2025.2
# via
# pandas
# speed-logger
requests==2.32.5
# via cloudflarepycli
six==1.17.0
# via python-dateutil
tzdata==2025.3
# via pandas
urllib3==2.6.2
# via requests
werkzeug==3.1.4
# via flask