Modernize pycrash: type hints, tests, CLI, metrics, JSON persistence, AWD bugfix#2
Open
hordruma wants to merge 40 commits into
Open
Modernize pycrash: type hints, tests, CLI, metrics, JSON persistence, AWD bugfix#2hordruma wants to merge 40 commits into
hordruma wants to merge 40 commits into
Conversation
Documents architecture, data flow, all three collision models (SDOF, IMPC, sideswipe), vehicle dynamics, key classes, build instructions, simulation defaults, and development notes. https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
…AWD tire bug - Type hints across all public API and core internals using TYPE_CHECKING pattern - 137 pytest tests covering vehicle, SDOF, tire model, AR equations, vehicle dynamics - pyproject.toml with modern packaging, pytest/mypy/ruff config - Click-based CLI entry point (pycrash info/sdof/vehicle/project) - Metric unit conversion module (units.py) with MetricVehicle/MetricResults - JSON save/load as safer alternative to pickle persistence - Fix AWD right-front tire parenthesis bug in tire_model.py (rf_app mu_max scope) - numpy 2.0 compat (np.trapz→np.trapezoid shim), scipy cumtrapz compat - Version bump to 0.0.18 https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
The AWD tire_model.py parenthesis bug is fixed, so tests should assert correct ~0.8g deceleration, not the old buggy +24 ft/s² behavior. https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
…t, PRD Full agentic crash reconstruction platform: - docker-compose.yml: api + worker + redis, one command startup - FastAPI backend with sync/async SDOF simulation endpoints - Claude-powered police report extraction agent (with mock fallback) - Monte Carlo analysis via Celery distributed workers - PDF report generation with WeasyPrint - Vehicle database with 20 common US vehicles - Pydantic models for full request/response validation - 15 API tests (all passing without Docker via sync endpoints) - Design thinking PRD with personas, jobs-to-be-done, phased roadmap Run locally: ./pycrash_ai/run_local.sh Run with Docker: cd pycrash_ai && docker compose up Run tests: pytest pycrash_ai/tests/ -v https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
…unity Replaced business model section with community growth strategy. Reframed value prop around free self-hosted tooling, not managed services. BYO API key model for AI features - no middleman. https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
…n, and full pipeline integration - FalkorDB-backed evidence graph: schema (nodes: Case, Vehicle, Evidence, Source, Scene, SimConfig, Gap; edges: INVOLVED_IN, OBSERVED, APPLIES_TO, SUPPORTS, CONTRADICTS, INFERRED_FROM, PROJECTED_TO), CaseGraph/CaseGraphStore with InMemory fallback for testing - Case graph API routes: CRUD for cases, vehicles, evidence, sources; gap detection, contradiction detection, evidence-to-pycrash projection, .crash file export/import - LLM provider abstraction: Anthropic (Claude) + OpenAI (GPT) with MockProvider for testing, auto-detection from env vars - Dual-path document ingestion: PyMuPDF text extraction + vision model for scanned PDFs, OpenAI/Anthropic message format builders - Pipeline now builds a case graph from extraction results, stores vehicle specs as evidence, and exports graph state - FalkorDB added to docker-compose as dedicated graph database service - 38 API tests all passing (graph store, case API, pipeline with graph, LLM providers, ingestion, extraction, SDOF, vehicles) https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
…ical Refactored flat case graph into a composable 6-layer hypergraph architecture. Each layer is a mixin class (layers/*.py), composed via multiple inheritance into InMemoryCaseGraph. Cross-layer edges connect nodes across dimensions. Layers: - Entity: vehicles, drivers, pedestrians, objects - Temporal: events, phases, timeline ordering, crash sequence - Spatial: positions, trajectories, impact points, geometry - Evidence: sources, confidence, contradictions, gap detection - Causal: contributing factors, causal chains, counterfactual traces - Physical: delta-V vectors, forces, crush profiles, energy dissipation Cross-layer queries: full timeline (temporal+spatial+causal+physical), causal chain tracing (causal→temporal→physical), evidence-to-pycrash projection, layer summary statistics. .crash v2.0 format: exports full raw graph (_nodes/_edges) for lossless reimport, plus structured per-layer data for human readability. 57 API tests passing, 137 core tests passing (194 total). https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
Step-by-step Docker setup, copy-paste examples for every endpoint, troubleshooting section, and full API reference table. https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
Before: everything crammed under api/ with infra files mixed in
After: clean separation of concerns
pycrash_ai/
__init__.py # proper package init (was missing)
app.py # FastAPI app (was api/main.py)
config.py # app config (was api/config.py)
models.py # Pydantic models (was api/models.py)
agent/ # LLM extraction agents
graph/ # hypergraph store + layers
routes/ # API route handlers
tasks/ # Celery async tasks
data/ # vehicle database (was api/db/)
docker/ # Dockerfile + compose (was at package root)
scripts/ # run_local.sh (was at package root)
tests/ # test suite
All imports simplified: pycrash_ai.api.X -> pycrash_ai.X
All 194 tests passing (57 API + 137 core).
https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
libgdk-pixbuf2.0-0 -> libgdk-pixbuf-2.0-0 (renamed in newer Debian). Also remove obsolete docker-compose version key. https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
- Delete requirements.txt: frozen 2020 lockfile with pins contradicting pyproject.toml (pandas==1.2.0 vs >=2.0, matplotlib==3.3.3 vs >=3.7, etc) - pyproject.toml is now single source of truth for all deps - Add [ai] optional extra with all pycrash_ai deps (fastapi, anthropic, etc) - Dockerfile simplified: `pip install -e ".[dev,ai]"` instead of manual list - Fix setup.py python_requires: 3.6 -> 3.9 - Include pycrash_ai in package find https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
- Update CLAUDE.md with pycrash_ai directory layout and testing commands - Update PRD.md project structure to match actual layout - Fix stale path references in test comments New tests (20): - TestConfig: settings defaults, reports dir - TestModels: SDOFRequest validation, ExtractedVehicle optionals, ExtractionResponse - TestSchema: NodeLabel/GraphLayer enums, NODE_LAYER mapping, EVIDENCE_TO_PYCRASH converter, CrashPhase/ContributingFactor enums, REQUIRED_VEHICLE_PARAMS - TestTools: tool definitions exist, required fields, extract_vehicle schema - TestHeuristicExtraction: speed extraction, vehicle info, empty text handling 214 total tests passing (137 core + 77 API). https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
Use the standard setuptools.build_meta backend. https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
Old pip (24.0) fails on editable installs with pyproject.toml. Upgrade pip/setuptools/wheel first, then use regular install. https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
setup.py reads README.md for long_description but the Dockerfile wasn't copying it into the container. Added COPY README.md and a try/except fallback in setup.py for resilience. https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
Setuptools 82+ enforces PEP 639 which prohibits license classifiers alongside license expressions. Switched to license-expression field and removed the license classifier from both pyproject.toml and setup.py. https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
Pin setuptools<82 in both build-system requires and Dockerfile to avoid
PEP 639 enforcement that creates a catch-22: setuptools 82 rejects license
classifiers alongside license field, but its validator also rejects the
new license-expression field. Using table-style license = {text = "..."}
with setuptools <82 resolves both issues.
https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
Redis only needs to be accessible within the Docker network. Removing the host port binding prevents conflicts when port 6379 is already in use. https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
Stale import path from old directory structure was crashing the worker. https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
…e name autodiscover_tasks looks for a 'tasks.py' inside each package, but ours is named 'simulation_tasks.py'. Using conf.include explicitly registers the correct module so tasks appear in the worker. https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
Creates appuser to avoid running Celery/Uvicorn as root, which eliminates the Celery superuser security warning. https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
Full single-page application served from FastAPI: - index.html shell with dark sidebar, Alpine.js router, page loading - 7 page partials: dashboard, pipeline, simulator, monte carlo, vehicles, cases, reports - 6 JS modules: simulator, montecarlo, vehicles, cases, pipeline, reports - Custom CSS with animations and transitions - All pages use Alpine.js for reactivity, Tailwind CSS, Plotly.js charts - Added delete case endpoint - Uses Alpine.initTree() for dynamic page loading https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
pycrash_ai has grown into its own platform (web UI, Docker stack, graph DB, Celery workers, LLM agents). This creates a self-contained project in pycrash_ai_standalone/ that imports pycrash as an external PyPI dep. Standalone project includes: - pyproject.toml with pycrash>=0.0.18 as dependency - Docker setup (Dockerfile + compose with Redis, FalkorDB) - Complete web UI (Alpine.js + Tailwind + Plotly.js) - All routes, graph layers, agents, tasks, tests - README for non-technical users - .env.example, .gitignore Also removes [ai] extra from pycrash's pyproject.toml since pycrash_ai is now its own project. To use: copy pycrash_ai_standalone/ contents into a fresh repo. https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
Work in progress from parallel agents: - Sync Monte Carlo endpoint (no Celery needed) - IMPC and sideswipe model endpoints - API key auth middleware (optional via PYCRASH_API_KEY) - Rate limiting (100/min general, 10/min simulation) - Request logging middleware - LLM prompt injection sanitization - Case persistence config - CLAUDE.md for standalone project - Applied to both pycrash_ai/ and standalone copy https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
- store.py: disk persistence for cases (auto-save/load from data dir) - simulate.py: IMPC momentum-based collision endpoint - ingest.py (standalone): input sanitization for document ingestion https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
- Vehicle database: 20 -> 68 vehicles (sedans, SUVs, trucks, luxury, EVs) - Scene diagram: new visualization endpoint + UI page + JS - Case persistence: Docker volume mount, cases_dir config, auto-save - Cases routes: _persist_case() called after all mutations - Alpine.js: robust page loading with proper cleanup - index.html: added Scene Diagram nav item + visualize.js https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
The host volume mount (../..:/app) overlays /app in the container, which can cause bare 'uvicorn' and 'celery' commands to fail if /usr/local/bin isn't in the appuser's PATH. Using 'python -m uvicorn' and 'python -m celery' is more reliable. https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
When pycrash_ai was separated, the [ai] extra was removed from pycrash's pyproject.toml. The Dockerfile was only doing pip install ".[dev]" which installs pytest/ruff but not fastapi/uvicorn/celery. Added explicit pip install for all pycrash_ai dependencies. https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
- Project name: pycrash-ai (not generic 'docker') - Container names: pycrash-api, pycrash-worker, pycrash-redis, pycrash-falkordb - Dedicated network: pycrash-net (no conflicts with other projects) - Prefixed volumes: pycrash-reports, pycrash-cases, pycrash-falkordb-data - Fixed critical volume mount: was mounting ../..:/app which overwrote all pip-installed packages. Now mounts only source dirs (pycrash_ai/ and pycrash/) as read-only, preserving installed deps. https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
Replace the dry form-based simulator with a visual, interactive experience:
- Canvas-based 2D top-down crash animation with 4 phases (approach, impact, separation, results)
- Vehicle rendering with crush deformation, impact sparks, screen shake
- Slider-based inputs with plain English labels ("How heavy?", "How fast?")
- Big gradient CRASH! button, severity labels, fun force comparisons
- Delta-V arrows and result overlays on the animation canvas
- Technical charts hidden in collapsible section for power users
https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
Extended version with circular speedometer gauges, gravity-affected spark particles, distance markers on road, rear windows on vehicles, and a clickable replay button with hover cursor. https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
- Rename package directory pycrash_ai/ -> crashout/ - Update all Python imports, module paths, and logger names - Update pyproject.toml package name, entry points, tool config - Update Docker container/image/network/volume names to crashout-* - Update README, CLAUDE.md, and all documentation references https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Full modernization pass on pycrash — everything except CI/CD.
TYPE_CHECKINGpattern to avoid circular importspyproject.toml— modern packaging with pytest/mypy/ruff config, Python >=3.9, updated depspycrash/cli.py) — Click-based entry point:pycrash info|sdof|vehicle|projectpycrash/units.py) —MetricVehicle(dict)converts metric inputs to imperial,MetricResults(df)converts output DataFrame to metricsave_project_json()/load_project_json()as safer alternative to picklenp.trapz→np.trapezoidandcumtrapz→cumulative_trapezoidBug Fix: AWD Right-Front Tire
Found and fixed a parenthesis bug in
tire_model.py:117for AWD vehicles:This caused the RF tire to exceed the friction limit during braking, trigger the lock condition, and produce a forward-accelerating force instead of braking. AWD vehicles were getting +24 ft/s² acceleration instead of -25.76 ft/s² deceleration under full braking.
Files Changed
tests/conftest.py,test_ar.py,test_sdof.py,test_tire_model.py,test_vehicle.py,test_vehicle_model.pypycrash/cli.pypycrash/units.pypyproject.tomlvehicle.py,vehicle_model.py,impact_main.py,sdof_model.py,project.pytire_model.py,carpenter_momentum_calcs.py,impact_detect.py,sideswipe.py,sdof_calculations.py,spring_models.pyar.py,__init__.py,setup.pyCLAUDE.mdTest Plan
python -m pytest tests/ -v)https://claude.ai/code/session_01QLH89mFhr6EtaivkrygBcU