Skip to content

feat(integrations): Add startup/checkin endpoints + tooling fixes - #2822

Draft
vikramlc-cognite wants to merge 1 commit into
integrations-part2.2-core-api-testsfrom
integrations-part3-startup-checkin
Draft

feat(integrations): Add startup/checkin endpoints + tooling fixes#2822
vikramlc-cognite wants to merge 1 commit into
integrations-part2.2-core-api-testsfrom
integrations-part3-startup-checkin

Conversation

@vikramlc-cognite

Copy link
Copy Markdown

Summary

Adds the extractor self-registration/heartbeat protocol (startup, checkin) now that cognitedata/service-contracts PR #3378 removed their ifdef: internal marking, plus the retry-idempotency registration and codespell config needed to support the "checkin" identifier. Builds on the API client from #2820/#2821.

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that changes existing behavior)
  • Refactor (no functional change)
  • Documentation update
  • Chore / tooling / CI

What changed

  • New cognite/client/data_classes/integrations/checkin.py: TaskUpdate, ErrorWithTask, StartupRequest, CheckinRequest, CheckinResponse.
  • New IntegrationsAPI.startup() and IntegrationsAPI.checkin() methods, POST-ing to /integrations/startup and /integrations/checkin respectively with the same beta header as the rest of the module.
  • Added integrations/checkin and integrations/startup to the non-idempotent POST pattern list in utils/_url.py, with matching cases in test_api_client.py.
  • .pre-commit-config.yaml: added --ignore-words-list=checkin to the codespell hook args, since "checkin" is the API's real operationId/URL segment and can't be reworded to "check-in" without diverging from the actual wire contract. Passed as a hook arg rather than pyproject.toml's [tool.codespell] because reading TOML config requires tomli/tomllib, which isn't guaranteed available in the hook's isolated environment on Python <3.11.
  • New tests: test_startup/test_checkin in test_api/test_integrations/test_integrations.py, and round-trip tests for all 5 new data classes in test_data_classes/test_integrations.py.

Why it changed

What to focus on during review

  • startup()/checkin() are explicitly documented (Note: in the docstring) as normally only called by extractor implementations as part of the integrations protocol, not typical SDK consumers — worth confirming that framing reads clearly to a reviewer unfamiliar with the extractor side.
  • The codespell hook fix: an earlier attempt via pyproject.toml's [tool.codespell] worked locally but silently failed in CI (Python 3.10 in the hook's isolated venv couldn't parse the TOML without tomli) — this PR's .pre-commit-config.yaml args-based fix is the one that's CI-verified.

Test evidence

  • pytest tests/tests_unit/ -q → 6,708 passed, 8 failed (pre-existing, unrelated: missing geopandas/sympy in the local dev environment — confirmed via git stash/pop A-B testing that these fail identically on master), 6 skipped
  • python scripts/sync_client_codegen/main.py verify → sync mirrors up to date
  • ruff check / ruff format --check → clean (550 files)
  • mypy → no issues (550 source files)
  • Confirmed this branch reconstructs the original unsplit branch byte-for-byte (git diff against it is empty)

Risks and unknowns

  • startup/checkin are part of an extractor-facing heartbeat protocol rather than typical end-user SDK surface — low usage risk for most SDK consumers, but worth a sanity check from someone on the extractors side that the request/response shapes match what real extractors send.

Rollout and rollback

  • Same beta FeaturePreviewWarning gating as the rest of the module. No migrations. Revert is a straight revert of this commit.

Checklist

  • Self-reviewed the diff
  • Tests added or updated (or N/A with reason)
  • Docs updated (or N/A) — N/A, no public docs page exists yet for this beta API
  • No secrets, credentials, or PII committed
  • Breaking changes called out above and communicated to affected teams — N/A, no breaking changes

@vikramlc-cognite
vikramlc-cognite requested review from a team as code owners September 7, 2026 12:15

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements the extractor startup and check-in protocols for the Integrations API, introducing new data classes (StartupRequest, CheckinRequest, CheckinResponse, TaskUpdate, and ErrorWithTask) along with corresponding sync and async client methods. Feedback on the changes suggests removing the custom dump methods in StartupRequest and CheckinRequest because they are redundant and violate the Liskov Substitution Principle by altering the default camel_case parameter value.

Comment on lines +113 to +118
def dump(self, camel_case: bool = True) -> dict[str, Any]:
result = super().dump(camel_case)
result["extractor"] = self.extractor.dump(camel_case)
if self.tasks is not None:
result["tasks"] = [task.dump(camel_case) for task in self.tasks]
return result

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The custom dump method in StartupRequest is redundant and violates the Liskov Substitution Principle (LSP) by changing the default value of camel_case from False to True compared to the base class CogniteResource.dump. Since CogniteResource.dump already automatically and recursively serializes nested CogniteResource attributes (like extractor and tasks), this custom implementation can be safely removed to improve maintainability and consistency.

References
  1. Maintainability: Write code that is easy to modify and extend. Consistency: Follow established patterns across the codebase. (link)

Comment on lines +155 to +162
def dump(self, camel_case: bool = True) -> dict[str, Any]:
result = super().dump(camel_case)
if self.task_events is not None:
key = "taskEvents" if camel_case else "task_events"
result[key] = [event.dump(camel_case) for event in self.task_events]
if self.errors is not None:
result["errors"] = [error.dump(camel_case) for error in self.errors]
return result

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The custom dump method in CheckinRequest is redundant and violates the Liskov Substitution Principle (LSP) by changing the default value of camel_case from False to True compared to the base class CogniteResource.dump. Since CogniteResource.dump already automatically and recursively serializes nested CogniteResource attributes (like task_events and errors), this custom implementation can be safely removed to improve maintainability and consistency.

References
  1. Maintainability: Write code that is easy to modify and extend. Consistency: Follow established patterns across the codebase. (link)

@vikramlc-cognite
vikramlc-cognite marked this pull request as draft September 7, 2026 12:21
Adds the extractor self-registration/heartbeat protocol (startup,
checkin) now that service-contracts PR #3378 removed their
ifdef: internal marking, plus the retry-idempotency registration and
codespell config needed to support the "checkin" identifier.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@vikramlc-cognite
vikramlc-cognite force-pushed the integrations-part3-startup-checkin branch from 43aaa1d to 1a77b03 Compare September 7, 2026 12:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants