Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/pyright-type-checking.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ jobs:
- run: uv sync
- run: echo "$PWD/.venv/bin" >> $GITHUB_PATH

# No working-directory: pyright reads pyrightconfig.json from the repo root so the
# checked paths live in one place. src/rapidata/service was outside the old scope,
# which is how a dead import there shipped in 3.21.0 and broke every API call.
- uses: jakebailey/pyright-action@v2
with:
version: v1.1.396
working-directory: src/rapidata/rapidata_client
2 changes: 1 addition & 1 deletion pyrightconfig.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"include": ["src/rapidata/rapidata_client"]
"include": ["src/rapidata/rapidata_client", "src/rapidata/service"]
}
8 changes: 4 additions & 4 deletions src/rapidata/service/services/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
from rapidata.service.services.flow_service import FlowService
from rapidata.service.services.leaderboard_service import LeaderboardService
from rapidata.service.services.order_service import OrderService
from rapidata.service.services.pipeline_service import PipelineService
from rapidata.service.services.payment_service import PaymentService
from rapidata.service.services.rapid_service import RapidService
from rapidata.service.services.signal_service import SignalService
from rapidata.service.services.translation_service import TranslationService
from rapidata.service.services.validation_service import ValidationService
from rapidata.service.services.workflow_service import WorkflowService

__all__ = [
"AssetService",
Expand All @@ -19,9 +19,9 @@
"FlowService",
"LeaderboardService",
"OrderService",
"PipelineService",
"PaymentService",
"RapidService",
"SignalService",
"TranslationService",
"ValidationService",
"WorkflowService",
]
Empty file added tests/service/__init__.py
Empty file.
43 changes: 43 additions & 0 deletions tests/service/test_services_package.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""Tests that keep ``rapidata.service.services`` importable.

``openapi_service`` reaches every backend service through a lazy
``from rapidata.service.services.<name>_service import ...``, and that import
runs the package ``__init__`` first. So a single stale name in ``__init__``
breaks *every* API call in the published wheel, not just the service that was
removed — which is how 3.21.0 shipped with a dead ``pipeline_service`` import
and raised ``ModuleNotFoundError`` on any call.
"""

from __future__ import annotations

import importlib
from pathlib import Path

import pytest

import rapidata.service.services as services_package


def _service_modules() -> list[str]:
package_dir = Path(services_package.__file__).parent
return sorted(p.stem for p in package_dir.glob("*_service.py"))


class TestServicesPackage:
def test_every_exported_name_is_resolvable(self):
"""A name left in ``__all__`` after its module was deleted is the failure mode."""
for name in services_package.__all__:
assert (
getattr(services_package, name, None) is not None
), f"{name} is exported but not bound"

@pytest.mark.parametrize("module_name", _service_modules())
def test_every_service_module_is_exported(self, module_name: str):
"""Keeps ``__all__`` in sync with the modules actually on disk."""
module = importlib.import_module(f"rapidata.service.services.{module_name}")
expected = "".join(part.capitalize() for part in module_name.split("_"))

assert hasattr(module, expected), f"{module_name} has no {expected}"
assert (
expected in services_package.__all__
), f"{expected} is missing from rapidata.service.services.__all__"
Loading