simpleaudit-studio 0.2.6__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/.dockerignore +8 -2
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/.env.example +2 -19
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/.env.local.example +1 -9
- simpleaudit_studio-0.3.0/.github/workflows/ci.yml +44 -0
- simpleaudit_studio-0.3.0/.github/workflows/docker.yml +46 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/.github/workflows/publish.yml +10 -1
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/.gitignore +5 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/Dockerfile +19 -19
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/PKG-INFO +46 -21
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/README.md +41 -16
- simpleaudit_studio-0.3.0/accounts/admin_urls.py +11 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/accounts/auth_urls.py +1 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/accounts/migrations/0001_initial.py +6 -1
- simpleaudit_studio-0.2.6/accounts/migrations/0002_user_workos_user_id.py → simpleaudit_studio-0.3.0/accounts/migrations/0002_user_preferences.py +3 -3
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/accounts/models.py +6 -0
- simpleaudit_studio-0.3.0/accounts/serializers.py +173 -0
- simpleaudit_studio-0.3.0/accounts/services.py +411 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/accounts/views.py +100 -29
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/accounts/workos_auth.py +4 -71
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/audits/comparison.py +17 -17
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/audits/events.py +97 -21
- simpleaudit_studio-0.3.0/audits/experiments.py +374 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/audits/migrations/0001_initial.py +177 -7
- simpleaudit_studio-0.3.0/audits/migrations/0002_strip_api_keys_from_snapshots.py +41 -0
- simpleaudit_studio-0.3.0/audits/models.py +178 -0
- simpleaudit_studio-0.3.0/audits/monitors.py +487 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/audits/serializers.py +3 -3
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/audits/services.py +74 -33
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/audits/views.py +19 -21
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/config/settings.py +63 -50
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/config/urls.py +67 -26
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/deploy/compose/Dockerfile +1 -1
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/deploy/mock_openai_server.py +0 -3
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/deploy/postgres-init.sql +1 -1
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/docker-compose.yml +8 -32
- simpleaudit_studio-0.3.0/docs/architecture.md +87 -0
- simpleaudit_studio-0.3.0/docs/deployment.md +116 -0
- simpleaudit_studio-0.3.0/docs/domain-model.md +437 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/e2e/test_ui.py +31 -56
- simpleaudit_studio-0.3.0/infra/context_processors.py +85 -0
- simpleaudit_studio-0.3.0/infra/db.py +69 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/engine.py +37 -17
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/health.py +30 -43
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/health_api.py +2 -11
- simpleaudit_studio-0.3.0/infra/management/commands/dev_server.py +144 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/management/commands/purge_test_data.py +2 -2
- simpleaudit_studio-0.3.0/infra/management/commands/run_monitors.py +24 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/management/commands/seed_demo_audits.py +9 -15
- simpleaudit_studio-0.3.0/infra/management/commands/setup_local.py +66 -0
- simpleaudit_studio-0.3.0/infra/runs_table.py +227 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/seed.py +7 -30
- simpleaudit_studio-0.3.0/infra/seo.py +201 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/simpleaudit_package.py +0 -5
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/startup_checks.py +4 -15
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/factories.py +5 -15
- simpleaudit_studio-0.3.0/infra/tests/test_admin_api.py +151 -0
- simpleaudit_studio-0.3.0/infra/tests/test_admin_page.py +88 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_api_e2e.py +27 -19
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_audit_archive.py +13 -28
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_audit_clone.py +16 -11
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_audit_poll_results.py +7 -6
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_audit_rename.py +13 -13
- simpleaudit_studio-0.3.0/infra/tests/test_audit_results_live.py +130 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_audit_run_freeze.py +95 -35
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_audit_sse.py +7 -6
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_audit_submission.py +16 -13
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_audit_timing.py +13 -7
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_auth_projects.py +23 -10
- simpleaudit_studio-0.3.0/infra/tests/test_bootstrap.py +42 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_comparison.py +14 -11
- simpleaudit_studio-0.3.0/infra/tests/test_connection_delete.py +148 -0
- simpleaudit_studio-0.3.0/infra/tests/test_db_resilience.py +68 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_engine_integration.py +190 -14
- simpleaudit_studio-0.3.0/infra/tests/test_experiments.py +394 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_health_panel.py +5 -22
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_minimal_config.py +62 -37
- simpleaudit_studio-0.3.0/infra/tests/test_model_registry.py +47 -0
- simpleaudit_studio-0.3.0/infra/tests/test_monitors.py +518 -0
- simpleaudit_studio-0.3.0/infra/tests/test_profile.py +114 -0
- simpleaudit_studio-0.3.0/infra/tests/test_profile_ui.py +85 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_purge_test_data.py +21 -15
- simpleaudit_studio-0.3.0/infra/tests/test_runs_table.py +208 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_scenarios.py +0 -12
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_seed_platform.py +5 -31
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_smoke_all_pages.py +63 -18
- simpleaudit_studio-0.3.0/infra/tests/test_snapshot_secrets.py +79 -0
- simpleaudit_studio-0.3.0/infra/tests/test_workspace_archive.py +111 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_workspaces.py +24 -13
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_workspaces_ui.py +1 -1
- simpleaudit_studio-0.3.0/infra/tests/test_write_guard.py +116 -0
- simpleaudit_studio-0.3.0/infra/tests/utils.py +44 -0
- simpleaudit_studio-0.3.0/infra/ui.py +2217 -0
- simpleaudit_studio-0.3.0/infra/worker.py +1072 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/model_registry/admin.py +1 -8
- simpleaudit_studio-0.3.0/model_registry/migrations/0001_initial.py +116 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/model_registry/models.py +4 -36
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/model_registry/serializers.py +0 -32
- simpleaudit_studio-0.3.0/model_registry/services.py +78 -0
- simpleaudit_studio-0.3.0/model_registry/urls.py +7 -0
- simpleaudit_studio-0.3.0/model_registry/views.py +24 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/pyproject.toml +5 -4
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/scenarios/migrations/0001_initial.py +1 -1
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/scenarios/services.py +3 -1
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/scenarios/views.py +2 -1
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/simpleaudit_studio/__init__.py +0 -2
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/simpleaudit_studio/cli.py +112 -19
- simpleaudit_studio-0.3.0/templates/404.html +4 -0
- simpleaudit_studio-0.3.0/templates/admin.html +445 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/templates/auth/login.html +1 -8
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/templates/auth/register.html +1 -8
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/templates/auth/workos_login.html +1 -8
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/templates/auth/workos_verify.html +1 -8
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/templates/base.html +47 -54
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/templates/compare.html +15 -9
- simpleaudit_studio-0.3.0/templates/dashboard.html +440 -0
- simpleaudit_studio-0.3.0/templates/experiment_detail.html +197 -0
- simpleaudit_studio-0.3.0/templates/experiment_new.html +412 -0
- simpleaudit_studio-0.3.0/templates/experiment_review.html +248 -0
- simpleaudit_studio-0.3.0/templates/experiments.html +46 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/templates/health.html +35 -31
- simpleaudit_studio-0.3.0/templates/models.html +422 -0
- simpleaudit_studio-0.3.0/templates/monitor_detail.html +117 -0
- simpleaudit_studio-0.3.0/templates/monitors.html +63 -0
- simpleaudit_studio-0.3.0/templates/partials/auth_header.html +8 -0
- simpleaudit_studio-0.3.0/templates/partials/chip_input.html +18 -0
- simpleaudit_studio-0.3.0/templates/partials/compare_run_header.html +4 -0
- simpleaudit_studio-0.3.0/templates/partials/footer.html +10 -0
- simpleaudit_studio-0.3.0/templates/partials/local_time_js.html +37 -0
- simpleaudit_studio-0.3.0/templates/partials/model_pickers.html +49 -0
- simpleaudit_studio-0.3.0/templates/partials/multi_filter.html +18 -0
- simpleaudit_studio-0.2.6/templates/404.html → simpleaudit_studio-0.3.0/templates/partials/not_found.html +1 -5
- simpleaudit_studio-0.3.0/templates/partials/result_rep_panel.html +84 -0
- simpleaudit_studio-0.3.0/templates/partials/run_results.html +32 -0
- simpleaudit_studio-0.3.0/templates/partials/run_settings.html +67 -0
- simpleaudit_studio-0.3.0/templates/partials/run_settings_js.html +63 -0
- simpleaudit_studio-0.3.0/templates/partials/severity_badge.html +1 -0
- simpleaudit_studio-0.3.0/templates/partials/tooltips.html +73 -0
- simpleaudit_studio-0.3.0/templates/partials/ui_js.html +21 -0
- simpleaudit_studio-0.3.0/templates/profile.html +134 -0
- simpleaudit_studio-0.3.0/templates/public/base_public.html +20 -0
- simpleaudit_studio-0.3.0/templates/public/landing.html +99 -0
- simpleaudit_studio-0.3.0/templates/run_detail.html +835 -0
- simpleaudit_studio-0.3.0/templates/run_result.html +135 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/templates/scenarios.html +49 -55
- simpleaudit_studio-0.3.0/templates/seo/head.html +24 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/templates/workspaces.html +11 -23
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/uv.lock +121 -113
- simpleaudit_studio-0.2.6/.github/workflows/ci.yml +0 -50
- simpleaudit_studio-0.2.6/Makefile +0 -63
- simpleaudit_studio-0.2.6/accounts/serializers.py +0 -95
- simpleaudit_studio-0.2.6/accounts/services.py +0 -158
- simpleaudit_studio-0.2.6/audits/migrations/0002_add_audit_run_archived.py +0 -17
- simpleaudit_studio-0.2.6/audits/migrations/0003_auditrun_updated_at.py +0 -17
- simpleaudit_studio-0.2.6/audits/models.py +0 -77
- simpleaudit_studio-0.2.6/deploy/e2e_smoke.py +0 -235
- simpleaudit_studio-0.2.6/deploy/seed_bulk.py +0 -413
- simpleaudit_studio-0.2.6/docs/architecture.md +0 -383
- simpleaudit_studio-0.2.6/docs/deployment.md +0 -418
- simpleaudit_studio-0.2.6/docs/domain-model.md +0 -473
- simpleaudit_studio-0.2.6/infra/context_processors.py +0 -65
- simpleaudit_studio-0.2.6/infra/permissions.py +0 -31
- simpleaudit_studio-0.2.6/infra/tests/test_bootstrap.py +0 -68
- simpleaudit_studio-0.2.6/infra/tests/test_model_registry.py +0 -89
- simpleaudit_studio-0.2.6/infra/ui.py +0 -1417
- simpleaudit_studio-0.2.6/infra/worker.py +0 -671
- simpleaudit_studio-0.2.6/model_registry/migrations/0001_initial.py +0 -90
- simpleaudit_studio-0.2.6/model_registry/services.py +0 -39
- simpleaudit_studio-0.2.6/model_registry/urls.py +0 -13
- simpleaudit_studio-0.2.6/model_registry/views.py +0 -77
- simpleaudit_studio-0.2.6/templates/audit_detail.html +0 -373
- simpleaudit_studio-0.2.6/templates/dashboard.html +0 -145
- simpleaudit_studio-0.2.6/templates/models.html +0 -273
- simpleaudit_studio-0.2.6/templates/new_audit.html +0 -205
- simpleaudit_studio-0.2.6/templates/scenario_result_detail.html +0 -144
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/LICENSE +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/accounts/__init__.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/accounts/admin.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/accounts/apps.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/accounts/migrations/__init__.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/accounts/project_urls.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/audits/__init__.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/audits/admin.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/audits/apps.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/audits/migrations/__init__.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/audits/urls.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/config/__init__.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/config/asgi.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/config/wsgi.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/__init__.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/admin.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/apps.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/exceptions.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/fixtures/demo_audit_results.json +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/hashing.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/logging.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/management/__init__.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/management/commands/__init__.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/management/commands/bootstrap_platform.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/management/commands/run_worker.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/management/commands/seed_platform.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/middleware.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/minimal_config.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/readiness.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/__init__.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_audit_events.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_health.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_middleware.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/infra/tests/test_scenario_import_export.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/manage.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/model_registry/__init__.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/model_registry/apps.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/model_registry/migrations/__init__.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/scenarios/__init__.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/scenarios/admin.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/scenarios/apps.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/scenarios/migrations/__init__.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/scenarios/models.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/scenarios/serializers.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/scenarios/urls.py +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/static/favicon-16x16.svg +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/static/favicon-32x32.svg +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/static/favicon.svg +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/static/js/diff.min.js +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/static/logo.png +0 -0
- {simpleaudit_studio-0.2.6 → simpleaudit_studio-0.3.0}/static/logo.svg +0 -0
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
.git
|
|
2
|
+
.github
|
|
2
3
|
.env
|
|
4
|
+
.env.local
|
|
3
5
|
.venv
|
|
4
6
|
__pycache__/
|
|
5
7
|
*.pyc
|
|
8
|
+
*.sqlite3
|
|
9
|
+
*.sqlite3-*
|
|
10
|
+
app.pid
|
|
6
11
|
data/
|
|
7
12
|
staticfiles/
|
|
8
|
-
media/
|
|
9
13
|
.pytest_cache/
|
|
10
14
|
.mypy_cache/
|
|
11
15
|
.ruff_cache/
|
|
12
|
-
|
|
16
|
+
docs/
|
|
17
|
+
e2e/
|
|
18
|
+
copilot-instructions.md
|
|
@@ -8,14 +8,14 @@
|
|
|
8
8
|
# For a local (non-Docker) development setup, copy `.env.local.example` instead.
|
|
9
9
|
#
|
|
10
10
|
# NOTE: docker-compose.yml overrides a few values per service (POSTGRES_HOST,
|
|
11
|
-
# HATCHET_
|
|
11
|
+
# HATCHET_*) so the container-internal hostnames are used
|
|
12
12
|
# regardless of what is written here.
|
|
13
13
|
# =============================================================================
|
|
14
14
|
|
|
15
15
|
# --- Django -----------------------------------------------------------------
|
|
16
16
|
DJANGO_SECRET_KEY=change-me
|
|
17
17
|
DJANGO_DEBUG=false
|
|
18
|
-
DJANGO_ALLOWED_HOSTS
|
|
18
|
+
DJANGO_ALLOWED_HOSTS=*
|
|
19
19
|
LOG_LEVEL=INFO
|
|
20
20
|
|
|
21
21
|
# --- Bootstrap (idempotent; run automatically by the web container) ----------
|
|
@@ -46,14 +46,6 @@ POSTGRES_PASSWORD=change-me
|
|
|
46
46
|
POSTGRES_HOST=postgres
|
|
47
47
|
POSTGRES_PORT=5432
|
|
48
48
|
|
|
49
|
-
# --- MinIO / S3-compatible object storage (OFF by default) --------------------
|
|
50
|
-
# Enable with: docker compose --profile storage up -d
|
|
51
|
-
# Then uncomment and set real credentials:
|
|
52
|
-
# MINIO_ENDPOINT=http://minio:9000
|
|
53
|
-
# MINIO_ACCESS_KEY=change-me
|
|
54
|
-
# MINIO_SECRET_KEY=change-me
|
|
55
|
-
# MINIO_BUCKET=simpleaudit-artifacts
|
|
56
|
-
|
|
57
49
|
# --- Durable workflow system (Hatchet) ----------------------------------------
|
|
58
50
|
# Docker Compose: the compose service name `hatchet-server` resolves inside the
|
|
59
51
|
# compose network. HTTP API on :8888, gRPC on :7077 (see docker-compose.yml).
|
|
@@ -76,9 +68,6 @@ HATCHET_TLS_STRATEGY=none
|
|
|
76
68
|
WORKER_POOL=cpu
|
|
77
69
|
|
|
78
70
|
# --- Operational limits --------------------------------------------------------
|
|
79
|
-
MAX_CONCURRENT_AUDITS=2
|
|
80
|
-
MAX_SCENARIOS_PER_RUN=500
|
|
81
|
-
SSE_MAX_CONNECTIONS_PER_USER=10
|
|
82
71
|
|
|
83
72
|
# --- SimpleAudit engine ---------------------------------------------------------
|
|
84
73
|
# No configuration needed here. The engine is a normal pip dependency pinned in
|
|
@@ -99,10 +88,6 @@ SSE_MAX_CONNECTIONS_PER_USER=10
|
|
|
99
88
|
SEED_DEMO_AUDITS=true
|
|
100
89
|
|
|
101
90
|
# --- Optional observability -----------------------------------------------------
|
|
102
|
-
OTEL_EXPORTER_OTLP_ENDPOINT=
|
|
103
|
-
LANGFUSE_PUBLIC_KEY=
|
|
104
|
-
LANGFUSE_SECRET_KEY=
|
|
105
|
-
LANGFUSE_HOST=
|
|
106
91
|
|
|
107
92
|
# --- Sentry error tracking & tracing (leave empty to disable) -------------------
|
|
108
93
|
SENTRY_DSN=
|
|
@@ -113,5 +98,3 @@ SENTRY_ENVIRONMENT=development
|
|
|
113
98
|
# WORKOS_CLIENT_ID is public; WORKOS_API_KEY is server-side secret (keep out of git).
|
|
114
99
|
WORKOS_CLIENT_ID=
|
|
115
100
|
WORKOS_API_KEY=
|
|
116
|
-
# Public base URL used to build the OAuth redirect URI, e.g. http://localhost:8000
|
|
117
|
-
APP_BASE_URL=http://localhost:8000
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
# --- Django -----------------------------------------------------------------
|
|
18
18
|
DJANGO_SECRET_KEY=local-dev-key-not-for-prod
|
|
19
19
|
DJANGO_DEBUG=true
|
|
20
|
-
DJANGO_ALLOWED_HOSTS
|
|
20
|
+
DJANGO_ALLOWED_HOSTS=*
|
|
21
21
|
LOG_LEVEL=DEBUG
|
|
22
22
|
|
|
23
23
|
# --- Bootstrap ----------------------------------------------------------------
|
|
@@ -80,13 +80,5 @@ WORKER_POOL=cpu
|
|
|
80
80
|
# SIMULACHAT_API_KEY=sk-...
|
|
81
81
|
|
|
82
82
|
# --- Optional (leave empty to disable) ------------------------------------------
|
|
83
|
-
MINIO_ENDPOINT=
|
|
84
|
-
MINIO_ACCESS_KEY=
|
|
85
|
-
MINIO_SECRET_KEY=
|
|
86
|
-
MINIO_BUCKET=simpleaudit-artifacts
|
|
87
|
-
OTEL_EXPORTER_OTLP_ENDPOINT=
|
|
88
|
-
LANGFUSE_PUBLIC_KEY=
|
|
89
|
-
LANGFUSE_SECRET_KEY=
|
|
90
|
-
LANGFUSE_HOST=
|
|
91
83
|
SENTRY_DSN=
|
|
92
84
|
SENTRY_ENVIRONMENT=development
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths-ignore: ["docs/**", "**.md", "LICENSE"]
|
|
7
|
+
pull_request:
|
|
8
|
+
paths-ignore: ["docs/**", "**.md", "LICENSE"]
|
|
9
|
+
|
|
10
|
+
concurrency:
|
|
11
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
12
|
+
cancel-in-progress: true
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
ci:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
env:
|
|
18
|
+
DJANGO_SETTINGS_MODULE: config.settings
|
|
19
|
+
DJANGO_SECRET_KEY: ci-secret-key
|
|
20
|
+
DJANGO_DEBUG: "false"
|
|
21
|
+
DJANGO_ALLOWED_HOSTS: "*"
|
|
22
|
+
SIMPLEAUDIT_LOCAL_SQLITE: "1"
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v4
|
|
25
|
+
with:
|
|
26
|
+
fetch-depth: 0 # the embedded-Hatchet step diffs against origin/main
|
|
27
|
+
- uses: actions/setup-python@v5
|
|
28
|
+
with:
|
|
29
|
+
python-version: "3.12"
|
|
30
|
+
- uses: astral-sh/setup-uv@v7
|
|
31
|
+
- name: Install dependencies
|
|
32
|
+
run: uv sync --frozen --extra dev
|
|
33
|
+
- name: Lint (ruff)
|
|
34
|
+
run: uv run ruff check .
|
|
35
|
+
- name: Run tests (parallel)
|
|
36
|
+
run: uv run python manage.py test infra --parallel auto --exclude-tag embedded_hatchet
|
|
37
|
+
- name: Check if embedded Hatchet files changed
|
|
38
|
+
id: hatchet-changed
|
|
39
|
+
run: |
|
|
40
|
+
CHANGED=$(git diff --name-only origin/main...HEAD -- infra/minimal_config.py infra/worker.py 2>/dev/null || true)
|
|
41
|
+
if [ -n "$CHANGED" ]; then echo "changed=true" >> "$GITHUB_OUTPUT"; else echo "changed=false" >> "$GITHUB_OUTPUT"; fi
|
|
42
|
+
- name: Run tests (embedded Hatchet, serial)
|
|
43
|
+
if: steps.hatchet-changed.outputs.changed == 'true'
|
|
44
|
+
run: uv run python manage.py test infra.tests.test_minimal_config.TestEmbeddedHatchetLifecycle
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: Docker build
|
|
2
|
+
|
|
3
|
+
# Builds both images (no push) only when something that affects them changes,
|
|
4
|
+
# so Dockerfile / dependency / settings breakage is caught before deploying.
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
paths:
|
|
9
|
+
- "Dockerfile"
|
|
10
|
+
- "deploy/**"
|
|
11
|
+
- "docker-compose.yml"
|
|
12
|
+
- ".dockerignore"
|
|
13
|
+
- "pyproject.toml"
|
|
14
|
+
- "uv.lock"
|
|
15
|
+
- "config/settings.py"
|
|
16
|
+
- "infra/minimal_config.py"
|
|
17
|
+
- "simpleaudit_studio/**"
|
|
18
|
+
- ".github/workflows/docker.yml"
|
|
19
|
+
pull_request:
|
|
20
|
+
paths:
|
|
21
|
+
- "Dockerfile"
|
|
22
|
+
- "deploy/**"
|
|
23
|
+
- "docker-compose.yml"
|
|
24
|
+
- ".dockerignore"
|
|
25
|
+
- "pyproject.toml"
|
|
26
|
+
- "uv.lock"
|
|
27
|
+
- "config/settings.py"
|
|
28
|
+
- "infra/minimal_config.py"
|
|
29
|
+
- "simpleaudit_studio/**"
|
|
30
|
+
- ".github/workflows/docker.yml"
|
|
31
|
+
|
|
32
|
+
concurrency:
|
|
33
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
34
|
+
cancel-in-progress: true
|
|
35
|
+
|
|
36
|
+
jobs:
|
|
37
|
+
docker:
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
steps:
|
|
40
|
+
- uses: actions/checkout@v4
|
|
41
|
+
- name: Build HF Space / demo image
|
|
42
|
+
run: docker build -t simpleaudit-studio:ci .
|
|
43
|
+
- name: Build Compose image
|
|
44
|
+
run: docker build -f deploy/compose/Dockerfile -t simpleaudit-studio-compose:ci .
|
|
45
|
+
- name: Validate compose file
|
|
46
|
+
run: cp .env.example .env && docker compose config --quiet
|
|
@@ -20,7 +20,16 @@ jobs:
|
|
|
20
20
|
uses: actions/setup-python@v5
|
|
21
21
|
with:
|
|
22
22
|
python-version: "3.12"
|
|
23
|
-
-
|
|
23
|
+
- uses: astral-sh/setup-uv@v7
|
|
24
|
+
- name: Test before publishing
|
|
25
|
+
env:
|
|
26
|
+
DJANGO_SECRET_KEY: ci-secret-key
|
|
27
|
+
SIMPLEAUDIT_LOCAL_SQLITE: "1"
|
|
28
|
+
run: |
|
|
29
|
+
uv sync --frozen --extra dev
|
|
30
|
+
uv run ruff check .
|
|
31
|
+
uv run python manage.py test infra --parallel auto --exclude-tag embedded_hatchet
|
|
32
|
+
- name: Install build tooling
|
|
24
33
|
run: |
|
|
25
34
|
python -m pip install --upgrade pip
|
|
26
35
|
pip install build
|
|
@@ -8,6 +8,7 @@ venv/
|
|
|
8
8
|
# Django
|
|
9
9
|
db.sqlite3
|
|
10
10
|
*.sqlite3
|
|
11
|
+
*.sqlite3-*
|
|
11
12
|
media/
|
|
12
13
|
staticfiles/
|
|
13
14
|
|
|
@@ -24,6 +25,7 @@ simpleaudit-dependency.yaml
|
|
|
24
25
|
.idea/
|
|
25
26
|
*.swp
|
|
26
27
|
.DS_Store
|
|
28
|
+
copilot-instructions.md
|
|
27
29
|
|
|
28
30
|
# Test/coverage
|
|
29
31
|
.coverage
|
|
@@ -37,5 +39,8 @@ docker-data/
|
|
|
37
39
|
*.log
|
|
38
40
|
logs/
|
|
39
41
|
|
|
42
|
+
# Runtime artifacts
|
|
43
|
+
app.pid
|
|
44
|
+
|
|
40
45
|
# Data artifacts (prototype)
|
|
41
46
|
data/
|
|
@@ -29,47 +29,47 @@ RUN apt-get update \
|
|
|
29
29
|
|
|
30
30
|
# --- Python dependencies -----------------------------------------------------
|
|
31
31
|
# pyproject.toml is the single source of truth; uv.lock pins exact versions.
|
|
32
|
-
# The postgres extra is included because Django imports the psycopg driver at
|
|
33
|
-
# startup even when SIMPLEAUDIT_MINIMAL=1 uses SQLite for the domain DB.
|
|
34
32
|
# uv sync creates /app/.venv; the PATH update keeps the `python` entrypoint.
|
|
35
33
|
COPY pyproject.toml uv.lock README.md ./
|
|
36
34
|
RUN pip install uv \
|
|
37
|
-
&& uv sync --frozen --no-install-project --no-dev
|
|
35
|
+
&& uv sync --frozen --no-install-project --no-dev
|
|
38
36
|
ENV PATH="/app/.venv/bin:$PATH"
|
|
39
37
|
|
|
40
|
-
# --- Application code --------------------------------------------------------
|
|
41
|
-
COPY . .
|
|
42
|
-
|
|
43
|
-
# Collect static files so Django can serve them without DEBUG.
|
|
44
|
-
RUN python manage.py collectstatic --noinput
|
|
45
|
-
|
|
46
|
-
# --- Non-root user ------------------------------------------------------------
|
|
47
|
-
RUN useradd --create-home appuser \
|
|
48
|
-
&& mkdir -p /app/staticfiles /app/media \
|
|
49
|
-
&& chown -R appuser:appuser /app
|
|
50
|
-
USER appuser
|
|
51
|
-
|
|
52
38
|
# --- Environment defaults for the Space --------------------------------------
|
|
53
39
|
# SIMPLEAUDIT_MINIMAL=1 enables the minimal config path (SQLite + embedded Hatchet).
|
|
54
40
|
# Override via HF Space Secrets for anything sensitive.
|
|
41
|
+
# Must be set BEFORE collectstatic: Django settings select the DB engine from it,
|
|
42
|
+
# and the postgres driver is an optional extra not installed in this image.
|
|
55
43
|
ENV SIMPLEAUDIT_MINIMAL=1 \
|
|
56
44
|
PORT=7860 \
|
|
57
45
|
DJANGO_SECRET_KEY=hf-space-demo-secret-key-change-in-production \
|
|
58
46
|
DJANGO_DEBUG=false \
|
|
59
|
-
DJANGO_ALLOWED_HOSTS
|
|
47
|
+
DJANGO_ALLOWED_HOSTS=* \
|
|
60
48
|
BOOTSTRAP_USERNAME=studio \
|
|
61
49
|
BOOTSTRAP_EMAIL=studio@example.local \
|
|
62
50
|
BOOTSTRAP_PASSWORD=admin123 \
|
|
63
51
|
BOOTSTRAP_PROJECT_NAME=Default \
|
|
64
52
|
DEMO_MODE=true \
|
|
65
53
|
DEMO_USERNAME=studio \
|
|
66
|
-
DEMO_PASSWORD=admin123
|
|
67
|
-
|
|
68
|
-
|
|
54
|
+
DEMO_PASSWORD=admin123
|
|
55
|
+
|
|
56
|
+
# --- Application code --------------------------------------------------------
|
|
57
|
+
COPY . .
|
|
58
|
+
|
|
59
|
+
# Collect static files so Django can serve them without DEBUG.
|
|
60
|
+
RUN python manage.py collectstatic --noinput
|
|
61
|
+
|
|
62
|
+
# --- Non-root user ------------------------------------------------------------
|
|
63
|
+
RUN useradd --create-home appuser \
|
|
64
|
+
&& mkdir -p /app/staticfiles \
|
|
65
|
+
&& chown -R appuser:appuser /app
|
|
66
|
+
USER appuser
|
|
69
67
|
|
|
70
68
|
EXPOSE 7860
|
|
71
69
|
|
|
72
70
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=90s --retries=5 \
|
|
73
71
|
CMD curl -fsS http://localhost:7860/healthz || exit 1
|
|
74
72
|
|
|
73
|
+
# Model connections point at OpenAI's real base URL (https://api.openai.com/v1).
|
|
74
|
+
# Users add their API key in the UI to run real audits.
|
|
75
75
|
CMD ["python", "-m", "simpleaudit_studio.cli"]
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: simpleaudit-studio
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Production AI model audit platform — one-liner demo mode via uvx
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Requires-Python: >=3.11
|
|
8
|
-
Requires-Dist:
|
|
9
|
-
Requires-Dist: django-cors-headers==4.7.0
|
|
8
|
+
Requires-Dist: cronsim==2.7
|
|
10
9
|
Requires-Dist: django==5.2.4
|
|
11
10
|
Requires-Dist: djangorestframework==3.16.0
|
|
12
11
|
Requires-Dist: drf-spectacular==0.28.0
|
|
13
12
|
Requires-Dist: hatchet-sdk==1.41.0
|
|
13
|
+
Requires-Dist: httpx>=0.27
|
|
14
14
|
Requires-Dist: pydantic<3,>=2.7
|
|
15
15
|
Requires-Dist: python-dotenv==1.1.1
|
|
16
16
|
Requires-Dist: requests==2.32.5
|
|
@@ -19,9 +19,9 @@ Requires-Dist: simpleaudit==0.2.1
|
|
|
19
19
|
Requires-Dist: workos==10.4.0
|
|
20
20
|
Provides-Extra: dev
|
|
21
21
|
Requires-Dist: factory-boy==3.3.2; extra == 'dev'
|
|
22
|
-
Requires-Dist: pytest; extra == 'dev'
|
|
23
|
-
Requires-Dist: pytest-django; extra == 'dev'
|
|
24
22
|
Requires-Dist: ruff; extra == 'dev'
|
|
23
|
+
Provides-Extra: e2e
|
|
24
|
+
Requires-Dist: playwright>=1.45; extra == 'e2e'
|
|
25
25
|
Provides-Extra: postgres
|
|
26
26
|
Requires-Dist: psycopg[binary]==3.2.13; extra == 'postgres'
|
|
27
27
|
Provides-Extra: server
|
|
@@ -78,7 +78,40 @@ The pre-seeded connections point at a built-in mock server. To run real audits,
|
|
|
78
78
|
| Together AI | `https://api.together.xyz/v1` | Many open models |
|
|
79
79
|
| Groq | `https://api.groq.com/openai/v1` | Fast inference |
|
|
80
80
|
|
|
81
|
-
Set the API key in the connection form (leave blank for local servers that don't require auth), then
|
|
81
|
+
Set the API key in the connection form (leave blank for local servers that don't require auth), then start a run from **New Experiment**.
|
|
82
|
+
|
|
83
|
+
## 🛠️ Local Development
|
|
84
|
+
|
|
85
|
+
For contributors working on the codebase, use [uv](https://docs.astral.sh/uv/) — no manual venv steps, no Makefile. Two verbs cover everything:
|
|
86
|
+
|
|
87
|
+
- **`uv sync`** — create/update `.venv` from `pyproject.toml` + `uv.lock`
|
|
88
|
+
- **`uv run <cmd>`** — run any command inside `.venv` (auto-syncs first if the lockfile changed)
|
|
89
|
+
|
|
90
|
+
### Setup (one time)
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
git clone https://github.com/SushantGautam/SimpleAuditStudio
|
|
94
|
+
cd SimpleAuditStudio
|
|
95
|
+
cp .env.local.example .env # minimal local config (SQLite + mock models)
|
|
96
|
+
|
|
97
|
+
uv sync --extra dev --extra postgres # create .venv + install all deps
|
|
98
|
+
uv run manage.py setup_local # migrate + create admin (studio / BOOTSTRAP_PASSWORD from .env) + seed data
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`setup_local` chains the three idempotent first-run steps (migrate → bootstrap admin → seed scenario packs & model connections) into one command. Re-run it any time — it skips what already exists.
|
|
102
|
+
|
|
103
|
+
### Daily work
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
uv run manage.py dev_server --embedded # easiest: web UI + API + audit worker, zero-Docker → http://localhost:8000
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Other options:
|
|
110
|
+
```bash
|
|
111
|
+
uv run manage.py runserver # web UI + API only (no worker)
|
|
112
|
+
uv run manage.py dev_server # web UI + worker, uses .env (edit POSTGRES_*/HATCHET_* to point at your infra)
|
|
113
|
+
SIMPLEAUDIT_LOCAL_SQLITE=1 uv run manage.py test infra # tests
|
|
114
|
+
```
|
|
82
115
|
|
|
83
116
|
## 🐳 Self-Hosting
|
|
84
117
|
|
|
@@ -92,22 +125,22 @@ cp .env.example .env
|
|
|
92
125
|
docker compose up -d
|
|
93
126
|
```
|
|
94
127
|
|
|
95
|
-
Services: Web UI (:8000), PostgreSQL, Hatchet queue (:8888), Worker. Optional
|
|
128
|
+
Services: Web UI (:8000), PostgreSQL, Hatchet queue (:8888), Worker. Optional profile: `--profile mock` (mock model API).
|
|
96
129
|
|
|
97
130
|
See [docs/deployment.md](docs/deployment.md) for production hardening, backups, and upgrades.
|
|
98
131
|
|
|
99
132
|
## ✨ What You Can Do
|
|
100
133
|
|
|
101
|
-
-
|
|
102
|
-
-
|
|
103
|
-
-
|
|
104
|
-
-
|
|
105
|
-
-
|
|
134
|
+
- Build versioned scenario sets and register OpenAI-compatible models
|
|
135
|
+
- Run experiments across models, scenario versions and settings, with a review step before launch
|
|
136
|
+
- Watch runs live, including per-repetition results
|
|
137
|
+
- Monitor models for drift on a schedule (interval or cron)
|
|
138
|
+
- Filter, customise and compare runs on an interactive dashboard
|
|
106
139
|
|
|
107
140
|
## 🏗️ Architecture
|
|
108
141
|
|
|
109
142
|
```
|
|
110
|
-
Browser → Django
|
|
143
|
+
Browser → Django (gunicorn :8000 in Compose; runserver :7860 in the HF Space / uvx demo)
|
|
111
144
|
↓
|
|
112
145
|
PostgreSQL 16 (domain + queue DBs)
|
|
113
146
|
↓
|
|
@@ -126,11 +159,3 @@ Browser → Django/Gunicorn (:7860)
|
|
|
126
159
|
## 🤝 Contributing
|
|
127
160
|
|
|
128
161
|
Architecture decisions are documented in [docs/architecture.md](docs/architecture.md).
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
@@ -48,7 +48,40 @@ The pre-seeded connections point at a built-in mock server. To run real audits,
|
|
|
48
48
|
| Together AI | `https://api.together.xyz/v1` | Many open models |
|
|
49
49
|
| Groq | `https://api.groq.com/openai/v1` | Fast inference |
|
|
50
50
|
|
|
51
|
-
Set the API key in the connection form (leave blank for local servers that don't require auth), then
|
|
51
|
+
Set the API key in the connection form (leave blank for local servers that don't require auth), then start a run from **New Experiment**.
|
|
52
|
+
|
|
53
|
+
## 🛠️ Local Development
|
|
54
|
+
|
|
55
|
+
For contributors working on the codebase, use [uv](https://docs.astral.sh/uv/) — no manual venv steps, no Makefile. Two verbs cover everything:
|
|
56
|
+
|
|
57
|
+
- **`uv sync`** — create/update `.venv` from `pyproject.toml` + `uv.lock`
|
|
58
|
+
- **`uv run <cmd>`** — run any command inside `.venv` (auto-syncs first if the lockfile changed)
|
|
59
|
+
|
|
60
|
+
### Setup (one time)
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
git clone https://github.com/SushantGautam/SimpleAuditStudio
|
|
64
|
+
cd SimpleAuditStudio
|
|
65
|
+
cp .env.local.example .env # minimal local config (SQLite + mock models)
|
|
66
|
+
|
|
67
|
+
uv sync --extra dev --extra postgres # create .venv + install all deps
|
|
68
|
+
uv run manage.py setup_local # migrate + create admin (studio / BOOTSTRAP_PASSWORD from .env) + seed data
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`setup_local` chains the three idempotent first-run steps (migrate → bootstrap admin → seed scenario packs & model connections) into one command. Re-run it any time — it skips what already exists.
|
|
72
|
+
|
|
73
|
+
### Daily work
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
uv run manage.py dev_server --embedded # easiest: web UI + API + audit worker, zero-Docker → http://localhost:8000
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Other options:
|
|
80
|
+
```bash
|
|
81
|
+
uv run manage.py runserver # web UI + API only (no worker)
|
|
82
|
+
uv run manage.py dev_server # web UI + worker, uses .env (edit POSTGRES_*/HATCHET_* to point at your infra)
|
|
83
|
+
SIMPLEAUDIT_LOCAL_SQLITE=1 uv run manage.py test infra # tests
|
|
84
|
+
```
|
|
52
85
|
|
|
53
86
|
## 🐳 Self-Hosting
|
|
54
87
|
|
|
@@ -62,22 +95,22 @@ cp .env.example .env
|
|
|
62
95
|
docker compose up -d
|
|
63
96
|
```
|
|
64
97
|
|
|
65
|
-
Services: Web UI (:8000), PostgreSQL, Hatchet queue (:8888), Worker. Optional
|
|
98
|
+
Services: Web UI (:8000), PostgreSQL, Hatchet queue (:8888), Worker. Optional profile: `--profile mock` (mock model API).
|
|
66
99
|
|
|
67
100
|
See [docs/deployment.md](docs/deployment.md) for production hardening, backups, and upgrades.
|
|
68
101
|
|
|
69
102
|
## ✨ What You Can Do
|
|
70
103
|
|
|
71
|
-
-
|
|
72
|
-
-
|
|
73
|
-
-
|
|
74
|
-
-
|
|
75
|
-
-
|
|
104
|
+
- Build versioned scenario sets and register OpenAI-compatible models
|
|
105
|
+
- Run experiments across models, scenario versions and settings, with a review step before launch
|
|
106
|
+
- Watch runs live, including per-repetition results
|
|
107
|
+
- Monitor models for drift on a schedule (interval or cron)
|
|
108
|
+
- Filter, customise and compare runs on an interactive dashboard
|
|
76
109
|
|
|
77
110
|
## 🏗️ Architecture
|
|
78
111
|
|
|
79
112
|
```
|
|
80
|
-
Browser → Django
|
|
113
|
+
Browser → Django (gunicorn :8000 in Compose; runserver :7860 in the HF Space / uvx demo)
|
|
81
114
|
↓
|
|
82
115
|
PostgreSQL 16 (domain + queue DBs)
|
|
83
116
|
↓
|
|
@@ -96,11 +129,3 @@ Browser → Django/Gunicorn (:7860)
|
|
|
96
129
|
## 🤝 Contributing
|
|
97
130
|
|
|
98
131
|
Architecture decisions are documented in [docs/architecture.md](docs/architecture.md).
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from django.urls import path
|
|
2
|
+
|
|
3
|
+
from . import views
|
|
4
|
+
|
|
5
|
+
urlpatterns = [
|
|
6
|
+
path("stats/", views.admin_stats, name="admin-stats"),
|
|
7
|
+
path("workspaces/<int:project_id>/archive/", views.admin_archive_workspace, name="admin-workspace-archive"),
|
|
8
|
+
path("workspaces/<int:project_id>/unarchive/", views.admin_unarchive_workspace, name="admin-workspace-unarchive"),
|
|
9
|
+
path("users/", views.admin_create_user_view, name="admin-user-create"),
|
|
10
|
+
path("users/<int:user_id>/", views.admin_update_user_view, name="admin-user-update"),
|
|
11
|
+
]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Generated by Django 5.2.4 on 2026-09-
|
|
1
|
+
# Generated by Django 5.2.4 on 2026-09-27 19:42
|
|
2
2
|
|
|
3
3
|
import django.contrib.auth.models
|
|
4
4
|
import django.contrib.auth.validators
|
|
@@ -31,6 +31,7 @@ class Migration(migrations.Migration):
|
|
|
31
31
|
("name", models.CharField(max_length=200, unique=True)),
|
|
32
32
|
("slug", models.SlugField(max_length=200, unique=True)),
|
|
33
33
|
("description", models.TextField(blank=True)),
|
|
34
|
+
("archived", models.BooleanField(db_index=True, default=False)),
|
|
34
35
|
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
35
36
|
("updated_at", models.DateTimeField(auto_now=True)),
|
|
36
37
|
],
|
|
@@ -121,6 +122,10 @@ class Migration(migrations.Migration):
|
|
|
121
122
|
default=django.utils.timezone.now, verbose_name="date joined"
|
|
122
123
|
),
|
|
123
124
|
),
|
|
125
|
+
(
|
|
126
|
+
"workos_user_id",
|
|
127
|
+
models.CharField(blank=True, max_length=64, null=True, unique=True),
|
|
128
|
+
),
|
|
124
129
|
(
|
|
125
130
|
"groups",
|
|
126
131
|
models.ManyToManyField(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Generated by Django 5.2.4 on 2026-09-
|
|
1
|
+
# Generated by Django 5.2.4 on 2026-09-27 20:23
|
|
2
2
|
|
|
3
3
|
from django.db import migrations, models
|
|
4
4
|
|
|
@@ -11,7 +11,7 @@ class Migration(migrations.Migration):
|
|
|
11
11
|
operations = [
|
|
12
12
|
migrations.AddField(
|
|
13
13
|
model_name="user",
|
|
14
|
-
name="
|
|
15
|
-
field=models.
|
|
14
|
+
name="preferences",
|
|
15
|
+
field=models.JSONField(blank=True, default=dict),
|
|
16
16
|
),
|
|
17
17
|
]
|
|
@@ -21,6 +21,9 @@ class User(AbstractUser):
|
|
|
21
21
|
|
|
22
22
|
# Stable WorkOS AuthKit user id; null for locally-created accounts.
|
|
23
23
|
workos_user_id = models.CharField(max_length=64, unique=True, null=True, blank=True)
|
|
24
|
+
# Per-user UI preferences (e.g. dashboard column layout). Keys are
|
|
25
|
+
# whitelisted by the preference endpoint; values are small JSON.
|
|
26
|
+
preferences = models.JSONField(default=dict, blank=True)
|
|
24
27
|
|
|
25
28
|
groups = models.ManyToManyField(
|
|
26
29
|
"auth.Group",
|
|
@@ -45,6 +48,9 @@ class Project(models.Model):
|
|
|
45
48
|
name = models.CharField(max_length=200, unique=True)
|
|
46
49
|
slug = models.SlugField(max_length=200, unique=True)
|
|
47
50
|
description = models.TextField(blank=True)
|
|
51
|
+
# Soft-hide a workspace that still contains data. Members keep read access;
|
|
52
|
+
# all mutations are blocked for non-superusers. Never deletes data.
|
|
53
|
+
archived = models.BooleanField(default=False, db_index=True)
|
|
48
54
|
created_at = models.DateTimeField(auto_now_add=True)
|
|
49
55
|
updated_at = models.DateTimeField(auto_now=True)
|
|
50
56
|
|