airbyte-cdk 6.33.1.dev1__py3-none-any.whl → 6.33.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@
3
3
  #
4
4
 
5
5
  from dataclasses import InitVar, dataclass, field
6
- from datetime import timedelta
6
+ from datetime import datetime, timedelta
7
7
  from typing import Any, List, Mapping, MutableMapping, Optional, Union
8
8
 
9
9
  from airbyte_cdk.sources.declarative.auth.declarative_authenticator import DeclarativeAuthenticator
@@ -232,8 +232,13 @@ class DeclarativeOauth2Authenticator(AbstractOauth2Authenticator, DeclarativeAut
232
232
  return self._refresh_request_headers.eval(self.config)
233
233
 
234
234
  def get_token_expiry_date(self) -> AirbyteDateTime:
235
+ if not self._has_access_token_been_initialized():
236
+ return AirbyteDateTime.from_datetime(datetime.min)
235
237
  return self._token_expiry_date # type: ignore # _token_expiry_date is an AirbyteDateTime. It is never None despite what mypy thinks
236
238
 
239
+ def _has_access_token_been_initialized(self) -> bool:
240
+ return self._access_token is not None
241
+
237
242
  def set_token_expiry_date(self, value: Union[str, int]) -> None:
238
243
  self._token_expiry_date = self._parse_token_expiration_date(value)
239
244
 
@@ -3,7 +3,7 @@
3
3
  #
4
4
 
5
5
  import logging
6
- from typing import Any, Generic, Iterator, List, Mapping, Optional, Tuple
6
+ from typing import Any, Generic, Iterator, List, Mapping, MutableMapping, Optional, Tuple
7
7
 
8
8
  from airbyte_cdk.models import (
9
9
  AirbyteCatalog,
@@ -224,6 +224,7 @@ class ConcurrentDeclarativeSource(ManifestDeclarativeSource, Generic[TState]):
224
224
  stream_state = self._connector_state_manager.get_stream_state(
225
225
  stream_name=declarative_stream.name, namespace=declarative_stream.namespace
226
226
  )
227
+ stream_state = self._migrate_state(declarative_stream, stream_state)
227
228
 
228
229
  retriever = self._get_retriever(declarative_stream, stream_state)
229
230
 
@@ -331,6 +332,8 @@ class ConcurrentDeclarativeSource(ManifestDeclarativeSource, Generic[TState]):
331
332
  stream_state = self._connector_state_manager.get_stream_state(
332
333
  stream_name=declarative_stream.name, namespace=declarative_stream.namespace
333
334
  )
335
+ stream_state = self._migrate_state(declarative_stream, stream_state)
336
+
334
337
  partition_router = declarative_stream.retriever.stream_slicer._partition_router
335
338
 
336
339
  perpartition_cursor = (
@@ -521,3 +524,14 @@ class ConcurrentDeclarativeSource(ManifestDeclarativeSource, Generic[TState]):
521
524
  if stream.stream.name not in concurrent_stream_names
522
525
  ]
523
526
  )
527
+
528
+ @staticmethod
529
+ def _migrate_state(
530
+ declarative_stream: DeclarativeStream, stream_state: MutableMapping[str, Any]
531
+ ) -> MutableMapping[str, Any]:
532
+ for state_migration in declarative_stream.state_migrations:
533
+ if state_migration.should_migrate(stream_state):
534
+ # The state variable is expected to be mutable but the migrate method returns an immutable mapping.
535
+ stream_state = dict(state_migration.migrate(stream_state))
536
+
537
+ return stream_state
@@ -40,12 +40,6 @@ properties:
40
40
  "$ref": "#/definitions/Spec"
41
41
  concurrency_level:
42
42
  "$ref": "#/definitions/ConcurrencyLevel"
43
- api_budget:
44
- title: API Budget
45
- description: Defines how many requests can be made to the API in a given time frame. This field accepts either a generic APIBudget or an HTTP-specific configuration (HTTPAPIBudget) to be applied across all streams.
46
- anyOf:
47
- - "$ref": "#/definitions/APIBudget"
48
- - "$ref": "#/definitions/HTTPAPIBudget"
49
43
  metadata:
50
44
  type: object
51
45
  description: For internal Airbyte use only - DO NOT modify manually. Used by consumers of declarative manifests for storing related metadata.
@@ -800,7 +794,7 @@ definitions:
800
794
  description: This option is used to adjust the upper and lower boundaries of each datetime window to beginning and end of the provided target period (day, week, month)
801
795
  type: object
802
796
  required:
803
- - target
797
+ - target
804
798
  properties:
805
799
  target:
806
800
  title: Target
@@ -1371,207 +1365,6 @@ definitions:
1371
1365
  $parameters:
1372
1366
  type: object
1373
1367
  additional_properties: true
1374
- APIBudget:
1375
- title: API Budget
1376
- description: >
1377
- A generic API budget configuration that defines the policies (rate limiting rules)
1378
- and the maximum number of attempts to acquire a call credit. This budget does not automatically
1379
- update itself based on HTTP response headers.
1380
- type: object
1381
- required:
1382
- - type
1383
- - policies
1384
- properties:
1385
- type:
1386
- type: string
1387
- enum: [APIBudget]
1388
- policies:
1389
- title: Policies
1390
- description: List of call rate policies that define how many calls are allowed.
1391
- type: array
1392
- items:
1393
- anyOf:
1394
- - "$ref": "#/definitions/FixedWindowCallRatePolicy"
1395
- - "$ref": "#/definitions/MovingWindowCallRatePolicy"
1396
- - "$ref": "#/definitions/UnlimitedCallRatePolicy"
1397
- maximum_attempts_to_acquire:
1398
- title: Maximum Attempts to Acquire
1399
- description: The maximum number of attempts to acquire a call before giving up.
1400
- type: integer
1401
- default: 100000
1402
- additionalProperties: true
1403
- HTTPAPIBudget:
1404
- title: HTTP API Budget
1405
- description: >
1406
- An HTTP-specific API budget that extends APIBudget by updating rate limiting information based
1407
- on HTTP response headers. It extracts available calls and the next reset timestamp from the HTTP responses.
1408
- type: object
1409
- required:
1410
- - type
1411
- - policies
1412
- properties:
1413
- type:
1414
- type: string
1415
- enum: [HTTPAPIBudget]
1416
- policies:
1417
- title: Policies
1418
- description: List of call rate policies that define how many calls are allowed.
1419
- type: array
1420
- items:
1421
- anyOf:
1422
- - "$ref": "#/definitions/FixedWindowCallRatePolicy"
1423
- - "$ref": "#/definitions/MovingWindowCallRatePolicy"
1424
- - "$ref": "#/definitions/UnlimitedCallRatePolicy"
1425
- ratelimit_reset_header:
1426
- title: Rate Limit Reset Header
1427
- description: The HTTP response header name that indicates when the rate limit resets.
1428
- type: string
1429
- default: "ratelimit-reset"
1430
- ratelimit_remaining_header:
1431
- title: Rate Limit Remaining Header
1432
- description: The HTTP response header name that indicates the number of remaining allowed calls.
1433
- type: string
1434
- default: "ratelimit-remaining"
1435
- status_codes_for_ratelimit_hit:
1436
- title: Status Codes for Rate Limit Hit
1437
- description: List of HTTP status codes that indicate a rate limit has been hit.
1438
- type: array
1439
- items:
1440
- type: integer
1441
- default: [429]
1442
- maximum_attempts_to_acquire:
1443
- title: Maximum Attempts to Acquire
1444
- description: The maximum number of attempts to acquire a call before giving up.
1445
- type: integer
1446
- default: 100000
1447
- additionalProperties: true
1448
- FixedWindowCallRatePolicy:
1449
- title: Fixed Window Call Rate Policy
1450
- description: A policy that allows a fixed number of calls within a specific time window.
1451
- type: object
1452
- required:
1453
- - type
1454
- - next_reset_ts
1455
- - period
1456
- - call_limit
1457
- - matchers
1458
- properties:
1459
- type:
1460
- type: string
1461
- enum: [FixedWindowCallRatePolicy]
1462
- next_reset_ts:
1463
- title: Next Reset Timestamp
1464
- description: The timestamp when the rate limit will reset.
1465
- type: string
1466
- format: date-time
1467
- period:
1468
- title: Period
1469
- description: The time interval for the rate limit window.
1470
- type: string
1471
- format: duration
1472
- call_limit:
1473
- title: Call Limit
1474
- description: The maximum number of calls allowed within the period.
1475
- type: integer
1476
- matchers:
1477
- title: Matchers
1478
- description: List of matchers that define which requests this policy applies to.
1479
- type: array
1480
- items:
1481
- "$ref": "#/definitions/HttpRequestRegexMatcher"
1482
- additionalProperties: true
1483
- MovingWindowCallRatePolicy:
1484
- title: Moving Window Call Rate Policy
1485
- description: A policy that allows a fixed number of calls within a moving time window.
1486
- type: object
1487
- required:
1488
- - type
1489
- - rates
1490
- - matchers
1491
- properties:
1492
- type:
1493
- type: string
1494
- enum: [MovingWindowCallRatePolicy]
1495
- rates:
1496
- title: Rates
1497
- description: List of rates that define the call limits for different time intervals.
1498
- type: array
1499
- items:
1500
- "$ref": "#/definitions/Rate"
1501
- matchers:
1502
- title: Matchers
1503
- description: List of matchers that define which requests this policy applies to.
1504
- type: array
1505
- items:
1506
- "$ref": "#/definitions/HttpRequestRegexMatcher"
1507
- additionalProperties: true
1508
- UnlimitedCallRatePolicy:
1509
- title: Unlimited Call Rate Policy
1510
- description: A policy that allows unlimited calls for specific requests.
1511
- type: object
1512
- required:
1513
- - type
1514
- - matchers
1515
- properties:
1516
- type:
1517
- type: string
1518
- enum: [UnlimitedCallRatePolicy]
1519
- matchers:
1520
- title: Matchers
1521
- description: List of matchers that define which requests this policy applies to.
1522
- type: array
1523
- items:
1524
- "$ref": "#/definitions/HttpRequestRegexMatcher"
1525
- additionalProperties: true
1526
- Rate:
1527
- title: Rate
1528
- description: Defines a rate limit with a specific number of calls allowed within a time interval.
1529
- type: object
1530
- required:
1531
- - limit
1532
- - interval
1533
- properties:
1534
- limit:
1535
- title: Limit
1536
- description: The maximum number of calls allowed within the interval.
1537
- type: integer
1538
- interval:
1539
- title: Interval
1540
- description: The time interval for the rate limit.
1541
- type: string
1542
- format: duration
1543
- additionalProperties: true
1544
- HttpRequestRegexMatcher:
1545
- title: HTTP Request Matcher
1546
- description: >
1547
- Matches HTTP requests based on method, base URL, URL path pattern, query parameters, and headers.
1548
- Use `url_base` to specify the scheme and host (without trailing slash) and
1549
- `url_path_pattern` to apply a regex to the request path.
1550
- type: object
1551
- properties:
1552
- method:
1553
- title: Method
1554
- description: The HTTP method to match (e.g., GET, POST).
1555
- type: string
1556
- url_base:
1557
- title: URL Base
1558
- description: The base URL (scheme and host, e.g. "https://api.example.com") to match.
1559
- type: string
1560
- url_path_pattern:
1561
- title: URL Path Pattern
1562
- description: A regular expression pattern to match the URL path.
1563
- type: string
1564
- params:
1565
- title: Parameters
1566
- description: The query parameters to match.
1567
- type: object
1568
- additionalProperties: true
1569
- headers:
1570
- title: Headers
1571
- description: The headers to match.
1572
- type: object
1573
- additionalProperties: true
1574
- additionalProperties: true
1575
1368
  DefaultErrorHandler:
1576
1369
  title: Default Error Handler
1577
1370
  description: Component defining how to handle errors. Default behavior includes only retrying server errors (HTTP 5XX) and too many requests (HTTP 429) with an exponential backoff.
@@ -137,10 +137,6 @@ class ManifestDeclarativeSource(DeclarativeSource):
137
137
  self._source_config, config
138
138
  )
139
139
 
140
- api_budget_model = self._source_config.get("api_budget")
141
- if api_budget_model:
142
- self._constructor.set_api_budget(api_budget_model, config)
143
-
144
140
  source_streams = [
145
141
  self._constructor.create_component(
146
142
  DeclarativeStreamModel,
@@ -3,7 +3,6 @@
3
3
 
4
4
  from __future__ import annotations
5
5
 
6
- from datetime import datetime, timedelta
7
6
  from enum import Enum
8
7
  from typing import Any, Dict, List, Literal, Optional, Union
9
8
 
@@ -643,45 +642,6 @@ class OAuthAuthenticator(BaseModel):
643
642
  parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
644
643
 
645
644
 
646
- class Rate(BaseModel):
647
- class Config:
648
- extra = Extra.allow
649
-
650
- limit: int = Field(
651
- ...,
652
- description="The maximum number of calls allowed within the interval.",
653
- title="Limit",
654
- )
655
- interval: timedelta = Field(
656
- ..., description="The time interval for the rate limit.", title="Interval"
657
- )
658
-
659
-
660
- class HttpRequestRegexMatcher(BaseModel):
661
- class Config:
662
- extra = Extra.allow
663
-
664
- method: Optional[str] = Field(
665
- None, description="The HTTP method to match (e.g., GET, POST).", title="Method"
666
- )
667
- url_base: Optional[str] = Field(
668
- None,
669
- description='The base URL (scheme and host, e.g. "https://api.example.com") to match.',
670
- title="URL Base",
671
- )
672
- url_path_pattern: Optional[str] = Field(
673
- None,
674
- description="A regular expression pattern to match the URL path.",
675
- title="URL Path Pattern",
676
- )
677
- params: Optional[Dict[str, Any]] = Field(
678
- None, description="The query parameters to match.", title="Parameters"
679
- )
680
- headers: Optional[Dict[str, Any]] = Field(
681
- None, description="The headers to match.", title="Headers"
682
- )
683
-
684
-
685
645
  class DpathExtractor(BaseModel):
686
646
  type: Literal["DpathExtractor"]
687
647
  field_path: List[str] = Field(
@@ -1624,60 +1584,6 @@ class DatetimeBasedCursor(BaseModel):
1624
1584
  parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
1625
1585
 
1626
1586
 
1627
- class FixedWindowCallRatePolicy(BaseModel):
1628
- class Config:
1629
- extra = Extra.allow
1630
-
1631
- type: Literal["FixedWindowCallRatePolicy"]
1632
- next_reset_ts: datetime = Field(
1633
- ...,
1634
- description="The timestamp when the rate limit will reset.",
1635
- title="Next Reset Timestamp",
1636
- )
1637
- period: timedelta = Field(
1638
- ..., description="The time interval for the rate limit window.", title="Period"
1639
- )
1640
- call_limit: int = Field(
1641
- ...,
1642
- description="The maximum number of calls allowed within the period.",
1643
- title="Call Limit",
1644
- )
1645
- matchers: List[HttpRequestRegexMatcher] = Field(
1646
- ...,
1647
- description="List of matchers that define which requests this policy applies to.",
1648
- title="Matchers",
1649
- )
1650
-
1651
-
1652
- class MovingWindowCallRatePolicy(BaseModel):
1653
- class Config:
1654
- extra = Extra.allow
1655
-
1656
- type: Literal["MovingWindowCallRatePolicy"]
1657
- rates: List[Rate] = Field(
1658
- ...,
1659
- description="List of rates that define the call limits for different time intervals.",
1660
- title="Rates",
1661
- )
1662
- matchers: List[HttpRequestRegexMatcher] = Field(
1663
- ...,
1664
- description="List of matchers that define which requests this policy applies to.",
1665
- title="Matchers",
1666
- )
1667
-
1668
-
1669
- class UnlimitedCallRatePolicy(BaseModel):
1670
- class Config:
1671
- extra = Extra.allow
1672
-
1673
- type: Literal["UnlimitedCallRatePolicy"]
1674
- matchers: List[HttpRequestRegexMatcher] = Field(
1675
- ...,
1676
- description="List of matchers that define which requests this policy applies to.",
1677
- title="Matchers",
1678
- )
1679
-
1680
-
1681
1587
  class DefaultErrorHandler(BaseModel):
1682
1588
  type: Literal["DefaultErrorHandler"]
1683
1589
  backoff_strategies: Optional[
@@ -1809,67 +1715,6 @@ class CompositeErrorHandler(BaseModel):
1809
1715
  parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
1810
1716
 
1811
1717
 
1812
- class APIBudget(BaseModel):
1813
- class Config:
1814
- extra = Extra.allow
1815
-
1816
- type: Literal["APIBudget"]
1817
- policies: List[
1818
- Union[
1819
- FixedWindowCallRatePolicy,
1820
- MovingWindowCallRatePolicy,
1821
- UnlimitedCallRatePolicy,
1822
- ]
1823
- ] = Field(
1824
- ...,
1825
- description="List of call rate policies that define how many calls are allowed.",
1826
- title="Policies",
1827
- )
1828
- maximum_attempts_to_acquire: Optional[int] = Field(
1829
- 100000,
1830
- description="The maximum number of attempts to acquire a call before giving up.",
1831
- title="Maximum Attempts to Acquire",
1832
- )
1833
-
1834
-
1835
- class HTTPAPIBudget(BaseModel):
1836
- class Config:
1837
- extra = Extra.allow
1838
-
1839
- type: Literal["HTTPAPIBudget"]
1840
- policies: List[
1841
- Union[
1842
- FixedWindowCallRatePolicy,
1843
- MovingWindowCallRatePolicy,
1844
- UnlimitedCallRatePolicy,
1845
- ]
1846
- ] = Field(
1847
- ...,
1848
- description="List of call rate policies that define how many calls are allowed.",
1849
- title="Policies",
1850
- )
1851
- ratelimit_reset_header: Optional[str] = Field(
1852
- "ratelimit-reset",
1853
- description="The HTTP response header name that indicates when the rate limit resets.",
1854
- title="Rate Limit Reset Header",
1855
- )
1856
- ratelimit_remaining_header: Optional[str] = Field(
1857
- "ratelimit-remaining",
1858
- description="The HTTP response header name that indicates the number of remaining allowed calls.",
1859
- title="Rate Limit Remaining Header",
1860
- )
1861
- status_codes_for_ratelimit_hit: Optional[List[int]] = Field(
1862
- [429],
1863
- description="List of HTTP status codes that indicate a rate limit has been hit.",
1864
- title="Status Codes for Rate Limit Hit",
1865
- )
1866
- maximum_attempts_to_acquire: Optional[int] = Field(
1867
- 100000,
1868
- description="The maximum number of attempts to acquire a call before giving up.",
1869
- title="Maximum Attempts to Acquire",
1870
- )
1871
-
1872
-
1873
1718
  class ZipfileDecoder(BaseModel):
1874
1719
  class Config:
1875
1720
  extra = Extra.allow
@@ -1903,11 +1748,6 @@ class DeclarativeSource1(BaseModel):
1903
1748
  definitions: Optional[Dict[str, Any]] = None
1904
1749
  spec: Optional[Spec] = None
1905
1750
  concurrency_level: Optional[ConcurrencyLevel] = None
1906
- api_budget: Optional[Union[APIBudget, HTTPAPIBudget]] = Field(
1907
- None,
1908
- description="Defines how many requests can be made to the API in a given time frame. This field accepts either a generic APIBudget or an HTTP-specific configuration (HTTPAPIBudget) to be applied across all streams.",
1909
- title="API Budget",
1910
- )
1911
1751
  metadata: Optional[Dict[str, Any]] = Field(
1912
1752
  None,
1913
1753
  description="For internal Airbyte use only - DO NOT modify manually. Used by consumers of declarative manifests for storing related metadata.",
@@ -1934,11 +1774,6 @@ class DeclarativeSource2(BaseModel):
1934
1774
  definitions: Optional[Dict[str, Any]] = None
1935
1775
  spec: Optional[Spec] = None
1936
1776
  concurrency_level: Optional[ConcurrencyLevel] = None
1937
- api_budget: Optional[Union[APIBudget, HTTPAPIBudget]] = Field(
1938
- None,
1939
- description="Defines how many requests can be made to the API in a given time frame. This field accepts either a generic APIBudget or an HTTP-specific configuration (HTTPAPIBudget) to be applied across all streams.",
1940
- title="API Budget",
1941
- )
1942
1777
  metadata: Optional[Dict[str, Any]] = Field(
1943
1778
  None,
1944
1779
  description="For internal Airbyte use only - DO NOT modify manually. Used by consumers of declarative manifests for storing related metadata.",
@@ -112,9 +112,6 @@ from airbyte_cdk.sources.declarative.models.declarative_component_schema import
112
112
  from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
113
113
  AddFields as AddFieldsModel,
114
114
  )
115
- from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
116
- APIBudget as APIBudgetModel,
117
- )
118
115
  from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
119
116
  ApiKeyAuthenticator as ApiKeyAuthenticatorModel,
120
117
  )
@@ -229,9 +226,6 @@ from airbyte_cdk.sources.declarative.models.declarative_component_schema import
229
226
  from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
230
227
  ExponentialBackoffStrategy as ExponentialBackoffStrategyModel,
231
228
  )
232
- from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
233
- FixedWindowCallRatePolicy as FixedWindowCallRatePolicyModel,
234
- )
235
229
  from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
236
230
  FlattenFields as FlattenFieldsModel,
237
231
  )
@@ -241,18 +235,12 @@ from airbyte_cdk.sources.declarative.models.declarative_component_schema import
241
235
  from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
242
236
  GzipParser as GzipParserModel,
243
237
  )
244
- from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
245
- HTTPAPIBudget as HTTPAPIBudgetModel,
246
- )
247
238
  from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
248
239
  HttpComponentsResolver as HttpComponentsResolverModel,
249
240
  )
250
241
  from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
251
242
  HttpRequester as HttpRequesterModel,
252
243
  )
253
- from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
254
- HttpRequestRegexMatcher as HttpRequestRegexMatcherModel,
255
- )
256
244
  from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
257
245
  HttpResponseFilter as HttpResponseFilterModel,
258
246
  )
@@ -307,9 +295,6 @@ from airbyte_cdk.sources.declarative.models.declarative_component_schema import
307
295
  from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
308
296
  MinMaxDatetime as MinMaxDatetimeModel,
309
297
  )
310
- from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
311
- MovingWindowCallRatePolicy as MovingWindowCallRatePolicyModel,
312
- )
313
298
  from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
314
299
  NoAuth as NoAuthModel,
315
300
  )
@@ -328,9 +313,6 @@ from airbyte_cdk.sources.declarative.models.declarative_component_schema import
328
313
  from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
329
314
  ParentStreamConfig as ParentStreamConfigModel,
330
315
  )
331
- from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
332
- Rate as RateModel,
333
- )
334
316
  from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
335
317
  RecordFilter as RecordFilterModel,
336
318
  )
@@ -374,9 +356,6 @@ from airbyte_cdk.sources.declarative.models.declarative_component_schema import
374
356
  from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
375
357
  TypesMap as TypesMapModel,
376
358
  )
377
- from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
378
- UnlimitedCallRatePolicy as UnlimitedCallRatePolicyModel,
379
- )
380
359
  from airbyte_cdk.sources.declarative.models.declarative_component_schema import ValueType
381
360
  from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
382
361
  WaitTimeFromHeader as WaitTimeFromHeaderModel,
@@ -490,15 +469,6 @@ from airbyte_cdk.sources.message import (
490
469
  MessageRepository,
491
470
  NoopMessageRepository,
492
471
  )
493
- from airbyte_cdk.sources.streams.call_rate import (
494
- APIBudget,
495
- FixedWindowCallRatePolicy,
496
- HttpAPIBudget,
497
- HttpRequestRegexMatcher,
498
- MovingWindowCallRatePolicy,
499
- Rate,
500
- UnlimitedCallRatePolicy,
501
- )
502
472
  from airbyte_cdk.sources.streams.concurrent.clamping import (
503
473
  ClampingEndProvider,
504
474
  ClampingStrategy,
@@ -550,7 +520,6 @@ class ModelToComponentFactory:
550
520
  self._evaluate_log_level(emit_connector_builder_messages)
551
521
  )
552
522
  self._connector_state_manager = connector_state_manager or ConnectorStateManager()
553
- self._api_budget: Optional[Union[APIBudget, HttpAPIBudget]] = None
554
523
 
555
524
  def _init_mappings(self) -> None:
556
525
  self.PYDANTIC_MODEL_TO_CONSTRUCTOR: Mapping[Type[BaseModel], Callable[..., Any]] = {
@@ -638,13 +607,6 @@ class ModelToComponentFactory:
638
607
  StreamConfigModel: self.create_stream_config,
639
608
  ComponentMappingDefinitionModel: self.create_components_mapping_definition,
640
609
  ZipfileDecoderModel: self.create_zipfile_decoder,
641
- APIBudgetModel: self.create_api_budget,
642
- HTTPAPIBudgetModel: self.create_http_api_budget,
643
- FixedWindowCallRatePolicyModel: self.create_fixed_window_call_rate_policy,
644
- MovingWindowCallRatePolicyModel: self.create_moving_window_call_rate_policy,
645
- UnlimitedCallRatePolicyModel: self.create_unlimited_call_rate_policy,
646
- RateModel: self.create_rate,
647
- HttpRequestRegexMatcherModel: self.create_http_request_matcher,
648
610
  }
649
611
 
650
612
  # Needed for the case where we need to perform a second parse on the fields of a custom component
@@ -972,6 +934,17 @@ class ModelToComponentFactory:
972
934
  parameters={},
973
935
  )
974
936
 
937
+ @staticmethod
938
+ def apply_stream_state_migrations(
939
+ stream_state_migrations: List[Any] | None, stream_state: MutableMapping[str, Any]
940
+ ) -> MutableMapping[str, Any]:
941
+ if stream_state_migrations:
942
+ for state_migration in stream_state_migrations:
943
+ if state_migration.should_migrate(stream_state):
944
+ # The state variable is expected to be mutable but the migrate method returns an immutable mapping.
945
+ stream_state = dict(state_migration.migrate(stream_state))
946
+ return stream_state
947
+
975
948
  def create_concurrent_cursor_from_datetime_based_cursor(
976
949
  self,
977
950
  model_type: Type[BaseModel],
@@ -981,6 +954,7 @@ class ModelToComponentFactory:
981
954
  config: Config,
982
955
  message_repository: Optional[MessageRepository] = None,
983
956
  runtime_lookback_window: Optional[datetime.timedelta] = None,
957
+ stream_state_migrations: Optional[List[Any]] = None,
984
958
  **kwargs: Any,
985
959
  ) -> ConcurrentCursor:
986
960
  # Per-partition incremental streams can dynamically create child cursors which will pass their current
@@ -991,6 +965,7 @@ class ModelToComponentFactory:
991
965
  if "stream_state" not in kwargs
992
966
  else kwargs["stream_state"]
993
967
  )
968
+ stream_state = self.apply_stream_state_migrations(stream_state_migrations, stream_state)
994
969
 
995
970
  component_type = component_definition.get("type")
996
971
  if component_definition.get("type") != model_type.__name__:
@@ -1226,6 +1201,7 @@ class ModelToComponentFactory:
1226
1201
  config: Config,
1227
1202
  stream_state: MutableMapping[str, Any],
1228
1203
  partition_router: PartitionRouter,
1204
+ stream_state_migrations: Optional[List[Any]] = None,
1229
1205
  **kwargs: Any,
1230
1206
  ) -> ConcurrentPerPartitionCursor:
1231
1207
  component_type = component_definition.get("type")
@@ -1274,8 +1250,10 @@ class ModelToComponentFactory:
1274
1250
  stream_namespace=stream_namespace,
1275
1251
  config=config,
1276
1252
  message_repository=NoopMessageRepository(),
1253
+ stream_state_migrations=stream_state_migrations,
1277
1254
  )
1278
1255
  )
1256
+ stream_state = self.apply_stream_state_migrations(stream_state_migrations, stream_state)
1279
1257
 
1280
1258
  # Return the concurrent cursor and state converter
1281
1259
  return ConcurrentPerPartitionCursor(
@@ -1784,6 +1762,7 @@ class ModelToComponentFactory:
1784
1762
  stream_name=model.name or "",
1785
1763
  stream_namespace=None,
1786
1764
  config=config or {},
1765
+ stream_state_migrations=model.state_migrations,
1787
1766
  )
1788
1767
  return (
1789
1768
  self._create_component_from_model(model=model.incremental_sync, config=config)
@@ -1940,8 +1919,6 @@ class ModelToComponentFactory:
1940
1919
  )
1941
1920
  )
1942
1921
 
1943
- api_budget = self._api_budget
1944
-
1945
1922
  request_options_provider = InterpolatedRequestOptionsProvider(
1946
1923
  request_body_data=model.request_body_data,
1947
1924
  request_body_json=model.request_body_json,
@@ -1962,7 +1939,6 @@ class ModelToComponentFactory:
1962
1939
  path=model.path,
1963
1940
  authenticator=authenticator,
1964
1941
  error_handler=error_handler,
1965
- api_budget=api_budget,
1966
1942
  http_method=HttpMethod[model.http_method.value],
1967
1943
  request_options_provider=request_options_provider,
1968
1944
  config=config,
@@ -2964,103 +2940,3 @@ class ModelToComponentFactory:
2964
2940
  return isinstance(parser.inner_parser, JsonParser)
2965
2941
  else:
2966
2942
  return False
2967
-
2968
- def create_api_budget(self, model: APIBudgetModel, config: Config, **kwargs: Any) -> APIBudget:
2969
- policies = [
2970
- self._create_component_from_model(model=policy, config=config)
2971
- for policy in model.policies
2972
- ]
2973
-
2974
- return APIBudget(
2975
- policies=policies,
2976
- maximum_attempts_to_acquire=model.maximum_attempts_to_acquire or 100000,
2977
- )
2978
-
2979
- def create_http_api_budget(
2980
- self, model: HTTPAPIBudgetModel, config: Config, **kwargs: Any
2981
- ) -> HttpAPIBudget:
2982
- policies = [
2983
- self._create_component_from_model(model=policy, config=config)
2984
- for policy in model.policies
2985
- ]
2986
-
2987
- return HttpAPIBudget(
2988
- policies=policies,
2989
- maximum_attempts_to_acquire=model.maximum_attempts_to_acquire or 100000,
2990
- ratelimit_reset_header=model.ratelimit_reset_header or "ratelimit-reset",
2991
- ratelimit_remaining_header=model.ratelimit_remaining_header or "ratelimit-remaining",
2992
- status_codes_for_ratelimit_hit=model.status_codes_for_ratelimit_hit or (429,),
2993
- )
2994
-
2995
- def create_fixed_window_call_rate_policy(
2996
- self, model: FixedWindowCallRatePolicyModel, config: Config, **kwargs: Any
2997
- ) -> FixedWindowCallRatePolicy:
2998
- matchers = [
2999
- self._create_component_from_model(model=matcher, config=config)
3000
- for matcher in model.matchers
3001
- ]
3002
- return FixedWindowCallRatePolicy(
3003
- next_reset_ts=model.next_reset_ts,
3004
- period=model.period,
3005
- call_limit=model.call_limit,
3006
- matchers=matchers,
3007
- )
3008
-
3009
- def create_moving_window_call_rate_policy(
3010
- self, model: MovingWindowCallRatePolicyModel, config: Config, **kwargs: Any
3011
- ) -> MovingWindowCallRatePolicy:
3012
- rates = [
3013
- self._create_component_from_model(model=rate, config=config) for rate in model.rates
3014
- ]
3015
- matchers = [
3016
- self._create_component_from_model(model=matcher, config=config)
3017
- for matcher in model.matchers
3018
- ]
3019
- return MovingWindowCallRatePolicy(
3020
- rates=rates,
3021
- matchers=matchers,
3022
- )
3023
-
3024
- def create_unlimited_call_rate_policy(
3025
- self, model: UnlimitedCallRatePolicyModel, config: Config, **kwargs: Any
3026
- ) -> UnlimitedCallRatePolicy:
3027
- matchers = [
3028
- self._create_component_from_model(model=matcher, config=config)
3029
- for matcher in model.matchers
3030
- ]
3031
-
3032
- return UnlimitedCallRatePolicy(
3033
- matchers=matchers,
3034
- )
3035
-
3036
- def create_rate(self, model: RateModel, config: Config, **kwargs: Any) -> Rate:
3037
- return Rate(
3038
- limit=model.limit,
3039
- interval=model.interval,
3040
- )
3041
-
3042
- def create_http_request_matcher(
3043
- self, model: HttpRequestRegexMatcherModel, config: Config, **kwargs: Any
3044
- ) -> HttpRequestRegexMatcher:
3045
- return HttpRequestRegexMatcher(
3046
- method=model.method,
3047
- url_base=model.url_base,
3048
- url_path_pattern=model.url_path_pattern,
3049
- params=model.params,
3050
- headers=model.headers,
3051
- )
3052
-
3053
- def set_api_budget(self, component_definition: ComponentDefinition, config: Config) -> None:
3054
- model_str = component_definition.get("type")
3055
- if model_str == "APIBudget":
3056
- # Annotate model_type as a type that is a subclass of BaseModel
3057
- model_type: Union[Type[APIBudgetModel], Type[HTTPAPIBudgetModel]] = APIBudgetModel
3058
- elif model_str == "HTTPAPIBudget":
3059
- model_type = HTTPAPIBudgetModel
3060
- else:
3061
- raise ValueError(f"Unknown API Budget type: {model_str}")
3062
-
3063
- # create_component expects a type[BaseModel] and returns an instance of that model.
3064
- self._api_budget = self.create_component(
3065
- model_type=model_type, component_definition=component_definition, config=config
3066
- )
@@ -22,7 +22,6 @@ from airbyte_cdk.sources.declarative.requesters.request_options.interpolated_req
22
22
  )
23
23
  from airbyte_cdk.sources.declarative.requesters.requester import HttpMethod, Requester
24
24
  from airbyte_cdk.sources.message import MessageRepository, NoopMessageRepository
25
- from airbyte_cdk.sources.streams.call_rate import APIBudget
26
25
  from airbyte_cdk.sources.streams.http import HttpClient
27
26
  from airbyte_cdk.sources.streams.http.error_handlers import ErrorHandler
28
27
  from airbyte_cdk.sources.types import Config, StreamSlice, StreamState
@@ -56,7 +55,6 @@ class HttpRequester(Requester):
56
55
  http_method: Union[str, HttpMethod] = HttpMethod.GET
57
56
  request_options_provider: Optional[InterpolatedRequestOptionsProvider] = None
58
57
  error_handler: Optional[ErrorHandler] = None
59
- api_budget: Optional[APIBudget] = None
60
58
  disable_retries: bool = False
61
59
  message_repository: MessageRepository = NoopMessageRepository()
62
60
  use_cache: bool = False
@@ -93,7 +91,6 @@ class HttpRequester(Requester):
93
91
  name=self.name,
94
92
  logger=self.logger,
95
93
  error_handler=self.error_handler,
96
- api_budget=self.api_budget,
97
94
  authenticator=self._authenticator,
98
95
  use_cache=self.use_cache,
99
96
  backoff_strategy=backoff_strategies,
@@ -6,12 +6,10 @@ import abc
6
6
  import dataclasses
7
7
  import datetime
8
8
  import logging
9
- import re
10
9
  import time
11
- from dataclasses import InitVar, dataclass, field
12
10
  from datetime import timedelta
13
11
  from threading import RLock
14
- from typing import TYPE_CHECKING, Any, Mapping, Optional, Union
12
+ from typing import TYPE_CHECKING, Any, Mapping, Optional
15
13
  from urllib import parse
16
14
 
17
15
  import requests
@@ -162,100 +160,6 @@ class HttpRequestMatcher(RequestMatcher):
162
160
  return True
163
161
 
164
162
 
165
- class HttpRequestRegexMatcher(RequestMatcher):
166
- """
167
- Extended RequestMatcher for HTTP requests that supports matching on:
168
- - HTTP method (case-insensitive)
169
- - URL base (scheme + netloc) optionally
170
- - URL path pattern (a regex applied to the path portion of the URL)
171
- - Query parameters (must be present)
172
- - Headers (header names compared case-insensitively)
173
- """
174
-
175
- def __init__(
176
- self,
177
- method: Optional[str] = None,
178
- url_base: Optional[str] = None,
179
- url_path_pattern: Optional[str] = None,
180
- params: Optional[Mapping[str, Any]] = None,
181
- headers: Optional[Mapping[str, Any]] = None,
182
- ):
183
- """
184
- :param method: HTTP method (e.g. "GET", "POST"); compared case-insensitively.
185
- :param url_base: Base URL (scheme://host) that must match.
186
- :param url_path_pattern: A regex pattern that will be applied to the path portion of the URL.
187
- :param params: Dictionary of query parameters that must be present in the request.
188
- :param headers: Dictionary of headers that must be present (header keys are compared case-insensitively).
189
- """
190
- self._method = method.upper() if method else None
191
-
192
- # Normalize the url_base if provided: remove trailing slash.
193
- self._url_base = url_base.rstrip("/") if url_base else None
194
-
195
- # Compile the URL path pattern if provided.
196
- self._url_path_pattern = re.compile(url_path_pattern) if url_path_pattern else None
197
-
198
- # Normalize query parameters to strings.
199
- self._params = {str(k): str(v) for k, v in (params or {}).items()}
200
-
201
- # Normalize header keys to lowercase.
202
- self._headers = {str(k).lower(): str(v) for k, v in (headers or {}).items()}
203
-
204
- @staticmethod
205
- def _match_dict(obj: Mapping[str, Any], pattern: Mapping[str, Any]) -> bool:
206
- """Check that every key/value in the pattern exists in the object."""
207
- return pattern.items() <= obj.items()
208
-
209
- def __call__(self, request: Any) -> bool:
210
- """
211
- :param request: A requests.Request or requests.PreparedRequest instance.
212
- :return: True if the request matches all provided criteria; False otherwise.
213
- """
214
- # Prepare the request (if needed) and extract the URL details.
215
- if isinstance(request, requests.Request):
216
- prepared_request = request.prepare()
217
- elif isinstance(request, requests.PreparedRequest):
218
- prepared_request = request
219
- else:
220
- return False
221
-
222
- # Check HTTP method.
223
- if self._method is not None and prepared_request.method is not None:
224
- if prepared_request.method.upper() != self._method:
225
- return False
226
-
227
- # Parse the URL.
228
- parsed_url = parse.urlsplit(prepared_request.url)
229
- # Reconstruct the base: scheme://netloc
230
- request_url_base = f"{str(parsed_url.scheme)}://{str(parsed_url.netloc)}"
231
- # The path (without query parameters)
232
- request_path = str(parsed_url.path).rstrip("/")
233
-
234
- # If a base URL is provided, check that it matches.
235
- if self._url_base is not None:
236
- if request_url_base != self._url_base:
237
- return False
238
-
239
- # If a URL path pattern is provided, ensure the path matches the regex.
240
- if self._url_path_pattern is not None:
241
- if not self._url_path_pattern.search(request_path):
242
- return False
243
-
244
- # Check query parameters.
245
- if self._params:
246
- query_params = dict(parse.parse_qsl(str(parsed_url.query)))
247
- if not self._match_dict(query_params, self._params):
248
- return False
249
-
250
- # Check headers (normalize keys to lower-case).
251
- if self._headers:
252
- req_headers = {k.lower(): v for k, v in prepared_request.headers.items()}
253
- if not self._match_dict(req_headers, self._headers):
254
- return False
255
-
256
- return True
257
-
258
-
259
163
  class BaseCallRatePolicy(AbstractCallRatePolicy, abc.ABC):
260
164
  def __init__(self, matchers: list[RequestMatcher]):
261
165
  self._matchers = matchers
@@ -495,17 +399,24 @@ class AbstractAPIBudget(abc.ABC):
495
399
  """
496
400
 
497
401
 
498
- @dataclass
499
402
  class APIBudget(AbstractAPIBudget):
500
- """
501
- Default APIBudget implementation.
502
- """
403
+ """Default APIBudget implementation"""
404
+
405
+ def __init__(
406
+ self, policies: list[AbstractCallRatePolicy], maximum_attempts_to_acquire: int = 100000
407
+ ) -> None:
408
+ """Constructor
409
+
410
+ :param policies: list of policies in this budget
411
+ :param maximum_attempts_to_acquire: number of attempts before throwing hit ratelimit exception, we put some big number here
412
+ to avoid situations when many threads compete with each other for a few lots over a significant amount of time
413
+ """
503
414
 
504
- policies: list[AbstractCallRatePolicy]
505
- maximum_attempts_to_acquire: int = 100000
415
+ self._policies = policies
416
+ self._maximum_attempts_to_acquire = maximum_attempts_to_acquire
506
417
 
507
418
  def get_matching_policy(self, request: Any) -> Optional[AbstractCallRatePolicy]:
508
- for policy in self.policies:
419
+ for policy in self._policies:
509
420
  if policy.matches(request):
510
421
  return policy
511
422
  return None
@@ -526,7 +437,7 @@ class APIBudget(AbstractAPIBudget):
526
437
  policy = self.get_matching_policy(request)
527
438
  if policy:
528
439
  self._do_acquire(request=request, policy=policy, block=block, timeout=timeout)
529
- elif self.policies:
440
+ elif self._policies:
530
441
  logger.info("no policies matched with requests, allow call by default")
531
442
 
532
443
  def update_from_response(self, request: Any, response: Any) -> None:
@@ -549,7 +460,7 @@ class APIBudget(AbstractAPIBudget):
549
460
  """
550
461
  last_exception = None
551
462
  # sometimes we spend all budget before a second attempt, so we have few more here
552
- for attempt in range(1, self.maximum_attempts_to_acquire):
463
+ for attempt in range(1, self._maximum_attempts_to_acquire):
553
464
  try:
554
465
  policy.try_acquire(request, weight=1)
555
466
  return
@@ -573,18 +484,31 @@ class APIBudget(AbstractAPIBudget):
573
484
 
574
485
  if last_exception:
575
486
  logger.info(
576
- "we used all %s attempts to acquire and failed", self.maximum_attempts_to_acquire
487
+ "we used all %s attempts to acquire and failed", self._maximum_attempts_to_acquire
577
488
  )
578
489
  raise last_exception
579
490
 
580
491
 
581
- @dataclass
582
492
  class HttpAPIBudget(APIBudget):
583
493
  """Implementation of AbstractAPIBudget for HTTP"""
584
494
 
585
- ratelimit_reset_header: str = "ratelimit-reset"
586
- ratelimit_remaining_header: str = "ratelimit-remaining"
587
- status_codes_for_ratelimit_hit: Union[tuple[int], list[int]] = (429,)
495
+ def __init__(
496
+ self,
497
+ ratelimit_reset_header: str = "ratelimit-reset",
498
+ ratelimit_remaining_header: str = "ratelimit-remaining",
499
+ status_codes_for_ratelimit_hit: tuple[int] = (429,),
500
+ **kwargs: Any,
501
+ ):
502
+ """Constructor
503
+
504
+ :param ratelimit_reset_header: name of the header that has a timestamp of the next reset of call budget
505
+ :param ratelimit_remaining_header: name of the header that has the number of calls left
506
+ :param status_codes_for_ratelimit_hit: list of HTTP status codes that signal about rate limit being hit
507
+ """
508
+ self._ratelimit_reset_header = ratelimit_reset_header
509
+ self._ratelimit_remaining_header = ratelimit_remaining_header
510
+ self._status_codes_for_ratelimit_hit = status_codes_for_ratelimit_hit
511
+ super().__init__(**kwargs)
588
512
 
589
513
  def update_from_response(self, request: Any, response: Any) -> None:
590
514
  policy = self.get_matching_policy(request)
@@ -599,17 +523,17 @@ class HttpAPIBudget(APIBudget):
599
523
  def get_reset_ts_from_response(
600
524
  self, response: requests.Response
601
525
  ) -> Optional[datetime.datetime]:
602
- if response.headers.get(self.ratelimit_reset_header):
526
+ if response.headers.get(self._ratelimit_reset_header):
603
527
  return datetime.datetime.fromtimestamp(
604
- int(response.headers[self.ratelimit_reset_header])
528
+ int(response.headers[self._ratelimit_reset_header])
605
529
  )
606
530
  return None
607
531
 
608
532
  def get_calls_left_from_response(self, response: requests.Response) -> Optional[int]:
609
- if response.headers.get(self.ratelimit_remaining_header):
610
- return int(response.headers[self.ratelimit_remaining_header])
533
+ if response.headers.get(self._ratelimit_remaining_header):
534
+ return int(response.headers[self._ratelimit_remaining_header])
611
535
 
612
- if response.status_code in self.status_codes_for_ratelimit_hit:
536
+ if response.status_code in self._status_codes_for_ratelimit_hit:
613
537
  return 0
614
538
 
615
539
  return None
@@ -261,6 +261,9 @@ class AbstractOauth2Authenticator(AuthBase):
261
261
 
262
262
  :return: expiration datetime
263
263
  """
264
+ if not value and not self.token_has_expired():
265
+ # No expiry token was provided but the previous one is not expired so it's fine
266
+ return self.get_token_expiry_date()
264
267
 
265
268
  if self.token_expiry_is_time_of_expiration:
266
269
  if not self.token_expiry_date_format:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: airbyte-cdk
3
- Version: 6.33.1.dev1
3
+ Version: 6.33.2
4
4
  Summary: A framework for writing Airbyte Connectors.
5
5
  Home-page: https://airbyte.com
6
6
  License: MIT
@@ -53,7 +53,7 @@ airbyte_cdk/sources/declarative/async_job/timer.py,sha256=Fb8P72CQ7jIzJyzMSSNuBf
53
53
  airbyte_cdk/sources/declarative/auth/__init__.py,sha256=e2CRrcBWGhz3sQu3Oh34d1riEIwXipGS8hrSB1pu0Oo,284
54
54
  airbyte_cdk/sources/declarative/auth/declarative_authenticator.py,sha256=nf-OmRUHYG4ORBwyb5CANzuHEssE-oNmL-Lccn41Td8,1099
55
55
  airbyte_cdk/sources/declarative/auth/jwt.py,sha256=SICqNsN2Cn_EgKadIgWuZpQxuMHyzrMZD_2-Uwy10rY,8539
56
- airbyte_cdk/sources/declarative/auth/oauth.py,sha256=fibXa-dqtM54jIUscWbz7DEA5uY6F2o1LfARjEeGRy0,13926
56
+ airbyte_cdk/sources/declarative/auth/oauth.py,sha256=SUfib1oSzlyRRnOSg8Bui73mfyrcyr9OssdchbKdu4s,14162
57
57
  airbyte_cdk/sources/declarative/auth/selective_authenticator.py,sha256=qGwC6YsCldr1bIeKG6Qo-A9a5cTdHw-vcOn3OtQrS4c,1540
58
58
  airbyte_cdk/sources/declarative/auth/token.py,sha256=2EnE78EhBOY9hbeZnQJ9AuFaM-G7dccU-oKo_LThRQk,11070
59
59
  airbyte_cdk/sources/declarative/auth/token_provider.py,sha256=9CuSsmOoHkvlc4k-oZ3Jx5luAgfTMm1I_5HOZxw7wMU,3075
@@ -63,11 +63,11 @@ airbyte_cdk/sources/declarative/checks/check_stream.py,sha256=dAA-UhmMj0WLXCkRQr
63
63
  airbyte_cdk/sources/declarative/checks/connection_checker.py,sha256=MBRJo6WJlZQHpIfOGaNOkkHUmgUl_4wDM6VPo41z5Ss,1383
64
64
  airbyte_cdk/sources/declarative/concurrency_level/__init__.py,sha256=5XUqrmlstYlMM0j6crktlKQwALek0uiz2D3WdM46MyA,191
65
65
  airbyte_cdk/sources/declarative/concurrency_level/concurrency_level.py,sha256=YIwCTCpOr_QSNW4ltQK0yUGWInI8PKNY216HOOegYLk,2101
66
- airbyte_cdk/sources/declarative/concurrent_declarative_source.py,sha256=7uqf_zQd2T08AYdMDJ80Zt0W1QHqZd-dvltXC-3g8W4,28136
66
+ airbyte_cdk/sources/declarative/concurrent_declarative_source.py,sha256=ThOqmaaqPykS2gTDKnlLSPy0p7djjV1Svazes58Rmic,28844
67
67
  airbyte_cdk/sources/declarative/datetime/__init__.py,sha256=l9LG7Qm6e5r_qgqfVKnx3mXYtg1I9MmMjomVIPfU4XA,177
68
68
  airbyte_cdk/sources/declarative/datetime/datetime_parser.py,sha256=SX9JjdesN1edN2WVUVMzU_ptqp2QB1OnsnjZ4mwcX7w,2579
69
69
  airbyte_cdk/sources/declarative/datetime/min_max_datetime.py,sha256=0BHBtDNQZfvwM45-tY5pNlTcKAFSGGNxemoi0Jic-0E,5785
70
- airbyte_cdk/sources/declarative/declarative_component_schema.yaml,sha256=_pL5eEPf9N7U5kyzfB6YJG2xUHAPNTrJSApLYlQS9vw,147556
70
+ airbyte_cdk/sources/declarative/declarative_component_schema.yaml,sha256=51R-WLE1Xhrk57DoiHFxWZSP8V9HtCEi1UE8_KtEOuM,140375
71
71
  airbyte_cdk/sources/declarative/declarative_source.py,sha256=nF7wBqFd3AQmEKAm4CnIo29CJoQL562cJGSCeL8U8bA,1531
72
72
  airbyte_cdk/sources/declarative/declarative_stream.py,sha256=venZjfpvtqr3oFSuvMBWtn4h9ayLhD4L65ACuXCDZ64,10445
73
73
  airbyte_cdk/sources/declarative/decoders/__init__.py,sha256=KSpQetKGqPCv-38QgcVJ5kzM5nzbFldTSsYDCS3Xf0Y,1035
@@ -104,18 +104,18 @@ airbyte_cdk/sources/declarative/interpolation/interpolated_string.py,sha256=LYEZ
104
104
  airbyte_cdk/sources/declarative/interpolation/interpolation.py,sha256=-V5UddGm69UKEB6o_O1EIES9kfY8FV_X4Ji8w1yOuSA,981
105
105
  airbyte_cdk/sources/declarative/interpolation/jinja.py,sha256=BtsY_jtT4MihFqeQgc05HXj3Ndt-e2ESQgGwbg3Sdxc,6430
106
106
  airbyte_cdk/sources/declarative/interpolation/macros.py,sha256=Y5AWYxbJTUtJ_Jm7DV9qrZDiymFR9LST7fBt4piT2-U,4585
107
- airbyte_cdk/sources/declarative/manifest_declarative_source.py,sha256=TN6GCgLXaWDONTaJwQ3A5ELqC-sxwKz-UYSraJYB-dI,17078
107
+ airbyte_cdk/sources/declarative/manifest_declarative_source.py,sha256=26qMXRugdPAd3zyYRH6YpNi--TorGZVOtxzY5O6muL0,16912
108
108
  airbyte_cdk/sources/declarative/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
109
109
  airbyte_cdk/sources/declarative/migrations/legacy_to_per_partition_state_migration.py,sha256=iemy3fKLczcU0-Aor7tx5jcT6DRedKMqyK7kCOp01hg,3924
110
110
  airbyte_cdk/sources/declarative/migrations/state_migration.py,sha256=KWPjealMLKSMtajXgkdGgKg7EmTLR-CqqD7UIh0-eDU,794
111
111
  airbyte_cdk/sources/declarative/models/__init__.py,sha256=nUFxNCiKeYRVXuZEKA7GD-lTHxsiKcQ8FitZjKhPIvE,100
112
- airbyte_cdk/sources/declarative/models/declarative_component_schema.py,sha256=4C2CQ3IkDI39X0Pkf5j-X5pfKUVTrfwjy6wAJoaI6cE,104148
112
+ airbyte_cdk/sources/declarative/models/declarative_component_schema.py,sha256=7qzq5ZV3V90uYRMa_-CGTbJ7aVv5jyPqGGjpJb9zdHk,98706
113
113
  airbyte_cdk/sources/declarative/parsers/__init__.py,sha256=ZnqYNxHsKCgO38IwB34RQyRMXTs4GTvlRi3ImKnIioo,61
114
114
  airbyte_cdk/sources/declarative/parsers/custom_code_compiler.py,sha256=958MMX6_ZOJUlDDdNr9Krosgi2bCKGx2Z765M2Woz18,5505
115
115
  airbyte_cdk/sources/declarative/parsers/custom_exceptions.py,sha256=Rir9_z3Kcd5Es0-LChrzk-0qubAsiK_RSEnLmK2OXm8,553
116
116
  airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py,sha256=CXwTfD3wSQq3okcqwigpprbHhSURUokh4GK2OmOyKC8,9132
117
117
  airbyte_cdk/sources/declarative/parsers/manifest_reference_resolver.py,sha256=IWUOdF03o-aQn0Occo1BJCxU0Pz-QILk5L67nzw2thw,6803
118
- airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py,sha256=xbGhVLZZGnXA2-W6ajv1v8pJl-L-5RdLcRQI77gF4CQ,134141
118
+ airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py,sha256=MuzhEy8ST0-VijWck1VEeO7NTFRW4BpJ9LafFHxOTwo,129444
119
119
  airbyte_cdk/sources/declarative/partition_routers/__init__.py,sha256=HJ-Syp3p7RpyR_OK0X_a2kSyISfu3W-PKrRI16iY0a8,957
120
120
  airbyte_cdk/sources/declarative/partition_routers/async_job_partition_router.py,sha256=VelO7zKqKtzMJ35jyFeg0ypJLQC0plqqIBNXoBW1G2E,3001
121
121
  airbyte_cdk/sources/declarative/partition_routers/cartesian_product_stream_slicer.py,sha256=c5cuVFM6NFkuQqG8Z5IwkBuwDrvXZN1CunUOM_L0ezg,6892
@@ -139,7 +139,7 @@ airbyte_cdk/sources/declarative/requesters/error_handlers/default_http_response_
139
139
  airbyte_cdk/sources/declarative/requesters/error_handlers/error_handler.py,sha256=Tan66odx8VHzfdyyXMQkXz2pJYksllGqvxmpoajgcK4,669
140
140
  airbyte_cdk/sources/declarative/requesters/error_handlers/http_response_filter.py,sha256=E-fQbt4ShfxZVoqfnmOx69C6FUPWZz8BIqI3DN9Kcjs,7935
141
141
  airbyte_cdk/sources/declarative/requesters/http_job_repository.py,sha256=3GtOefPH08evlSUxaILkiKLTHbIspFY4qd5B3ZqNE60,10063
142
- airbyte_cdk/sources/declarative/requesters/http_requester.py,sha256=Ek5hS60-CYjvEaFD-bI7qA-bPgbOPb9hTbMBU4n5zNs,14994
142
+ airbyte_cdk/sources/declarative/requesters/http_requester.py,sha256=C6YT7t4UZMfarFeQ9fc362R5TbQ2jNSew8ESP-9yuZQ,14851
143
143
  airbyte_cdk/sources/declarative/requesters/paginators/__init__.py,sha256=uArbKs9JKNCt7t9tZoeWwjDpyI1HoPp29FNW0JzvaEM,644
144
144
  airbyte_cdk/sources/declarative/requesters/paginators/default_paginator.py,sha256=dSm_pKGOZjzvg-X_Vif-MjrnlUG23fCa69bocq8dVIs,11693
145
145
  airbyte_cdk/sources/declarative/requesters/paginators/no_pagination.py,sha256=j6j9QRPaTbKQ2N661RFVKthhkWiodEp6ut0tKeEd0Ng,2019
@@ -249,7 +249,7 @@ airbyte_cdk/sources/message/repository.py,sha256=SG7avgti_-dj8FcRHTTrhgLLGJbElv1
249
249
  airbyte_cdk/sources/source.py,sha256=KIBBH5VLEb8BZ8B9aROlfaI6OLoJqKDPMJ10jkAR7nk,3611
250
250
  airbyte_cdk/sources/streams/__init__.py,sha256=8fzTKpRTnSx5PggXgQPKJzHNZUV2BCA40N-dI6JM1xI,256
251
251
  airbyte_cdk/sources/streams/availability_strategy.py,sha256=_RU4JITrxMEN36g1RDHMu0iSw0I_3yWGfo5N8_YRvOg,3247
252
- airbyte_cdk/sources/streams/call_rate.py,sha256=WHMJ0-8xf0w_DiI0RkhPA8KEaPzaojNb23AEnKfcuS4,23939
252
+ airbyte_cdk/sources/streams/call_rate.py,sha256=Um_Ny8R7WZ2B0PWoxr-wrWPsgc5we7HrHalaMcozuVs,21052
253
253
  airbyte_cdk/sources/streams/checkpoint/__init__.py,sha256=3oy7Hd4ivVWTZlN6dKAf4Fv_G7U5iZrvhO9hT871UIo,712
254
254
  airbyte_cdk/sources/streams/checkpoint/checkpoint_reader.py,sha256=6HMT2NI-FQuaW0nt95NcyWrt5rZN4gF-Arx0sxdgbv4,15221
255
255
  airbyte_cdk/sources/streams/checkpoint/cursor.py,sha256=3e-3c-54k8U7Awno7DMmAD9ndbnl9OM48EnbEgeDUO0,3499
@@ -295,7 +295,7 @@ airbyte_cdk/sources/streams/http/http.py,sha256=0uariNq8OFnlX7iqOHwBhecxA-Hfd5hS
295
295
  airbyte_cdk/sources/streams/http/http_client.py,sha256=tDE0ROtxjGMVphvsw8INvGMtZ97hIF-v47pZ3jIyiwc,23011
296
296
  airbyte_cdk/sources/streams/http/rate_limiting.py,sha256=IwdjrHKUnU97XO4qONgYRv4YYW51xQ8SJm4WLafXDB8,6351
297
297
  airbyte_cdk/sources/streams/http/requests_native_auth/__init__.py,sha256=RN0D3nOX1xLgwEwKWu6pkGy3XqBFzKSNZ8Lf6umU2eY,413
298
- airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py,sha256=n-jlPNcUtZkDv3hQEGqTzqVFuF0hbWHkru-po3ResFU,18596
298
+ airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py,sha256=cM5CM1mnbTEMiY6gKHblGXr9KTS5VEziGoc-TXC302k,18791
299
299
  airbyte_cdk/sources/streams/http/requests_native_auth/abstract_token.py,sha256=Y3n7J-sk5yGjv_OxtY6Z6k0PEsFZmtIRi-x0KCbaHdA,1010
300
300
  airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py,sha256=C2j2uVfi9d-3KgHO3NGxIiFdfASjHOtsd6g_LWPYOAs,20311
301
301
  airbyte_cdk/sources/streams/http/requests_native_auth/token.py,sha256=h5PTzcdH-RQLeCg7xZ45w_484OPUDSwNWl_iMJQmZoI,2526
@@ -351,9 +351,9 @@ airbyte_cdk/utils/slice_hasher.py,sha256=EDxgROHDbfG-QKQb59m7h_7crN1tRiawdf5uU7G
351
351
  airbyte_cdk/utils/spec_schema_transformations.py,sha256=-5HTuNsnDBAhj-oLeQXwpTGA0HdcjFOf2zTEMUTTg_Y,816
352
352
  airbyte_cdk/utils/stream_status_utils.py,sha256=ZmBoiy5HVbUEHAMrUONxZvxnvfV9CesmQJLDTAIWnWw,1171
353
353
  airbyte_cdk/utils/traced_exception.py,sha256=C8uIBuCL_E4WnBAOPSxBicD06JAldoN9fGsQDp463OY,6292
354
- airbyte_cdk-6.33.1.dev1.dist-info/LICENSE.txt,sha256=Wfe61S4BaGPj404v8lrAbvhjYR68SHlkzeYrg3_bbuM,1051
355
- airbyte_cdk-6.33.1.dev1.dist-info/LICENSE_SHORT,sha256=aqF6D1NcESmpn-cqsxBtszTEnHKnlsp8L4x9wAh3Nxg,55
356
- airbyte_cdk-6.33.1.dev1.dist-info/METADATA,sha256=QAd1UPmncyipNd9wFUIju_Hwfg6pb--xisbMrYhl5PA,6015
357
- airbyte_cdk-6.33.1.dev1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
358
- airbyte_cdk-6.33.1.dev1.dist-info/entry_points.txt,sha256=fj-e3PAQvsxsQzyyq8UkG1k8spunWnD4BAH2AwlR6NM,95
359
- airbyte_cdk-6.33.1.dev1.dist-info/RECORD,,
354
+ airbyte_cdk-6.33.2.dist-info/LICENSE.txt,sha256=Wfe61S4BaGPj404v8lrAbvhjYR68SHlkzeYrg3_bbuM,1051
355
+ airbyte_cdk-6.33.2.dist-info/LICENSE_SHORT,sha256=aqF6D1NcESmpn-cqsxBtszTEnHKnlsp8L4x9wAh3Nxg,55
356
+ airbyte_cdk-6.33.2.dist-info/METADATA,sha256=8_7_yrHWUow7tK9vqk_hqRiXhf9geY_kN_N1cU1XpLY,6010
357
+ airbyte_cdk-6.33.2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
358
+ airbyte_cdk-6.33.2.dist-info/entry_points.txt,sha256=fj-e3PAQvsxsQzyyq8UkG1k8spunWnD4BAH2AwlR6NM,95
359
+ airbyte_cdk-6.33.2.dist-info/RECORD,,