port-ocean 0.1.3rc4__py3-none-any.whl → 0.1.4.dev2__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.

Potentially problematic release.


This version of port-ocean might be problematic. Click here for more details.

@@ -3,6 +3,7 @@
3
3
  import click
4
4
  from cookiecutter.main import cookiecutter # type: ignore
5
5
 
6
+ from port_ocean import __version__
6
7
  from port_ocean.cli.commands.main import cli_start, print_logo, console
7
8
  from port_ocean.cli.utils import cli_root_path
8
9
 
@@ -21,7 +22,11 @@ def new(path: str) -> None:
21
22
  "🚢 Unloading cargo... Setting up your integration at the dock.", style="bold"
22
23
  )
23
24
 
24
- result = cookiecutter(f"{cli_root_path}/cookiecutter", output_dir=path)
25
+ result = cookiecutter(
26
+ f"{cli_root_path}/cookiecutter",
27
+ output_dir=path,
28
+ extra_context={"version": __version__},
29
+ )
25
30
  name = result.split("/")[-1]
26
31
 
27
32
  console.print(
@@ -6,7 +6,7 @@ authors = ["{{cookiecutter.full_name}} <{{cookiecutter.email}}>"]
6
6
 
7
7
  [tool.poetry.dependencies]
8
8
  python = "^3.11"
9
- port_ocean = { version = "^0.1.0", extras = ["cli"] }
9
+ port_ocean = { version = "^{{ cookiecutter.version }}", extras = ["cli"] }
10
10
 
11
11
  [tool.poetry.group.dev.dependencies]
12
12
  pytest = "^7.2"
port_ocean/config/base.py CHANGED
@@ -8,7 +8,7 @@ from humps import decamelize
8
8
  from pydantic import BaseSettings
9
9
  from pydantic.env_settings import EnvSettingsSource, InitSettingsSource
10
10
 
11
- PROVIDER_WRAPPER_PATTERN = r"\\{\\{ from (.*) \\}\\}"
11
+ PROVIDER_WRAPPER_PATTERN = r"{{ from (.*) }}"
12
12
  PROVIDER_CONFIG_PATTERN = r"^[a-zA-Z0-9]+ .*$"
13
13
 
14
14
 
@@ -5,6 +5,9 @@ from pydantic import BaseModel, Extra
5
5
 
6
6
 
7
7
  class EventListenerEvents(TypedDict):
8
+ """
9
+ A dictionary containing event types and their corresponding event handlers.
10
+ """
8
11
  on_resync: Callable[[dict[Any, Any]], Awaitable[None]]
9
12
 
10
13
 
@@ -24,4 +27,8 @@ class EventListenerSettings(BaseModel, extra=Extra.allow):
24
27
  type: str
25
28
 
26
29
  def to_request(self) -> dict[str, Any]:
30
+ """
31
+ Converts the Settings object to a dictionary representation (request format).
32
+ This method is used when configuring the event listener settings for the Polling event listener.
33
+ """
27
34
  return {"type": self.type}
@@ -20,6 +20,16 @@ from port_ocean.exceptions.core import UnsupportedEventListenerTypeException
20
20
 
21
21
 
22
22
  class EventListenerFactory(BaseWithContext):
23
+ """
24
+ This class is responsible for creating different types of event listeners based on the provided configuration.
25
+ The factory takes a PortOceanContext, installation_id, and events dictionary as parameters.
26
+
27
+ Parameters:
28
+ context (PortOceanContext): The PortOceanContext object containing information about the current application context.
29
+ installation_id (str): The identifier of the installation associated with the event listener.
30
+ events (EventListenerEvents): A dictionary containing event types and their corresponding event handlers.
31
+
32
+ """
23
33
  def __init__(
24
34
  self,
25
35
  context: PortOceanContext,
@@ -31,6 +41,13 @@ class EventListenerFactory(BaseWithContext):
31
41
  self.events = events
32
42
 
33
43
  async def create_event_listener(self) -> BaseEventListener:
44
+ """
45
+ Creates and returns a specific event listener based on the provided configuration.
46
+ The event listener is wrapped with the events provided in the factory's initialization.
47
+
48
+ Raises:
49
+ UnsupportedEventListenerTypeException: If the event listener type is not supported.
50
+ """
34
51
  wrapped_events: EventListenerEvents = {"on_resync": self.events["on_resync"]}
35
52
  event_listener: BaseEventListener
36
53
  config = self.context.config.event_listener
File without changes
@@ -13,6 +13,15 @@ from port_ocean.core.event_listener.base import (
13
13
 
14
14
 
15
15
  class HttpEventListenerSettings(EventListenerSettings):
16
+ """
17
+ This class inherits from `EventListenerSettings`, which provides a foundation for defining event listener configurations.
18
+ The `HttpEventListenerSettings` specifically includes settings related to the HTTP event listener (Webhook).
19
+
20
+ Attributes:
21
+ type (Literal["WEBHOOK"]): A literal indicating the type of the event listener, which is set to "WEBHOOK" for this class.
22
+ app_host (AnyHttpUrl): The base URL of the application hosting the webhook.
23
+ The "AnyHttpUrl" type indicates that the value must be a valid HTTP/HTTPS URL.
24
+ """
16
25
  type: Literal["WEBHOOK"]
17
26
  app_host: AnyHttpUrl
18
27
 
@@ -24,6 +33,16 @@ class HttpEventListenerSettings(EventListenerSettings):
24
33
 
25
34
 
26
35
  class HttpEventListener(BaseEventListener):
36
+ """
37
+ HTTP event listener that listens for webhook events and triggers "on_resync" event.
38
+
39
+ This class inherits from `BaseEventListener`, which provides a foundation for creating event listeners.
40
+ The `HttpEventListener` listens for HTTP POST requests to the `/resync` endpoint and triggers the "on_resync" event.
41
+
42
+ Parameters:
43
+ events (EventListenerEvents): A dictionary containing event types and their corresponding event handlers.
44
+ event_listener_config (HttpEventListenerSettings): Configuration settings for the HTTP event listener.
45
+ """
27
46
  def __init__(
28
47
  self,
29
48
  events: EventListenerEvents,
@@ -33,6 +52,10 @@ class HttpEventListener(BaseEventListener):
33
52
  self.event_listener_config = event_listener_config
34
53
 
35
54
  async def start(self) -> None:
55
+ """
56
+ Starts the HTTP event listener.
57
+ It sets up an APIRouter to handle the `/resync` endpoint and registers the "on_resync" event handler.
58
+ """
36
59
  logger.info("Setting up HTTP Event Listener")
37
60
  target_channel_router = APIRouter()
38
61
 
File without changes
@@ -17,6 +17,23 @@ from port_ocean.core.event_listener.base import (
17
17
 
18
18
 
19
19
  class KafkaEventListenerSettings(EventListenerSettings):
20
+ """
21
+ This class inherits from `EventListenerSettings`, which provides a foundation for defining event listener configurations.
22
+ The `KafkaEventListenerSettings` specifically includes settings related to the Kafka event listener.
23
+
24
+ Attributes:
25
+ type (Literal["KAFKA"]): A literal indicating the type of the event listener, which is set to "KAFKA" for this class.
26
+ brokers (str): The comma-separated list of Kafka broker URLs to connect to.
27
+ security_protocol (str): The security protocol used for communication with Kafka brokers.
28
+ The default value is "SASL_SSL".
29
+ authentication_mechanism (str): The authentication mechanism used for secure access to Kafka brokers.
30
+ The default value is "SCRAM-SHA-512".
31
+ kafka_security_enabled (bool): A flag indicating whether Kafka security is enabled.
32
+ If True, credentials and security settings are used to connect to Kafka.
33
+ The default value is True.
34
+ consumer_poll_timeout (int): The maximum time in seconds to wait for messages during a poll.
35
+ The default value is 1 second.
36
+ """
20
37
  type: Literal["KAFKA"]
21
38
  brokers: str = "b-1-public.publicclusterprod.t9rw6w.c1.kafka.eu-west-1.amazonaws.com:9196,b-2-public.publicclusterprod.t9rw6w.c1.kafka.eu-west-1.amazonaws.com:9196,b-3-public.publicclusterprod.t9rw6w.c1.kafka.eu-west-1.amazonaws.com:9196"
22
39
  security_protocol: str = "SASL_SSL"
@@ -26,6 +43,16 @@ class KafkaEventListenerSettings(EventListenerSettings):
26
43
 
27
44
 
28
45
  class KafkaEventListener(BaseEventListener):
46
+ """
47
+ The `KafkaEventListener` specifically listens for messages from a Kafka consumer related to changes in an integration.
48
+
49
+ Parameters:
50
+ events (EventListenerEvents): A dictionary containing event types and their corresponding event handlers.
51
+ event_listener_config (KafkaEventListenerSettings): Configuration settings for the Kafka event listener.
52
+ org_id (str): The identifier of the organization associated with the integration.
53
+ integration_identifier (str): The identifier of the integration being monitored.
54
+ integration_type (str): The type of the integration being monitored.
55
+ """
29
56
  def __init__(
30
57
  self,
31
58
  events: EventListenerEvents,
@@ -41,6 +68,11 @@ class KafkaEventListener(BaseEventListener):
41
68
  self.integration_type = integration_type
42
69
 
43
70
  async def _get_kafka_config(self) -> KafkaConsumerConfig:
71
+ """
72
+ A private method that returns the Kafka consumer configuration based on the provided settings.
73
+ If Kafka security is enabled, it fetches Kafka credentials using the ocean.port_client.get_kafka_creds() method.
74
+ Otherwise, it returns the KafkaConsumerConfig object parsed from the event_listener_config.
75
+ """
44
76
  if self.event_listener_config.kafka_security_enabled:
45
77
  creds = await ocean.port_client.get_kafka_creds()
46
78
  return KafkaConsumerConfig(
@@ -52,7 +84,11 @@ class KafkaEventListener(BaseEventListener):
52
84
 
53
85
  return KafkaConsumerConfig.parse_obj(self.event_listener_config.dict())
54
86
 
55
- def should_be_processed(self, msg_value: dict[Any, Any], topic: str) -> bool:
87
+ def _should_be_processed(self, msg_value: dict[Any, Any], topic: str) -> bool:
88
+ """
89
+ Determines if a given message should be processed based on the integration identifier and topic.
90
+ Returns True if the message should be processed, False otherwise.
91
+ """
56
92
  integration_identifier = (
57
93
  msg_value.get("diff", {}).get("after", {}).get("identifier")
58
94
  )
@@ -64,15 +100,22 @@ class KafkaEventListener(BaseEventListener):
64
100
  return False
65
101
 
66
102
  async def _handle_message(self, message: dict[Any, Any], topic: str) -> None:
67
- if not self.should_be_processed(message, topic):
103
+ """
104
+ A private method that handles incoming Kafka messages.
105
+ If the message should be processed (determined by `_should_be_processed`), it triggers the corresponding event handler.
106
+ """
107
+ if not self._should_be_processed(message, topic):
68
108
  return
69
109
 
70
110
  if "change.log" in topic and message is not None:
71
111
  await self.events["on_resync"](message)
72
112
 
73
- def wrapped_start(
113
+ def _wrapped_start(
74
114
  self, context: PortOceanContext, func: Callable[[], None]
75
115
  ) -> Callable[[], None]:
116
+ """
117
+ A method that wraps the `start` method, initializing the PortOceanContext and invoking the given function.
118
+ """
76
119
  ocean_app = context.app
77
120
 
78
121
  def wrapper() -> None:
@@ -82,6 +125,10 @@ class KafkaEventListener(BaseEventListener):
82
125
  return wrapper
83
126
 
84
127
  async def start(self) -> None:
128
+ """
129
+ The main method that starts the Kafka consumer.
130
+ It creates a KafkaConsumer instance with the given configuration and starts it in a separate thread.
131
+ """
85
132
  consumer = KafkaConsumer(
86
133
  msg_process=self._handle_message,
87
134
  config=await self._get_kafka_config(),
@@ -90,5 +137,5 @@ class KafkaEventListener(BaseEventListener):
90
137
  logger.info("Starting Kafka consumer")
91
138
  threading.Thread(
92
139
  name="ocean_kafka_consumer",
93
- target=self.wrapped_start(ocean, consumer.start),
140
+ target=self._wrapped_start(ocean, consumer.start),
94
141
  ).start()
@@ -12,6 +12,14 @@ from port_ocean.core.event_listener.polling.utils import repeat_every
12
12
 
13
13
 
14
14
  class PollingEventListenerSettings(EventListenerSettings):
15
+ """
16
+ Attributes:
17
+ type (Literal["POLLING"]): A literal indicating the type of the event listener, which is set to "POLLING" for this class.
18
+ resync_on_start (bool): A flag indicating whether to trigger a resync event on the start of the polling event listener.
19
+ If True, the "on_resync" event will be triggered immediately when the polling listener starts.
20
+ interval (int): The interval in seconds at which the polling event listener checks for changes in the integration.
21
+ The default interval is set to 60 seconds.
22
+ """
15
23
  type: Literal["POLLING"]
16
24
  resync_on_start: bool = True
17
25
  interval: int = 60
@@ -21,6 +29,15 @@ class PollingEventListenerSettings(EventListenerSettings):
21
29
 
22
30
 
23
31
  class PollingEventListener(BaseEventListener):
32
+ """
33
+ Polling event listener that checks for changes in the integration every `interval` seconds.
34
+
35
+ The `PollingEventListener` periodically checks for changes in the integration and triggers the "on_resync" event if changes are detected.
36
+
37
+ Parameters:
38
+ events (EventListenerEvents): A dictionary containing event types and their corresponding event handlers.
39
+ event_listener_config (PollingEventListenerSettings): Configuration settings for the Polling event listener.
40
+ """
24
41
  def __init__(
25
42
  self,
26
43
  events: EventListenerEvents,
@@ -31,6 +48,11 @@ class PollingEventListener(BaseEventListener):
31
48
  self._last_updated_at = None
32
49
 
33
50
  async def start(self) -> None:
51
+ """
52
+ Starts the polling event listener.
53
+ It registers the "on_resync" event to be called every `interval` seconds specified in the `event_listener_config`.
54
+ The `on_resync` event is triggered if the integration has changed since the last update.
55
+ """
34
56
  logger.info(
35
57
  f"Setting up Polling event listener with interval: {self.event_listener_config.interval}"
36
58
  )
@@ -1,4 +1,5 @@
1
1
  import asyncio
2
+ from collections import defaultdict
2
3
  from itertools import groupby
3
4
 
4
5
  from port_ocean.clients.port.client import PortClient
@@ -33,12 +34,18 @@ async def get_related_entities(
33
34
  for entity in entities_with_relations
34
35
  ]
35
36
 
36
- related_entities = []
37
+ blueprints_to_relations = defaultdict(list)
37
38
  for entity, blueprint in entity_to_blueprint:
38
39
  for relation_name, relation in entity.relations.items():
39
40
  relation_blueprint = blueprint.relations[relation_name].target
40
- related_entities.append(
41
- Entity(identifier=relation, blueprint=relation_blueprint)
41
+ blueprints_to_relations[relation_blueprint].extend(
42
+ relation if isinstance(relation, list) else [relation]
42
43
  )
43
44
 
44
- return related_entities
45
+ return [
46
+ Entity(identifier=relation, blueprint=blueprint)
47
+ for blueprint, relations in blueprints_to_relations.items()
48
+ # multiple entities can point to the same relation in the same blueprint, for performance reasons
49
+ # we want to avoid fetching the same relation multiple times
50
+ for relation in set(relations)
51
+ ]
@@ -19,11 +19,15 @@ def order_by_entities_dependencies(entities: list[Entity]) -> list[Entity]:
19
19
  entities_map[node(entity)] = entity
20
20
 
21
21
  for entity in entities:
22
- relation_target_ids = [
23
- identifier
24
- for relation in entity.relations.values()
25
- for identifier in relation
26
- ]
22
+ relation_target_ids: list[str] = sum(
23
+ [
24
+ identifier if isinstance(identifier, list) else [identifier]
25
+ for relation in entity.relations.values()
26
+ for identifier in relation
27
+ if identifier is not None
28
+ ],
29
+ [],
30
+ )
27
31
  related_entities = [
28
32
  related for related in entities if related.identifier in relation_target_ids
29
33
  ]
@@ -15,6 +15,29 @@ from port_ocean.exceptions.core import IntegrationAlreadyStartedException
15
15
 
16
16
 
17
17
  class BaseIntegration(SyncRawMixin, SyncMixin):
18
+ """
19
+ This is the default integration class that Ocean initializes when no custom integration class is
20
+ provided.
21
+
22
+ This class provides a foundation for implementing various integration types. It inherits from
23
+ both SyncRawMixin and SyncMixin, which provide synchronization and event handling functionality.
24
+
25
+ Parameters:
26
+ context (PortOceanContext): The PortOceanContext object providing the necessary context
27
+ for the integration.
28
+
29
+ Attributes:
30
+ started (bool): Flag indicating whether the integration has been started.
31
+ context (PortOceanContext): The PortOceanContext object containing integration context.
32
+ event_listener_factory (EventListenerFactory): Factory to create event listeners for
33
+ handling integration events.
34
+
35
+ Raises:
36
+ IntegrationAlreadyStartedException: Raised if the integration is attempted to be started
37
+ more than once.
38
+ NotImplementedError: Raised if the `on_resync` method is not implemented, and the event
39
+ strategy does not have a custom implementation for resync events.
40
+ """
18
41
  def __init__(self, context: PortOceanContext):
19
42
  SyncRawMixin.__init__(self)
20
43
  SyncMixin.__init__(self)
@@ -27,6 +50,9 @@ class BaseIntegration(SyncRawMixin, SyncMixin):
27
50
  )
28
51
 
29
52
  async def start(self) -> None:
53
+ """
54
+ Initializes handlers, establishes integration at the specified port, and starts the event listener.
55
+ """
30
56
  logger.info("Starting integration")
31
57
  if self.started:
32
58
  raise IntegrationAlreadyStartedException("Integration already started")
@@ -1,6 +1,7 @@
1
1
  from contextlib import contextmanager
2
2
  from typing import Awaitable, Generator, Callable
3
3
 
4
+ from loguru import logger
4
5
  from port_ocean.core.ocean_types import (
5
6
  ASYNC_GENERATOR_RESYNC_TYPE,
6
7
  RAW_RESULT,
@@ -20,9 +21,9 @@ def resync_error_handling() -> Generator[None, None, None]:
20
21
  except StopAsyncIteration:
21
22
  raise
22
23
  except Exception as error:
23
- raise OceanAbortException(
24
- f"Failed to execute resync function, error: {error}"
25
- ) from error
24
+ err_msg = f"Failed to execute resync function, error: {error}"
25
+ logger.exception(err_msg)
26
+ raise OceanAbortException(err_msg) from error
26
27
 
27
28
 
28
29
  async def resync_function_wrapper(
port_ocean/core/models.py CHANGED
@@ -10,7 +10,7 @@ class Entity(BaseModel):
10
10
  identifier: str
11
11
  blueprint: str
12
12
  title: str | None
13
- team: str | list[str] = []
13
+ team: str | None | list[str | None] = []
14
14
  properties: dict[str, Any] = {}
15
15
  relations: dict[str, Any] = {}
16
16
 
@@ -18,19 +18,7 @@ class Entity(BaseModel):
18
18
  def parse_obj(cls: Type["Model"], obj: dict[Any, Any]) -> "Model":
19
19
  obj["identifier"] = str(obj.get("identifier"))
20
20
  obj["blueprint"] = str(obj.get("blueprint"))
21
- if obj.get("team"):
22
- team = obj.get("team")
23
- obj["team"] = (
24
- [str(item) for item in team]
25
- if isinstance(team, list)
26
- else str(obj.get("team"))
27
- )
28
-
29
- for key, value in obj.get("relations", {}).items():
30
- if isinstance(value, list):
31
- obj["relations"][key] = [str(item) for item in value]
32
- else:
33
- obj["relations"][key] = str(value)
21
+
34
22
  return super(Entity, cls).parse_obj(obj)
35
23
 
36
24
 
@@ -1,5 +1,6 @@
1
1
  import sys
2
2
 
3
+ import loguru
3
4
  from loguru import logger
4
5
 
5
6
  from port_ocean.config.settings import LogLevelType
@@ -20,3 +21,16 @@ def setup_logger(level: LogLevelType) -> None:
20
21
  enqueue=True, # process logs in background
21
22
  diagnose=False, # hide variable values in log backtrace
22
23
  )
24
+ logger.configure(patcher=exception_deserializer)
25
+
26
+
27
+ def exception_deserializer(record: "loguru.Record") -> None:
28
+ """
29
+ Workaround for when trying to log exception objects with loguru.
30
+ loguru doesn't able to deserialize `Exception` subclasses.
31
+ https://github.com/Delgan/loguru/issues/504#issuecomment-917365972
32
+ """
33
+ exception: loguru.RecordException | None = record["exception"]
34
+ if exception is not None:
35
+ fixed = Exception(str(exception.value))
36
+ record["exception"] = exception._replace(value=fixed)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: port-ocean
3
- Version: 0.1.3rc4
3
+ Version: 0.1.4.dev2
4
4
  Summary: Port Ocean is a CLI tool for managing your Port projects.
5
5
  Home-page: https://app.getport.io
6
6
  Keywords: ocean,port-ocean,port
@@ -4,7 +4,7 @@ port_ocean/cli/cli.py,sha256=RvWTELEn5YFw9aM0vaNqm5YqZZrL50ILaBs27ptiGl0,57
4
4
  port_ocean/cli/commands/__init__.py,sha256=Wb3h7y-fjXCDZ_-WLDIh5Jl8R7QO74iZqUJYsRD9wNY,278
5
5
  port_ocean/cli/commands/list_integrations.py,sha256=DVVioFruGUE-_v6UUHlcemWNN6RlWwCrf1X4HmAXsf8,1134
6
6
  port_ocean/cli/commands/main.py,sha256=gj0lmuLep2XeLNuabB7Wk0UVYPT7_CD_rAw5AoUQWSE,1057
7
- port_ocean/cli/commands/new.py,sha256=8myppWaCXL8tf1qAwiWrnrl_oM0RSCUMgG2lp_Ma84Q,1710
7
+ port_ocean/cli/commands/new.py,sha256=net7346AnM4f4Mfy9dZWnPJzXicgvfCqM6lbsByicsU,1816
8
8
  port_ocean/cli/commands/pull.py,sha256=VvrRjLNlfPuLIf7KzeIcbzzdi98Z0M9wCRpXC3QPxdI,2306
9
9
  port_ocean/cli/commands/sail.py,sha256=6qEhg6hWoQgHrkg-eRh_uYuVWc05K7pukFfSjYFD01o,1534
10
10
  port_ocean/cli/commands/version.py,sha256=hEuIEIcm6Zkamz41Z9nxeSM_4g3oNlAgWwQyDGboh-E,536
@@ -22,7 +22,7 @@ port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/config.yaml,sha256
22
22
  port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/debug.py,sha256=_TRsA2s6GV2E3CTI8CHcsH-ZuH4_Eh5-juDXWaET0ho,65
23
23
  port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/main.py,sha256=KxxtBrRygYOP0bulXySVYwX0fm_mm3QHqeEqwDwgXgY,1669
24
24
  port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/poetry.toml,sha256=kENq8nNmFPIzw9vySheyG4xHxAPuBSpZO1CYGD6G2NE,46
25
- port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/pyproject.toml,sha256=8evGQoyuGY8Mkddpvgk1QkT2-Y8OFYgWU-dwlXhR1SI,1920
25
+ port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/pyproject.toml,sha256=u9tb2IFQApl_GSy_2C59GRN88fc3XqEkMn-XOIhMrZ0,1941
26
26
  port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  port_ocean/cli/utils.py,sha256=IUK2UbWqjci-lrcDdynZXqVP5B5TcjF0w5CpEVUks-k,54
28
28
  port_ocean/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -36,7 +36,7 @@ port_ocean/clients/port/mixins/integrations.py,sha256=wbK3EXqPv5pRZytQjIVKwDa2aL
36
36
  port_ocean/clients/port/types.py,sha256=NnT1W2H_tZ_9cyEFoDhb90q3apf8p9emkHYspbPoZJQ,593
37
37
  port_ocean/clients/port/utils.py,sha256=jgF0Gq8lZA9qkpsHlzPTuKoAdY6AlvF1Bl5JB4SnQGE,781
38
38
  port_ocean/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
- port_ocean/config/base.py,sha256=ppibshn1EnCe2Mv_81-t5ZeGcF6tANPUlpMgLvTtngU,4019
39
+ port_ocean/config/base.py,sha256=nqHIZJZK3IyR48cOQGKQaQv4kz5IG_oUhrP9dJScC-U,4011
40
40
  port_ocean/config/dynamic.py,sha256=CIRDnqFUPSnNMLZ-emRCMVAjEQNBlIujhZ7OGwi_aKs,1816
41
41
  port_ocean/config/settings.py,sha256=Ghg71GJgeIPzFMyvAanErfCMCVDbc-roDGkdtgtTYf8,1231
42
42
  port_ocean/consumers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -48,19 +48,21 @@ port_ocean/context/ocean.py,sha256=tb6S9s5gV-Dyph0_503zXCZJr6kjiXgdrQ5MNztzeKk,4
48
48
  port_ocean/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
49
  port_ocean/core/base.py,sha256=gyF4b5_3YbO9u7wq9_HHSYbU5oouAWGuLibBfJteKE0,219
50
50
  port_ocean/core/event_listener/__init__.py,sha256=fsSfwMB44pi6Wb8mckbPXxv4vcbobyALmUF66PS0rjw,607
51
- port_ocean/core/event_listener/base.py,sha256=tUHfWmxD2Tsthhl7vAe9dOcDP9FBy2YeUt9oHO49RJQ,580
52
- port_ocean/core/event_listener/factory.py,sha256=1ApLyU1i_7QIqpP_aNiqALXvllljYUVlnZGQfxiAJw4,2555
53
- port_ocean/core/event_listener/http/event_listener.py,sha256=yrxj7ykINhYZZ4xMzGL5peXDERy8qERrzYO5Orw7-Dw,1165
54
- port_ocean/core/event_listener/kafka/event_listener.py,sha256=6IEq6ITKnUb_xir_EpqbyUQelbfQ9SaSq75GZb6WzSY,3349
55
- port_ocean/core/event_listener/polling/event_listener.py,sha256=0Oju_KcOm99pMWOwJIeszbUzC2KRSrt0cVc3-7d5MWE,1867
51
+ port_ocean/core/event_listener/base.py,sha256=QhZBDGw-ji6fpl4uG2UvMrwNRVuUW9KeolmfIphI4XE,891
52
+ port_ocean/core/event_listener/factory.py,sha256=iPAqZOzxcc-0-NKIEIxdkRwZ9a1EtQTBkGMjjOj3amE,3474
53
+ port_ocean/core/event_listener/http/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
+ port_ocean/core/event_listener/http/event_listener.py,sha256=Piv5_9xq6hhKVuKw4XYEQ_FzXwYVeC0IBdAXXK4Dlmc,2511
55
+ port_ocean/core/event_listener/kafka/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
+ port_ocean/core/event_listener/kafka/event_listener.py,sha256=B5TlSa3Zqlnf_Z-pBb3RR3JspkqOWiD38Uv6KY6nmPI,6351
57
+ port_ocean/core/event_listener/polling/event_listener.py,sha256=fkL5dAljXCfucl3A6YyfgsMPYkRodh0AUr1fMsMLU-Q,3264
56
58
  port_ocean/core/event_listener/polling/utils.py,sha256=qjBdLP0Wnn2T3U97SXHBsOTqP0QMzVLdiIIXdFUaazs,2799
57
59
  port_ocean/core/handlers/__init__.py,sha256=EW54s6OkpSYCG2CYstSqkgneI6KjvigEeC1Cxg5V2bM,716
58
60
  port_ocean/core/handlers/entities_state_applier/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
61
  port_ocean/core/handlers/entities_state_applier/base.py,sha256=P31b_5JU5AbnblNFY4HD3oeXSH1spNtCZUJjpchWcAI,869
60
62
  port_ocean/core/handlers/entities_state_applier/port/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
63
  port_ocean/core/handlers/entities_state_applier/port/applier.py,sha256=SCgcY01aCTLjCkikxhy6_4ChWNsOv_pWP8bZReOTfJI,7977
62
- port_ocean/core/handlers/entities_state_applier/port/get_related_entities.py,sha256=RyiiWuuzKD3BBxvzWkJ9z6BniNfa6-v80lNYRxlct7s,1339
63
- port_ocean/core/handlers/entities_state_applier/port/order_by_entities_dependencies.py,sha256=lbFwg5mRYxulYBvo5KmN5vQ59a-ChWzwwUtqfyigR-o,988
64
+ port_ocean/core/handlers/entities_state_applier/port/get_related_entities.py,sha256=1zncwCbE-Gej0xaWKlzZgoXxOBe9bgs_YxlZ8QW3NdI,1751
65
+ port_ocean/core/handlers/entities_state_applier/port/order_by_entities_dependencies.py,sha256=QMMcoGoMmDj9tRZAXOQlWmxSS_I2NBJpM2F61ZRu3O0,1151
64
66
  port_ocean/core/handlers/entities_state_applier/port/validate_entity_relations.py,sha256=nKuQ-RlalGG07olxm6l5NHeOuQT9dEZLoMpD-AN5nq0,1392
65
67
  port_ocean/core/handlers/entity_processor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
68
  port_ocean/core/handlers/entity_processor/base.py,sha256=3_THK7X6LgXjaA_iqr8DP6kFCsg7YEevSPbQCIhuWXo,955
@@ -70,13 +72,13 @@ port_ocean/core/handlers/port_app_config/api.py,sha256=Q1dDO7YUVQ_Yb7LqBC4i1Ww-G
70
72
  port_ocean/core/handlers/port_app_config/base.py,sha256=DAj8QxFyMw5o6n1HO92MqelOJJaAauSOaUp0otsG3uI,651
71
73
  port_ocean/core/handlers/port_app_config/models.py,sha256=pkVIWQlJJgG168MUxu2Dzirt5H03B9e7WkVY0E3Q1Ig,1810
72
74
  port_ocean/core/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
- port_ocean/core/integrations/base.py,sha256=BOsefDVks1ybWhExycIey4RPo7KPwXiP6pdkn1eJfHE,1912
75
+ port_ocean/core/integrations/base.py,sha256=fTqpl6Zz0qSeFWIz4InVhphOfeu_SFoe3JlvoiaAgnY,3162
74
76
  port_ocean/core/integrations/mixins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
77
  port_ocean/core/integrations/mixins/events.py,sha256=yjh5jmZcGoklqDIV8MBvTCGK1r_b7oc9H7htIvssfGk,698
76
78
  port_ocean/core/integrations/mixins/handler.py,sha256=3chtZ1RCIH2h1V19hd9CteAV8M0wuhTNnta6_Jlviog,2569
77
79
  port_ocean/core/integrations/mixins/sync.py,sha256=OFJsK_7yV9Wvnb9STCBiX2FGAS1j-R8sIZsxM7m-i3M,11843
78
- port_ocean/core/integrations/mixins/utils.py,sha256=zwmkbodyQRR-el388YSDZTYgkTACKjpz2N5Yu8CKC3M,1683
79
- port_ocean/core/models.py,sha256=7d-FTnReypT9Yq6yBUGd3DIzjQLAyPIc6Fy-45eV7hw,1368
80
+ port_ocean/core/integrations/mixins/utils.py,sha256=KC3wEbNmCFRBoM0BdMumOdXp-Fj5rHF39ZPjifD63ao,1747
81
+ port_ocean/core/models.py,sha256=WuG92EAVXixehj6hU2x24AR9kdAWPJfvhkgjCR4aGO0,909
80
82
  port_ocean/core/ocean_types.py,sha256=gQANgXkxYXV98M9ukQfv_UCuUFRBrhyYN9I707OLKqM,781
81
83
  port_ocean/core/utils.py,sha256=B040Wokk28g9tQj_06qk_uvm85RIXc6XGXysZV6gtQw,1957
82
84
  port_ocean/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -86,15 +88,15 @@ port_ocean/exceptions/clients.py,sha256=LKLLs-Zy3caNG85rwxfOw2rMr8qqVV6SHUq4fRCZ
86
88
  port_ocean/exceptions/context.py,sha256=8pUlWbXpRof5tlArpPooXCbEVHQCyY2sBAnMgPLzyEM,235
87
89
  port_ocean/exceptions/core.py,sha256=jABHL3elMfGiGXXB_OlAWh34vU4qaanMNw2Uw-_SpmI,532
88
90
  port_ocean/exceptions/port_defaults.py,sha256=R3ufJcfllb7NZSwHOpBs8kbjsIZVQLM6vKO6dz4w-EE,407
89
- port_ocean/logger_setup.py,sha256=wMamLdlQMSXkrq9N5lmKl0zCgxTF8_Uzu_QPYujYM3c,551
91
+ port_ocean/logger_setup.py,sha256=UGTvSdbV2FMvDCQRxCGcBw6m9VpEkl-pGBNOL47BrH8,1107
90
92
  port_ocean/middlewares.py,sha256=8rGu9XSKvbNCQGzWvfaijDrp-0ATJrWAQfBji2CnSck,2475
91
93
  port_ocean/ocean.py,sha256=CBuRr1gJRpWRJ6TUStG-ocLptHohFALgJqFXMItWHL0,2263
92
94
  port_ocean/port_defaults.py,sha256=QzrO_7Q0hRX-bgMpm-6XTedMbTZQH73NfHby3l1FEDw,7161
93
95
  port_ocean/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
96
  port_ocean/run.py,sha256=Bd6c6qYqQZlZqTLyRWRIkf579NQNqrr-o4mVAnBIISA,2834
95
97
  port_ocean/utils.py,sha256=2a30qmGMSPgsTxfpz2RiI3xDsM0-TkaKAbvJBaYqvCc,1007
96
- port_ocean-0.1.3rc4.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
97
- port_ocean-0.1.3rc4.dist-info/METADATA,sha256=XYm51wAD0X5ERWxcVsYemoSJnFfEg1YHs6YDD60t5S0,6359
98
- port_ocean-0.1.3rc4.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
99
- port_ocean-0.1.3rc4.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
100
- port_ocean-0.1.3rc4.dist-info/RECORD,,
98
+ port_ocean-0.1.4.dev2.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
99
+ port_ocean-0.1.4.dev2.dist-info/METADATA,sha256=f01Rc91icIJpWp9m_iIL4uHssrroFzKiVvG3ZkKu0Zg,6361
100
+ port_ocean-0.1.4.dev2.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
101
+ port_ocean-0.1.4.dev2.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
102
+ port_ocean-0.1.4.dev2.dist-info/RECORD,,