Files
calminer/scripts/_route_verification.py
zwitschi b1a6df9f90 feat: Add profitability calculation schemas and service functions
- Introduced Pydantic schemas for profitability calculations in `schemas/calculations.py`.
- Implemented service functions for profitability calculations in `services/calculations.py`.
- Added new exception class `ProfitabilityValidationError` for handling validation errors.
- Created repositories for managing project and scenario profitability snapshots.
- Developed a utility script for verifying authenticated routes.
- Added a new HTML template for the profitability calculator interface.
- Implemented a script to fix user ID sequence in the database.
2025-11-12 22:22:29 +01:00

113 lines
3.4 KiB
Python

"""Utility script to verify key authenticated routes respond without errors."""
from __future__ import annotations
import json
import os
import sys
import urllib.parse
from http.client import HTTPConnection
from http.cookies import SimpleCookie
from typing import Dict, List, Tuple
HOST = "127.0.0.1"
PORT = 8000
cookies: Dict[str, str] = {}
def _update_cookies(headers: List[Tuple[str, str]]) -> None:
for name, value in headers:
if name.lower() != "set-cookie":
continue
cookie = SimpleCookie()
cookie.load(value)
for key, morsel in cookie.items():
cookies[key] = morsel.value
def _cookie_header() -> str | None:
if not cookies:
return None
return "; ".join(f"{key}={value}" for key, value in cookies.items())
def request(method: str, path: str, *, body: bytes | None = None, headers: Dict[str, str] | None = None) -> Tuple[int, Dict[str, str], bytes]:
conn = HTTPConnection(HOST, PORT, timeout=10)
prepared_headers = {"User-Agent": "route-checker"}
if headers:
prepared_headers.update(headers)
cookie_header = _cookie_header()
if cookie_header:
prepared_headers["Cookie"] = cookie_header
conn.request(method, path, body=body, headers=prepared_headers)
resp = conn.getresponse()
payload = resp.read()
status = resp.status
reason = resp.reason
response_headers = {name: value for name, value in resp.getheaders()}
_update_cookies(list(resp.getheaders()))
conn.close()
print(f"{method} {path} -> {status} {reason}")
return status, response_headers, payload
def main() -> int:
status, _, _ = request("GET", "/login")
if status != 200:
print("Unexpected status for GET /login", file=sys.stderr)
return 1
admin_username = os.getenv("CALMINER_SEED_ADMIN_USERNAME", "admin")
admin_password = os.getenv("CALMINER_SEED_ADMIN_PASSWORD", "M11ffpgm.")
login_payload = urllib.parse.urlencode(
{"username": admin_username, "password": admin_password}
).encode()
status, headers, _ = request(
"POST",
"/login",
body=login_payload,
headers={"Content-Type": "application/x-www-form-urlencoded"},
)
if status not in {200, 303}:
print("Login failed", file=sys.stderr)
return 1
location = headers.get("Location", "/")
redirect_path = urllib.parse.urlsplit(location).path or "/"
request("GET", redirect_path)
request("GET", "/")
request("GET", "/projects/ui")
status, headers, body = request(
"GET",
"/projects",
headers={"Accept": "application/json"},
)
projects: List[dict] = []
if headers.get("Content-Type", "").startswith("application/json"):
projects = json.loads(body.decode())
if projects:
project_id = projects[0]["id"]
request("GET", f"/projects/{project_id}/view")
status, headers, body = request(
"GET",
f"/projects/{project_id}/scenarios",
headers={"Accept": "application/json"},
)
scenarios: List[dict] = []
if headers.get("Content-Type", "").startswith("application/json"):
scenarios = json.loads(body.decode())
if scenarios:
scenario_id = scenarios[0]["id"]
request("GET", f"/scenarios/{scenario_id}/view")
print("Cookies:", cookies)
return 0
if __name__ == "__main__":
raise SystemExit(main())