Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #231 +/- ##
=========================================
Coverage ? 72.32%
=========================================
Files ? 63
Lines ? 4304
Branches ? 0
=========================================
Hits ? 3113
Misses ? 1191
Partials ? 0 ☔ View full report in Codecov by Sentry. |
| from pandas import NaT, Timedelta, to_datetime | ||
|
|
||
| __all__ = [ | ||
| "Formatter", |
| from functools import wraps | ||
|
|
||
| @wraps(func) | ||
| def wrapper(*args: Any, **kwargs: Any) -> Any: |
There was a problem hiding this comment.
Pull request overview
This PR removes the database-level “default event” concept and associated dead code, refactoring event selection to be explicit (or via DEFAULT_EVENT_ID) across the CLI/TUI, while also modernising table/formatting infrastructure and tightening ORM loading patterns.
Changes:
- Remove default-event model/trigger/API/CLI command and update docs + tests to select events explicitly.
- Replace the old
utils._tablerendering with model-driven column metadata (RichColSpec/TuiColSpec) and shared formatters + CLIjson_to_table. - Add eager-loading (
selectinload) and small UX improvements (e.g. scroll-pan in seismogram plots) to reduce N+1 patterns and improve interactivity.
Reviewed changes
Copilot reviewed 65 out of 66 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/utils/test_table.py | Removes unit tests tied to the deleted utils._table table renderer. |
| tests/unit/test_config.py | Updates monkeypatch target for the new CLI table module path. |
| tests/unit/_cli/test_common.py | Removes unit tests tied to the deleted aimbat._cli.common module. |
| tests/integration/models/test_operations.py | Refactors snapshot tests to use an explicit event fixture instead of default event. |
| tests/integration/models/test_models.py | Removes default-event trigger tests and updates snapshot tests to use explicit events. |
| tests/integration/core/test_views.py | Updates quality-view tests to fetch an event directly rather than via default. |
| tests/integration/core/test_station.py | Updates station tests/fixtures to select a station/event explicitly. |
| tests/integration/core/test_seismogram.py | Updates seismogram tests to select an event explicitly and adjust CLI expectations. |
| tests/integration/core/test_mccc.py | Updates MCCC tests to select an event explicitly. |
| tests/integration/core/test_iccs.py | Updates ICCS tests to select an event explicitly. |
| tests/integration/core/test_event.py | Removes default-event tests and updates event table expectations. |
| tests/integration/core/test_data.py | Updates dry-run tests to assert returned structured results instead of printed output. |
| tests/functional/test_shell.py | Removes _inject_event tests and updates completion expectations after removing event default. |
| tests/functional/test_cli_basic_ops.py | Updates functional CLI tests to pass --event-id (or all) and verifies removed commands. |
| tests/conftest.py | Removes default-event setup during fixture loading; adds helper event_id fixture. |
| src/aimbat/utils/formatters.py | Introduces shared formatting helpers for CLI/TUI output. |
| src/aimbat/utils/_table.py | Deletes the old Rich table rendering implementation. |
| src/aimbat/utils/_sqlalchemy.py | Adds rel() helper to satisfy mypy for relationship loader options. |
| src/aimbat/utils/init.py | Stops exporting table helpers and exports the new SQLAlchemy helper module. |
| src/aimbat/plot/_seismograms.py | Adds scroll-pan interaction and adjusts scaling/limits for improved plotting UX. |
| src/aimbat/models/_readers.py | Adds rich/tui column metadata and formatters to read models; adjusts station CC aggregation logic. |
| src/aimbat/models/_models.py | Removes AimbatEvent.is_default; adds Rich column metadata on some model fields. |
| src/aimbat/models/_format.py | Adds RichColSpec and TuiColSpec metadata containers. |
| src/aimbat/models/init.py | Updates package docs and exports format metadata. |
| src/aimbat/core/_station.py | Adds eager-loading for station-related queries and table dumps. |
| src/aimbat/core/_snapshot.py | Adds eager-loading for snapshot operations; splits snapshot dump into multiple table-specific dump functions. |
| src/aimbat/core/_seismogram.py | Adds eager-loading to reduce lazy-load churn in seismogram operations and dumps. |
| src/aimbat/core/_quality.py | Refactors station-quality aggregation to avoid per-event latest-snapshot querying; adds eager-loading. |
| src/aimbat/core/_project.py | Removes SQLite triggers enforcing single default event; renumbers remaining triggers. |
| src/aimbat/core/_iccs.py | Adds eager-loading when constructing ICCS from event/snapshot. |
| src/aimbat/core/_event.py | Adds resolve_event() (explicit-only) and eager-loading for event listing/parameter updates. |
| src/aimbat/core/_default_event.py | Deletes default-event API module. |
| src/aimbat/core/_data.py | Changes dry-run behaviour to return structured data instead of printing tables directly. |
| src/aimbat/core/init.py | Removes default-event exports and updates module overview docs. |
| src/aimbat/app.py | Switches to importing CLI sub-apps via aimbat._cli package exports. |
| src/aimbat/_tui/modals.py | Refactors event switcher modal to use model-driven headers/cell formatting. |
| src/aimbat/_tui/app.py | Refactors TUI tables to use shared formatting helpers and updated snapshot dump API. |
| src/aimbat/_tui/_format.py | Adds shared TUI formatting utilities (display titles, cell formatting, SEM formatting helpers). |
| src/aimbat/_config.py | Updates settings table printing to use the new CLI json_to_table with a local Pydantic model. |
| src/aimbat/_cli/utils/init.py | Minor export adjustment for CLI utils app. |
| src/aimbat/_cli/station.py | Updates station CLI to require/select event via --event-id/all and uses model-driven table rendering. |
| src/aimbat/_cli/snapshot.py | Updates snapshot CLI to require event for create/list; expands JSON dump with quality tables; updates details view rendering. |
| src/aimbat/_cli/shell.py | Updates shell event context handling to use DEFAULT_EVENT_ID env var rather than token injection. |
| src/aimbat/_cli/seismogram.py | Updates seismogram CLI to use event selection helpers and model-driven tables; improves ID parameter handling. |
| src/aimbat/_cli/project.py | Updates project info to accept an explicit event context parameter. |
| src/aimbat/_cli/plot.py | Updates plot commands to require explicit --event-id (or env fallback). |
| src/aimbat/_cli/pick.py | Updates pick commands to require explicit event context; aligns option naming/parameter helpers. |
| src/aimbat/_cli/event.py | Removes event default; updates event/parameter commands to explicit event selection and new table renderer. |
| src/aimbat/_cli/data.py | Reintroduces dry-run table output in CLI layer; updates list command to use --event-id/all. |
| src/aimbat/_cli/common/_table.py | Adds new model-driven Rich table renderer used across CLI. |
| src/aimbat/_cli/common/_parameters.py | Adds shared CLI parameter converters (UUID prefix resolution, all, env-var fallback). |
| src/aimbat/_cli/common/_decorators.py | Extracts common CLI exception handling/decorators. |
| src/aimbat/_cli/common/init.py | New package-style re-export for CLI common helpers. |
| src/aimbat/_cli/common.py | Deletes old monolithic CLI common module. |
| src/aimbat/_cli/align.py | Updates align commands to require explicit event context and simplifies parameter handling. |
| src/aimbat/_cli/init.py | Adds a package-level CLI registry for app wiring. |
| src/aimbat/_cli/quality.py | Removes CLI quality command module (dead code per refactor). |
| pyproject.toml | Adds dependency and normalises dev extras formatting. |
| docs/usage/index.md | Updates docs to describe event selection via --event-id/DEFAULT_EVENT_ID. |
| docs/usage/event-selection.md | Updates event-selection docs to remove default-event concept and document the new workflow. |
| CHANGELOG.md | Updates changelog entries to reflect docs/TUI improvements and quality metric storage. |
| def fmt_float(val: float | object) -> str: | ||
| """Format a float to 3 decimal places, or `—` for None/NaN.""" | ||
| if val is None or (isinstance(val, float) and math.isnan(val)): | ||
| return "— " | ||
| if isinstance(val, float): | ||
| return f"{val:.3f}" | ||
| return str(val) |
| def fmt_timestamp(val: Any) -> str: | ||
| """Format a timestamp as `YYYY-MM-DD HH:MM:SS`, or `—` for missing values.""" | ||
| if isinstance(val, str) and val.strip(): | ||
| try: | ||
| val = to_datetime(val) | ||
| except (ValueError, TypeError): | ||
| return str(val) | ||
| if val is None or val is NaT or val == "": | ||
| return "— " | ||
| if hasattr(val, "strftime"): | ||
| return val.strftime("%Y-%m-%d %H:%M:%S") | ||
| return str(val) |
| def fmt_timedelta(val: Timedelta | object) -> str: | ||
| """Format a Timedelta as total seconds to 5 decimal places, or `—` for None.""" | ||
| if val is None: | ||
| return "— " | ||
| if isinstance(val, Timedelta): | ||
| return f"{val.total_seconds():.5f} s" | ||
| return str(val) |
| def json_to_table( | ||
| data: dict[str, Any] | list[dict[str, Any]], | ||
| model: type[BaseModel], | ||
| title: str | None = None, | ||
| raw: bool = False, | ||
| col_specs: dict[str, RichColSpec] | None = None, | ||
| column_order: list[str] | None = None, | ||
| key_header: str = "Property", | ||
| value_header: str = "Value", | ||
| ) -> None: | ||
| """Print a JSON dict or list of dicts as a rich table driven by a Pydantic model. | ||
|
|
||
| Args: | ||
| data: A single row (dict) or list of rows to display. | ||
| model: Pydantic model whose field metadata drives column configuration. | ||
| title: Optional table title. | ||
| raw: If `True`, ignore `RichColSpec` metadata and render using only | ||
| type-based heuristics. Useful for a quick unformatted view. | ||
| col_specs: Optional per-field overrides. Each entry is merged on top of | ||
| the spec derived from the model field, so only the attributes that | ||
| differ need to be set. Ignored when `raw=True`. | ||
| column_order: Optional list of field names that should appear first, in | ||
| that order. Fields not listed appear after in model-declaration order. | ||
| key_header: Header for the property-name column in vertical (dict) tables. | ||
| value_header: Header for the value column in vertical (dict) tables. | ||
| """ | ||
| console = Console() | ||
| table = Table(title=title) | ||
|
|
||
| data_list = [data] if isinstance(data, dict) else data | ||
| if not data_list: | ||
| console.print(table) | ||
| return |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
dc21460 to
1f5c312
Compare
| @overload | ||
| def _make_uuid_converter( | ||
| model_class: type, allow_all: Literal[False] = ... | ||
| ) -> Callable[..., UUID]: ... |
| @overload | ||
| def _make_uuid_converter( | ||
| model_class: type, allow_all: Literal[True] | ||
| ) -> Callable[..., UUID | Literal["all"]]: ... |
| event_id: UUID | None = ..., | ||
| dry_run: Literal[False] = ..., | ||
| disable_progress_bar: bool = ..., | ||
| ) -> None: ... |
| *, | ||
| dry_run: Literal[True], | ||
| disable_progress_bar: bool = ..., | ||
| ) -> tuple[list[AimbatDataSource], set[UUID], set[UUID], set[UUID]]: ... |
📚 Documentation preview 📚: https://aimbat--231.org.readthedocs.build/en/231/