chore: regenerate stale .pi-map.md / .pi-map.index.md project maps

Project map had drifted: claimed recharts unused (was used), ObservabilityPage.tsx
exists (refactored to service-tabs/), missed JellyfinNowPlayingWidget +
authentik/backups service types. Regenerate to reflect post-change reality:
new Qbittorrent/LineSeriesChart/Prometheus{Gauge,Mean}Widget files,
service_data.py/qbittorrent_store.py, canonical prometheus-charting +
service-storage specs, archived changes.
This commit is contained in:
Developer
2026-07-09 14:05:56 +00:00
parent 98f17f6e5d
commit ec7ebd7013
189 changed files with 1215 additions and 428 deletions
@@ -2,7 +2,7 @@
dir: backend/src/media_library_viewer_api/routers
## role
FastAPI router package that exposes all REST API endpoints for the media library viewer backend, organized by domain (files, media, jobs, backups, dashboard, monitoring, services, settings, tasks, users, widgets).
FastAPI router package that defines all HTTP API endpoints for the media library viewer backend, organizing routes by domain (auth, backups, dashboards, files, jobs, media, monitoring, services, settings, tasks, widgets).
## parent
index: backend/src/media_library_viewer_api/.pi-map.index.md
map: backend/src/media_library_viewer_api/.pi-map.md
@@ -10,8 +10,10 @@ map: backend/src/media_library_viewer_api/.pi-map.md
-
## files
- __init__.py
- authentik_users.py
- backups.py
- dashboard.py
- dashboards.py
- files.py
- jobs.py
- media.py
@@ -19,14 +21,12 @@ map: backend/src/media_library_viewer_api/.pi-map.md
- services.py
- settings.py
- tasks.py
- users.py
- users_impl.py
- widgets.py
## links
index: backend/src/media_library_viewer_api/routers/.pi-map.index.md
map: backend/src/media_library_viewer_api/routers/.pi-map.md
## workflows
- change routers behavior
read: __init__.py, backups.py, dashboard.py
read: __init__.py, authentik_users.py, backups.py
## dirty
-
@@ -4,26 +4,27 @@ dir: backend/src/media_library_viewer_api/routers
index: backend/src/media_library_viewer_api/routers/.pi-map.index.md
## role
FastAPI router package that exposes all REST API endpoints for the media library viewer backend, organized by domain (files, media, jobs, backups, dashboard, monitoring, services, settings, tasks, users, widgets).
FastAPI router package that defines all HTTP API endpoints for the media library viewer backend, organizing routes by domain (auth, backups, dashboards, files, jobs, media, monitoring, services, settings, tasks, widgets).
## files
- __init__.py | Marks the directory as a Python package for routers.
- backups.py | FastAPI router that provides REST endpoints for reporting, tracking, and alerting on backup jobs and runs. | exp: func:_get_or_create_job(store: SettingsStore, report: BackupReportRequest) → dict[str, Any], call:store.get_backup_job_by_name, call:store.upsert_backup_job, call:store.get_backup_job, func:post_backup_report(report: BackupReportRequest, store, _auth) → BackupRunResponse, call:_get_or_create_job, call:store.list_backup_runs, call:int, call:report.started_at.timestamp, call:abs, call:BackupRunResponse, call:report.ended_at.timestamp, call:store.create_backup_run, call:record_backup_run, call:generate_alerts_for_run, call:store.create_backup_alert, call:store.resolve_backup_alerts_for_job, call:run.pop, func:post_backup_start(report: BackupReportRequest, store, _auth) → BackupRunResponse, call:_get_or_create_job, call:int, call:report.started_at.timestamp, call:store.create_backup_run, call:record_backup_run, call:run.pop, call:BackupRunResponse, func:get_backup_jobs(store) → list[dict[str, Any]], call:store.list_backup_jobs, func:get_backup_job(job_id: str, store) → dict[str, Any], call:store.get_backup_job, call:store.list_backup_runs, raise:HTTPException, func:get_backup_runs(job_id, status, limit, store) → list[BackupRunResponse], call:store.list_backup_runs, call:BackupRunResponse, func:get_backup_run(run_id: str, store) → BackupRunResponse, call:store.get_backup_run, call:BackupRunResponse, raise:HTTPException, func:get_backup_alerts(job_id, acknowledged, severity, store) → list[BackupAlertResponse], call:store.list_backup_alerts, call:BackupAlertResponse, func:acknowledge_backup_alert(alert_id: str, store) → BackupAlertResponse, call:store.acknowledge_backup_alert, call:BackupAlertResponse, raise:HTTPException | dep: typing, fastapi, ..auth, ..models.backups, ..observability, ..services.backup_alert_engine, ..services.settings_store
- authentik_users.py | Provides a FastAPI router that proxies paginated user directory queries and email message enqueueing through an Authentik service client. | exp: class:MessageRequest, func:_build_client(service: ServiceRecord) → AuthentikClient, call:str(service.config.get("base_url") or "").rstrip, call:service.config.get, call:service.secrets.get, call:float, call:AuthentikClient, func:_empty(error: str) → dict[str, Any], func:get_authentik_users(service_id: str, search, page, page_size, store) → dict[str, Any], call:resolve_service_record, call:logger.info, call:_empty, call:_build_client, call:client.users, call:logger.exception, func:get_authentik_message_status(service_id: str, store, mail_queue) → dict[str, Any], call:resolve_service_record, call:mail_queue.status, func:post_authentik_message(service_id: str, body: MessageRequest, store, mail_queue) → dict[str, Any], call:resolve_service_record, call:r.strip, call:get_settings, call:validate_smtp_settings, call:mail_queue.enqueue, call:logger.info, call:len | dep: logging, typing, fastapi, pydantic, media_library_viewer_api.clients.authentik, media_library_viewer_api.config, media_library_viewer_api.dependencies, media_library_viewer_api.services.mail_queue, media_library_viewer_api.services.mailer, media_library_viewer_api.services.service_resolution, media_library_viewer_api.services.settings_store, media_library_viewer_api.widgets.sources
- backups.py | FastAPI router for receiving backup run reports, managing backup jobs/runs, and generating/acknowledging backup alerts. | exp: func:_resolve_backup_service_id(store: SettingsStore, explicit) → str, call:store.list_services, call:svc.get, func:_get_or_create_job(store: SettingsStore, report: BackupReportRequest, service_id) → dict[str, Any], call:store.get_backup_job_by_name, call:store.upsert_backup_job, call:store.get_backup_job, func:post_backup_report(report: BackupReportRequest, service_id, store, _auth) → BackupRunResponse, call:_resolve_backup_service_id, call:_get_or_create_job, call:store.list_backup_runs, call:int, call:report.started_at.timestamp, call:abs, call:BackupRunResponse, call:report.ended_at.timestamp, call:store.create_backup_run, call:record_backup_run, call:generate_alerts_for_run, call:store.create_backup_alert, call:store.resolve_backup_alerts_for_job, call:run.pop, func:post_backup_start(report: BackupReportRequest, service_id, store, _auth) → BackupRunResponse, call:_resolve_backup_service_id, call:_get_or_create_job, call:int, call:report.started_at.timestamp, call:store.create_backup_run, call:record_backup_run, call:run.pop, call:BackupRunResponse, func:get_backup_jobs(store) → list[dict[str, Any]], call:store.list_backup_jobs, func:get_backup_job(job_id: str, store) → dict[str, Any], call:store.get_backup_job, call:store.list_backup_runs, raise:HTTPException, func:get_backup_runs(job_id, status, limit, store) → list[BackupRunResponse], call:store.list_backup_runs, call:BackupRunResponse, func:get_backup_run(run_id: str, store) → BackupRunResponse, call:store.get_backup_run, call:BackupRunResponse, raise:HTTPException, func:get_backup_alerts(job_id, acknowledged, severity, store) → list[BackupAlertResponse], call:store.list_backup_alerts, call:BackupAlertResponse, func:acknowledge_backup_alert(alert_id: str, store) → BackupAlertResponse, call:store.acknowledge_backup_alert, call:BackupAlertResponse, raise:HTTPException | dep: typing, fastapi, ..auth, ..models.backups, ..observability, ..services.backup_alert_engine, ..services.settings_store
- dashboard.py | FastAPI router providing dashboard endpoints for media counts, library breakdowns, shortcuts CRUD, activity sessions, and backup summaries. | exp: func:get_counts(client, user_id) → dict[str, int], call:client.media_counts, call:logger.info, func:get_library_counts(client, user_id) → list[dict[str, Any]], call:client.libraries, call:logger.info, call:len, call:client.library_item_counts, func:get_shortcuts() → list[dict[str, Any]], call:store.list_shortcuts, call:logger.info, call:len, func:create_shortcut(payload: dict[str, Any]) → dict[str, Any], call:store.upsert_shortcut, call:logger.info, call:shortcut.get, func:update_shortcut(shortcut_id: str, payload: dict[str, Any]) → dict[str, Any], call:store.upsert_shortcut, call:logger.info, call:shortcut.get, func:delete_shortcut(shortcut_id: str) → dict[str, str], call:store.delete_shortcut, call:logger.info, func:get_activity(client) → list[dict[str, Any]], call:client.sessions, call:_map_sessions_to_activity_rows, call:rows.sort, call:state_rank.get, call:r.get, call:str(r.get("user", "")).lower, call:logger.info, call:len, func:get_now_playing(client) → list[dict[str, Any]], call:get_activity, func:get_backup_dashboard(store) → BackupDashboardSummary, call:build_backup_dashboard_summary | dep: logging, typing, fastapi, media_library_viewer_api.clients.jellyfin, media_library_viewer_api.dependencies, media_library_viewer_api.domain.dashboard, media_library_viewer_api.models.backups, media_library_viewer_api.services.settings_store
- dashboards.py | Provides CRUD API endpoints for managing named dashboards via a FastAPI router. | exp: func:list_dashboards(store) → list[NamedDashboard], call:store.list_dashboards, call:NamedDashboard, func:get_dashboard_by_slug(slug: str, store) → NamedDashboard, call:store.get_dashboard_by_slug, call:NamedDashboard, raise:HTTPException, func:create_dashboard(body: NamedDashboardInput, store) → NamedDashboard, call:store.upsert_dashboard, call:body.model_dump, call:NamedDashboard, func:update_dashboard(dashboard_id: str, body: NamedDashboardInput, store) → NamedDashboard, call:store.get_dashboard, call:store.upsert_dashboard, call:body.model_dump, call:NamedDashboard, raise:HTTPException, func:delete_dashboard(dashboard_id: str, store) → dict[str, str], call:store.get_dashboard, call:store.delete_dashboard, raise:HTTPException | dep: fastapi, media_library_viewer_api.dependencies, media_library_viewer_api.models.dashboards, media_library_viewer_api.services.settings_store
- files.py | FastAPI router providing endpoints for remote file operations including directory listing, ffprobe media analysis, stat, and path resolution via SSH. | exp: func:list_directory(path, ssh) → dict[str, Any], call:ssh.list_dir, call:logger.warning, call:json.loads, call:logger.info, call:len, raise:HTTPException, func:get_ffprobe(path, ssh) → dict[str, Any], call:ssh.ffprobe_json, call:logger.warning, call:logger.info, raise:HTTPException, func:get_stat(path, ssh) → dict[str, str], call:ssh.stat_path, call:logger.warning, call:logger.info, raise:HTTPException, func:resolve_path(path) → dict[str, str], call:get_settings, call:resolve_remote_media_path, call:logger.info | dep: json, logging, typing, fastapi, media_library_viewer_api.clients.ssh, media_library_viewer_api.config, media_library_viewer_api.dependencies, media_library_viewer_api.path_utils
- jobs.py | FastAPI router that exposes endpoints to list available job templates and execute them on remote paths via SSH. | exp: class:RunJobRequest, func:get_templates() → list[dict[str, str]], call:JOB_TEMPLATES.items, call:logger.info, call:len, func:post_run_job(request: RunJobRequest, ssh) → dict[str, Any], call:logger.warning, call:logger.info, call:run_job, raise:HTTPException | dep: logging, typing, fastapi, pydantic, media_library_viewer_api.clients.ssh, media_library_viewer_api.dependencies, media_library_viewer_api.jobs
- media.py | FastAPI router that manages media index lifecycle (status, build, stop, query) with subprocess worker orchestration and cooperative/force cancellation. | exp: func:get_media_index() → MediaIndex, call:MediaIndex, func:_set_build_metadata(index: MediaIndex, state: dict[str, Any]) → None, call:state.items, call:index.set_metadata, func:_staging_db_path(index: MediaIndex) → Path, call:index.db_path.with_name, func:_pid_is_alive(pid: int | None) → bool, call:os.kill, func:_clean_stale_build_state(index: MediaIndex) → Any, call:index.status, call:_pid_is_alive, call:logger.warning, call:_set_build_metadata, func:_serialize_status(status: Any) → dict[str, Any], func:_worker_command(final_db_path: Path, staging_db_path: Path) → list[str], call:str, func:_start_worker(index: MediaIndex) → subprocess.Popen[bytes], call:_staging_db_path, call:staging_path.unlink, call:subprocess.Popen, call:_worker_command, call:os.environ.copy, func:get_index_status(index) → dict[str, Any], call:_clean_stale_build_state, call:logger.info, call:_serialize_status, func:post_build_index(client, user_id, index) → dict[str, Any], call:_clean_stale_build_state, call:_pid_is_alive, call:logger.warning, call:client.libraries, call:logger.info, call:len, call:_start_worker, call:_set_build_metadata, call:index.status, call:record_media_index_build, call:_serialize_status, raise:HTTPException, func:stop_build(index) → dict[str, Any], call:_clean_stale_build_state, call:logger.warning, call:logger.info, call:_set_build_metadata, call:index.status, call:_serialize_status, raise:HTTPException, func:force_stop_build(index) → dict[str, Any], call:_clean_stale_build_state, call:logger.warning, call:_pid_is_alive, call:_set_build_metadata, call:index.status, call:_serialize_status, call:logger.info, call:os.killpg, call:time.time, call:time.sleep, call:record_media_index_build, raise:HTTPException, func:query_media(libraries, types, search, hdr_filter, sort_key, sort_order, limit, offset, client, user_id, index) → dict[str, Any], call:lid.strip, call:libraries.split, call:client.libraries, call:t.strip, call:types.split, call:logger.info, call:len, call:",".join, call:index.query | dep: logging, os, signal, subprocess, sys, threading, time, pathlib, typing, fastapi, media_library_viewer_api.clients.jellyfin, media_library_viewer_api.dependencies, media_library_viewer_api.observability, media_library_viewer_api.services.media_index, media_library_viewer_api.workers.media_index_worker
- monitoring.py | FastAPI router providing endpoints to check the health/status of Alertmanager, Grafana, and Prometheus services and expose Prometheus scrape targets. | exp: func:_resolve_service_record(store: SettingsStore, service_type: str, service_id) → ServiceRecord | None, call:store.get_service, call:row.get, call:build_service_record, call:store.list_services, func:_base_url(service: ServiceRecord) → str, call:str(service.config.get("base_url") or "").rstrip, call:service.config.get, func:_timeout(service: ServiceRecord, default: int) → int, call:int, call:service.config.get, func:_auth_headers(service: ServiceRecord) → dict[str, str], call:str, call:service.secrets.get, func:_status_response(service: ServiceRecord | None, version, error) → dict[str, Any], func:_summary_from_alerts(alerts: list[dict[str, Any]]) → dict[str, Any], call:summarize_alerts, func:get_machines(store) → list[dict[str, Any]], call:store.list_machines, call:m.get, func:get_prometheus_targets(store) → list[dict[str, Any]], call:build_node_exporter_targets, call:logger.info, call:len, func:get_alertmanager_alerts(service_id, store) → dict[str, Any], call:_resolve_service_record, call:requests.get, call:_base_url, call:_auth_headers, call:_timeout, call:response.raise_for_status, call:response.json, call:logger.exception, call:data.get, call:_summary_from_alerts, call:logger.info, func:get_alertmanager_status(service_id, store) → dict[str, Any], call:_resolve_service_record, call:requests.get, call:_base_url, call:_auth_headers, call:_timeout, call:response.raise_for_status, call:response.json, call:logger.exception, call:data.get("versionInfo", {}).get, call:status.get, call:p.get, call:cluster.get, func:get_grafana_status(service_id, store) → dict[str, Any], call:_resolve_service_record, call:_status_response, call:requests.get, call:_base_url, call:_auth_headers, call:_timeout, call:response.raise_for_status, call:response.json, call:logger.exception, call:data.get, func:get_prometheus_status(service_id, store) → dict[str, Any], call:_resolve_service_record, call:_status_response, call:_base_url, call:_timeout, call:_auth_headers, call:requests.get, call:health.raise_for_status, call:build_info.raise_for_status, call:build_info.json().get("data", {}).get, call:logger.exception, func:receive_alertmanager_webhook(payload) → dict[str, str], call:payload.get, call:logger.info, call:len | dep: logging, typing, requests, fastapi, media_library_viewer_api.dependencies, media_library_viewer_api.services.settings_store, media_library_viewer_api.services.targets, media_library_viewer_api.widgets.sources, media_library_viewer_api.integrations.alertmanager
- media.py | FastAPI router providing endpoints to manage media index lifecycle operations including status checks, building (via subprocess workers), stopping, force-stopping, and querying the media library index. | exp: func:get_media_index() → MediaIndex, call:MediaIndex, func:_set_build_metadata(index: MediaIndex, state: dict[str, Any]) → None, call:state.items, call:index.set_metadata, func:_staging_db_path(index: MediaIndex) → Path, call:index.db_path.with_name, func:_pid_is_alive(pid: int | None) → bool, call:os.kill, func:_clean_stale_build_state(index: MediaIndex) → Any, call:index.status, call:_pid_is_alive, call:logger.warning, call:_set_build_metadata, func:_serialize_status(status: Any) → dict[str, Any], func:_worker_command(final_db_path: Path, staging_db_path: Path, service_id) → list[str], call:str, func:_start_worker(index: MediaIndex, service_id) → subprocess.Popen[bytes], call:_staging_db_path, call:staging_path.unlink, call:subprocess.Popen, call:_worker_command, call:os.environ.copy, func:get_index_status(index) → dict[str, Any], call:_clean_stale_build_state, call:logger.info, call:_serialize_status, func:post_build_index(jellyfin_service_id, index) → dict[str, Any], call:_clean_stale_build_state, call:_pid_is_alive, call:logger.warning, call:logger.info, call:_start_worker, call:_set_build_metadata, call:index.status, call:record_media_index_build, call:_serialize_status, raise:HTTPException, func:stop_build(index) → dict[str, Any], call:_clean_stale_build_state, call:logger.warning, call:logger.info, call:_set_build_metadata, call:index.status, call:_serialize_status, raise:HTTPException, func:force_stop_build(index) → dict[str, Any], call:_clean_stale_build_state, call:logger.warning, call:_pid_is_alive, call:_set_build_metadata, call:index.status, call:_serialize_status, call:logger.info, call:os.killpg, call:time.time, call:time.sleep, call:record_media_index_build, raise:HTTPException, func:query_media(libraries, types, search, hdr_filter, sort_key, sort_order, limit, offset, jellyfin_service_id, client, user_id, index) → dict[str, Any], call:lid.strip, call:libraries.split, call:client.libraries, call:t.strip, call:types.split, call:logger.info, call:len, call:",".join, call:index.query | dep: logging, os, signal, subprocess, sys, threading, time, pathlib, typing, fastapi, media_library_viewer_api.clients.jellyfin, media_library_viewer_api.dependencies, media_library_viewer_api.observability, media_library_viewer_api.services.media_index
- monitoring.py | FastAPI router providing monitoring observability endpoints that proxy and aggregate status, alerts, and scrape targets from Alertmanager and Prometheus. | exp: func:_base_url(service: ServiceRecord) → str, call:str(service.config.get("base_url") or "").rstrip, call:service.config.get, func:_timeout(service: ServiceRecord, default: int) → int, call:int, call:service.config.get, func:_auth_headers(service: ServiceRecord) → dict[str, str], call:str, call:service.secrets.get, func:_status_response(service: ServiceRecord | None, version, error) → dict[str, Any], func:_summary_from_alerts(alerts: list[dict[str, Any]]) → dict[str, Any], call:summarize_alerts, func:get_machines(store) → list[dict[str, Any]], call:store.list_machines, call:m.get, func:get_prometheus_targets(store) → list[dict[str, Any]], call:build_node_exporter_targets, call:logger.info, call:len, func:get_alertmanager_alerts(service_id, store) → dict[str, Any], call:resolve_service_record, call:requests.get, call:_base_url, call:_auth_headers, call:_timeout, call:response.raise_for_status, call:response.json, call:logger.exception, call:data.get, call:_summary_from_alerts, call:logger.info, func:get_alertmanager_status(service_id, store) → dict[str, Any], call:resolve_service_record, call:requests.get, call:_base_url, call:_auth_headers, call:_timeout, call:response.raise_for_status, call:response.json, call:logger.exception, call:data.get("versionInfo", {}).get, call:status.get, call:p.get, call:cluster.get, func:get_prometheus_status(service_id, store) → dict[str, Any], call:resolve_service_record, call:_status_response, call:_base_url, call:_timeout, call:_auth_headers, call:requests.get, call:health.raise_for_status, call:build_info.raise_for_status, call:build_info.json().get("data", {}).get, call:logger.exception, func:receive_alertmanager_webhook(payload) → dict[str, str], call:payload.get, call:logger.info, call:len | dep: logging, typing, requests, fastapi, media_library_viewer_api.dependencies, media_library_viewer_api.services.service_resolution, media_library_viewer_api.services.settings_store, media_library_viewer_api.services.targets, media_library_viewer_api.widgets.sources, media_library_viewer_api.integrations.alertmanager
- services.py | Provides REST API endpoints for managing service instances in a service registry, including listing service types and CRUD operations for instances while ensuring plaintext secrets are never exposed. | exp: func:_to_type_info(service_type: str) → ServiceTypeInfo, call:require_service_definition, call:ServiceTypeInfo, call:SecretFieldInfo, call:WidgetKindInfo, func:_to_instance(row: dict[str, Any]) → ServiceInstance, call:get_service_definition, call:set, call:row.get, call:bool, call:ServiceInstance, func:_validate_input(body: ServiceInstanceInput) → None, call:get_service_definition, call:validate_config, call:set, raise:HTTPException, func:list_types() → list[ServiceTypeInfo], call:_to_type_info, call:sorted, func:list_instances(service_type, store) → list[ServiceInstance], call:store.list_services, call:_to_instance, func:create_instance(body: ServiceInstanceInput, store) → ServiceInstance, call:_validate_input, call:store.upsert_service, call:_to_instance, func:update_instance(service_id: str, body: ServiceInstanceInput, store) → ServiceInstance, call:store.get_service, call:_validate_input, call:store.upsert_service, call:_to_instance, raise:HTTPException, func:delete_instance(service_id: str, store) → dict[str, str], call:store.get_service, call:store.delete_service, raise:HTTPException | dep: logging, typing, fastapi, media_library_viewer_api.dependencies, media_library_viewer_api.integrations.base, media_library_viewer_api.integrations.registry, media_library_viewer_api.models.services, media_library_viewer_api.services.settings_store
- settings.py | FastAPI router for managing machine definitions, SSH keys, SSH connection validation, and local database resets. | exp: class:MonitoringMachineInput, class:SSHKeyInput, class:SSHKeyGenerateInput, class:ResetLocalDatabaseInput, func:get_machines(store) → list[dict[str, Any]], call:store.list_machines, func:_resolve_ssh_client(machine: MonitoringMachineInput, store: SettingsStore) → tuple[RemoteSSHClient, str, int], call:machine.host.strip, call:machine.username.strip, call:int, call:store.get_ssh_key, call:str, call:ssh_key.get, call:get_settings, call:RemoteSSHClient, raise:HTTPException, func:_raise_ssh_validation_error(host: str, port: int, exc: Exception) → None, call:str, call:message.lower, raise:HTTPException, func:_validate_saved_machine_ssh(machine: MonitoringMachineInput, store: SettingsStore) → None, call:str(machine.mode or "").strip().lower, call:_resolve_ssh_client, call:client.connect, call:_raise_ssh_validation_error, call:client.close, func:test_machine_ssh(machine: MonitoringMachineInput, store) → dict[str, Any], call:str(machine.mode or "").strip().lower, call:_resolve_ssh_client, call:get_settings, call:has_known_host, call:client.connect, call:message.lower, call:client.close, raise:HTTPException, func:post_machine(machine: MonitoringMachineInput, store) → dict[str, Any], call:store.upsert_machine, call:machine.model_dump, call:MonitoringMachineInput.model_validate, call:_validate_saved_machine_ssh, func:put_machine(machine_id: str, machine: MonitoringMachineInput, store) → dict[str, Any], call:store.get_machine, call:store.upsert_machine, call:machine.model_dump, call:MonitoringMachineInput.model_validate, call:_validate_saved_machine_ssh, raise:HTTPException, func:delete_machine(machine_id: str, store) → dict[str, str], call:store.get_machine, call:store.delete_machine, raise:HTTPException, func:generate_ssh_key(payload: SSHKeyGenerateInput) → dict[str, Any], call:paramiko.RSAKey.generate, call:StringIO, call:key.write_private_key, call:private_buffer.getvalue, call:key.get_name, call:key.get_base64, call:":".join, call:key.get_fingerprint, func:get_ssh_keys(store) → list[dict[str, Any]], call:store.list_ssh_keys, func:post_ssh_key(key: SSHKeyInput, store) → dict[str, Any], call:store.upsert_ssh_key, call:key.model_dump, func:put_ssh_key(key_id: str, key: SSHKeyInput, store) → dict[str, Any], call:store.get_ssh_key, call:store.upsert_ssh_key, call:key.model_dump, raise:HTTPException, func:delete_ssh_key(key_id: str, store) → dict[str, str], call:store.get_ssh_key, call:store.delete_ssh_key, raise:HTTPException, func:reset_local_database(payload: ResetLocalDatabaseInput, store) → dict[str, Any], call:payload.confirm_phrase.strip().upper, call:remove_sqlite_database, call:MediaIndex, call:bool, raise:HTTPException | dep: logging, io, typing, paramiko, fastapi, pydantic, media_library_viewer_api.clients.ssh, media_library_viewer_api.config, media_library_viewer_api.dependencies, media_library_viewer_api.services.db_maintenance, media_library_viewer_api.services.known_hosts, media_library_viewer_api.services.media_index, media_library_viewer_api.services.settings_store
- tasks.py | FastAPI router providing CRUD endpoints and execution for saved server tasks with SSH service resolution | exp: class:TaskInput, class:RunTaskRequest, func:_service_label(service: dict[str, Any] | None) → str, call:str, call:service.get, func:_resolve_service_for_task(store: SettingsStore, task: dict[str, Any], service_id: str | None) → dict[str, Any] | None, call:store.get_service, call:str(task.get("default_service_id") or "").strip, call:task.get, call:store.list_services, call:svc.get, func:_service_row_to_record(service_row: dict[str, Any]) → ServiceRecord, call:build_service_record, call:get_settings_store, func:list_tasks(store) → list[dict[str, Any]], call:store.list_tasks, func:create_task(task: TaskInput, store) → dict[str, Any], call:store.upsert_task, call:task.model_dump, func:update_task(task_id: str, task: TaskInput, store) → dict[str, Any], call:store.get_task, call:store.upsert_task, call:task.model_dump, raise:HTTPException, func:delete_task(task_id: str, store) → dict[str, str], call:store.get_task, call:store.delete_task, raise:HTTPException, func:list_task_runs(task_id: str, limit, store) → dict[str, Any], call:store.get_task, call:store.list_service_task_runs, call:len, raise:HTTPException, func:run_task(request: RunTaskRequest, service_id, store) → dict[str, Any], call:store.get_task, call:task.get, call:_resolve_service_for_task, call:service_row.get, call:_service_row_to_record, call:run_saved_task, call:_service_label, raise:HTTPException | dep: logging, typing, fastapi, pydantic, media_library_viewer_api.dependencies, media_library_viewer_api.services.settings_store, media_library_viewer_api.services.task_runner, media_library_viewer_api.widgets.sources
- users.py | Re-exports all public names from the users_impl module to provide a unified public API for user-related functionality. | dep: .users_impl, users_impl
- users_impl.py | FastAPI router that fetches and merges Jellyfin users with optional Jellyseerr enrichment, plus endpoints for queueing user emails via a background mail worker. | exp: func:_safe_int(value: Any) → int, call:int, func:_permission_labels(permissions: int) → list[str], func:_role_label(permissions: int) → str, func:_account_type(user_type: Any) → str, call:_USER_TYPES.get, call:_safe_int, func:_merge_users(jellyfin_users: list[dict[str, Any]], jellyseerr_jellyfin_users: list[dict[str, Any]] | None, jellyseerr_users: list[dict[str, Any]] | None, jellyseerr_client: JellyseerrClient | None) → dict[str, Any], call:str(value or "").strip().lower, call:bool, call:_looks_like_email, call:str(value).strip, call:", ".join, call:_normalize, call:item.get, call:_lookup_keys, call:user.get, call:linked_by_jellyfin_id.get, call:(jf_link or {}).get, call:seerr_by_key.get, call:_pick_source_and_value, call:(seerr_user or {}).get, call:_first_value, call:jellyseerr_client.absolute_url, call:_safe_int, call:_role_label, call:_source_summary, call:items.append, call:_account_type, call:_permission_labels, call:logger.info, call:len, func:_normalize(value: Any) → str, call:str(value or "").strip().lower, func:_looks_like_email(value: Any) → bool, call:str(value or "").strip, call:bool, func:_pick_source_and_value(candidates: list[tuple[str, Any]]) → tuple[str, str], call:_looks_like_email, call:str(value).strip, func:_first_value(candidates: list[tuple[str, Any]]) → tuple[str, str], call:str(value or "").strip, func:_source_summary(name_source: str, email_source: str, avatar_source: str, access_source: str) → str, call:", ".join, func:_lookup_keys(item: dict[str, Any]) → list[str], call:_normalize, call:item.get, func:get_users(jellyfin, jellyseerr) → dict[str, Any], call:jellyfin.users, call:logger.info, call:len, call:jellyseerr.jellyfin_users, call:logger.exception, call:jellyseerr.users, call:_merge_users, call:bool, func:get_user_message_status() → dict[str, Any], call:mail_queue.status, func:post_user_message(recipient_ids, subject, html_body, text_body, attachments, jellyfin, jellyseerr) → dict[str, Any], call:json.loads, call:isinstance, call:str(item).strip, call:subject.strip, call:get_users, call:item.get, call:directory.get, call:users_by_id.get, call:skipped.append, call:str(item.get("email") or "").strip, call:recipients.append, call:recipient_labels.append, call:get_settings, call:validate_smtp_settings, call:mail_queue.status, call:upload.read, call:attachment_payloads.append, call:EmailAttachment, call:mail_queue.enqueue, call:str(getattr(settings, "smtp_from_address", "") or "").strip, call:getattr, call:str(getattr(settings, "smtp_username", "") or "").strip, call:logger.info, call:len, raise:HTTPException | dep: json, logging, typing, fastapi, media_library_viewer_api.clients.jellyfin, media_library_viewer_api.clients.jellyseerr, media_library_viewer_api.config, media_library_viewer_api.dependencies, media_library_viewer_api.services.mailer
- widgets.py | Provides a FastAPI REST API for managing dashboard widget instances, including CRUD operations, built-in widget discovery, and data fetching through service or built-in adapters. | exp: func:_validate_widget_input(body: WidgetInstanceInput, store: SettingsStore) → None, call:store.get_service, call:get_service_definition, call:definition.widget_kind, call:validate_config, call:is_builtin_kind, call:validate_builtin_config, raise:HTTPException, func:list_builtin_kinds() → list[BuiltinWidgetKindInfo], call:BuiltinWidgetKindInfo, call:BUILTIN_WIDGET_KINDS.values, func:list_instances(store) → list[dict[str, Any]], call:WidgetInstance(**widget).model_dump, call:store.list_widgets, func:create_instance(body: WidgetInstanceInput, store) → dict[str, Any], call:_validate_widget_input, call:store.upsert_widget, call:body.model_dump, call:WidgetInstance(**widget).model_dump, func:update_instance(widget_id: str, body: WidgetInstanceInput, store) → dict[str, Any], call:store.get_widget, call:_validate_widget_input, call:store.upsert_widget, call:body.model_dump, call:WidgetInstance(**widget).model_dump, raise:HTTPException, func:delete_instance(widget_id: str, store) → dict[str, str], call:store.get_widget, call:store.delete_widget, raise:HTTPException, func:fetch_data(widget_id: str, store) → dict[str, Any], call:store.get_widget, call:widget.get, call:store.get_service, call:WidgetDataResponse( widget_id=widget_id, error=f"Service {service_id} not found", fetched_at=int(time.time()), ).model_dump, call:int, call:time.time, call:service_row.get, call:WidgetDataResponse( widget_id=widget_id, error="Service is disabled", fetched_at=int(time.time()), ).model_dump, call:get_service_adapter, call:WidgetDataResponse( widget_id=widget_id, error=f"No adapter for service type {service_row['service_type']}", fetched_at=int(time.time()), ).model_dump, call:build_service_record, call:get_builtin_adapter, call:WidgetDataResponse( widget_id=widget_id, error=f"Unknown built-in widget kind: {widget_kind}", fetched_at=int(time.time()), ).model_dump, call:adapter.fetch, call:logger.exception, call:WidgetDataResponse( widget_id=widget_id, data=data if "error" not in data else None, error=data.get("error"), fetched_at=int(time.time()), ).model_dump, call:data.get, raise:HTTPException | dep: logging, time, typing, fastapi, media_library_viewer_api.dependencies, media_library_viewer_api.integrations.base, media_library_viewer_api.integrations.registry, media_library_viewer_api.models.widgets, media_library_viewer_api.services.settings_store, media_library_viewer_api.widgets.builtin, media_library_viewer_api.widgets.sources
- widgets.py | Provides a FastAPI REST API for managing dashboard widget instances and their references, including CRUD operations, data fetching, and live-link detachments. | exp: class:WidgetReferenceCreate, func:_validate_widget_input(body: WidgetInstanceInput, store: SettingsStore) → None, call:store.get_service, call:get_service_definition, call:definition.widget_kind, call:validate_config, call:is_builtin_kind, call:validate_builtin_config, raise:HTTPException, func:list_builtin_kinds() → list[BuiltinWidgetKindInfo], call:BuiltinWidgetKindInfo, call:BUILTIN_WIDGET_KINDS.values, func:list_instances(service_id, scope, store) → list[dict[str, Any]], call:WidgetInstance(**widget).model_dump, call:store.list_widgets, func:create_instance(body: WidgetInstanceInput, store) → dict[str, Any], call:_validate_widget_input, call:store.upsert_widget, call:body.model_dump, call:WidgetInstance(**widget).model_dump, func:update_instance(widget_id: str, body: WidgetInstanceInput, store) → dict[str, Any], call:store.get_widget, call:_validate_widget_input, call:store.upsert_widget, call:body.model_dump, call:WidgetInstance(**widget).model_dump, raise:HTTPException, func:delete_instance(widget_id: str, store) → dict[str, str], call:store.get_widget, call:store.delete_widget, raise:HTTPException, func:fetch_data(widget_id: str, store) → dict[str, Any], call:store.get_widget, call:widget.get, call:store.get_service, call:WidgetDataResponse( widget_id=widget_id, error=f"Service {service_id} not found", fetched_at=int(time.time()), ).model_dump, call:int, call:time.time, call:service_row.get, call:WidgetDataResponse( widget_id=widget_id, error="Service is disabled", fetched_at=int(time.time()), ).model_dump, call:get_service_adapter, call:WidgetDataResponse( widget_id=widget_id, error=f"No adapter for service type {service_row['service_type']}", fetched_at=int(time.time()), ).model_dump, call:build_service_record, call:get_builtin_adapter, call:WidgetDataResponse( widget_id=widget_id, error=f"Unknown built-in widget kind: {widget_kind}", fetched_at=int(time.time()), ).model_dump, call:adapter.fetch, call:logger.exception, call:WidgetDataResponse( widget_id=widget_id, data=data if "error" not in data else None, error=data.get("error"), fetched_at=int(time.time()), ).model_dump, call:data.get, raise:HTTPException, func:list_references(dashboard_scope: str, store) → list[dict[str, Any]], call:store.list_widget_references, func:create_reference(body: WidgetReferenceCreate, store) → dict[str, Any], call:store.create_widget_reference, raise:HTTPException, func:delete_reference(reference_id: str, store) → dict[str, str], call:store.delete_widget_reference, func:update_reference(reference_id: str, sort_order: int, store) → dict[str, Any], call:store.update_widget_reference, raise:HTTPException, func:detach_reference(reference_id: str, store) → dict[str, Any], call:store.detach_widget_reference, call:WidgetInstance(**cloned).model_dump, raise:HTTPException | dep: logging, time, typing, fastapi, pydantic, media_library_viewer_api.dependencies, media_library_viewer_api.integrations.base, media_library_viewer_api.integrations.registry, media_library_viewer_api.models.widgets, media_library_viewer_api.services.settings_store, media_library_viewer_api.widgets.builtin, media_library_viewer_api.widgets.sources
## arch
Modular router-per-domain pattern where each file defines an isolated FastAPI APIRouter; routers are registered by the parent application and share common dependencies for SSH orchestration, database access, and service resolution.
Modular FastAPI APIRouter pattern where each domain module exports its own router instance; routers encapsulate endpoint definitions and delegate business logic to underlying service clients, SSH utilities, and subprocess workers.
## tags
call:, service, raise:httpexception, get, backup, media_library_viewer_api, ssh, call:logger.info
call:, raise:httpexception, service, backup, get, media_library_viewer_api, ssh, call:store.get
## symbols
- MessageRequest
- RunJobRequest
- MonitoringMachineInput
- SSHKeyInput
@@ -31,9 +32,8 @@ call:, service, raise:httpexception, get, backup, media_library_viewer_api, ssh,
- ResetLocalDatabaseInput
- TaskInput
- RunTaskRequest
- _get_or_create_job
## workflows
- change routers behavior
read: __init__.py, backups.py, dashboard.py
read: __init__.py, authentik_users.py, backups.py
## dirty
-