Skip to content

fix: migrate deprecated framework contracts - #85

Closed
seonghobae wants to merge 1 commit into
mainfrom
fix/deprecation-free-runtime-contract
Closed

fix: migrate deprecated framework contracts#85
seonghobae wants to merge 1 commit into
mainfrom
fix/deprecation-free-runtime-contract

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Root cause

The protected-main test/runtime boundary emitted four warning classes that were being tolerated instead of resolved:

  • Starlette 1.6 now prefers httpx2 for TestClient; the dev extra still installed legacy httpx.
  • Pydantic models declared schema, shadowing the deprecated BaseModel.schema API.
  • FastAPI startup used the deprecated on_event hook.
  • two synthetic HS256 fixtures used a key below the RFC 7518 minimum, and the fuzz property module was not importable as a package in a clean checkout.

Change

  • pin httpx2==2.12.0 and commit the reproducible uv.lock;
  • preserve the public JSON key schema through Pydantic aliases while using the non-conflicting internal dataset_schema;
  • migrate startup seeding to the ASGI lifespan contract and add lifecycle coverage;
  • use an adequate synthetic HMAC key and make the test namespace importable.

No warning suppression is added. The external API continues accepting and emitting schema.

Verification

uv run pytest -q -W error::DeprecationWarning -W error::UserWarning

Result: full suite passed, including Hypothesis properties; eight live-integration tests skipped by their existing runtime guard. git diff --check passed.

Authoritative references

Starlette. (2026). Test client. https://www.starlette.io/testclient/

Pydantic Services Inc. (2026). HTTPX2 2.12.0. https://pypi.org/project/httpx2/2.12.0/


Open in Devin Review

@seonghobae
seonghobae enabled auto-merge (squash) August 26, 2026 13:38
@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 45 minutes.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 013b208b-ae84-4c4a-ae9a-89708e60138f

📥 Commits

Reviewing files that changed from the base of the PR and between e48aa13 and e507bff.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (15)
  • pyproject.toml
  • src/sdp/api.py
  • src/sdp/browse.py
  • src/sdp/catalog.py
  • src/sdp/connectors.py
  • src/sdp/orchestrator.py
  • src/sdp/policy.py
  • src/sdp/seed.py
  • src/sdp_core/contracts.py
  • tests/__init__.py
  • tests/test_api.py
  • tests/test_authz.py
  • tests/test_browse.py
  • tests/test_catalog.py
  • tests/test_orchestrator.py

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Closed as superseded: the deprecation-free runtime migration directly overlapped #73 in src/sdp/api.py and tests/test_api.py, so commit e507bff was merged without force into #73 and validated on the combined exact tree. Delivery evidence must be collected on #73 current head; this PR must not merge independently.

@seonghobae seonghobae closed this Aug 26, 2026
auto-merge was automatically disabled August 26, 2026 13:41

Pull request was closed

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Devin Review found 4 potential issues.

Open in Devin Review

Comment thread src/sdp/catalog.py

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 Datasets with no schema pass validation and publish

After the field rename, getattr(dataset, "schema", None) in validate_metadata resolves to Pydantic's deprecated schema method instead of the column list, because _REQUIRED_METADATA_FIELDS still holds the string "schema" (catalog.py:146). The method is always truthy, so a dataset with an empty schema is never flagged missing, and publish_dataset publishes it.

(Refers to this code)

Prompt for agents
The Dataset model field was renamed from `schema` to `dataset_schema` (with alias `schema`) in src/sdp_core/contracts.py. However `_REQUIRED_METADATA_FIELDS` in src/sdp/catalog.py (line 146) still lists the string "schema", and validate_metadata (line 364) checks presence via getattr(dataset, field, None). Since `schema` is no longer an attribute of the model, getattr now returns Pydantic's deprecated BaseModel.schema method, which is always truthy, so the schema requirement is never detected as missing. This lets datasets with an empty schema pass validate_metadata and be published. Fix validate_metadata so the schema requirement maps to the actual attribute `dataset_schema` (e.g. a name-mapping table {public_name: attr_name}) while keeping the public-facing `required_fields`/`missing` list using the external name "schema" for API compatibility.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread src/sdp/catalog.py

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Alias round-trip in patch_dataset is consistent

serialize_by_alias=True makes model_dump() emit schema, and patch_dataset both keys off "schema" in updates and rebuilds with model_validate; populate_by_name=True keeps the round-trip valid. The interaction is subtle and easy to break in later edits.

(Refers to this code)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread pyproject.toml
dev = [
"pytest==9.1.1",
"httpx==0.28.1",
"httpx2==2.12.0",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 Test suite broken by swapping httpx for httpx2

The dev extra now pins httpx2 instead of httpx. Starlette's TestClient does import httpx and raises if it is absent, and httpx2 does not provide the httpx module. Installing .[dev] no longer pulls httpx, so importing TestClient fails and every API test errors.

Suggested change
"httpx2==2.12.0",
"httpx==0.28.1",
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread pyproject.toml
dev = [
"pytest==9.1.1",
"httpx==0.28.1",
"httpx2==2.12.0",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔍 Requirements lockfiles not regenerated for dep change

requirements-dev.txt and requirements-test.txt still pin httpx==0.28.1 while the dev extra changed. CLAUDE.md requires regenerating these with uv pip compile --generate-hashes on any dependency change; they were not touched here.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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.

1 participant