port-ocean 0.27.3__tar.gz → 0.27.6__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.
Files changed (213) hide show
  1. {port_ocean-0.27.3 → port_ocean-0.27.6}/PKG-INFO +5 -2
  2. {port_ocean-0.27.3 → port_ocean-0.27.6}/integrations/_infra/Dockerfile.Deb +4 -1
  3. {port_ocean-0.27.3 → port_ocean-0.27.6}/integrations/_infra/Dockerfile.local +3 -1
  4. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/config/settings.py +9 -0
  5. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/event_listener/kafka.py +14 -0
  6. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/helpers/async_client.py +7 -0
  7. port_ocean-0.27.6/port_ocean/helpers/stream.py +71 -0
  8. port_ocean-0.27.6/port_ocean/tests/core/event_listener/test_kafka.py +70 -0
  9. {port_ocean-0.27.3 → port_ocean-0.27.6}/pyproject.toml +6 -2
  10. {port_ocean-0.27.3 → port_ocean-0.27.6}/LICENSE.md +0 -0
  11. {port_ocean-0.27.3 → port_ocean-0.27.6}/README.md +0 -0
  12. {port_ocean-0.27.3 → port_ocean-0.27.6}/integrations/_infra/Dockerfile.alpine +0 -0
  13. {port_ocean-0.27.3 → port_ocean-0.27.6}/integrations/_infra/Dockerfile.base.builder +0 -0
  14. {port_ocean-0.27.3 → port_ocean-0.27.6}/integrations/_infra/Dockerfile.base.runner +0 -0
  15. {port_ocean-0.27.3 → port_ocean-0.27.6}/integrations/_infra/Dockerfile.dockerignore +0 -0
  16. {port_ocean-0.27.3 → port_ocean-0.27.6}/integrations/_infra/Makefile +0 -0
  17. {port_ocean-0.27.3 → port_ocean-0.27.6}/integrations/_infra/README.md +0 -0
  18. {port_ocean-0.27.3 → port_ocean-0.27.6}/integrations/_infra/entry_local.sh +0 -0
  19. {port_ocean-0.27.3 → port_ocean-0.27.6}/integrations/_infra/grpcio.sh +0 -0
  20. {port_ocean-0.27.3 → port_ocean-0.27.6}/integrations/_infra/init.sh +0 -0
  21. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/__init__.py +0 -0
  22. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/bootstrap.py +0 -0
  23. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cache/__init__.py +0 -0
  24. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cache/base.py +0 -0
  25. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cache/disk.py +0 -0
  26. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cache/errors.py +0 -0
  27. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cache/memory.py +0 -0
  28. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/__init__.py +0 -0
  29. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cli.py +0 -0
  30. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/commands/__init__.py +0 -0
  31. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/commands/defaults/__init___.py +0 -0
  32. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/commands/defaults/clean.py +0 -0
  33. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/commands/defaults/dock.py +0 -0
  34. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/commands/defaults/group.py +0 -0
  35. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/commands/list_integrations.py +0 -0
  36. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/commands/main.py +0 -0
  37. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/commands/new.py +0 -0
  38. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/commands/pull.py +0 -0
  39. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/commands/sail.py +0 -0
  40. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/commands/version.py +0 -0
  41. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/__init__.py +0 -0
  42. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/cookiecutter.json +0 -0
  43. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/extensions.py +0 -0
  44. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/hooks/post_gen_project.py +0 -0
  45. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.env.example +0 -0
  46. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.gitignore +0 -0
  47. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/.gitignore +0 -0
  48. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/blueprints.json +0 -0
  49. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/port-app-config.yml +0 -0
  50. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/spec.yaml +0 -0
  51. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CHANGELOG.md +0 -0
  52. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CONTRIBUTING.md +0 -0
  53. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/README.md +0 -0
  54. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/changelog/.gitignore +0 -0
  55. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/debug.py +0 -0
  56. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/main.py +0 -0
  57. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/poetry.toml +0 -0
  58. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/pyproject.toml +0 -0
  59. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/sonar-project.properties +0 -0
  60. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/tests/__init__.py +0 -0
  61. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/tests/test_sample.py +0 -0
  62. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/cli/utils.py +0 -0
  63. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/clients/__init__.py +0 -0
  64. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/clients/auth/__init__.py +0 -0
  65. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/clients/auth/auth_client.py +0 -0
  66. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/clients/auth/oauth_client.py +0 -0
  67. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/clients/port/__init__.py +0 -0
  68. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/clients/port/authentication.py +0 -0
  69. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/clients/port/client.py +0 -0
  70. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/clients/port/mixins/__init__.py +0 -0
  71. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/clients/port/mixins/blueprints.py +0 -0
  72. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/clients/port/mixins/entities.py +0 -0
  73. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/clients/port/mixins/integrations.py +0 -0
  74. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/clients/port/mixins/migrations.py +0 -0
  75. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/clients/port/mixins/organization.py +0 -0
  76. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/clients/port/retry_transport.py +0 -0
  77. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/clients/port/types.py +0 -0
  78. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/clients/port/utils.py +0 -0
  79. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/config/__init__.py +0 -0
  80. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/config/base.py +0 -0
  81. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/config/dynamic.py +0 -0
  82. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/consumers/__init__.py +0 -0
  83. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/consumers/kafka_consumer.py +0 -0
  84. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/context/__init__.py +0 -0
  85. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/context/event.py +0 -0
  86. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/context/metric_resource.py +0 -0
  87. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/context/ocean.py +0 -0
  88. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/context/resource.py +0 -0
  89. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/__init__.py +0 -0
  90. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/defaults/__init__.py +0 -0
  91. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/defaults/clean.py +0 -0
  92. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/defaults/common.py +0 -0
  93. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/defaults/initialize.py +0 -0
  94. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/event_listener/__init__.py +0 -0
  95. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/event_listener/base.py +0 -0
  96. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/event_listener/factory.py +0 -0
  97. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/event_listener/http.py +0 -0
  98. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/event_listener/once.py +0 -0
  99. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/event_listener/polling.py +0 -0
  100. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/event_listener/webhooks_only.py +0 -0
  101. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/__init__.py +0 -0
  102. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/base.py +0 -0
  103. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/entities_state_applier/__init__.py +0 -0
  104. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/entities_state_applier/base.py +0 -0
  105. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/entities_state_applier/port/__init__.py +0 -0
  106. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/entities_state_applier/port/applier.py +0 -0
  107. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/entities_state_applier/port/get_related_entities.py +0 -0
  108. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/entities_state_applier/port/order_by_entities_dependencies.py +0 -0
  109. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/entity_processor/__init__.py +0 -0
  110. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/entity_processor/base.py +0 -0
  111. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/entity_processor/jq_entity_processor.py +0 -0
  112. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/port_app_config/__init__.py +0 -0
  113. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/port_app_config/api.py +0 -0
  114. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/port_app_config/base.py +0 -0
  115. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/port_app_config/models.py +0 -0
  116. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/queue/__init__.py +0 -0
  117. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/queue/abstract_queue.py +0 -0
  118. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/queue/group_queue.py +0 -0
  119. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/queue/local_queue.py +0 -0
  120. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/resync_state_updater/__init__.py +0 -0
  121. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/resync_state_updater/updater.py +0 -0
  122. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/webhook/__init__.py +0 -0
  123. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/webhook/abstract_webhook_processor.py +0 -0
  124. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/webhook/processor_manager.py +0 -0
  125. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/handlers/webhook/webhook_event.py +0 -0
  126. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/integrations/__init__.py +0 -0
  127. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/integrations/base.py +0 -0
  128. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/integrations/mixins/__init__.py +0 -0
  129. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/integrations/mixins/events.py +0 -0
  130. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/integrations/mixins/handler.py +0 -0
  131. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/integrations/mixins/live_events.py +0 -0
  132. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/integrations/mixins/sync.py +0 -0
  133. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/integrations/mixins/sync_raw.py +0 -0
  134. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/integrations/mixins/utils.py +0 -0
  135. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/models.py +0 -0
  136. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/ocean_types.py +0 -0
  137. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/utils/entity_topological_sorter.py +0 -0
  138. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/core/utils/utils.py +0 -0
  139. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/debug_cli.py +0 -0
  140. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/exceptions/__init__.py +0 -0
  141. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/exceptions/api.py +0 -0
  142. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/exceptions/base.py +0 -0
  143. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/exceptions/clients.py +0 -0
  144. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/exceptions/context.py +0 -0
  145. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/exceptions/core.py +0 -0
  146. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/exceptions/port_defaults.py +0 -0
  147. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/exceptions/utils.py +0 -0
  148. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/exceptions/webhook_processor.py +0 -0
  149. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/helpers/__init__.py +0 -0
  150. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/helpers/metric/metric.py +0 -0
  151. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/helpers/metric/utils.py +0 -0
  152. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/helpers/retry.py +0 -0
  153. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/log/__init__.py +0 -0
  154. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/log/handlers.py +0 -0
  155. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/log/logger_setup.py +0 -0
  156. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/log/sensetive.py +0 -0
  157. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/middlewares.py +0 -0
  158. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/ocean.py +0 -0
  159. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/py.typed +0 -0
  160. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/run.py +0 -0
  161. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/sonar-project.properties +0 -0
  162. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/__init__.py +0 -0
  163. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/cache/__init__.py +0 -0
  164. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/cache/test_disk_cache.py +0 -0
  165. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/cache/test_memory_cache.py +0 -0
  166. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/clients/__init__.py +0 -0
  167. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/clients/oauth/__init__.py +0 -0
  168. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/clients/oauth/test_oauth_client.py +0 -0
  169. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/clients/port/mixins/test_entities.py +0 -0
  170. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/clients/port/mixins/test_integrations.py +0 -0
  171. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/clients/port/mixins/test_organization_mixin.py +0 -0
  172. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/config/test_config.py +0 -0
  173. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/conftest.py +0 -0
  174. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/core/conftest.py +0 -0
  175. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/core/defaults/test_common.py +0 -0
  176. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/core/handlers/entities_state_applier/test_applier.py +0 -0
  177. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/core/handlers/entity_processor/test_jq_entity_processor.py +0 -0
  178. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/core/handlers/mixins/test_live_events.py +0 -0
  179. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/core/handlers/mixins/test_sync_raw.py +0 -0
  180. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/core/handlers/port_app_config/test_api.py +0 -0
  181. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/core/handlers/port_app_config/test_base.py +0 -0
  182. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/core/handlers/queue/test_group_queue.py +0 -0
  183. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/core/handlers/queue/test_local_queue.py +0 -0
  184. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/core/handlers/webhook/test_abstract_webhook_processor.py +0 -0
  185. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/core/handlers/webhook/test_processor_manager.py +0 -0
  186. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/core/handlers/webhook/test_webhook_event.py +0 -0
  187. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/core/test_utils.py +0 -0
  188. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/core/utils/test_entity_topological_sorter.py +0 -0
  189. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/core/utils/test_resolve_entities_diff.py +0 -0
  190. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/helpers/__init__.py +0 -0
  191. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/helpers/fake_port_api.py +0 -0
  192. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/helpers/fixtures.py +0 -0
  193. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/helpers/integration.py +0 -0
  194. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/helpers/ocean_app.py +0 -0
  195. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/helpers/port_client.py +0 -0
  196. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/helpers/smoke_test.py +0 -0
  197. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/log/test_handlers.py +0 -0
  198. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/test_metric.py +0 -0
  199. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/test_ocean.py +0 -0
  200. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/test_smoke.py +0 -0
  201. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/utils/test_async_iterators.py +0 -0
  202. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/tests/utils/test_cache.py +0 -0
  203. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/utils/__init__.py +0 -0
  204. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/utils/async_http.py +0 -0
  205. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/utils/async_iterators.py +0 -0
  206. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/utils/cache.py +0 -0
  207. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/utils/ipc.py +0 -0
  208. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/utils/misc.py +0 -0
  209. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/utils/queue_utils.py +0 -0
  210. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/utils/repeat.py +0 -0
  211. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/utils/signal.py +0 -0
  212. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/utils/time.py +0 -0
  213. {port_ocean-0.27.3 → port_ocean-0.27.6}/port_ocean/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: port-ocean
3
- Version: 0.27.3
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: fastapi (>=0.115.3,<0.116.0)
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)
@@ -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
 
@@ -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
  [tool.poetry]
2
2
  name = "port-ocean"
3
- version = "0.27.3"
3
+ version = "0.27.6"
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"
@@ -44,7 +44,7 @@ pydantic = { version = "^1.10.8", extras = ["dotenv"] }
44
44
  loguru = "^0.7.0"
45
45
  pyyaml = "^6.0"
46
46
  werkzeug = ">=2.3.4,<4.0.0"
47
- fastapi = "^0.115.3"
47
+ fastapi = "^0.116.0"
48
48
  uvicorn = "^0.34.3"
49
49
  confluent-kafka = "^2.10.1"
50
50
  httpx = "^0.28.1"
@@ -65,6 +65,9 @@ cookiecutter = { version = "^2.1.1", optional = true }
65
65
  jinja2-time = { version = "^0.2.0", optional = true }
66
66
  prometheus-client = "^0.21.1"
67
67
  pytest-cov = "^6.0.0"
68
+ ijson = "^3.4.0"
69
+ aiofiles = "^24.1.0"
70
+ cryptography = "^44.0.1"
68
71
 
69
72
  [tool.poetry.extras]
70
73
  cli = ["click", "rich", "cookiecutter", "jinja2-time"]
@@ -90,6 +93,7 @@ cryptography = ">=43.0.1,<45.0.0"
90
93
  psutil = "^7.0.0"
91
94
  memray = "^1.17.2"
92
95
  faker = "^37.3.0"
96
+ types-aiofiles = "^24.1.0.20250809"
93
97
 
94
98
  [tool.towncrier]
95
99
  directory = "changelog"
File without changes
File without changes