Skip to content

Commit 05f4db7

Browse files
committed
Delete code from another branch
1 parent 342375c commit 05f4db7

File tree

3 files changed

+0
-279
lines changed

3 files changed

+0
-279
lines changed

unit_tests/sources/declarative/parsers/test_model_to_component_factory.py

Lines changed: 0 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@
142142
from airbyte_cdk.sources.declarative.transformations import AddFields, RemoveFields
143143
from airbyte_cdk.sources.declarative.transformations.add_fields import AddedFieldDefinition
144144
from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource
145-
from airbyte_cdk.sources.streams.call_rate import MovingWindowCallRatePolicy
146145
from airbyte_cdk.sources.streams.concurrent.clamping import (
147146
ClampingEndProvider,
148147
DayClampingStrategy,
@@ -3685,161 +3684,3 @@ def test_create_async_retriever():
36853684
assert isinstance(selector, RecordSelector)
36863685
assert isinstance(extractor, DpathExtractor)
36873686
assert extractor.field_path == ["data"]
3688-
3689-
3690-
def test_api_budget():
3691-
manifest = {
3692-
"type": "DeclarativeSource",
3693-
"api_budget": {
3694-
"type": "HTTPAPIBudget",
3695-
"ratelimit_reset_header": "X-RateLimit-Reset",
3696-
"ratelimit_remaining_header": "X-RateLimit-Remaining",
3697-
"status_codes_for_ratelimit_hit": [429, 503],
3698-
"policies": [
3699-
{
3700-
"type": "MovingWindowCallRatePolicy",
3701-
"rates": [
3702-
{
3703-
"type": "Rate",
3704-
"limit": 3,
3705-
"interval": "PT0.1S", # 0.1 seconds
3706-
}
3707-
],
3708-
"matchers": [
3709-
{
3710-
"type": "HttpRequestRegexMatcher",
3711-
"method": "GET",
3712-
"url_base": "https://api.sendgrid.com",
3713-
"url_path_pattern": "/v3/marketing/lists",
3714-
}
3715-
],
3716-
}
3717-
],
3718-
},
3719-
"my_requester": {
3720-
"type": "HttpRequester",
3721-
"path": "/v3/marketing/lists",
3722-
"url_base": "https://api.sendgrid.com",
3723-
"http_method": "GET",
3724-
"authenticator": {
3725-
"type": "BasicHttpAuthenticator",
3726-
"username": "admin",
3727-
"password": "{{ config['password'] }}",
3728-
},
3729-
},
3730-
}
3731-
3732-
config = {
3733-
"password": "verysecrettoken",
3734-
}
3735-
3736-
factory = ModelToComponentFactory()
3737-
if "api_budget" in manifest:
3738-
factory.set_api_budget(manifest["api_budget"], config)
3739-
3740-
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
3741-
HttpRequester as HttpRequesterModel,
3742-
)
3743-
3744-
requester_definition = manifest["my_requester"]
3745-
assert requester_definition["type"] == "HttpRequester"
3746-
3747-
http_requester = factory.create_component(
3748-
model_type=HttpRequesterModel,
3749-
component_definition=requester_definition,
3750-
config=config,
3751-
name="lists_stream",
3752-
decoder=None,
3753-
)
3754-
3755-
assert http_requester.api_budget is not None
3756-
assert http_requester.api_budget.ratelimit_reset_header == "X-RateLimit-Reset"
3757-
assert http_requester.api_budget.status_codes_for_ratelimit_hit == [429, 503]
3758-
assert len(http_requester.api_budget.policies) == 1
3759-
3760-
# The single policy is a MovingWindowCallRatePolicy
3761-
policy = http_requester.api_budget.policies[0]
3762-
assert isinstance(policy, MovingWindowCallRatePolicy)
3763-
assert policy._bucket.rates[0].limit == 3
3764-
# The 0.1s from 'PT0.1S' is stored in ms by PyRateLimiter internally
3765-
# but here just check that the limit and interval exist
3766-
assert policy._bucket.rates[0].interval == 100 # 100 ms
3767-
3768-
3769-
def test_api_budget_fixed_window_policy():
3770-
manifest = {
3771-
"type": "DeclarativeSource",
3772-
# Root-level api_budget referencing a FixedWindowCallRatePolicy
3773-
"api_budget": {
3774-
"type": "APIBudget",
3775-
"maximum_attempts_to_acquire": 9999,
3776-
"policies": [
3777-
{
3778-
"type": "FixedWindowCallRatePolicy",
3779-
"next_reset_ts": "2025-01-01T00:00:00Z",
3780-
"period": "PT1M", # 1 minute
3781-
"call_limit": 10,
3782-
"matchers": [
3783-
{
3784-
"type": "HttpRequestRegexMatcher",
3785-
"method": "GET",
3786-
"url_base": "https://example.org",
3787-
"url_path_pattern": "/v2/data",
3788-
}
3789-
],
3790-
}
3791-
],
3792-
},
3793-
# We'll define a single HttpRequester that references that base
3794-
"my_requester": {
3795-
"type": "HttpRequester",
3796-
"path": "/v2/data",
3797-
"url_base": "https://example.org",
3798-
"http_method": "GET",
3799-
"authenticator": {"type": "NoAuth"},
3800-
},
3801-
}
3802-
3803-
config = {}
3804-
3805-
factory = ModelToComponentFactory()
3806-
if "api_budget" in manifest:
3807-
factory.set_api_budget(manifest["api_budget"], config)
3808-
3809-
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
3810-
HttpRequester as HttpRequesterModel,
3811-
)
3812-
3813-
requester_definition = manifest["my_requester"]
3814-
assert requester_definition["type"] == "HttpRequester"
3815-
http_requester = factory.create_component(
3816-
model_type=HttpRequesterModel,
3817-
component_definition=requester_definition,
3818-
config=config,
3819-
name="my_stream",
3820-
decoder=None,
3821-
)
3822-
3823-
assert http_requester.api_budget is not None
3824-
assert http_requester.api_budget.maximum_attempts_to_acquire == 9999
3825-
assert len(http_requester.api_budget.policies) == 1
3826-
3827-
from airbyte_cdk.sources.streams.call_rate import FixedWindowCallRatePolicy
3828-
3829-
policy = http_requester.api_budget.policies[0]
3830-
assert isinstance(policy, FixedWindowCallRatePolicy)
3831-
assert policy._call_limit == 10
3832-
# The period is "PT1M" => 60 seconds
3833-
assert policy._offset.total_seconds() == 60
3834-
3835-
expected_reset_dt = datetime(2025, 1, 1, 0, 0, 0, tzinfo=timezone.utc)
3836-
assert policy._next_reset_ts == expected_reset_dt
3837-
3838-
assert len(policy._matchers) == 1
3839-
matcher = policy._matchers[0]
3840-
from airbyte_cdk.sources.streams.call_rate import HttpRequestRegexMatcher
3841-
3842-
assert isinstance(matcher, HttpRequestRegexMatcher)
3843-
assert matcher._method == "GET"
3844-
assert matcher._url_base == "https://example.org"
3845-
assert matcher._url_path_pattern.pattern == "/v2/data"

unit_tests/sources/declarative/requesters/test_http_requester.py

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@
22
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
33
#
44

5-
from datetime import timedelta
65
from typing import Any, Mapping, Optional
76
from unittest import mock
87
from unittest.mock import MagicMock
98
from urllib.parse import parse_qs, urlparse
109

1110
import pytest as pytest
1211
import requests
13-
import requests.sessions
1412
from requests import PreparedRequest
1513

1614
from airbyte_cdk.sources.declarative.auth.declarative_authenticator import DeclarativeAuthenticator
@@ -29,12 +27,6 @@
2927
InterpolatedRequestOptionsProvider,
3028
)
3129
from airbyte_cdk.sources.message import MessageRepository
32-
from airbyte_cdk.sources.streams.call_rate import (
33-
AbstractAPIBudget,
34-
HttpAPIBudget,
35-
MovingWindowCallRatePolicy,
36-
Rate,
37-
)
3830
from airbyte_cdk.sources.streams.http.error_handlers.response_models import ResponseAction
3931
from airbyte_cdk.sources.streams.http.exceptions import (
4032
RequestBodyException,
@@ -53,7 +45,6 @@ def factory(
5345
request_options_provider: Optional[InterpolatedRequestOptionsProvider] = None,
5446
authenticator: Optional[DeclarativeAuthenticator] = None,
5547
error_handler: Optional[ErrorHandler] = None,
56-
api_budget: Optional[HttpAPIBudget] = None,
5748
config: Optional[Config] = None,
5849
parameters: Mapping[str, Any] = None,
5950
disable_retries: bool = False,
@@ -70,7 +61,6 @@ def factory(
7061
http_method=http_method,
7162
request_options_provider=request_options_provider,
7263
error_handler=error_handler,
73-
api_budget=api_budget,
7464
disable_retries=disable_retries,
7565
message_repository=message_repository or MagicMock(),
7666
use_cache=use_cache,
@@ -944,25 +934,3 @@ def test_backoff_strategy_from_manifest_is_respected(http_requester_factory: Any
944934
http_requester._http_client._request_attempt_count.get(request_mock)
945935
== http_requester._http_client._max_retries + 1
946936
)
947-
948-
949-
def test_http_requester_with_mock_apibudget(http_requester_factory, monkeypatch):
950-
mock_budget = MagicMock(spec=HttpAPIBudget)
951-
952-
requester = http_requester_factory(
953-
url_base="https://example.com",
954-
path="test",
955-
api_budget=mock_budget,
956-
)
957-
958-
dummy_response = requests.Response()
959-
dummy_response.status_code = 200
960-
send_mock = MagicMock(return_value=dummy_response)
961-
monkeypatch.setattr(requests.Session, "send", send_mock)
962-
963-
response = requester.send_request()
964-
965-
assert send_mock.call_count == 1
966-
assert response.status_code == 200
967-
968-
assert mock_budget.acquire_call.call_count == 1

unit_tests/sources/streams/test_call_rate.py

Lines changed: 0 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
CallRateLimitHit,
1818
FixedWindowCallRatePolicy,
1919
HttpRequestMatcher,
20-
HttpRequestRegexMatcher,
2120
MovingWindowCallRatePolicy,
2221
Rate,
2322
UnlimitedCallRatePolicy,
@@ -358,90 +357,3 @@ def test_with_cache(self, mocker, requests_mock):
358357
assert next(records) == {"data": "some_data"}
359358

360359
assert MovingWindowCallRatePolicy.try_acquire.call_count == 1
361-
362-
363-
class TestHttpRequestRegexMatcher:
364-
"""
365-
Tests for the new regex-based logic:
366-
- Case-insensitive HTTP method matching
367-
- Optional url_base (scheme://netloc)
368-
- Regex-based path matching
369-
- Query params (must be present)
370-
- Headers (case-insensitive keys)
371-
"""
372-
373-
def test_case_insensitive_method(self):
374-
matcher = HttpRequestRegexMatcher(method="GET")
375-
376-
req_ok = Request("get", "https://example.com/test/path")
377-
req_wrong = Request("POST", "https://example.com/test/path")
378-
379-
assert matcher(req_ok)
380-
assert not matcher(req_wrong)
381-
382-
def test_url_base(self):
383-
matcher = HttpRequestRegexMatcher(url_base="https://example.com")
384-
385-
req_ok = Request("GET", "https://example.com/test/path?foo=bar")
386-
req_wrong = Request("GET", "https://another.com/test/path?foo=bar")
387-
388-
assert matcher(req_ok)
389-
assert not matcher(req_wrong)
390-
391-
def test_url_path_pattern(self):
392-
matcher = HttpRequestRegexMatcher(url_path_pattern=r"/test/")
393-
394-
req_ok = Request("GET", "https://example.com/test/something")
395-
req_wrong = Request("GET", "https://example.com/other/something")
396-
397-
assert matcher(req_ok)
398-
assert not matcher(req_wrong)
399-
400-
def test_query_params(self):
401-
matcher = HttpRequestRegexMatcher(params={"foo": "bar"})
402-
403-
req_ok = Request("GET", "https://example.com/api?foo=bar&extra=123")
404-
req_missing = Request("GET", "https://example.com/api?not_foo=bar")
405-
406-
assert matcher(req_ok)
407-
assert not matcher(req_missing)
408-
409-
def test_headers_case_insensitive(self):
410-
matcher = HttpRequestRegexMatcher(headers={"X-Custom-Header": "abc"})
411-
412-
req_ok = Request(
413-
"GET",
414-
"https://example.com/api?foo=bar",
415-
headers={"x-custom-header": "abc", "other": "123"},
416-
)
417-
req_wrong = Request("GET", "https://example.com/api", headers={"x-custom-header": "wrong"})
418-
419-
assert matcher(req_ok)
420-
assert not matcher(req_wrong)
421-
422-
def test_combined_criteria(self):
423-
matcher = HttpRequestRegexMatcher(
424-
method="GET",
425-
url_base="https://example.com",
426-
url_path_pattern=r"/test/",
427-
params={"foo": "bar"},
428-
headers={"X-Test": "123"},
429-
)
430-
431-
req_ok = Request("GET", "https://example.com/test/me?foo=bar", headers={"x-test": "123"})
432-
req_bad_base = Request(
433-
"GET", "https://other.com/test/me?foo=bar", headers={"x-test": "123"}
434-
)
435-
req_bad_path = Request("GET", "https://example.com/nope?foo=bar", headers={"x-test": "123"})
436-
req_bad_param = Request(
437-
"GET", "https://example.com/test/me?extra=xyz", headers={"x-test": "123"}
438-
)
439-
req_bad_header = Request(
440-
"GET", "https://example.com/test/me?foo=bar", headers={"some-other-header": "xyz"}
441-
)
442-
443-
assert matcher(req_ok)
444-
assert not matcher(req_bad_base)
445-
assert not matcher(req_bad_path)
446-
assert not matcher(req_bad_param)
447-
assert not matcher(req_bad_header)

0 commit comments

Comments
 (0)