bizon 0.1.2__py3-none-any.whl → 0.2.0__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.
Files changed (77) hide show
  1. bizon/alerting/alerts.py +0 -1
  2. bizon/common/models.py +182 -4
  3. bizon/connectors/destinations/bigquery/src/config.py +0 -1
  4. bizon/connectors/destinations/bigquery/src/destination.py +11 -8
  5. bizon/connectors/destinations/bigquery_streaming/config/bigquery_streaming.example.yml +74 -0
  6. bizon/connectors/destinations/bigquery_streaming/src/destination.py +4 -5
  7. bizon/connectors/destinations/bigquery_streaming_v2/config/bigquery_streaming_v2.example.yml +79 -0
  8. bizon/connectors/destinations/bigquery_streaming_v2/src/destination.py +4 -6
  9. bizon/connectors/destinations/file/config/file.example.yml +40 -0
  10. bizon/connectors/destinations/file/src/config.py +1 -1
  11. bizon/connectors/destinations/file/src/destination.py +0 -5
  12. bizon/connectors/destinations/logger/config/logger.example.yml +30 -0
  13. bizon/connectors/destinations/logger/src/config.py +0 -2
  14. bizon/connectors/destinations/logger/src/destination.py +1 -2
  15. bizon/connectors/sources/cycle/src/source.py +2 -6
  16. bizon/connectors/sources/dummy/src/source.py +0 -4
  17. bizon/connectors/sources/gsheets/src/source.py +2 -3
  18. bizon/connectors/sources/hubspot/src/hubspot_base.py +0 -1
  19. bizon/connectors/sources/hubspot/src/hubspot_objects.py +3 -4
  20. bizon/connectors/sources/hubspot/src/models/hs_object.py +0 -1
  21. bizon/connectors/sources/kafka/config/kafka_streams.example.yml +124 -0
  22. bizon/connectors/sources/kafka/src/config.py +10 -6
  23. bizon/connectors/sources/kafka/src/decode.py +2 -2
  24. bizon/connectors/sources/kafka/src/source.py +147 -46
  25. bizon/connectors/sources/notion/config/api_key.example.yml +35 -0
  26. bizon/connectors/sources/notion/src/__init__.py +0 -0
  27. bizon/connectors/sources/notion/src/config.py +59 -0
  28. bizon/connectors/sources/notion/src/source.py +1159 -0
  29. bizon/connectors/sources/notion/tests/notion_pipeline.py +7 -0
  30. bizon/connectors/sources/notion/tests/test_notion.py +113 -0
  31. bizon/connectors/sources/periscope/src/source.py +0 -6
  32. bizon/connectors/sources/pokeapi/src/source.py +0 -1
  33. bizon/connectors/sources/sana_ai/config/sana.example.yml +25 -0
  34. bizon/connectors/sources/sana_ai/src/source.py +85 -0
  35. bizon/destination/buffer.py +0 -1
  36. bizon/destination/config.py +0 -1
  37. bizon/destination/destination.py +1 -4
  38. bizon/engine/backend/adapters/sqlalchemy/backend.py +2 -5
  39. bizon/engine/backend/adapters/sqlalchemy/config.py +0 -1
  40. bizon/engine/config.py +0 -1
  41. bizon/engine/engine.py +0 -1
  42. bizon/engine/pipeline/consumer.py +0 -1
  43. bizon/engine/pipeline/producer.py +1 -5
  44. bizon/engine/queue/adapters/kafka/config.py +1 -1
  45. bizon/engine/queue/adapters/kafka/queue.py +0 -1
  46. bizon/engine/queue/adapters/python_queue/consumer.py +0 -1
  47. bizon/engine/queue/adapters/python_queue/queue.py +0 -2
  48. bizon/engine/queue/adapters/rabbitmq/consumer.py +0 -1
  49. bizon/engine/queue/adapters/rabbitmq/queue.py +0 -1
  50. bizon/engine/queue/config.py +0 -2
  51. bizon/engine/runner/adapters/process.py +0 -2
  52. bizon/engine/runner/adapters/streaming.py +55 -1
  53. bizon/engine/runner/adapters/thread.py +0 -2
  54. bizon/engine/runner/config.py +0 -1
  55. bizon/engine/runner/runner.py +0 -2
  56. bizon/monitoring/datadog/monitor.py +5 -3
  57. bizon/monitoring/noop/monitor.py +1 -1
  58. bizon/source/auth/authenticators/abstract_oauth.py +11 -3
  59. bizon/source/auth/authenticators/abstract_token.py +2 -1
  60. bizon/source/auth/authenticators/basic.py +1 -1
  61. bizon/source/auth/authenticators/cookies.py +2 -1
  62. bizon/source/auth/authenticators/oauth.py +8 -3
  63. bizon/source/config.py +0 -2
  64. bizon/source/cursor.py +8 -16
  65. bizon/source/discover.py +3 -6
  66. bizon/source/models.py +0 -1
  67. bizon/source/session.py +0 -1
  68. bizon/source/source.py +17 -2
  69. bizon/transform/config.py +0 -2
  70. bizon/transform/transform.py +0 -3
  71. {bizon-0.1.2.dist-info → bizon-0.2.0.dist-info}/METADATA +62 -42
  72. bizon-0.2.0.dist-info/RECORD +136 -0
  73. {bizon-0.1.2.dist-info → bizon-0.2.0.dist-info}/WHEEL +1 -1
  74. bizon-0.2.0.dist-info/entry_points.txt +2 -0
  75. bizon-0.1.2.dist-info/RECORD +0 -123
  76. bizon-0.1.2.dist-info/entry_points.txt +0 -3
  77. {bizon-0.1.2.dist-info → bizon-0.2.0.dist-info/licenses}/LICENSE +0 -0
@@ -130,7 +130,12 @@ class DatadogMonitor(AbstractMonitor):
130
130
 
131
131
  try:
132
132
  from ddtrace import tracer
133
+ except ImportError:
134
+ logger.warning("ddtrace not available, skipping tracing")
135
+ yield None
136
+ return
133
137
 
138
+ try:
134
139
  # Combine tags
135
140
  all_tags = self.tags.copy()
136
141
  if extra_tags:
@@ -145,9 +150,6 @@ class DatadogMonitor(AbstractMonitor):
145
150
  span.set_tag(key, value)
146
151
  span.set_tag("_sampling_priority_v1", 1)
147
152
  yield span
148
- except ImportError:
149
- logger.warning("ddtrace not available, skipping tracing")
150
- yield None
151
153
  except Exception as e:
152
154
  logger.warning(f"Failed to create trace: {e}")
153
155
  yield None
@@ -1,7 +1,7 @@
1
1
  from contextlib import contextmanager
2
2
  from typing import Dict
3
3
 
4
- from bizon.common.models import BizonConfig, SyncMetadata
4
+ from bizon.common.models import SyncMetadata
5
5
  from bizon.engine.pipeline.models import PipelineReturnStatus
6
6
  from bizon.monitoring.config import MonitoringConfig
7
7
  from bizon.monitoring.monitor import AbstractMonitor
@@ -1,7 +1,9 @@
1
1
  from abc import abstractmethod
2
- from typing import Any, List, Mapping, MutableMapping, Tuple, Union
2
+ from collections.abc import Mapping, MutableMapping
3
+ from typing import Any, List, Tuple, Union
3
4
 
4
5
  import backoff
6
+ import dpath
5
7
  import pendulum
6
8
  import requests
7
9
  from loguru import logger
@@ -52,8 +54,8 @@ class AbstractOauth2Authenticator(AuthBase):
52
54
  "refresh_token": self.get_refresh_token(),
53
55
  }
54
56
 
55
- if self.get_scopes:
56
- payload["scopes"] = self.get_scopes()
57
+ if self.get_scopes():
58
+ payload["scope"] = ",".join(self.get_scopes())
57
59
 
58
60
  if self.get_refresh_request_body():
59
61
  for key, val in self.get_refresh_request_body().items():
@@ -92,6 +94,8 @@ class AbstractOauth2Authenticator(AuthBase):
92
94
  :return: a tuple of (access_token, token_lifespan_in_seconds)
93
95
  """
94
96
  response_json = self._get_refresh_access_token_response()
97
+ if self.get_response_field_path():
98
+ response_json = dpath.get(response_json, self.get_response_field_path())
95
99
  return response_json[self.get_access_token_name()], int(response_json[self.get_expires_in_name()])
96
100
 
97
101
  @abstractmethod
@@ -138,6 +142,10 @@ class AbstractOauth2Authenticator(AuthBase):
138
142
  def get_grant_type(self) -> str:
139
143
  """Returns grant_type specified for requesting access_token"""
140
144
 
145
+ @abstractmethod
146
+ def get_response_field_path(self) -> str:
147
+ """Returns the path to the response field"""
148
+
141
149
  @property
142
150
  @abstractmethod
143
151
  def access_token(self) -> str:
@@ -1,5 +1,6 @@
1
1
  from abc import abstractmethod
2
- from typing import Any, Mapping
2
+ from collections.abc import Mapping
3
+ from typing import Any
3
4
 
4
5
  from requests.auth import AuthBase
5
6
 
@@ -27,7 +27,7 @@ class BasicHttpAuthenticator(AbstractHeaderAuthenticator):
27
27
  return f"{self._auth_method} {self._token}"
28
28
 
29
29
  def __init__(self, params: BasicHttpAuthParams):
30
- auth_string = f"{params.username}:{params.password}".encode("utf8")
30
+ auth_string = f"{params.username}:{params.password}".encode()
31
31
  b64_encoded = base64.b64encode(auth_string).decode("utf8")
32
32
  self._auth_header = params.auth_header
33
33
  self._auth_method = params.auth_method
@@ -1,4 +1,5 @@
1
- from typing import Any, Mapping, Optional
1
+ from collections.abc import Mapping
2
+ from typing import Any, Optional
2
3
 
3
4
  from pydantic import BaseModel, Field
4
5
  from requests import PreparedRequest
@@ -1,4 +1,5 @@
1
- from typing import Any, List, Mapping, Union
1
+ from collections.abc import Mapping
2
+ from typing import Any, List, Optional, Union
2
3
 
3
4
  import pendulum
4
5
  from pydantic import BaseModel, Field
@@ -11,7 +12,7 @@ class Oauth2AuthParams(BaseModel):
11
12
  token_refresh_endpoint: str = Field(..., description="URL to refresh the token")
12
13
  client_id: str = Field(..., description="Client ID")
13
14
  client_secret: str = Field(..., description="Client Secret")
14
- refresh_token: str = Field(..., description="Refresh Token")
15
+ refresh_token: Union[str, None] = Field(None, description="Refresh Token")
15
16
  scopes: List[str] = Field(None, description="Scopes")
16
17
  token_expiry_date: DateTime = Field(None, description="Token expiry date")
17
18
  token_expiry_date_format: str = Field(None, description="Token expiry date format")
@@ -19,6 +20,7 @@ class Oauth2AuthParams(BaseModel):
19
20
  expires_in_name: str = Field("expires_in", description="Name of the expires in")
20
21
  refresh_request_body: Mapping[str, Any] = Field(None, description="Request body to refresh the token")
21
22
  grant_type: str = Field("refresh_token", description="Grant type")
23
+ response_field_path: Optional[str] = Field(None, description="Path in dpath to the response field")
22
24
 
23
25
 
24
26
  class Oauth2Authenticator(AbstractOauth2Authenticator):
@@ -37,7 +39,7 @@ class Oauth2Authenticator(AbstractOauth2Authenticator):
37
39
  self._expires_in_name = params.expires_in_name
38
40
  self._refresh_request_body = params.refresh_request_body
39
41
  self._grant_type = params.grant_type
40
-
42
+ self._response_field_path = params.response_field_path
41
43
  self._token_expiry_date = params.token_expiry_date or pendulum.now().subtract(days=1)
42
44
  self._token_expiry_date_format = params.token_expiry_date_format
43
45
  self._access_token = None
@@ -69,6 +71,9 @@ class Oauth2Authenticator(AbstractOauth2Authenticator):
69
71
  def get_grant_type(self) -> str:
70
72
  return self._grant_type
71
73
 
74
+ def get_response_field_path(self) -> str:
75
+ return self._response_field_path
76
+
72
77
  def get_token_expiry_date(self) -> DateTime:
73
78
  return self._token_expiry_date
74
79
 
bizon/source/config.py CHANGED
@@ -8,7 +8,6 @@ from .auth.config import AuthConfig
8
8
 
9
9
 
10
10
  class SourceSyncModes(str, Enum):
11
-
12
11
  # Full refresh
13
12
  # - creates a new StreamJob
14
13
  # - start syncing data from scratch till pagination is empty
@@ -30,7 +29,6 @@ class APIConfig(BaseModel):
30
29
 
31
30
 
32
31
  class SourceConfig(BaseModel, ABC):
33
-
34
32
  # Connector identifier to use, match a unique connector code
35
33
  name: str = Field(..., description="Name of the source to sync")
36
34
  stream: str = Field(..., description="Name of the stream to sync")
bizon/source/cursor.py CHANGED
@@ -9,7 +9,6 @@ from bizon.engine.backend.models import JobStatus
9
9
 
10
10
  class Cursor:
11
11
  def __init__(self, source_name: str, stream_name: str, job_id: str, total_records: int = None):
12
-
13
12
  self.source_name: str = source_name
14
13
  self.stream_name: str = stream_name
15
14
  self._job_id: str = job_id
@@ -79,7 +78,6 @@ class Cursor:
79
78
  return f"{self.source_name}.{self.stream_name}"
80
79
 
81
80
  def update_state(self, pagination_dict: dict, nb_records_fetched: int):
82
-
83
81
  # - 1. update the pagination
84
82
  self._pagination = pagination_dict
85
83
 
@@ -93,10 +91,8 @@ class Cursor:
93
91
  percentage_str = f"({self.percentage_fetched:.3%})" if self.percentage_fetched else ""
94
92
 
95
93
  logger.info(
96
- (
97
- f"Source: {self.source_full_name} - Iteration {self.iteration} - "
98
- f"Fetched: {self.rows_fetched} {percentage_str} successfully."
99
- )
94
+ f"Source: {self.source_full_name} - Iteration {self.iteration} - "
95
+ f"Fetched: {self.rows_fetched} {percentage_str} successfully."
100
96
  )
101
97
 
102
98
  # - 5 Handle next status depending on the pagination
@@ -107,19 +103,15 @@ class Cursor:
107
103
 
108
104
  if self.total_records is not None and self.rows_fetched != self.total_records:
109
105
  logger.info(
110
- (
111
- f"Source: {self.source_full_name} - Iteration {self.iteration} - "
112
- f"Total records fetched: {self.rows_fetched} "
113
- f"does not match the total records available: {self.total_records}"
114
- )
106
+ f"Source: {self.source_full_name} - Iteration {self.iteration} - "
107
+ f"Total records fetched: {self.rows_fetched} "
108
+ f"does not match the total records available: {self.total_records}"
115
109
  )
116
110
  else:
117
111
  logger.info(
118
- (
119
- f"Source: {self.source_full_name} - Iteration {self.iteration} - "
120
- f"Total records fetched: {self.rows_fetched} "
121
- f"matches the total records available: {self.total_records}"
122
- )
112
+ f"Source: {self.source_full_name} - Iteration {self.iteration} - "
113
+ f"Total records fetched: {self.rows_fetched} "
114
+ f"matches the total records available: {self.total_records}"
123
115
  )
124
116
  return
125
117
 
bizon/source/discover.py CHANGED
@@ -4,7 +4,8 @@ import importlib.util
4
4
  import inspect
5
5
  import os
6
6
  import traceback
7
- from typing import Any, List, Mapping, Type
7
+ from collections.abc import Mapping
8
+ from typing import Any, List, Type
8
9
 
9
10
  from loguru import logger
10
11
  from pydantic import BaseModel
@@ -36,7 +37,7 @@ class SourceModel(BaseModel):
36
37
 
37
38
  def find_inherited_classes(file_path):
38
39
  # Open the file and parse its content using ast
39
- with open(file_path, "r") as file:
40
+ with open(file_path) as file:
40
41
  tree = ast.parse(file.read())
41
42
 
42
43
  # List to store classes that inherit from the given class name
@@ -79,7 +80,6 @@ def find_all_source_paths(source_dir_name: str = "src") -> Mapping[str, str]:
79
80
  base_dir = os.path.join(BIZON_ABSOLUTE_PATH, "connectors", "sources")
80
81
 
81
82
  for source_name in os.listdir(base_dir):
82
-
83
83
  # First check that it's a dir and contains a dir called src
84
84
  if os.path.isdir(os.path.join(base_dir, source_name)) and os.path.exists(
85
85
  os.path.join(base_dir, source_name, source_dir_name)
@@ -131,7 +131,6 @@ def is_source_class_implementing_incremental(source_class: Type[AbstractSource])
131
131
 
132
132
 
133
133
  def parse_streams_from_filepath(source_name: str, filepath: str, skip_unavailable_sources: bool) -> List[Stream]:
134
-
135
134
  streams = []
136
135
 
137
136
  # Find all classes that inherit from AbstractSource
@@ -141,7 +140,6 @@ def parse_streams_from_filepath(source_name: str, filepath: str, skip_unavailabl
141
140
 
142
141
  # If classes are found
143
142
  for source_class_name in source_classes_name:
144
-
145
143
  # Transform the relative path to a python import path and import the module
146
144
  python_import_path = get_python_import_path(relative_path)
147
145
  logger.debug(f"Importing {python_import_path}")
@@ -246,7 +244,6 @@ def get_external_source_class_by_source_and_stream(
246
244
  stream_names = []
247
245
 
248
246
  for class_name in class_names:
249
-
250
247
  # Extract the module name from the file (remove directory and extension)
251
248
  module_name = os.path.splitext(os.path.basename(filepath))[0]
252
249
 
bizon/source/models.py CHANGED
@@ -18,7 +18,6 @@ source_record_schema = pl.Schema(
18
18
 
19
19
  ### /!\ These models Source* will be used in all sources so we better never have to change them !!!
20
20
  class SourceRecord(BaseModel):
21
-
22
21
  id: str = Field(..., description="Unique identifier of the record in the source")
23
22
 
24
23
  data: dict = Field(..., description="JSON payload of the record")
bizon/source/session.py CHANGED
@@ -46,7 +46,6 @@ class Session(requests.Session):
46
46
  *args,
47
47
  **kwargs,
48
48
  ) -> requests.Response:
49
-
50
49
  self.headers.update({"content-type": content_type})
51
50
 
52
51
  try:
bizon/source/source.py CHANGED
@@ -5,12 +5,11 @@ from requests.auth import AuthBase
5
5
 
6
6
  from .callback import AbstractSourceCallback, NoOpSourceCallback
7
7
  from .config import SourceConfig
8
- from .models import SourceIncrementalState, SourceIteration, SourceRecord
8
+ from .models import SourceIncrementalState, SourceIteration
9
9
  from .session import Session
10
10
 
11
11
 
12
12
  class AbstractSource(ABC):
13
-
14
13
  def __init__(self, config: SourceConfig):
15
14
  self.config = config
16
15
  self.session = self.get_session()
@@ -104,3 +103,19 @@ class AbstractSource(ABC):
104
103
  def commit(self):
105
104
  """Commit the records to the source"""
106
105
  pass
106
+
107
+ def set_streams_config(self, streams: list) -> None:
108
+ """Optional method for sources that support stream routing.
109
+
110
+ This method is called by the runner when a top-level 'streams' configuration
111
+ is present in the BizonConfig. Sources can override this method to accept
112
+ and use stream-based routing instead of legacy configuration.
113
+
114
+ Args:
115
+ streams: List of StreamConfig objects from BizonConfig.streams
116
+
117
+ Example:
118
+ For a Kafka source, this method can extract topic-to-destination mappings
119
+ from the streams config and override the legacy topic_map.
120
+ """
121
+ pass
bizon/transform/config.py CHANGED
@@ -1,5 +1,3 @@
1
- from typing import Optional
2
-
3
1
  from pydantic import BaseModel, Field
4
2
 
5
3
 
@@ -8,7 +8,6 @@ from .config import TransformModel
8
8
 
9
9
 
10
10
  class Transform:
11
-
12
11
  def __init__(self, transforms: list[TransformModel]):
13
12
  self.transforms = transforms
14
13
 
@@ -17,12 +16,10 @@ class Transform:
17
16
 
18
17
  # Process the transformations
19
18
  for transform in self.transforms:
20
-
21
19
  logger.debug(f"Applying transform {transform.label}")
22
20
 
23
21
  # Create a function to be executed in the desired context
24
22
  def my_transform(data: str) -> str:
25
-
26
23
  data = json.loads(data)
27
24
 
28
25
  # Start writing here
@@ -1,52 +1,47 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: bizon
3
- Version: 0.1.2
3
+ Version: 0.2.0
4
4
  Summary: Extract and load your data reliably from API Clients with native fault-tolerant and checkpointing mechanism.
5
- Author: Antoine Balliet
6
- Author-email: antoine.balliet@gmail.com
7
- Requires-Python: >=3.9,<3.13
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: Programming Language :: Python :: 3.9
10
- Classifier: Programming Language :: Python :: 3.10
11
- Classifier: Programming Language :: Python :: 3.11
12
- Classifier: Programming Language :: Python :: 3.12
5
+ Author-email: Antoine Balliet <antoine.balliet@gmail.com>, Anas El Mhamdi <anas.elmhamdi@gmail.com>
6
+ License-File: LICENSE
7
+ Requires-Python: <3.13,>=3.9
8
+ Requires-Dist: backoff>=2.2.1
9
+ Requires-Dist: click>=8.1.7
10
+ Requires-Dist: dpath>=2.2.0
11
+ Requires-Dist: google-cloud-storage>=2.17.0
12
+ Requires-Dist: loguru>=0.7.2
13
+ Requires-Dist: orjson>=3.10.16
14
+ Requires-Dist: pendulum>=3.0.0
15
+ Requires-Dist: polars>=1.16.0
16
+ Requires-Dist: pyarrow>=16.1.0
17
+ Requires-Dist: pydantic-extra-types>=2.9.0
18
+ Requires-Dist: pydantic>=2.8.2
19
+ Requires-Dist: python-dotenv>=1.0.1
20
+ Requires-Dist: pytz>=2024.2
21
+ Requires-Dist: pyyaml>=6.0.1
22
+ Requires-Dist: requests>=2.28.2
23
+ Requires-Dist: simplejson>=3.20.1
24
+ Requires-Dist: sqlalchemy>=2.0.32
25
+ Requires-Dist: tenacity>=9.0.0
13
26
  Provides-Extra: bigquery
27
+ Requires-Dist: google-cloud-bigquery-storage>=2.25.0; extra == 'bigquery'
28
+ Requires-Dist: google-cloud-bigquery>=3.25.0; extra == 'bigquery'
29
+ Requires-Dist: protobuf>=4.24.0; extra == 'bigquery'
30
+ Requires-Dist: sqlalchemy-bigquery>=1.11.0; extra == 'bigquery'
14
31
  Provides-Extra: datadog
32
+ Requires-Dist: datadog>=0.50.2; extra == 'datadog'
33
+ Requires-Dist: ddtrace>=3.10.0; extra == 'datadog'
15
34
  Provides-Extra: gsheets
35
+ Requires-Dist: gspread>=6.1.2; extra == 'gsheets'
16
36
  Provides-Extra: kafka
37
+ Requires-Dist: avro>=1.12.0; extra == 'kafka'
38
+ Requires-Dist: confluent-kafka>=2.6.0; extra == 'kafka'
39
+ Requires-Dist: fastavro>=1.9.7; extra == 'kafka'
40
+ Requires-Dist: kafka-python>=2.0.2; extra == 'kafka'
17
41
  Provides-Extra: postgres
42
+ Requires-Dist: psycopg2-binary>=2.9.9; extra == 'postgres'
18
43
  Provides-Extra: rabbitmq
19
- Requires-Dist: avro (>=1.12.0,<2.0.0) ; extra == "kafka"
20
- Requires-Dist: backoff (>=2.2.1,<3.0.0)
21
- Requires-Dist: click (>=8.1.7,<9.0.0)
22
- Requires-Dist: confluent-kafka (>=2.6.0,<3.0.0) ; extra == "kafka"
23
- Requires-Dist: datadog (>=0.50.2,<0.51.0) ; extra == "datadog"
24
- Requires-Dist: ddtrace (>=3.10.0,<4.0.0) ; extra == "datadog"
25
- Requires-Dist: dpath (>=2.2.0,<3.0.0)
26
- Requires-Dist: fastavro (>=1.9.7,<2.0.0) ; extra == "kafka"
27
- Requires-Dist: google-cloud-bigquery (>=3.25.0,<4.0.0) ; extra == "bigquery"
28
- Requires-Dist: google-cloud-bigquery-storage (>=2.25.0,<3.0.0) ; extra == "bigquery"
29
- Requires-Dist: google-cloud-storage (>=2.17.0,<3.0.0)
30
- Requires-Dist: gspread (>=6.1.2,<7.0.0) ; extra == "gsheets"
31
- Requires-Dist: kafka-python (>=2.0.2,<3.0.0) ; extra == "kafka"
32
- Requires-Dist: loguru (>=0.7.2,<0.8.0)
33
- Requires-Dist: orjson (>=3.10.16,<4.0.0)
34
- Requires-Dist: pendulum (>=3.0.0,<4.0.0)
35
- Requires-Dist: pika (>=1.3.2,<2.0.0) ; extra == "rabbitmq"
36
- Requires-Dist: polars (>=1.16.0,<2.0.0)
37
- Requires-Dist: protobuf (>=4.24.0,<5.0.0) ; extra == "bigquery"
38
- Requires-Dist: psycopg2-binary (>=2.9.9,<3.0.0) ; extra == "postgres"
39
- Requires-Dist: pyarrow (>=16.1.0,<17.0.0)
40
- Requires-Dist: pydantic (>=2.8.2,<3.0.0)
41
- Requires-Dist: pydantic-extra-types (>=2.9.0,<3.0.0)
42
- Requires-Dist: python-dotenv (>=1.0.1,<2.0.0)
43
- Requires-Dist: pytz (>=2024.2,<2025.0)
44
- Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
45
- Requires-Dist: requests (>=2.28.2,<3.0.0)
46
- Requires-Dist: simplejson (>=3.20.1,<4.0.0)
47
- Requires-Dist: sqlalchemy (>=2.0.32,<3.0.0)
48
- Requires-Dist: sqlalchemy-bigquery (>=1.11.0,<2.0.0) ; extra == "bigquery"
49
- Requires-Dist: tenacity (>=9.0.0,<10.0.0)
44
+ Requires-Dist: pika>=1.3.2; extra == 'rabbitmq'
50
45
  Description-Content-Type: text/markdown
51
46
 
52
47
  # bizon ⚡️
@@ -73,8 +68,34 @@ Extract and load your largest data streams with a framework you can trust for bi
73
68
  - `pyarrow` for Parquet file format
74
69
 
75
70
  ## Installation
71
+
72
+ ### For Users
76
73
  ```bash
77
74
  pip install bizon
75
+
76
+ # With optional dependencies
77
+ pip install bizon[postgres] # PostgreSQL backend
78
+ pip install bizon[kafka] # Kafka queue
79
+ pip install bizon[bigquery] # BigQuery backend/destination
80
+ pip install bizon[rabbitmq] # RabbitMQ queue
81
+ ```
82
+
83
+ ### For Development
84
+ ```bash
85
+ # Install uv (if not already installed)
86
+ pip install uv
87
+
88
+ # Clone and install
89
+ git clone https://github.com/bizon-data/bizon-core.git
90
+ cd bizon-core
91
+ uv sync --all-extras --all-groups
92
+
93
+ # Run tests
94
+ uv run pytest tests/
95
+
96
+ # Format code
97
+ uv run ruff format .
98
+ uv run ruff check --fix .
78
99
  ```
79
100
 
80
101
  ## Usage
@@ -176,4 +197,3 @@ engine:
176
197
  host: localhost
177
198
  queue_name: bizon
178
199
  ```
179
-
@@ -0,0 +1,136 @@
1
+ bizon/__main__.py,sha256=6GV4zEg2wC8UBnmESrr71ZmpWo4cNWlrYE3PQuKwFHA,69
2
+ bizon/utils.py,sha256=HXaPiyxpWKoy3XN5vSYOve1ezlFeOYin3aFqTjcabUQ,81
3
+ bizon/alerting/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ bizon/alerting/alerts.py,sha256=i3c5Y7WcyzPHqilkP8CrujwXVd058Lb0W7XsjB1Ef7w,675
5
+ bizon/alerting/models.py,sha256=kWTeoT7dDC6UrkybU1sRAIXNAE0Wwipf8W7dEEhMZM0,553
6
+ bizon/alerting/slack/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ bizon/alerting/slack/config.py,sha256=D_CAtzXu-O41OVoyrlYRlBxnGN9rNbnohYQ9CmBYt_E,84
8
+ bizon/alerting/slack/handler.py,sha256=0m6IUSkxqDMlpDWslkImQX74ScD8wIx3YtrhfpYNGUA,1620
9
+ bizon/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ bizon/cli/main.py,sha256=pQnphPLznllBVzifyIrn3es0U9E1VGSzeEv_COzq9FI,3364
11
+ bizon/cli/utils.py,sha256=aZ47YjFfifHkW95bAVzWfEQD3ZnxGSMT32bkRLmc5-c,953
12
+ bizon/common/models.py,sha256=eL_Ii0CkeJFIjak1CKrB74mbC3OkmWP2uI27ynlYgkQ,10070
13
+ bizon/common/errors/backoff.py,sha256=z7RkQt1Npdh0sfD3hBDaiWQKe4iqS6ewvT1Q4Fds5aU,508
14
+ bizon/common/errors/errors.py,sha256=mrYx1uE2kOuR2pEaB7ztK1l2m0E4V-_-hxq-DuILerY,682
15
+ bizon/connectors/destinations/bigquery/config/bigquery.example.yml,sha256=sy5-Piew00BlcjX5CFayFVrUq9G_vFYWXDmpWi9beTY,1263
16
+ bizon/connectors/destinations/bigquery/src/config.py,sha256=q55zR_9V5-ZZmOmSK7fDOHSzzYhoT-fwlppDzX4he9U,4000
17
+ bizon/connectors/destinations/bigquery/src/destination.py,sha256=wJHT9KO5aA8sLEqgVbb9aVCXZ51_5ccgkPtTCXuBp6s,9503
18
+ bizon/connectors/destinations/bigquery_streaming/config/bigquery_streaming.example.yml,sha256=rF0mQ5IaOe6oqsbVy6q0innn7SXsOoBdBvIN8BTwPVc,1869
19
+ bizon/connectors/destinations/bigquery_streaming/src/config.py,sha256=LdBKEqHPaGll8PW6c6q_lH7PJvsGdtv2BCrtB-TukTA,1898
20
+ bizon/connectors/destinations/bigquery_streaming/src/destination.py,sha256=6PLO0zMbPskwtaeKfnOvu5Ls0Z-gl11uXHMCPIEdHmc,16043
21
+ bizon/connectors/destinations/bigquery_streaming_v2/config/bigquery_streaming_v2.example.yml,sha256=hIQXlXtiBT8DgMVAs0x_h-19xoLkjHr-Ko7oSn8jnc0,2023
22
+ bizon/connectors/destinations/bigquery_streaming_v2/src/config.py,sha256=cdHST5Vx1VQbLsIVsPkoEtOJKmbA35XjsKzj6fZ5DHw,1907
23
+ bizon/connectors/destinations/bigquery_streaming_v2/src/destination.py,sha256=GSByVunYPXqaVbPbQGDKJX3b4ngUenHbvdJKIlb95a8,18680
24
+ bizon/connectors/destinations/bigquery_streaming_v2/src/proto_utils.py,sha256=aWYVzMPMTgsdDapYniu8h6Tf2Pty4fDisT_33d9yEJ4,3692
25
+ bizon/connectors/destinations/file/config/file.example.yml,sha256=sMeX92hTrTQUrLmQgQFsq5OdG5Dk3BbpDo0NhRbBahI,986
26
+ bizon/connectors/destinations/file/src/config.py,sha256=dU64aFe7J63aBGh6Os8mXl2kvECj3s4pPC7H3EmOvb8,585
27
+ bizon/connectors/destinations/file/src/destination.py,sha256=iVmFjLjjuGRD6jbivOUqSlYxtIIMz9buB5fvXpYMsYA,1827
28
+ bizon/connectors/destinations/logger/config/logger.example.yml,sha256=KtQRmqqFeziJtBZ7vzrXGQLdTgWZNjxx2sdFXpIgIp4,672
29
+ bizon/connectors/destinations/logger/src/config.py,sha256=vIV_G0k9c8DPcDxU6CGvEOL2zAEvAmKZcx3RV0eRi7A,426
30
+ bizon/connectors/destinations/logger/src/destination.py,sha256=-KosqybNiJq3-mlrrxa0cSUdwmaDcelfeRQcytbfjBQ,1226
31
+ bizon/connectors/sources/cycle/config/cycle.example.yml,sha256=UDiqOa-8ZsykmNT625kxq9tyXOj_gKe9CFwg9r_8SYk,230
32
+ bizon/connectors/sources/cycle/src/source.py,sha256=6sXMneq59XZAT5oJseM9k6sGJaoQw4NDp8FTtg8lPhk,4213
33
+ bizon/connectors/sources/cycle/tests/cycle_customers.py,sha256=A48S20LxIC0A74JLoFn4NTHNTgBWV_5stTFtF1Gfk2c,271
34
+ bizon/connectors/sources/dummy/config/dummy.example.yml,sha256=Wvn8v644u1aKvRRsPzPPML4kYmWk0ZhMGrCPFoSbVZQ,331
35
+ bizon/connectors/sources/dummy/src/fake_api.py,sha256=5EEETp9INOmDJ57FNXm6wnsRtofQmR1xYp8hUKjn0Es,3067
36
+ bizon/connectors/sources/dummy/src/source.py,sha256=IAfNdd2CX8QzprAwLLVDGT3dd5a-bFa5BkkuRUTWGTc,4078
37
+ bizon/connectors/sources/dummy/tests/dummy_pipeline.py,sha256=V9EKvugFXm3aNQVip-kMzlmvjlW6sZNGldxW1WdRa-E,397
38
+ bizon/connectors/sources/dummy/tests/dummy_pipeline_bigquery_backend.py,sha256=SO_x_IH9iY1e09NHJlS1-CON0SI21fxGFqljSz4EmM4,542
39
+ bizon/connectors/sources/dummy/tests/dummy_pipeline_kafka.py,sha256=zKhE7dhd6C4E_7VMepR8nSsGnesTJWXwlak-Dj01GD0,473
40
+ bizon/connectors/sources/dummy/tests/dummy_pipeline_rabbitmq.py,sha256=A6KmSEOlWMK0UuIZhZxWO8y-z8h19rtWEV8DuhKX8Xs,686
41
+ bizon/connectors/sources/dummy/tests/dummy_pipeline_unnest.py,sha256=64ZhjXUyZHzaIZTL_DO425yN6SlpB1vxzfhziE_pSEw,510
42
+ bizon/connectors/sources/dummy/tests/dummy_pipeline_write_data_bigquery.py,sha256=oTV9HmOzjs3B2WwTPzDlIT_VkoYuXxy1BtSkeTGkQqw,686
43
+ bizon/connectors/sources/dummy/tests/dummy_pipeline_write_data_bigquery_through_kafka.py,sha256=PFUhDuFw1Q1AMNMsnXPQxoqHIWf_wHEL1hLQodYlLcQ,596
44
+ bizon/connectors/sources/gsheets/config/default_auth.example.yml,sha256=KOBp6MfO4uJwpwEYW0tJ4X5ctVwwdur9poJB4Ohba6s,348
45
+ bizon/connectors/sources/gsheets/config/service_account.example.yml,sha256=XxVUnk9gGWc3lDb8CnzTHjTu8xz4Asyr5tXzY6qLvPg,1081
46
+ bizon/connectors/sources/gsheets/src/source.py,sha256=xNF5FR9QLTM4kCiZ2eKZ5CZWNhLw6tyLaJZbliNzYnY,5675
47
+ bizon/connectors/sources/gsheets/tests/gsheets_pipeline.py,sha256=lNSM3kZTd4W_-ajGIO3mdp8qGdEbnmWqsMm5pRiS0cw,181
48
+ bizon/connectors/sources/hubspot/config/api_key.example.yml,sha256=VDTRloE5caqAdGdXgvsJZ6nQT46JHzX_YboxeGbpP18,389
49
+ bizon/connectors/sources/hubspot/config/oauth.example.yml,sha256=YqBtj1IxIsdM9E85_4eVWl6mPiHsQNoQn41EzCqORy0,499
50
+ bizon/connectors/sources/hubspot/src/hubspot_base.py,sha256=THo8ImrPrIxeTuFcBMRJYwaDMstIfLIGjrQLE2cqqsU,3424
51
+ bizon/connectors/sources/hubspot/src/hubspot_objects.py,sha256=ykqvxaFihv0e0A3-gGDmentp1KCGCoYvvDwZ3CcHzNg,6301
52
+ bizon/connectors/sources/hubspot/src/models/hs_object.py,sha256=IuuMB_54kiEAZRDvl3AOVdktyZsLeYDRB2qoOVd1TZg,1234
53
+ bizon/connectors/sources/hubspot/tests/hubspot_pipeline.py,sha256=e6dCF5_MHMySkeiF6kKrSAuCa_48J22-ZeSCZSjrfUI,216
54
+ bizon/connectors/sources/kafka/config/kafka.example.yml,sha256=taIj3QUL3jynQCpO-YlDtt6nGvQp8hOzGkS0_RJFUQU,933
55
+ bizon/connectors/sources/kafka/config/kafka_debezium.example.yml,sha256=lqFbNbSAFRh1Q8a9xQ_7nhhvVsyVIZM4amGEvCqHXQE,2254
56
+ bizon/connectors/sources/kafka/config/kafka_streams.example.yml,sha256=aGiGMDMG6l0RUhrSVYl9djw1yy6T--2QOfwesuNhF1g,3368
57
+ bizon/connectors/sources/kafka/src/callback.py,sha256=NgP9PLquHbVagz6E9VJK5Vx-kK8K2l80MhoeenbhOXY,484
58
+ bizon/connectors/sources/kafka/src/config.py,sha256=Plb-d59PmQSie7vxAIPpJrwbpbA7pT6Xua0joR86nKI,2764
59
+ bizon/connectors/sources/kafka/src/decode.py,sha256=RhPjazRQHb72D9iBhb763Nje7SH9t_6EKaFW-BtGVpM,2800
60
+ bizon/connectors/sources/kafka/src/source.py,sha256=0Hv6viyVZGAd4azhQnqCteyHuwsbbDL4rSGEjMCff9E,19722
61
+ bizon/connectors/sources/kafka/tests/kafka_pipeline.py,sha256=9LaCqXJIEx2ye3dkWq0YK_bPX7d4fCX_OcDOJCk34WE,206
62
+ bizon/connectors/sources/notion/config/api_key.example.yml,sha256=TagqOqaho4u_G5ZP4L8je89Y4G_NvCo8s4Wf9e8yVH8,1061
63
+ bizon/connectors/sources/notion/src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
+ bizon/connectors/sources/notion/src/config.py,sha256=L-FZWijUa-aWK9VenWGsl6mv40i4ww46FacjYoX9gXo,1886
65
+ bizon/connectors/sources/notion/src/source.py,sha256=QG0z6uCRpIKa-BI7NfLUubb_p7_-z6WSWr8gpjWNHfY,50548
66
+ bizon/connectors/sources/notion/tests/notion_pipeline.py,sha256=lyiD9b5uUF3oih8vY4gk7QXnfySGSawnbrBuSdTLym8,200
67
+ bizon/connectors/sources/notion/tests/test_notion.py,sha256=-G0DbTLDS2Gc_Bx8xR2VXnY89vW64s1-puwPc9x2N7A,4029
68
+ bizon/connectors/sources/periscope/config/periscope_charts.example.yml,sha256=9OgFDB7vguiNz2F2fmRqDNV8S_ddO9ncN5hgW9MhME4,350
69
+ bizon/connectors/sources/periscope/config/periscope_dashboards.example.yml,sha256=mQey_04cfCzNpm-tYICDRUmPOFTZGSaTYI2OpK604d0,364
70
+ bizon/connectors/sources/periscope/src/source.py,sha256=WePeQLn5hkPArhzgJ5gBCRu6VXbTpvOImUk7NN4mi0c,12270
71
+ bizon/connectors/sources/periscope/tests/periscope_pipeline_charts.py,sha256=mU0JtfhS1KmWsS3iovGhGxK7iPVWiYzjBM_QfRL3ZQI,275
72
+ bizon/connectors/sources/periscope/tests/periscope_pipeline_dashboard.py,sha256=VmkixgCMLTqNPXYXPYqcK7ncHeeR96h68IXPcuC70iA,290
73
+ bizon/connectors/sources/pokeapi/config/pokeapi_pokemon_to_json.example.yml,sha256=H3FpBsyft5qSvuyurh-hhaASpq7GnehNeVAOOn31Txk,283
74
+ bizon/connectors/sources/pokeapi/config/pokeapi_pokemon_to_logger.example.yml,sha256=wuJUob6QF1jwm5pnfNcFfXeO01HCcu-TEoZCeuYl_lo,134
75
+ bizon/connectors/sources/pokeapi/src/source.py,sha256=OeDUXKciu7p5tBJ2LeA6oseMd-gqqpxk50g7DXVaODA,2537
76
+ bizon/connectors/sources/sana_ai/config/sana.example.yml,sha256=sWOGxKMG9Cjgn11rNDCjcBL_YZdnUYvBLU7P9zfS3DE,802
77
+ bizon/connectors/sources/sana_ai/src/source.py,sha256=ZAfv_OwkPXuwJF7KFe6eYQ0rmadTdot20X3L_gmTrs8,3212
78
+ bizon/destination/buffer.py,sha256=tCwlm0iGo0RM5EeTnOiKI5Pz_JfHsJv6U3oIA9Va8_0,3155
79
+ bizon/destination/config.py,sha256=dv_zHrFUs4X4paCglaKdSbBLfZRzfaNEQKUSVv0j8tU,3033
80
+ bizon/destination/destination.py,sha256=qkEhnfCxI8JmCf43fyyFVpYuGiY6oc3pkVl5o2RaQeI,14614
81
+ bizon/destination/models.py,sha256=_LUnkbbD_9XauYrNTthh9VmbYwWsVgPHF90FX6vmSjg,1278
82
+ bizon/engine/config.py,sha256=tqc3K2i99BH_SSRRzfRpzSXoqux929Q6eg2oRsfjjcY,2038
83
+ bizon/engine/engine.py,sha256=Xl8Bghx0kMlvST8S3uwxrcZ6cvqy525Kv94BOvAvr8U,1705
84
+ bizon/engine/backend/backend.py,sha256=4J6uLKVh0hIPkOYO5XEg4ia8mPlOS13C3hSrIJ171VA,5849
85
+ bizon/engine/backend/config.py,sha256=GhRzPWRGMaO-UJJRXkaqN_nlkFOCW6UOovwZLHLXrA8,900
86
+ bizon/engine/backend/models.py,sha256=ECImDNji7u9eSkkjiw8sYq80l17vDF7MplTFvCpMgqA,5101
87
+ bizon/engine/backend/adapters/sqlalchemy/backend.py,sha256=ipJ7eY_iiqjrvtq4NS39C5lH8VShMjXDAaApgTHJtpY,15435
88
+ bizon/engine/backend/adapters/sqlalchemy/config.py,sha256=CeTWncVK27Y6lEKMVCF5RxD8Illhx2IQqqFkGrf0WKA,1845
89
+ bizon/engine/pipeline/consumer.py,sha256=DtCR3mG791h35poYJdXjL9geNO-GWPKl_YC0zPsF5qI,3207
90
+ bizon/engine/pipeline/models.py,sha256=qOra2MJGN6-PuouKpKuZRjutnQmzom0mgWDFZ16LcM8,405
91
+ bizon/engine/pipeline/producer.py,sha256=8e7cKcZh3_Irz4ceb3NzIDD8X915U26eGONqgNiYpKQ,10017
92
+ bizon/engine/queue/config.py,sha256=0XwiQSB2OKTs-rODCSZqT5txNZzGOic2-PvODbcSrGg,1267
93
+ bizon/engine/queue/queue.py,sha256=Y9uj31d-ZgW2f0F02iccp_o-m-RoMm_jR61NkLdMQ2M,3461
94
+ bizon/engine/queue/adapters/kafka/config.py,sha256=ndNEXRT-nIgyWgoqlNXFhmlN206v87GobXIW9Z0zrSA,1085
95
+ bizon/engine/queue/adapters/kafka/consumer.py,sha256=JPpvp3u5NXGvKRo60-ihRI4DlZxGJB1qH5Qw91XT8qc,2576
96
+ bizon/engine/queue/adapters/kafka/queue.py,sha256=4baF7ns7LH3rQOjLjLSw2P7Ey4omRaVrxs_0atYyeSo,2000
97
+ bizon/engine/queue/adapters/python_queue/config.py,sha256=_pyiIm1_PUjBo3WhKTATQcT2gazk-iHv0SdzNoGTeow,961
98
+ bizon/engine/queue/adapters/python_queue/consumer.py,sha256=uVXOnS6tjhZG5NI_IU_qWg6-Uk3qjFJaMvDBDjQXjZg,1817
99
+ bizon/engine/queue/adapters/python_queue/queue.py,sha256=jwKeqvJ4wzPbXIY1JnVrqBemRQ52A2tLzybwyJk4TL8,2670
100
+ bizon/engine/queue/adapters/rabbitmq/config.py,sha256=9N_7WREvNjJgcNTC3Y2kHII-iId2MZa3ssHHks6PyAs,987
101
+ bizon/engine/queue/adapters/rabbitmq/consumer.py,sha256=WlNHEqd5wZc31cwNLYYf_7YYPo2B3jYHTiyG5pW3Bj4,2037
102
+ bizon/engine/queue/adapters/rabbitmq/queue.py,sha256=O0DfzNKqzKfUZCTOnEcbaHY_W67WbZkKDSeZAkh4Nf0,1744
103
+ bizon/engine/runner/config.py,sha256=Clxa8ToeisaBH5BveZz06jSJeq8QRJTH-a_oXBIWxgw,2455
104
+ bizon/engine/runner/runner.py,sha256=P5GJigzsbPQp7NKrX1pHqXdqmxiXHNtlrx3DB7vOA3Y,11067
105
+ bizon/engine/runner/adapters/process.py,sha256=D1KJxK85GNvi4bGQ_YMoV44psWZvhNvqdMu-OfhNO5o,3049
106
+ bizon/engine/runner/adapters/streaming.py,sha256=PPdhwA5oTNXH7NXB5-uye2asT4L0Zhfrx_wZFDDCsq4,8300
107
+ bizon/engine/runner/adapters/thread.py,sha256=jQ2jzSe7zlZoPP_g46Oh70UN6RqJkGOMXC01SYg9s2o,3790
108
+ bizon/monitoring/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
109
+ bizon/monitoring/config.py,sha256=wRZRfW4ejjFDSG6swWj7kIULlaNYUPdbIKblQC9lzsk,1112
110
+ bizon/monitoring/monitor.py,sha256=aJ3JEgD-f-HydGFAmprwL8YCA0WumDeXpm2P-uqp4wM,2627
111
+ bizon/monitoring/datadog/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
112
+ bizon/monitoring/datadog/monitor.py,sha256=YSdyMVEIjkDyp91_mGED_kx8j76MbQyQGkGJCijpAJ0,6152
113
+ bizon/monitoring/noop/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
114
+ bizon/monitoring/noop/monitor.py,sha256=Pu7Qt9SpUG1UvC8aWysgtoDY-t5tnKd4FlUXAC4MjbI,1066
115
+ bizon/source/callback.py,sha256=lfTwU_bzJwR0q5sbiKoK8uedQ-dhfHzoYkPVqm8b_Ho,602
116
+ bizon/source/config.py,sha256=0wQiX8VJJq9w0hALJkqIxMH4Wa760LhsieCy2VmUcfo,2223
117
+ bizon/source/cursor.py,sha256=Wjh9eNEiHV5P9YnjS5bdS2ahyFc0gPm9QLQtD-QjQCI,4089
118
+ bizon/source/discover.py,sha256=h9IVqtAQsTH-XxR-UkAFgNvEphLP2LgataQCCuHbGrk,11174
119
+ bizon/source/models.py,sha256=cncnIgZF-kQM0e08trvNgOHQ6AnQK8ko3GzgOGuWwgE,1705
120
+ bizon/source/session.py,sha256=klbCv0g6sm6ac-pzM50eAJSP8DdQ9DOegHgjpmKKUrI,1978
121
+ bizon/source/source.py,sha256=k_fHOOvam5ixZ9oPuQzUa9Kq3jVvv2HY7ghrCo-0o3I,4342
122
+ bizon/source/auth/builder.py,sha256=hc4zBNj31LZc-QqgIyx1VQEYTm9Xv81vY5pJiwQroJo,860
123
+ bizon/source/auth/config.py,sha256=2jjcBLP95XsCkfKxdUei4X2yHI2WX92lJb8D8Txw86g,750
124
+ bizon/source/auth/authenticators/abstract_oauth.py,sha256=T4iv4IDeQgRn1d_0ODJeGA23PlieSpaD8w5zgLXPFI8,5573
125
+ bizon/source/auth/authenticators/abstract_token.py,sha256=GYM4srti2VLYVuAvozv6AdqXrIzXw0HROzhvVq5YhCo,926
126
+ bizon/source/auth/authenticators/basic.py,sha256=xMD9g1PCN-xBmGRT8R1zCiSrkqA_OpOb_pU54SgZoUk,1284
127
+ bizon/source/auth/authenticators/cookies.py,sha256=mqNp6TGEfyam7ou-s-908Jh8R0ZeX89ftbeExDWg1oY,829
128
+ bizon/source/auth/authenticators/oauth.py,sha256=tY_UZsWTy4FkifqJ7-smPaD61gg1dMJizO9_iSqTt5o,3670
129
+ bizon/source/auth/authenticators/token.py,sha256=P6SKRAarAEv28YiWp8hQLSKAV7twNlyNTGRr9sxlx58,956
130
+ bizon/transform/config.py,sha256=Q9F7jlsuaXK8OYrO5qcdk8lxXTDoIgzoVMhhHW3igEw,213
131
+ bizon/transform/transform.py,sha256=Ufla8YFx9C9WEiN0ppmZS1a86Sk0PgggqC-8DIvDeAQ,1414
132
+ bizon-0.2.0.dist-info/METADATA,sha256=ArxHLLJlMkVTo6mYoaeiLco_inGdcjPivIB9gOki-QA,6322
133
+ bizon-0.2.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
134
+ bizon-0.2.0.dist-info/entry_points.txt,sha256=hHZPN-V6JwwhSYWNCKVu3WNxekuhXtIAaz_zdwO7NDo,45
135
+ bizon-0.2.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
136
+ bizon-0.2.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.1.3
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ bizon = bizon.cli.main:cli