port-ocean 0.12.7__tar.gz → 0.12.9__tar.gz

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.

Files changed (148) hide show
  1. {port_ocean-0.12.7 → port_ocean-0.12.9}/PKG-INFO +2 -2
  2. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/clients/port/mixins/integrations.py +0 -1
  3. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/log/handlers.py +23 -2
  4. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/log/logger_setup.py +1 -0
  5. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/ocean.py +1 -0
  6. port_ocean-0.12.9/port_ocean/tests/log/test_handlers.py +71 -0
  7. {port_ocean-0.12.7 → port_ocean-0.12.9}/pyproject.toml +3 -2
  8. {port_ocean-0.12.7 → port_ocean-0.12.9}/LICENSE.md +0 -0
  9. {port_ocean-0.12.7 → port_ocean-0.12.9}/README.md +0 -0
  10. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/__init__.py +0 -0
  11. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/bootstrap.py +0 -0
  12. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/__init__.py +0 -0
  13. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cli.py +0 -0
  14. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/commands/__init__.py +0 -0
  15. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/commands/defaults/__init___.py +0 -0
  16. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/commands/defaults/clean.py +0 -0
  17. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/commands/defaults/dock.py +0 -0
  18. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/commands/defaults/group.py +0 -0
  19. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/commands/list_integrations.py +0 -0
  20. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/commands/main.py +0 -0
  21. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/commands/new.py +0 -0
  22. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/commands/pull.py +0 -0
  23. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/commands/sail.py +0 -0
  24. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/commands/version.py +0 -0
  25. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/__init__.py +0 -0
  26. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/cookiecutter.json +0 -0
  27. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/extensions.py +0 -0
  28. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/hooks/post_gen_project.py +0 -0
  29. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.dockerignore +0 -0
  30. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.env.example +0 -0
  31. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.gitignore +0 -0
  32. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/.gitignore +0 -0
  33. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/blueprints.json +0 -0
  34. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/port-app-config.yml +0 -0
  35. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/spec.yaml +0 -0
  36. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CHANGELOG.md +0 -0
  37. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CONTRIBUTING.md +0 -0
  38. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/Dockerfile +0 -0
  39. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/README.md +0 -0
  40. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/changelog/.gitignore +0 -0
  41. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/debug.py +0 -0
  42. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/main.py +0 -0
  43. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/poetry.toml +0 -0
  44. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/pyproject.toml +0 -0
  45. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/sonar-project.properties +0 -0
  46. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/tests/__init__.py +0 -0
  47. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/tests/test_sample.py +0 -0
  48. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/cli/utils.py +0 -0
  49. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/clients/__init__.py +0 -0
  50. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/clients/port/__init__.py +0 -0
  51. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/clients/port/authentication.py +0 -0
  52. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/clients/port/client.py +0 -0
  53. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/clients/port/mixins/__init__.py +0 -0
  54. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/clients/port/mixins/blueprints.py +0 -0
  55. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/clients/port/mixins/entities.py +0 -0
  56. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/clients/port/mixins/migrations.py +0 -0
  57. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/clients/port/retry_transport.py +0 -0
  58. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/clients/port/types.py +0 -0
  59. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/clients/port/utils.py +0 -0
  60. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/config/__init__.py +0 -0
  61. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/config/base.py +0 -0
  62. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/config/dynamic.py +0 -0
  63. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/config/settings.py +0 -0
  64. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/consumers/__init__.py +0 -0
  65. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/consumers/kafka_consumer.py +0 -0
  66. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/context/__init__.py +0 -0
  67. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/context/event.py +0 -0
  68. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/context/ocean.py +0 -0
  69. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/context/resource.py +0 -0
  70. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/__init__.py +0 -0
  71. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/defaults/__init__.py +0 -0
  72. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/defaults/clean.py +0 -0
  73. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/defaults/common.py +0 -0
  74. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/defaults/initialize.py +0 -0
  75. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/event_listener/__init__.py +0 -0
  76. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/event_listener/base.py +0 -0
  77. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/event_listener/factory.py +0 -0
  78. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/event_listener/http.py +0 -0
  79. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/event_listener/kafka.py +0 -0
  80. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/event_listener/once.py +0 -0
  81. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/event_listener/polling.py +0 -0
  82. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/handlers/__init__.py +0 -0
  83. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/handlers/base.py +0 -0
  84. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/handlers/entities_state_applier/__init__.py +0 -0
  85. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/handlers/entities_state_applier/base.py +0 -0
  86. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/handlers/entities_state_applier/port/__init__.py +0 -0
  87. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/handlers/entities_state_applier/port/applier.py +0 -0
  88. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/handlers/entities_state_applier/port/get_related_entities.py +0 -0
  89. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/handlers/entities_state_applier/port/order_by_entities_dependencies.py +0 -0
  90. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/handlers/entity_processor/__init__.py +0 -0
  91. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/handlers/entity_processor/base.py +0 -0
  92. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/handlers/entity_processor/jq_entity_processor.py +0 -0
  93. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/handlers/port_app_config/__init__.py +0 -0
  94. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/handlers/port_app_config/api.py +0 -0
  95. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/handlers/port_app_config/base.py +0 -0
  96. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/handlers/port_app_config/models.py +0 -0
  97. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/handlers/resync_state_updater/__init__.py +0 -0
  98. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/handlers/resync_state_updater/updater.py +0 -0
  99. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/integrations/__init__.py +0 -0
  100. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/integrations/base.py +0 -0
  101. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/integrations/mixins/__init__.py +0 -0
  102. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/integrations/mixins/events.py +0 -0
  103. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/integrations/mixins/handler.py +0 -0
  104. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/integrations/mixins/sync.py +0 -0
  105. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/integrations/mixins/sync_raw.py +0 -0
  106. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/integrations/mixins/utils.py +0 -0
  107. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/models.py +0 -0
  108. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/ocean_types.py +0 -0
  109. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/core/utils.py +0 -0
  110. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/exceptions/__init__.py +0 -0
  111. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/exceptions/api.py +0 -0
  112. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/exceptions/base.py +0 -0
  113. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/exceptions/clients.py +0 -0
  114. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/exceptions/context.py +0 -0
  115. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/exceptions/core.py +0 -0
  116. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/exceptions/port_defaults.py +0 -0
  117. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/exceptions/utils.py +0 -0
  118. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/helpers/__init__.py +0 -0
  119. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/helpers/async_client.py +0 -0
  120. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/helpers/retry.py +0 -0
  121. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/log/__init__.py +0 -0
  122. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/log/sensetive.py +0 -0
  123. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/middlewares.py +0 -0
  124. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/py.typed +0 -0
  125. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/run.py +0 -0
  126. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/sonar-project.properties +0 -0
  127. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/tests/__init__.py +0 -0
  128. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/tests/clients/port/mixins/test_entities.py +0 -0
  129. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/tests/conftest.py +0 -0
  130. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/tests/core/handlers/entity_processor/test_jq_entity_processor.py +0 -0
  131. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/tests/helpers/__init__.py +0 -0
  132. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/tests/helpers/fixtures.py +0 -0
  133. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/tests/helpers/integration.py +0 -0
  134. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/tests/helpers/ocean_app.py +0 -0
  135. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/tests/helpers/port_client.py +0 -0
  136. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/tests/helpers/smoke_test.py +0 -0
  137. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/tests/test_smoke.py +0 -0
  138. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/tests/utils/test_async_iterators.py +0 -0
  139. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/utils/__init__.py +0 -0
  140. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/utils/async_http.py +0 -0
  141. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/utils/async_iterators.py +0 -0
  142. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/utils/cache.py +0 -0
  143. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/utils/misc.py +0 -0
  144. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/utils/queue_utils.py +0 -0
  145. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/utils/repeat.py +0 -0
  146. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/utils/signal.py +0 -0
  147. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/utils/time.py +0 -0
  148. {port_ocean-0.12.7 → port_ocean-0.12.9}/port_ocean/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: port-ocean
3
- Version: 0.12.7
3
+ Version: 0.12.9
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
@@ -26,7 +26,7 @@ Requires-Dist: aiostream (>=0.5.2,<0.7.0)
26
26
  Requires-Dist: click (>=8.1.3,<9.0.0) ; extra == "cli"
27
27
  Requires-Dist: confluent-kafka (>=2.1.1,<3.0.0)
28
28
  Requires-Dist: cookiecutter (>=2.1.1,<3.0.0) ; extra == "cli"
29
- Requires-Dist: fastapi (>=0.100,<0.112)
29
+ Requires-Dist: fastapi (>=0.115.3,<0.116.0)
30
30
  Requires-Dist: httpx (>=0.24.1,<0.28.0)
31
31
  Requires-Dist: jinja2-time (>=0.2.0,<0.3.0) ; extra == "cli"
32
32
  Requires-Dist: jq (>=1.8.0,<2.0.0)
@@ -3,7 +3,6 @@ from urllib.parse import quote_plus
3
3
 
4
4
  import httpx
5
5
  from loguru import logger
6
-
7
6
  from port_ocean.clients.port.authentication import PortAuthentication
8
7
  from port_ocean.clients.port.utils import handle_status_code
9
8
  from port_ocean.log.sensetive import sensitive_log_filter
@@ -11,16 +11,22 @@ from loguru import logger
11
11
 
12
12
  from port_ocean import Ocean
13
13
  from port_ocean.context.ocean import ocean
14
+ from copy import deepcopy
15
+ from traceback import format_exception
14
16
 
15
17
 
16
18
  def _serialize_record(record: logging.LogRecord) -> dict[str, Any]:
19
+ extra = {**deepcopy(record.__dict__["extra"])}
20
+ if isinstance(extra.get("exc_info"), Exception):
21
+ serialized_exception = "".join(format_exception(extra.get("exc_info")))
22
+ extra["exc_info"] = serialized_exception
17
23
  return {
18
24
  "message": record.msg,
19
25
  "level": record.levelname,
20
26
  "timestamp": datetime.utcfromtimestamp(record.created).strftime(
21
27
  "%Y-%m-%dT%H:%M:%S.%fZ"
22
28
  ),
23
- "extra": record.__dict__["extra"],
29
+ "extra": extra,
24
30
  }
25
31
 
26
32
 
@@ -37,6 +43,7 @@ class HTTPMemoryHandler(MemoryHandler):
37
43
  self.flush_size = flush_size
38
44
  self.last_flush_time = time.time()
39
45
  self._serialized_buffer: list[dict[str, Any]] = []
46
+ self._thread_pool: list[threading.Thread] = []
40
47
 
41
48
  @property
42
49
  def ocean(self) -> Ocean | None:
@@ -46,6 +53,7 @@ class HTTPMemoryHandler(MemoryHandler):
46
53
  return None
47
54
 
48
55
  def emit(self, record: logging.LogRecord) -> None:
56
+
49
57
  self._serialized_buffer.append(_serialize_record(record))
50
58
  super().emit(record)
51
59
 
@@ -61,6 +69,11 @@ class HTTPMemoryHandler(MemoryHandler):
61
69
  return True
62
70
  return False
63
71
 
72
+ def wait_for_lingering_threads(self) -> None:
73
+ for thread in self._thread_pool:
74
+ if thread.is_alive():
75
+ thread.join()
76
+
64
77
  def flush(self) -> None:
65
78
  if self.ocean is None or not self.buffer:
66
79
  return
@@ -70,13 +83,21 @@ class HTTPMemoryHandler(MemoryHandler):
70
83
  loop.run_until_complete(self.send_logs(_ocean, logs_to_send))
71
84
  loop.close()
72
85
 
86
+ def clear_thread_pool() -> None:
87
+ for thread in self._thread_pool:
88
+ if not thread.is_alive():
89
+ self._thread_pool.remove(thread)
90
+
73
91
  self.acquire()
74
92
  logs = list(self._serialized_buffer)
75
93
  if logs:
76
94
  self.buffer.clear()
77
95
  self._serialized_buffer.clear()
78
96
  self.last_flush_time = time.time()
79
- threading.Thread(target=_wrap_event_loop, args=(self.ocean, logs)).start()
97
+ clear_thread_pool()
98
+ thread = threading.Thread(target=_wrap_event_loop, args=(self.ocean, logs))
99
+ thread.start()
100
+ self._thread_pool.append(thread)
80
101
  self.release()
81
102
 
82
103
  async def send_logs(
@@ -55,6 +55,7 @@ def _http_loguru_handler(level: LogLevelType) -> None:
55
55
  logger.configure(patcher=exception_deserializer)
56
56
 
57
57
  http_memory_handler = HTTPMemoryHandler()
58
+ signal_handler.register(http_memory_handler.wait_for_lingering_threads)
58
59
  signal_handler.register(http_memory_handler.flush)
59
60
 
60
61
  queue_listener = QueueListener(queue, http_memory_handler)
@@ -123,6 +123,7 @@ class Ocean:
123
123
  yield None
124
124
  except Exception:
125
125
  logger.exception("Integration had a fatal error. Shutting down.")
126
+ logger.complete()
126
127
  sys.exit("Server stopped")
127
128
  finally:
128
129
  signal_handler.exit()
@@ -0,0 +1,71 @@
1
+ from port_ocean.log.handlers import _serialize_record
2
+ from loguru import logger
3
+ from logging import LogRecord
4
+ from queue import Queue
5
+ from logging.handlers import QueueHandler
6
+ from typing import Callable, Any
7
+
8
+
9
+ log_message = "This is a test log message."
10
+ exception_grouop_message = "Test Exception group"
11
+ exception_message = "Test Exception"
12
+ expected_keys = ["message", "level", "timestamp", "extra"]
13
+
14
+
15
+ def test_serialize_record_log_shape() -> None:
16
+ record = log_record(
17
+ lambda: logger.exception(
18
+ log_message,
19
+ exc_info=None,
20
+ )
21
+ )
22
+ serialized_record = _serialize_record(record)
23
+ assert all(key in serialized_record for key in expected_keys)
24
+ assert log_message in serialized_record.get("message", None)
25
+
26
+
27
+ def test_serialize_record_exc_info_single_exception() -> None:
28
+ record = log_record(
29
+ lambda: logger.exception(
30
+ log_message,
31
+ exc_info=ExceptionGroup(
32
+ exception_grouop_message, [Exception(exception_message)]
33
+ ),
34
+ )
35
+ )
36
+ serialized_record = _serialize_record(record)
37
+ exc_info = assert_extra(serialized_record.get("extra", {}))
38
+ assert exception_grouop_message in exc_info
39
+ assert exception_message in exc_info
40
+
41
+
42
+ def test_serialize_record_exc_info_group_exception() -> None:
43
+ record = log_record(
44
+ lambda: logger.exception(log_message, exc_info=Exception(exception_message))
45
+ )
46
+ serialized_record = _serialize_record(record)
47
+ exc_info = assert_extra(serialized_record.get("extra", {}))
48
+ assert exception_message in exc_info
49
+
50
+
51
+ def assert_extra(extra: dict[str, Any]) -> str:
52
+ exc_info = extra.get("exc_info", None)
53
+ assert type(exc_info) is str
54
+ return exc_info
55
+
56
+
57
+ def log_record(cb: Callable[[], None]) -> LogRecord:
58
+ queue = Queue[LogRecord]()
59
+ queue_handler = QueueHandler(queue)
60
+ logger_id = logger.add(
61
+ queue_handler,
62
+ level="DEBUG",
63
+ format="{message}",
64
+ diagnose=False,
65
+ enqueue=True,
66
+ )
67
+ cb()
68
+ logger.complete()
69
+ logger.remove(logger_id)
70
+ record = queue.get()
71
+ return record
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "port-ocean"
3
- version = "0.12.7"
3
+ version = "0.12.9"
4
4
  description = "Port Ocean is a CLI tool for managing your Port projects."
5
5
  readme = "README.md"
6
6
  homepage = "https://app.getport.io"
@@ -40,7 +40,7 @@ pydantic = { version = "^1.10.8", extras = ["dotenv"] }
40
40
  loguru = "^0.7.0"
41
41
  pyyaml = "^6.0"
42
42
  werkzeug = ">=2.3.4,<4.0.0"
43
- fastapi = ">=0.100,<0.112"
43
+ fastapi = "^0.115.3"
44
44
  uvicorn = ">=0.22,<0.31"
45
45
  confluent-kafka = "^2.1.1"
46
46
  httpx = ">=0.24.1,<0.28.0"
@@ -147,6 +147,7 @@ disallow_untyped_defs = true
147
147
  # Never enforce `E501` (line length violations).
148
148
  ignore = ["E501"]
149
149
  exclude = ['venv', '.venv', 'integrations']
150
+ target-version = "py311"
150
151
 
151
152
  [tool.pydantic-mypy]
152
153
  init_forbid_extra = true
File without changes
File without changes