Skip to content

feat(declarative): expose request_url to HttpResponseFilter error_message and predicate - #1229

Merged
Anatolii Yatsuk (tolik0) merged 4 commits into
mainfrom
tolik0/http-response-filter-request-url
Oct 14, 2026
Merged

Anatolii Yatsuk (tolik0) merged 4 commits into
mainfrom
tolik0/http-response-filter-request-url

Conversation

@tolik0

Copy link
Copy Markdown
Contributor

What

HttpResponseFilter can now use request_url in its error_message and predicate interpolation, alongside response and headers (and config for error_message).

request_url is the URL of the response: the final URL after any redirects, with the query string, fragment and userinfo (user:password@) removed. The path is kept as-is, so it should not be surfaced for APIs that put a credential in the path. It is an empty string when the response has no URL.

Why

A custom error_message replaces the default "Ignoring response for '' request to ''" log line on IGNORE, so a skip message today cannot say which partition was skipped. Connectors that need this (for example, source-github's stargazers skip after GitHub restricted listing stargazers to collaborators) currently need a CustomErrorHandler subclass just to put the repository in the message. With this change it becomes:

error_message: "Repository `{{ request_url | regex_search('/repos/([^/]+/[^/]+)/') }}`: ..."

The query string is dropped because some APIs authenticate with a query parameter, and an error message can end up in a user-facing failure.

Changes

  • http_response_filter.py: new _request_url(response) helper, passed as request_url to both the error_message and predicate evaluations.
  • declarative_component_schema.yaml: request_url added to both fields' interpolation_context, new examples, and a documented request_url entry in the interpolation variables.
  • declarative_component_schema.py: examples mirrored by hand. The generator needs dagger, and only examples changed.
  • Unit tests covering query strings, credentials, ports, fragments, IPv6 hosts, a response with no URL, and the predicate (including a 200 response that must not match the example predicate).

Compatibility

This is additive. Interpolation kwargs are local to these two evaluations, so a config key named request_url is still reached as config['request_url'], and no existing manifest changes behavior.

Testing

  • unit_tests/sources/declarative/requesters/error_handlers: 156 passed
  • ruff format --check, ruff check and mypy are clean on the changed files

🤖 Generated with Claude Code

…essage and predicate

A filter's error_message and predicate could only interpolate the config, the
parsed response body and the response headers. When the body does not identify
the resource (a bare 404, for example), the message cannot say which partition
was skipped, and setting error_message on an IGNORE filter also replaces the
CDK's own log line that carried the URL.

request_url is the URL of the response with the query string and any userinfo
removed, since some APIs authenticate through a query parameter and an error
message can reach a user-facing failure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s edge cases

- Say that the query string, fragment and userinfo are removed and the path is kept, in the schema and the HttpResponseFilter docstring.
- Match the YAML order of the predicate examples in the generated model.
- Test a port, an IPv6 host and a response without a URL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…esponses

HttpResponseFilter runs on every response, including successful pages, so a
predicate that checks only the URL matches every 200 of that stream. Pair the
example with an error-body condition and assert in the test that a successful
page does not match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ects

requests follows redirects, so `request_url` reflects the last hop rather
than the URL the requester built (for example, GitHub redirects renamed
repositories to /repositories/<id>/...).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

👋 Greetings, Airbyte Team Member!

Here are some helpful tips and reminders for your convenience.

💡 Show Tips and Tricks

Testing This CDK Version

You 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@tolik0/http-response-filter-request-url#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 tolik0/http-response-filter-request-url

PR Slash Commands

Airbyte Maintainers can execute the following slash commands on your PR:

  • /autofix - Fixes most formatting and linting issues
  • /poetry-lock - Updates poetry.lock file
  • /test - Runs connector tests with the updated CDK
  • /prerelease - Triggers a prerelease publish with default arguments
  • /poe build - Regenerate git-committed build artifacts, such as the pydantic models which are generated from the manifest JSON schema in YAML.
  • /poe <command> - Runs any poe command in the CDK environment
📚 Show Repo Guidance

Helpful Resources

📝 Edit this welcome message.

@github-actions

Copy link
Copy Markdown

PyTest Results (Fast)

5 754 tests  +6   5 723 ✅ +5   11m 55s ⏱️ -15s
    1 suites ±0      31 💤 +1 
    1 files   ±0       0 ❌ ±0 

Results for commit acb3e61. ± Comparison against base commit 2082c2d.

This pull request skips 1 test.
unit_tests.resources.source_pokeapi_w_components_py.integration_tests.test_airbyte_standards.TestSuiteSourcePokeAPI ‑ test_docker_image_spec_backward_compatibility

@github-actions

Copy link
Copy Markdown

PyTest Results (Full)

5 757 tests  +6   5 726 ✅ +5   16m 51s ⏱️ -9s
    1 suites ±0      31 💤 +1 
    1 files   ±0       0 ❌ ±0 

Results for commit acb3e61. ± Comparison against base commit 2082c2d.

This pull request skips 1 test.
unit_tests.resources.source_pokeapi_w_components_py.integration_tests.test_airbyte_standards.TestSuiteSourcePokeAPI ‑ test_docker_image_spec_backward_compatibility

@tolik0
Anatolii Yatsuk (tolik0) marked this pull request as ready for review October 14, 2026 14:40
@tolik0
Anatolii Yatsuk (tolik0) requested a review from a team as a code owner October 14, 2026 14:40
@tolik0
Anatolii Yatsuk (tolik0) marked this pull request as draft October 14, 2026 14:41
@tolik0
Anatolii Yatsuk (tolik0) marked this pull request as ready for review October 14, 2026 15:14
@tolik0

Anatolii Yatsuk (tolik0) commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor Author

/prerelease

Prerelease Job Info

This job triggers the publish workflow with default arguments to create a prerelease.

Prerelease job started... Check job output.

✅ Prerelease workflow triggered successfully.

View the publish workflow run: https://github.com/airbytehq/airbyte-python-cdk/actions/runs/38587689913

This branch was successfully deployed

2 active deployments
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