port-ocean 0.27.3__py3-none-any.whl → 0.27.6__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.
- integrations/_infra/Dockerfile.Deb +4 -1
- integrations/_infra/Dockerfile.local +3 -1
- port_ocean/config/settings.py +9 -0
- port_ocean/core/event_listener/kafka.py +14 -0
- port_ocean/helpers/async_client.py +7 -0
- port_ocean/helpers/stream.py +71 -0
- port_ocean/tests/core/event_listener/test_kafka.py +70 -0
- {port_ocean-0.27.3.dist-info → port_ocean-0.27.6.dist-info}/METADATA +5 -2
- {port_ocean-0.27.3.dist-info → port_ocean-0.27.6.dist-info}/RECORD +12 -10
- {port_ocean-0.27.3.dist-info → port_ocean-0.27.6.dist-info}/LICENSE.md +0 -0
- {port_ocean-0.27.3.dist-info → port_ocean-0.27.6.dist-info}/WHEEL +0 -0
- {port_ocean-0.27.3.dist-info → port_ocean-0.27.6.dist-info}/entry_points.txt +0 -0
@@ -28,11 +28,14 @@ ARG INTEGRATION_VERSION
|
|
28
28
|
ARG BUILD_CONTEXT
|
29
29
|
ARG PROMETHEUS_MULTIPROC_DIR=/tmp/ocean/prometheus/metrics
|
30
30
|
ARG OAUTH_CONFIG_DIR=/app/.config
|
31
|
+
ARG STREAMING_LOCATION=/tmp/ocean/streaming
|
31
32
|
|
32
33
|
ENV LIBRDKAFKA_VERSION=2.8.2 \
|
33
|
-
PROMETHEUS_MULTIPROC_DIR=${PROMETHEUS_MULTIPROC_DIR}
|
34
|
+
PROMETHEUS_MULTIPROC_DIR=${PROMETHEUS_MULTIPROC_DIR} \
|
35
|
+
STREAMING_LOCATION=${STREAMING_LOCATION}
|
34
36
|
|
35
37
|
RUN mkdir -p ${PROMETHEUS_MULTIPROC_DIR}
|
38
|
+
RUN mkdir -p ${STREAMING_LOCATION}
|
36
39
|
RUN chown -R ocean:appgroup /tmp/ocean && chmod -R 755 /tmp/ocean
|
37
40
|
|
38
41
|
RUN mkdir -p ${OAUTH_CONFIG_DIR}
|
@@ -33,13 +33,15 @@ RUN apt-get update \
|
|
33
33
|
|
34
34
|
ARG BUILD_CONTEXT
|
35
35
|
ARG PROMETHEUS_MULTIPROC_DIR=/tmp/ocean/prometheus/metrics
|
36
|
+
ARG STREAMING_LOCATION=/tmp/ocean/streaming
|
36
37
|
|
37
38
|
ENV PROMETHEUS_MULTIPROC_DIR=${PROMETHEUS_MULTIPROC_DIR}
|
38
|
-
|
39
|
+
ENV STREAMING_LOCATION=${STREAMING_LOCATION}
|
39
40
|
# Create /tmp/ocean directory and set permissions
|
40
41
|
|
41
42
|
|
42
43
|
RUN mkdir -p ${PROMETHEUS_MULTIPROC_DIR}
|
44
|
+
RUN mkdir -p ${STREAMING_LOCATION}
|
43
45
|
|
44
46
|
WORKDIR /app
|
45
47
|
|
port_ocean/config/settings.py
CHANGED
@@ -73,6 +73,13 @@ class MetricsSettings(BaseOceanModel, extra=Extra.allow):
|
|
73
73
|
webhook_url: str | None = Field(default=None)
|
74
74
|
|
75
75
|
|
76
|
+
class StreamingSettings(BaseOceanModel, extra=Extra.allow):
|
77
|
+
enabled: bool = Field(default=False)
|
78
|
+
max_buffer_size_mb: int = Field(default=1024 * 1024 * 20) # 20 mb
|
79
|
+
chunk_size: int = Field(default=1024 * 64) # 64 kb
|
80
|
+
location: str = Field(default="/tmp/ocean/streaming")
|
81
|
+
|
82
|
+
|
76
83
|
class IntegrationConfiguration(BaseOceanSettings, extra=Extra.allow):
|
77
84
|
_integration_config_model: BaseModel | None = None
|
78
85
|
|
@@ -114,6 +121,8 @@ class IntegrationConfiguration(BaseOceanSettings, extra=Extra.allow):
|
|
114
121
|
yield_items_to_parse: bool = False
|
115
122
|
yield_items_to_parse_batch_size: int = 10
|
116
123
|
|
124
|
+
streaming: StreamingSettings = Field(default_factory=lambda: StreamingSettings())
|
125
|
+
|
117
126
|
@validator("process_execution_mode")
|
118
127
|
def validate_process_execution_mode(
|
119
128
|
cls, process_execution_mode: ProcessExecutionMode
|
@@ -16,6 +16,7 @@ from port_ocean.core.event_listener.base import (
|
|
16
16
|
EventListenerEvents,
|
17
17
|
EventListenerSettings,
|
18
18
|
)
|
19
|
+
from pydantic import validator
|
19
20
|
|
20
21
|
|
21
22
|
class KafkaEventListenerSettings(EventListenerSettings):
|
@@ -46,6 +47,19 @@ class KafkaEventListenerSettings(EventListenerSettings):
|
|
46
47
|
kafka_security_enabled: bool = True
|
47
48
|
consumer_poll_timeout: int = 1
|
48
49
|
|
50
|
+
@validator("brokers")
|
51
|
+
@classmethod
|
52
|
+
def parse_brokers(cls, v: str) -> str:
|
53
|
+
# If it's a JSON array string, parse and join
|
54
|
+
if v.strip().startswith("[") and v.strip().endswith("]"):
|
55
|
+
try:
|
56
|
+
parsed = json.loads(v)
|
57
|
+
if isinstance(parsed, list):
|
58
|
+
return ",".join(parsed)
|
59
|
+
except json.JSONDecodeError:
|
60
|
+
pass
|
61
|
+
return v
|
62
|
+
|
49
63
|
def get_changelog_destination_details(self) -> dict[str, Any]:
|
50
64
|
"""
|
51
65
|
Returns the changelog destination configuration for the Kafka event listener.
|
@@ -4,6 +4,7 @@ import httpx
|
|
4
4
|
from loguru import logger
|
5
5
|
|
6
6
|
from port_ocean.helpers.retry import RetryTransport
|
7
|
+
from port_ocean.helpers.stream import Stream
|
7
8
|
|
8
9
|
|
9
10
|
class OceanAsyncClient(httpx.AsyncClient):
|
@@ -50,3 +51,9 @@ class OceanAsyncClient(httpx.AsyncClient):
|
|
50
51
|
logger=logger,
|
51
52
|
**(self._transport_kwargs or {}),
|
52
53
|
)
|
54
|
+
|
55
|
+
async def get_stream(self, url: str, **kwargs: Any) -> Stream:
|
56
|
+
req = self.build_request("GET", url, **kwargs)
|
57
|
+
response = await self.send(req, stream=True)
|
58
|
+
response.raise_for_status()
|
59
|
+
return Stream(response)
|
@@ -0,0 +1,71 @@
|
|
1
|
+
import os
|
2
|
+
from typing import Any, AsyncGenerator
|
3
|
+
import uuid
|
4
|
+
|
5
|
+
import aiofiles
|
6
|
+
import httpx
|
7
|
+
import ijson # type: ignore[import-untyped]
|
8
|
+
from cryptography.fernet import Fernet
|
9
|
+
|
10
|
+
import port_ocean.context.ocean as ocean_context
|
11
|
+
|
12
|
+
|
13
|
+
class Stream:
|
14
|
+
def __init__(self, response: httpx.Response):
|
15
|
+
self.response = response
|
16
|
+
self.headers = response.headers
|
17
|
+
self.status_code = response.status_code
|
18
|
+
|
19
|
+
async def _byte_stream(
|
20
|
+
self, chunk_size: int | None = None
|
21
|
+
) -> AsyncGenerator[bytes, None]:
|
22
|
+
if chunk_size is None:
|
23
|
+
chunk_size = ocean_context.ocean.config.streaming.chunk_size
|
24
|
+
|
25
|
+
file_name = f"{ocean_context.ocean.config.streaming.location}/{uuid.uuid4()}"
|
26
|
+
|
27
|
+
crypt = Fernet(Fernet.generate_key())
|
28
|
+
|
29
|
+
try:
|
30
|
+
async for chunk in self.response.aiter_bytes(chunk_size=chunk_size):
|
31
|
+
async with aiofiles.open(f"{file_name}", "ab") as f:
|
32
|
+
if len(chunk) > 0:
|
33
|
+
await f.write(crypt.encrypt(chunk))
|
34
|
+
await f.write(b"\n")
|
35
|
+
finally:
|
36
|
+
await self.response.aclose()
|
37
|
+
|
38
|
+
try:
|
39
|
+
async with aiofiles.open(f"{file_name}", mode="rb") as f:
|
40
|
+
while True:
|
41
|
+
line = await f.readline()
|
42
|
+
if not line:
|
43
|
+
break
|
44
|
+
data = crypt.decrypt(line)
|
45
|
+
yield data
|
46
|
+
finally:
|
47
|
+
try:
|
48
|
+
os.remove(file_name)
|
49
|
+
except FileNotFoundError:
|
50
|
+
pass
|
51
|
+
|
52
|
+
async def get_json_stream(
|
53
|
+
self,
|
54
|
+
target_items: str = "",
|
55
|
+
max_buffer_size_mb: int | None = None,
|
56
|
+
) -> AsyncGenerator[list[dict[str, Any]], None]:
|
57
|
+
if max_buffer_size_mb is None:
|
58
|
+
max_buffer_size_mb = ocean_context.ocean.config.streaming.max_buffer_size_mb
|
59
|
+
|
60
|
+
events = ijson.sendable_list()
|
61
|
+
coro = ijson.items_coro(events, target_items)
|
62
|
+
current_buffer_size = 0
|
63
|
+
async for chunk in self._byte_stream():
|
64
|
+
coro.send(chunk)
|
65
|
+
current_buffer_size += len(chunk)
|
66
|
+
if current_buffer_size >= max_buffer_size_mb:
|
67
|
+
if len(events) > 0:
|
68
|
+
yield events
|
69
|
+
events.clear()
|
70
|
+
current_buffer_size = 0
|
71
|
+
yield events
|
@@ -0,0 +1,70 @@
|
|
1
|
+
from port_ocean.core.event_listener.kafka import KafkaEventListenerSettings
|
2
|
+
import pytest
|
3
|
+
from pydantic import ValidationError
|
4
|
+
|
5
|
+
|
6
|
+
def test_default_kafka_settings() -> None:
|
7
|
+
"""Test default values are properly set"""
|
8
|
+
config = KafkaEventListenerSettings(type="KAFKA")
|
9
|
+
assert config.type == "KAFKA"
|
10
|
+
assert config.security_protocol == "SASL_SSL"
|
11
|
+
assert config.authentication_mechanism == "SCRAM-SHA-512"
|
12
|
+
assert config.kafka_security_enabled is True
|
13
|
+
assert config.consumer_poll_timeout == 1
|
14
|
+
assert "b-1-public.publicclusterprod" in config.brokers
|
15
|
+
|
16
|
+
|
17
|
+
def test_brokers_json_array_parsing() -> None:
|
18
|
+
"""Test that JSON array strings get converted to comma-separated"""
|
19
|
+
json_brokers = '["broker1:9092", "broker2:9092", "broker3:9092"]'
|
20
|
+
config = KafkaEventListenerSettings(type="KAFKA", brokers=json_brokers)
|
21
|
+
assert config.brokers == "broker1:9092,broker2:9092,broker3:9092"
|
22
|
+
|
23
|
+
|
24
|
+
def test_brokers_regular_string_unchanged() -> None:
|
25
|
+
"""Test that regular comma-separated strings pass through unchanged"""
|
26
|
+
regular_brokers = "broker1:9092,broker2:9092"
|
27
|
+
config = KafkaEventListenerSettings(type="KAFKA", brokers=regular_brokers)
|
28
|
+
assert config.brokers == regular_brokers
|
29
|
+
|
30
|
+
|
31
|
+
def test_brokers_malformed_json_unchanged() -> None:
|
32
|
+
"""Test that malformed JSON strings don't break validation"""
|
33
|
+
bad_json = "[broker1:9092, broker2:9092"
|
34
|
+
config = KafkaEventListenerSettings(type="KAFKA", brokers=bad_json)
|
35
|
+
assert config.brokers == bad_json
|
36
|
+
|
37
|
+
|
38
|
+
def test_custom_values() -> None:
|
39
|
+
"""Test overriding default values"""
|
40
|
+
config = KafkaEventListenerSettings(
|
41
|
+
type="KAFKA",
|
42
|
+
brokers="custom:9092",
|
43
|
+
security_protocol="PLAINTEXT",
|
44
|
+
authentication_mechanism="PLAIN",
|
45
|
+
kafka_security_enabled=False,
|
46
|
+
consumer_poll_timeout=5,
|
47
|
+
)
|
48
|
+
assert config.brokers == "custom:9092"
|
49
|
+
assert config.security_protocol == "PLAINTEXT"
|
50
|
+
assert config.authentication_mechanism == "PLAIN"
|
51
|
+
assert config.kafka_security_enabled is False
|
52
|
+
assert config.consumer_poll_timeout == 5
|
53
|
+
|
54
|
+
|
55
|
+
def test_type_literal_validation() -> None:
|
56
|
+
"""Test that type field only accepts KAFKA"""
|
57
|
+
with pytest.raises(ValidationError):
|
58
|
+
KafkaEventListenerSettings(type="RABBITMQ") # type: ignore[arg-type]
|
59
|
+
|
60
|
+
|
61
|
+
def test_empty_brokers_array() -> None:
|
62
|
+
"""Test empty JSON array becomes empty string"""
|
63
|
+
config = KafkaEventListenerSettings(type="KAFKA", brokers="[]")
|
64
|
+
assert config.brokers == ""
|
65
|
+
|
66
|
+
|
67
|
+
def test_single_broker_array() -> None:
|
68
|
+
"""Test single broker in JSON array"""
|
69
|
+
config = KafkaEventListenerSettings(type="KAFKA", brokers='["single:9092"]')
|
70
|
+
assert config.brokers == "single:9092"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: port-ocean
|
3
|
-
Version: 0.27.
|
3
|
+
Version: 0.27.6
|
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
|
@@ -22,12 +22,15 @@ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
22
22
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
23
23
|
Classifier: Topic :: Utilities
|
24
24
|
Provides-Extra: cli
|
25
|
+
Requires-Dist: aiofiles (>=24.1.0,<25.0.0)
|
25
26
|
Requires-Dist: aiostream (>=0.5.2,<0.7.0)
|
26
27
|
Requires-Dist: click (>=8.1.3,<9.0.0) ; extra == "cli"
|
27
28
|
Requires-Dist: confluent-kafka (>=2.10.1,<3.0.0)
|
28
29
|
Requires-Dist: cookiecutter (>=2.1.1,<3.0.0) ; extra == "cli"
|
29
|
-
Requires-Dist:
|
30
|
+
Requires-Dist: cryptography (>=44.0.1,<45.0.0)
|
31
|
+
Requires-Dist: fastapi (>=0.116.0,<0.117.0)
|
30
32
|
Requires-Dist: httpx (>=0.28.1,<0.29.0)
|
33
|
+
Requires-Dist: ijson (>=3.4.0,<4.0.0)
|
31
34
|
Requires-Dist: jinja2 (>=3.1.6)
|
32
35
|
Requires-Dist: jinja2-time (>=0.2.0,<0.3.0) ; extra == "cli"
|
33
36
|
Requires-Dist: jq (>=1.8.0,<2.0.0)
|
@@ -1,9 +1,9 @@
|
|
1
|
-
integrations/_infra/Dockerfile.Deb,sha256=
|
1
|
+
integrations/_infra/Dockerfile.Deb,sha256=weK3VrskDEsuvYaxerak-XIqDgTx_wPorAFQQjYH_FU,2493
|
2
2
|
integrations/_infra/Dockerfile.alpine,sha256=7E4Sb-8supsCcseerHwTkuzjHZoYcaHIyxiBZ-wewo0,3482
|
3
3
|
integrations/_infra/Dockerfile.base.builder,sha256=ESe1PKC6itp_AuXawbLI75k1Kruny6NTANaTinxOgVs,743
|
4
4
|
integrations/_infra/Dockerfile.base.runner,sha256=uAcs2IsxrAAUHGXt_qULA5INr-HFguf5a5fCKiqEzbY,384
|
5
5
|
integrations/_infra/Dockerfile.dockerignore,sha256=CM1Fxt3I2AvSvObuUZRmy5BNLSGC7ylnbpWzFgD4cso,1163
|
6
|
-
integrations/_infra/Dockerfile.local,sha256=
|
6
|
+
integrations/_infra/Dockerfile.local,sha256=FFX9RvFqlaHvhUrRnnzUl0zQp2oKDFVRGkXJQPMQ7cI,1650
|
7
7
|
integrations/_infra/Makefile,sha256=YgLKvuF_Dw4IA7X98Nus6zIW_3cJ60M1QFGs3imj5c4,2430
|
8
8
|
integrations/_infra/README.md,sha256=ZtJFSMCTU5zTeM8ddRuW1ZL1ga8z7Ic2F3mxmgOSjgo,1195
|
9
9
|
integrations/_infra/entry_local.sh,sha256=Sn2TexTEpruH2ixIAGsk-fZV6Y7pT3jd2Pi9TxBeFuw,633
|
@@ -70,7 +70,7 @@ port_ocean/clients/port/utils.py,sha256=osFyAjw7Y5Qf2uVSqC7_RTCQfijiL1zS74JJM0go
|
|
70
70
|
port_ocean/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
71
71
|
port_ocean/config/base.py,sha256=x1gFbzujrxn7EJudRT81C6eN9WsYAb3vOHwcpcpX8Tc,6370
|
72
72
|
port_ocean/config/dynamic.py,sha256=Lrk4JRGtR-0YKQ9DDGexX5NGFE7EJ6VoHya19YYhssM,2687
|
73
|
-
port_ocean/config/settings.py,sha256
|
73
|
+
port_ocean/config/settings.py,sha256=Zz_D40EXZEm0hzNdYgwdUy_s5LbJ6iMg3Zcl2n5NLUY,7686
|
74
74
|
port_ocean/consumers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
75
75
|
port_ocean/consumers/kafka_consumer.py,sha256=N8KocjBi9aR0BOPG8hgKovg-ns_ggpEjrSxqSqF_BSo,4710
|
76
76
|
port_ocean/context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -87,7 +87,7 @@ port_ocean/core/event_listener/__init__.py,sha256=T3E52MKs79fNEW381p7zU9F2vOMvIi
|
|
87
87
|
port_ocean/core/event_listener/base.py,sha256=GFBTHiYhCzps50phzopQFUlTGAluQkCRlyaRqOG4g1Y,2995
|
88
88
|
port_ocean/core/event_listener/factory.py,sha256=M4Qi05pI840sjDIbdjUEgYe9Gp5ckoCkX-KgLBxUpZg,4096
|
89
89
|
port_ocean/core/event_listener/http.py,sha256=_hkQmi9nNh8YG6hbfLrhkATsmGVO8y3qBWvrBHX5Nhk,2992
|
90
|
-
port_ocean/core/event_listener/kafka.py,sha256=
|
90
|
+
port_ocean/core/event_listener/kafka.py,sha256=7bUq4EoVv5sIBxiJnfhi7zdAI7whKoSIaS64Ic9B4Ys,7963
|
91
91
|
port_ocean/core/event_listener/once.py,sha256=6DhxQLSz5hjEGhmgLU7aA2ZVRQw3tuwh8sh7N63gRdU,5855
|
92
92
|
port_ocean/core/event_listener/polling.py,sha256=iZt59z4Dyus_wVvNfIPbq-G1CozAW9kfPU7uRDLPJVE,3604
|
93
93
|
port_ocean/core/event_listener/webhooks_only.py,sha256=PTWnmbLtbJb3ySfotMpTWMYgDVy9zOSYIIGqNbWK0UU,1214
|
@@ -140,10 +140,11 @@ port_ocean/exceptions/port_defaults.py,sha256=2a7Koy541KxMan33mU-gbauUxsumG3NT4i
|
|
140
140
|
port_ocean/exceptions/utils.py,sha256=gjOqpi-HpY1l4WlMFsGA9yzhxDhajhoGGdDDyGbLnqI,197
|
141
141
|
port_ocean/exceptions/webhook_processor.py,sha256=4SnkVzVwiacH_Ip4qs1hRHa6GanhnojW_TLTdQQtm7Y,363
|
142
142
|
port_ocean/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
143
|
-
port_ocean/helpers/async_client.py,sha256=
|
143
|
+
port_ocean/helpers/async_client.py,sha256=LOgUlZ5Cs_WUSc8XujCVjPGvzZ_3AuFJNKPy0FKV3fA,1987
|
144
144
|
port_ocean/helpers/metric/metric.py,sha256=Aacz7bOd8ZCwEPpXAdwLbKRXf28Z4wiViG_GXiV_xWg,14529
|
145
145
|
port_ocean/helpers/metric/utils.py,sha256=1lAgrxnZLuR_wUNDyPOPzLrm32b8cDdioob2lvnPQ1A,1619
|
146
146
|
port_ocean/helpers/retry.py,sha256=VHAp6j9-Vid6aNR5sca3S0aW6b1S2oYw9vT9hi1N22U,18556
|
147
|
+
port_ocean/helpers/stream.py,sha256=_UwsThzXynxWzL8OlBT1pmb2evZBi9HaaqeAGNuTuOI,2338
|
147
148
|
port_ocean/log/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
148
149
|
port_ocean/log/handlers.py,sha256=ncVjgqrZRh6BhyRrA6DQG86Wsbxph1yWYuEC0cWfe-Q,3631
|
149
150
|
port_ocean/log/logger_setup.py,sha256=0K3zVG0YYrYOWEV8-rCGks1o-bMRxgHXlqawu9w_tSw,2656
|
@@ -167,6 +168,7 @@ port_ocean/tests/config/test_config.py,sha256=Rk4N-ldVSOfn1p23NzdVdfqUpPrqG2cMut
|
|
167
168
|
port_ocean/tests/conftest.py,sha256=JXASSS0IY0nnR6bxBflhzxS25kf4iNaABmThyZ0mZt8,101
|
168
169
|
port_ocean/tests/core/conftest.py,sha256=5shShx81LRuQTBwS2sDIjNJO2LSD6cUNz46SgNYzjGY,7686
|
169
170
|
port_ocean/tests/core/defaults/test_common.py,sha256=sR7RqB3ZYV6Xn6NIg-c8k5K6JcGsYZ2SCe_PYX5vLYM,5560
|
171
|
+
port_ocean/tests/core/event_listener/test_kafka.py,sha256=PH90qk2fvdrQOSZD2QrvkGy8w_WoYb_KHGnqJ6PLHAo,2681
|
170
172
|
port_ocean/tests/core/handlers/entities_state_applier/test_applier.py,sha256=7XWgwUB9uVYRov4VbIz1A-7n2YLbHTTYT-4rKJxjB0A,10711
|
171
173
|
port_ocean/tests/core/handlers/entity_processor/test_jq_entity_processor.py,sha256=TjSj8ssIqH23VJlO5PGovbudCqDbuE2-54iNQsD9K-I,14099
|
172
174
|
port_ocean/tests/core/handlers/mixins/test_live_events.py,sha256=6yUsYooBYchiZP_eYa8PN1IhiztJShBdPguoseyNMzY,12482
|
@@ -205,8 +207,8 @@ port_ocean/utils/repeat.py,sha256=U2OeCkHPWXmRTVoPV-VcJRlQhcYqPWI5NfmPlb1JIbc,32
|
|
205
207
|
port_ocean/utils/signal.py,sha256=mMVq-1Ab5YpNiqN4PkiyTGlV_G0wkUDMMjTZp5z3pb0,1514
|
206
208
|
port_ocean/utils/time.py,sha256=pufAOH5ZQI7gXvOvJoQXZXZJV-Dqktoj9Qp9eiRwmJ4,1939
|
207
209
|
port_ocean/version.py,sha256=UsuJdvdQlazzKGD3Hd5-U7N69STh8Dq9ggJzQFnu9fU,177
|
208
|
-
port_ocean-0.27.
|
209
|
-
port_ocean-0.27.
|
210
|
-
port_ocean-0.27.
|
211
|
-
port_ocean-0.27.
|
212
|
-
port_ocean-0.27.
|
210
|
+
port_ocean-0.27.6.dist-info/LICENSE.md,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
211
|
+
port_ocean-0.27.6.dist-info/METADATA,sha256=KzFgTmio2jk9gaqUyvyZDhMIsyanGS28gXG0J-1gzdg,7015
|
212
|
+
port_ocean-0.27.6.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
213
|
+
port_ocean-0.27.6.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
|
214
|
+
port_ocean-0.27.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|