Repository navigation
perf(declarative): skip runtime metaschema check of the component schema - #1224
devin-ai-integration[bot] wants to merge 2 commits into
Conversation
Co-Authored-By: bot_apk <apk@cognition.ai>
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
👋 Greetings, Airbyte Team Member!Here are some helpful tips and reminders for your convenience. 💡 Show Tips and TricksTesting This CDK VersionYou can test this version of the CDK using the following: # Run the CLI from this branch:
uvx 'git+https://github.com/airbytehq/airbyte-python-cdk.git@devin/1791502007-skip-component-schema-check#egg=airbyte-python-cdk[dev]' --help
# Update a connector to use the CDK from this branch ref:
cd airbyte-integrations/connectors/source-example
poe use-cdk-branch devin/1791502007-skip-component-schema-checkPR Slash CommandsAirbyte Maintainers can execute the following slash commands on your PR:
|
The issue this PR resolves has one addition, under "Proposed change", "Risks to cover" and "Acceptance criteria" of airbytehq/airbyte-internal-issues#17933. Please update the PR for it. Check the schema on the failure path When validation finds an error, or raises, call validator_class = validator_for(schema)
try:
error = best_match(validator_class(schema).iter_errors(manifest))
except Exception:
validator_class.check_schema(schema) # a broken schema is reported as SchemaError
raise
if error is not None:
validator_class.check_schema(schema)
raise ValidationError(...) from errorA valid manifest never reaches Why: a CDK developer who breaks
Please cover, for the concurrent and the legacy source:
The "Risk" section of the description will need updating too. |
…n fails Co-Authored-By: bot_apk <apk@cognition.ai>
|
Patrick Nilan (@pnilan) Done in 29b03be, reply to this comment.
I updated the Summary, Test Coverage and Risk sections of the description to match. |
Summary
_validate_source()inConcurrentDeclarativeSourceand the legacyManifestDeclarativeSourcecalledjsonschema.validators.validate(manifest, schema). In jsonschema 4.x that first runscls.check_schema(schema), which checks the CDK's own shippeddeclarative_component_schema.yamlagainst the Draft 7 metaschema again on every source build. It gets the same answer every time, and it runs a second time when_migrate_manifestvalidates again.This PR builds the validator directly, keeps
validate's error selection, and only checks the schema when validation fails:A valid manifest never reaches
check_schema, so it gets the full saving.best_matchis kept on purpose:Validator.validate()raises the first error, which is often a different one (see the issue).The metaschema check also runs in CI:
test_the_shipped_component_schema_is_a_valid_draft_7_schema.Resolves https://github.com/airbytehq/airbyte-internal-issues/issues/17933:
Close on merge: yes, internally filed, no customer to confirm with.
Part of https://github.com/airbytehq/airbyte-internal-issues/issues/17920. Requested by Patrick Nilan (Patrick Nilan (@pnilan)).
Timing
I timed validation directly. Each manifest is resolved with
ManifestReferenceResolverandManifestComponentTransformer, the best of 3 runs is kept, and the comparison is oldvalidate()vs newbest_match(iter_errors()). Setup: jsonschema 4.25.1, the 516manifest.yamlfiles underairbytehq/airbyte@79bef47d, and a dev VM.validate()best_match(validator.iter_errors())Draft7Validator.check_schema(component_schema)alone (min of 5)All 516 manifests are valid, so none of them reaches the failure-path
check_schema. The outcome was identical for all 516. Absolute numbers on this VM are higher than the issue's 1-CPU container numbers (25 ms saving). The saved step is the same in both measurements. An invalid manifest still pays forcheck_schemaonce, as it did before.Test Coverage
test_the_shipped_component_schema_is_a_valid_draft_7_schema(test_declarative_component_schema_is_loadable.py): asserts thatvalidator_for(schema) is Draft7Validator, then runscheck_schema.test_invalid_manifest_raises_the_best_match_error_not_the_first(concurrent and legacy): with the shipped schema, the manifest has two errors. The first error fromiter_errorsis at$.streams[0](a guard assertion checks this), and the best match is$.streams[1].retriever.requester.http_method(enum). The test checks that the wrapper message is unchanged. It also checks that__cause__matches whatjsonschema.validateraises on the same manifest in message,json_path,schema_path,validatorandvalidator_value.test_building_a_source_does_not_check_the_component_schema(concurrent and legacy): patchesDraft7Validator.check_schemato raise, then builds a valid source.test_a_broken_component_schema_that_fails_the_manifest_raises_schema_error(concurrent and legacy):HttpRequester.http_methodgetsenum: "GET", so a valid manifest fails validation. Building the source raisesSchemaError.test_a_broken_component_schema_that_breaks_validation_raises_schema_error(concurrent and legacy):HttpRequester.pathgetstype: strng, soiter_errorsraisesUnknownType(a guard checks this). Building the source raisesSchemaError.Verified against unfixed code: both
does_not_checktests fail onmain, becausevalidate()callscheck_schema. The four broken-schema tests fail on this branch's first commit, which raisedValidationErrorandUnknownTypeinstead. The best-match tests and the metaschema test pass onmaintoo, which shows the error is the same as before. With the fix, all pass: 139 passed, 1 skipped across the three test files. On the first commit I also ranunit_tests/sources/declarative,unit_tests/legacyandunit_tests/connector_builder(2547 passed, 1 skipped). Ruff and mypy pass on the changed source files.Risk
SchemaError, becausecheck_schemaruns before any validation error or exception is raised. Only a CDK change can break the schema, since it ships inside the CDK wheel. The metaschema test catches that before release.ValidateAdheresToSchemaandschema_helpersare intentionally unchanged, because their schemas come from the manifest or the connector.Link to Devin session: https://app.devin.ai/sessions/22162a3a9629407c95ac5ff107c3f0af
Open in Devin Desktop: https://app.devin.ai/desktop/session/22162a3a9629407c95ac5ff107c3f0af?variant=devin