Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[low-code connectors] Add request options and state to stream slicers #14552

Merged
merged 286 commits into from
Jul 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
286 commits
Select commit Hold shift + click to select a range
51fc8eb
comment
girarda Jul 1, 2022
efc40b5
comment
girarda Jul 1, 2022
e33e004
comments
girarda Jul 1, 2022
fc41d54
fix
girarda Jul 1, 2022
e2ef317
test for instantiating chain retrier
girarda Jul 1, 2022
b8faa8d
fix parsing
girarda Jul 1, 2022
6f96b26
cleanup
girarda Jul 1, 2022
d864b01
fix
girarda Jul 1, 2022
d209dd6
reset
girarda Jul 1, 2022
04fca0d
never raise on http error
girarda Jul 1, 2022
0301e9a
remove print
girarda Jul 1, 2022
0367f0f
comment
girarda Jul 1, 2022
994d125
comment
girarda Jul 1, 2022
f3a0af4
comment
girarda Jul 1, 2022
2140c28
comment
girarda Jul 1, 2022
77a0325
remove prints
girarda Jul 1, 2022
ecbfcf3
add declarative stream to registry
girarda Jul 1, 2022
5bda8f8
start working on limit paginator
girarda Jul 5, 2022
1521d40
support for offset pagination
girarda Jul 5, 2022
9f170ba
tests
girarda Jul 5, 2022
d8ca4f3
move limit value
girarda Jul 6, 2022
0f68ae1
extract request option
girarda Jul 6, 2022
67995c7
boilerplate
girarda Jul 6, 2022
233b805
page increment
girarda Jul 6, 2022
9803e59
delete offset paginator
girarda Jul 6, 2022
a23dcdc
update conditional paginator
girarda Jul 6, 2022
950d8fd
refactor and fix test
girarda Jul 6, 2022
9de8ccf
fix test
girarda Jul 6, 2022
1ddb4ad
small fix
girarda Jul 6, 2022
f507f91
Merge branch 'master' into alex/configurableRetrier
girarda Jul 6, 2022
b510b17
Delete dead code
girarda Jul 6, 2022
d03c809
Add docstrings
girarda Jul 6, 2022
4444c4e
Merge branch 'master' into alex/paginatorRefactor
girarda Jul 6, 2022
6471b15
Merge branch 'master' into alex/configurableRetrier
girarda Jul 7, 2022
b8b3c3a
quick fix
girarda Jul 7, 2022
71fa551
exponential backoff
girarda Jul 7, 2022
e0da35d
fix test
girarda Jul 7, 2022
f7bc427
fix
girarda Jul 7, 2022
0fca96c
delete unused properties
girarda Jul 7, 2022
04fc03e
fix
girarda Jul 7, 2022
dda7b9c
missing unit tests
girarda Jul 7, 2022
a35c9bc
merge master
girarda Jul 8, 2022
9862b4b
uppercase
girarda Jul 8, 2022
ad1cce6
docstrings
girarda Jul 8, 2022
15c3f4e
rename to success
girarda Jul 8, 2022
eca2f45
compare full request instead of just url
girarda Jul 8, 2022
5a756bb
renmae module
girarda Jul 8, 2022
9b289cb
rename test file
girarda Jul 8, 2022
fff16ed
rename interface
girarda Jul 8, 2022
918e31a
rename default retrier
girarda Jul 8, 2022
82fb6e8
rename to compositeerrorhandler
girarda Jul 8, 2022
98e17eb
fix missing renames
girarda Jul 8, 2022
9ab1008
move action to filter
girarda Jul 8, 2022
2a6c9d2
str -> minmaxdatetime
girarda Jul 8, 2022
8a72ac0
small fixes
girarda Jul 8, 2022
73279d7
plural
girarda Jul 8, 2022
181fb74
add example
girarda Jul 8, 2022
104ec1b
handle header variations
girarda Jul 8, 2022
cf17cae
also fix wait time from
girarda Jul 8, 2022
08a3663
allow using a regex to extract the value
girarda Jul 8, 2022
764eca0
group()
girarda Jul 8, 2022
34f3a77
docstring
girarda Jul 8, 2022
5cde974
add docs
girarda Jul 8, 2022
573dd90
update comment
girarda Jul 8, 2022
efdca4a
docstrings
girarda Jul 8, 2022
45df5d9
Merge branch 'master' into alex/configurableRetrier
girarda Jul 8, 2022
16e0287
merge
girarda Jul 8, 2022
7432ff7
fix tests
girarda Jul 8, 2022
86f7c6c
rename param
girarda Jul 8, 2022
9ae77f3
cleanup stop_condition
girarda Jul 8, 2022
64fbdff
cleanup
girarda Jul 8, 2022
b44aff2
Add examples
girarda Jul 8, 2022
0c09220
interpolated pagination strategy
girarda Jul 8, 2022
21d550d
dont need duplicate class
girarda Jul 8, 2022
07eecea
docstrings
girarda Jul 8, 2022
31517aa
more docstrings
girarda Jul 8, 2022
124b68b
docstrings
girarda Jul 8, 2022
725b8f9
fix tests
girarda Jul 8, 2022
996024f
first pass at substream
girarda Jul 9, 2022
5b8d5a8
seems to work for a single stream
girarda Jul 9, 2022
8120f00
can also be defined in requester with stream_state
girarda Jul 9, 2022
1a6a943
tmp update
girarda Jul 11, 2022
9bf3808
Merge branch 'master' into alex/configurableRetrier
girarda Jul 11, 2022
db47529
update comment
girarda Jul 11, 2022
9e5fddc
Merge branch 'master' into alex/configurableRetrier
girarda Jul 11, 2022
7aae31d
Update airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/…
girarda Jul 12, 2022
6656af3
version: Update Parquet library to latest release (#14502)
blarghmatey Jul 11, 2022
1a49c95
merge
girarda Jul 12, 2022
d30aa5b
🎉 Source Github: improve schema for stream `pull_request_commits` add…
grubberr Jul 12, 2022
a525afe
Docs: Fixed broken links (#14622)
Amruta-Ranade Jul 12, 2022
64750ec
source-hubspot: change mentioning of Mailchimp into HubSpot doc (#14…
bjgbeelen Jul 12, 2022
f3fc604
Helm Chart: Add external temporal option (#14597)
marcosmarxm Jul 12, 2022
2d2ef71
🎉 Add YAML format to source-file reader (#14588)
ChristopheDuong Jul 12, 2022
8b422c7
:tada: Source Okta: add GroupMembers stream (#14380)
YiyangLi Jul 12, 2022
73b47b1
split test files
girarda Jul 12, 2022
f97cfee
renames
girarda Jul 12, 2022
18e562a
missing unit test
girarda Jul 12, 2022
2d1312e
add missing unit tests
girarda Jul 12, 2022
a0ab86b
rename
girarda Jul 12, 2022
d4c7db1
merge
girarda Jul 12, 2022
32e34dc
assert isinstance
girarda Jul 12, 2022
187858f
start extracting to their own files
girarda Jul 12, 2022
bbc8cf5
use final instead of classmethod
girarda Jul 12, 2022
4647033
assert we retry 429 errors
girarda Jul 12, 2022
a201c3f
Add log
girarda Jul 12, 2022
198c1d2
replace asserts with valueexceptions
girarda Jul 12, 2022
0dbe4a9
delete superfluous print statement
girarda Jul 12, 2022
43a3d69
merge
girarda Jul 12, 2022
6cec644
Merge branch 'alex/paginatorRefactor' into alex/streamslicerRefactor
girarda Jul 12, 2022
09c43f7
only accept minmaxdatetime
girarda Jul 12, 2022
d996baa
fix factory so we don't need to union everything with strings
girarda Jul 12, 2022
47a56d8
get class_name from type
girarda Jul 13, 2022
22521bf
remove from class types registry
girarda Jul 13, 2022
6b77952
process error handlers one at a time
girarda Jul 13, 2022
598c36a
sort
girarda Jul 13, 2022
72dc105
delete print statement
girarda Jul 13, 2022
2d291b6
comment
girarda Jul 13, 2022
403521d
merge
girarda Jul 13, 2022
7673b52
comment
girarda Jul 13, 2022
7bdc243
merge master
girarda Jul 13, 2022
ee7de21
format
girarda Jul 13, 2022
58d154a
delete unused file
girarda Jul 13, 2022
a00c6a8
merge master
girarda Jul 13, 2022
129cea0
merge
girarda Jul 13, 2022
a3f708b
comment
girarda Jul 13, 2022
b9ab1f2
interpolatedboolean
girarda Jul 13, 2022
fb93593
comment
girarda Jul 13, 2022
2188b7d
not optional
girarda Jul 13, 2022
cea2206
not optional
girarda Jul 13, 2022
f30c33d
unit tests
girarda Jul 13, 2022
1b266fb
fix request body data
girarda Jul 13, 2022
e4a26e0
add test
girarda Jul 13, 2022
e80b543
move file to right module
girarda Jul 13, 2022
03990a1
merge master
girarda Jul 14, 2022
19ddda8
update
girarda Jul 14, 2022
ed11332
reset to master
girarda Jul 14, 2022
91443ed
format
girarda Jul 14, 2022
da663a1
Merge branch 'master' into alex/paginatorRefactor
girarda Jul 14, 2022
bda51cf
Merge branch 'master' into alex/paginatorRefactor
girarda Jul 14, 2022
d94da00
merge
girarda Jul 18, 2022
2f54949
rename to pass_by
girarda Jul 18, 2022
3987c72
rename to page size
girarda Jul 18, 2022
3dc3422
merge
girarda Jul 18, 2022
fae07e3
fix
girarda Jul 18, 2022
c5abb0a
merge
girarda Jul 18, 2022
d33c6e6
fix some tests
girarda Jul 18, 2022
923da6a
reset
girarda Jul 18, 2022
4794669
fix
girarda Jul 18, 2022
cce9b59
fix some of the tests
girarda Jul 18, 2022
f63a4b0
fix test
girarda Jul 18, 2022
864872d
fix more tests
girarda Jul 18, 2022
0319dec
all tests pass
girarda Jul 18, 2022
f6e4054
path is not optional
girarda Jul 18, 2022
831e32d
reset
girarda Jul 18, 2022
6851be6
reset
girarda Jul 18, 2022
f08ac16
reset
girarda Jul 18, 2022
8be4a09
delete print
girarda Jul 18, 2022
b16758c
remove prints
girarda Jul 18, 2022
ffefeb6
delete duplicate method
girarda Jul 18, 2022
7b51d06
Merge branch 'master' into alex/paginatorRefactor
girarda Jul 18, 2022
2ca69f1
add test
girarda Jul 18, 2022
b8326c0
fix body data
girarda Jul 18, 2022
52656e2
delete extra newlines
girarda Jul 18, 2022
cfc6da9
move to subpackage
girarda Jul 18, 2022
880dc19
fix imports
girarda Jul 19, 2022
00d6bfb
handle str body data
girarda Jul 19, 2022
a547040
Merge branch 'master' into alex/paginatorRefactor
girarda Jul 19, 2022
2023614
simplify
girarda Jul 19, 2022
69e99af
Merge branch 'alex/paginatorRefactor' into alex/streamslicerRefactor
girarda Jul 19, 2022
63188b8
Merge branch 'master' into alex/streamslicerRefactor
girarda Jul 19, 2022
c0808c8
Update tests
girarda Jul 19, 2022
227e537
filter dates before stream state
girarda Jul 19, 2022
e0e7dd2
Revert "Update tests"
girarda Jul 19, 2022
68f5dfe
update
girarda Jul 19, 2022
870ff1b
fix test
girarda Jul 19, 2022
c6d0e73
state management
girarda Jul 19, 2022
6ed0c9f
add test
girarda Jul 19, 2022
a624f2f
delete dead code
girarda Jul 19, 2022
2ba2a6f
update cursor
girarda Jul 19, 2022
4124210
update cursor cartesian
girarda Jul 19, 2022
256cce2
delete unused state class
girarda Jul 19, 2022
2d08a8c
fix
girarda Jul 19, 2022
19d4808
missing test
girarda Jul 19, 2022
87951bc
update cursor substreams
girarda Jul 19, 2022
3bc44ba
missing test
girarda Jul 19, 2022
27add18
fix typing
girarda Jul 19, 2022
ea5010d
fix typing
girarda Jul 19, 2022
16f21eb
Merge branch 'alex/paginatorRefactor' into alex/streamslicerRefactor
girarda Jul 19, 2022
c7071ee
delete unused field
girarda Jul 19, 2022
bb770ec
delete unused method
girarda Jul 19, 2022
319da0e
update datetime stream slice
girarda Jul 19, 2022
964d9c6
cleanup
girarda Jul 19, 2022
139a388
assert
girarda Jul 19, 2022
ef6a3bf
request options
girarda Jul 19, 2022
a901299
request option cartesian
girarda Jul 19, 2022
4b0aeb2
assert when passing by path
girarda Jul 19, 2022
d34563f
request options for substreams
girarda Jul 19, 2022
8be926b
Merge branch 'master' into alex/paginatorRefactor
girarda Jul 19, 2022
cda82eb
always return a map
girarda Jul 19, 2022
7fc6ab2
Merge branch 'alex/paginatorRefactor' into alex/streamslicerRefactor
girarda Jul 19, 2022
a447ef6
pass stream_state
girarda Jul 19, 2022
ad5d88a
refactor and almost done fixing tests
girarda Jul 19, 2022
91b106d
fix tests
girarda Jul 20, 2022
b41f713
Merge branch 'master' into alex/paginatorRefactor
girarda Jul 20, 2022
245ebc5
rename to inject_into
girarda Jul 20, 2022
77b8cf5
only accept enum
girarda Jul 20, 2022
d919e06
delete conditional paginator
girarda Jul 20, 2022
4489ba4
only return body data
girarda Jul 20, 2022
1fd3c91
missing test
girarda Jul 20, 2022
71d5c0c
update docstrings
girarda Jul 20, 2022
cf465ab
update docstrings
girarda Jul 20, 2022
56aad5e
Merge branch 'master' into alex/paginatorRefactor
girarda Jul 20, 2022
a594861
update comment
girarda Jul 20, 2022
134cf0b
merge
girarda Jul 20, 2022
5b4a66a
rename
girarda Jul 20, 2022
25ab261
rename
girarda Jul 20, 2022
acf4c67
tests
girarda Jul 20, 2022
fcd7d85
class_name -> type
girarda Jul 20, 2022
6195d1c
improve interface
girarda Jul 20, 2022
16a4130
fix some of the tests
girarda Jul 20, 2022
76031cb
fix more of the tests
girarda Jul 20, 2022
1e8d64c
fix tests
girarda Jul 20, 2022
2a17a9b
reset
girarda Jul 20, 2022
eb9a918
reset
girarda Jul 20, 2022
ce14cd9
Revert "reset"
girarda Jul 20, 2022
fca5c26
remove extra argument
girarda Jul 20, 2022
e2b5903
docstring
girarda Jul 20, 2022
8fc3f5b
update
girarda Jul 20, 2022
72bd263
delete unused file
girarda Jul 20, 2022
adfd416
reset
girarda Jul 20, 2022
46d9ae1
reset
girarda Jul 20, 2022
2d57df3
rename
girarda Jul 20, 2022
dcb6daf
fix timewindow
girarda Jul 20, 2022
c778730
merge
girarda Jul 21, 2022
31f4c79
create InterpolatedString
girarda Jul 21, 2022
45a0bfb
helper method
girarda Jul 21, 2022
4883766
assert on request option
girarda Jul 21, 2022
0440860
better asserts
girarda Jul 21, 2022
020f287
format
girarda Jul 21, 2022
bd38299
docstrings
girarda Jul 22, 2022
6b4b405
docstrings
girarda Jul 22, 2022
e06a808
remove optional from type hint
girarda Jul 25, 2022
fb6f49c
Update airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slic…
girarda Jul 25, 2022
edaa436
inherit from request options provider
girarda Jul 25, 2022
c516c8f
inherit from request options provider
girarda Jul 25, 2022
9419b15
remove optional from type hint
girarda Jul 25, 2022
b4a2ffb
merge
girarda Jul 25, 2022
909e381
remove extra parameter
girarda Jul 25, 2022
d8f5c1d
none check
girarda Jul 26, 2022
f488f3b
merge
girarda Jul 27, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from airbyte_cdk.sources.declarative.stream_slicers.cartesian_product_stream_slicer import CartesianProductStreamSlicer
from airbyte_cdk.sources.declarative.stream_slicers.datetime_stream_slicer import DatetimeStreamSlicer
from airbyte_cdk.sources.declarative.stream_slicers.list_stream_slicer import ListStreamSlicer
from airbyte_cdk.sources.declarative.stream_slicers.substream_slicer import SubstreamSlicer
from airbyte_cdk.sources.declarative.transformations import RemoveFields
from airbyte_cdk.sources.declarative.transformations.add_fields import AddFields

Expand Down Expand Up @@ -59,4 +60,5 @@
"RecordSelector": RecordSelector,
"RemoveFields": RemoveFields,
"SimpleRetriever": SimpleRetriever,
"SubstreamSlicer": SubstreamSlicer,
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,9 @@
from airbyte_cdk.sources.declarative.retrievers.simple_retriever import SimpleRetriever
from airbyte_cdk.sources.declarative.schema.json_schema import JsonSchema
from airbyte_cdk.sources.declarative.schema.schema_loader import SchemaLoader
from airbyte_cdk.sources.declarative.states.dict_state import DictState
from airbyte_cdk.sources.declarative.states.state import State
from airbyte_cdk.sources.declarative.stream_slicers.single_slice import SingleSlice
from airbyte_cdk.sources.declarative.stream_slicers.stream_slicer import StreamSlicer
from airbyte_cdk.sources.declarative.stream_slicers.substream_slicer import ParentStreamConfig
from airbyte_cdk.sources.streams.core import Stream

"""
Expand All @@ -55,8 +54,8 @@
RequestOptionsProvider: InterpolatedRequestOptionsProvider,
Requester: HttpRequester,
Retriever: SimpleRetriever,
ParentStreamConfig: ParentStreamConfig,
SchemaLoader: JsonSchema,
State: DictState,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

the stream slicer now owns the state

Stream: DeclarativeStream,
StreamSlicer: SingleSlice,
}
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ def request_body_data(self) -> Mapping[str, Any]:
def request_body_json(self) -> Mapping[str, Any]:
return self._get_request_options(RequestOptionType.body_json)

def request_kwargs(self) -> Mapping[str, Any]:
# Never update kwargs
return {}

def _get_request_options(self, option_type: RequestOptionType) -> Mapping[str, Any]:
options = {}
if self._page_token_option.inject_into == option_type:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,9 @@ def request_body_data(self) -> Union[Mapping[str, Any], str]:
def request_body_json(self) -> Mapping[str, Any]:
return {}

def request_kwargs(self) -> Mapping[str, Any]:
# Never update kwargs
return {}

def next_page_token(self, response: requests.Response, last_records: List[Mapping[str, Any]]) -> Mapping[str, Any]:
return {}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
# Copyright (c) 2022 Airbyte, Inc., all rights reserved.
#

from abc import ABC, abstractmethod
from abc import abstractmethod
from typing import Any, List, Mapping, Optional

import requests
from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import RequestOptionsProvider


class Paginator(ABC):
class Paginator(RequestOptionsProvider):
"""
Defines the token to use to fetch the next page of records from the API.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,13 @@ class RequestOptionsProvider(ABC):
"""

@abstractmethod
def request_params(
self, stream_state: StreamState, stream_slice: Optional[StreamSlice] = None, next_page_token: Optional[Mapping[str, Any]] = None
) -> MutableMapping[str, Any]:
def request_params(self, **kwargs) -> MutableMapping[str, Any]:
Copy link
Contributor Author

Choose a reason for hiding this comment

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

the stream slicer and paginator don't need these extra params

"""
Specifies the query parameters that should be set on an outgoing HTTP request given the inputs.

E.g: you might want to define query parameters for paging if next_page_token is not None.
"""
pass

@abstractmethod
def request_headers(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
from airbyte_cdk.sources.declarative.requesters.paginators.paginator import Paginator
from airbyte_cdk.sources.declarative.requesters.requester import Requester
from airbyte_cdk.sources.declarative.retrievers.retriever import Retriever
from airbyte_cdk.sources.declarative.states.dict_state import DictState
from airbyte_cdk.sources.declarative.states.state import State
from airbyte_cdk.sources.declarative.stream_slicers.single_slice import SingleSlice
from airbyte_cdk.sources.declarative.stream_slicers.stream_slicer import StreamSlicer
from airbyte_cdk.sources.declarative.types import Record, StreamSlice, StreamState
Expand Down Expand Up @@ -42,7 +40,6 @@ def __init__(
record_selector: HttpSelector,
paginator: Optional[Paginator] = None,
stream_slicer: Optional[StreamSlicer] = SingleSlice(),
state: Optional[State] = None,
):
"""
:param name: The stream's name
Expand All @@ -59,8 +56,7 @@ def __init__(
self._requester = requester
self._record_selector = record_selector
super().__init__(self._requester.get_authenticator())
self._iterator = stream_slicer
self._state: State = (state or DictState()).deep_copy()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

the stream slicer owns the state now

self._stream_slicer = stream_slicer
self._last_response = None
self._last_records = None

Expand Down Expand Up @@ -300,12 +296,14 @@ def read_records(
stream_state: Optional[StreamState] = None,
) -> Iterable[Mapping[str, Any]]:
# Warning: use self.state instead of the stream_state passed as argument!
stream_slice = stream_slice or {} # None-check
records_generator = HttpStream.read_records(self, sync_mode, cursor_field, stream_slice, self.state)
for r in records_generator:
self._state.update_state(stream_slice=stream_slice, stream_state=self.state, last_response=self._last_response, last_record=r)
self._stream_slicer.update_cursor(stream_slice, last_record=r)
yield r
else:
self._state.update_state(stream_slice=stream_slice, stream_state=self.state, last_reponse=self._last_response)
last_record = self._last_records[-1] if self._last_records else None
self._stream_slicer.update_cursor(stream_slice, last_record=last_record)
yield from []

def stream_slices(
Expand All @@ -320,13 +318,13 @@ def stream_slices(
:return:
"""
# Warning: use self.state instead of the stream_state passed as argument!
return self._iterator.stream_slices(sync_mode, self.state)
return self._stream_slicer.stream_slices(sync_mode, self.state)

@property
def state(self) -> StreamState:
return self._state.get_stream_state()
def state(self) -> MutableMapping[str, Any]:
return self._stream_slicer.get_stream_state()

@state.setter
def state(self, value: StreamState):
"""State setter, accept state serialized by state getter."""
self._state.set_state(value)
self._stream_slicer.update_cursor(value)

This file was deleted.

This file was deleted.

19 changes: 0 additions & 19 deletions airbyte-cdk/python/airbyte_cdk/sources/declarative/states/state.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import itertools
from collections import ChainMap
from typing import Any, Iterable, List, Mapping
from typing import Any, Iterable, List, Mapping, Optional

from airbyte_cdk.models import SyncMode
from airbyte_cdk.sources.declarative.stream_slicers.stream_slicer import StreamSlicer
Expand All @@ -28,8 +28,34 @@ class CartesianProductStreamSlicer(StreamSlicer):
"""

def __init__(self, stream_slicers: List[StreamSlicer]):
"""
:param stream_slicers: Underlying stream slicers. The RequestOptions (e.g: Request headers, parameters, etc..) returned by this slicer are the combination of the RequestOptions of its input slicers. If there are conflicts e.g: two slicers define the same header or request param, the conflict is resolved by taking the value from the first slicer, where ordering is determined by the order in which slicers were input to this composite slicer.
"""
self._stream_slicers = stream_slicers

def update_cursor(self, stream_slice: Mapping[str, Any], last_record: Optional[Mapping[str, Any]] = None):
for slicer in self._stream_slicers:
slicer.update_cursor(stream_slice, last_record)

def request_params(self) -> Mapping[str, Any]:
return dict(ChainMap(*[s.request_params() for s in self._stream_slicers]))
Copy link
Contributor

Choose a reason for hiding this comment

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

TIL about ChainMap


def request_headers(self) -> Mapping[str, Any]:
return dict(ChainMap(*[s.request_headers() for s in self._stream_slicers]))

def request_body_data(self) -> Mapping[str, Any]:
return dict(ChainMap(*[s.request_body_data() for s in self._stream_slicers]))

def request_body_json(self) -> Optional[Mapping]:
return dict(ChainMap(*[s.request_body_json() for s in self._stream_slicers]))
Copy link
Contributor

Choose a reason for hiding this comment

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

should there be an if not None for each of these for loops? what if an underlying slicer doesn't specify e.g; a body?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated the type hints to make it clear the methods should returns empty {} instead of None


def request_kwargs(self) -> Mapping[str, Any]:
# Never update kwargs
return {}

def get_stream_state(self) -> Mapping[str, Any]:
return dict(ChainMap(*[slicer.get_stream_state() for slicer in self._stream_slicers]))

def stream_slices(self, sync_mode: SyncMode, stream_state: Mapping[str, Any]) -> Iterable[Mapping[str, Any]]:
sub_slices = (s.stream_slices(sync_mode, stream_state) for s in self._stream_slicers)
return (ChainMap(*a) for a in itertools.product(*sub_slices))
Loading