port-ocean 0.22.0__tar.gz → 0.22.2__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 (194) hide show
  1. {port_ocean-0.22.0 → port_ocean-0.22.2}/PKG-INFO +2 -1
  2. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/clients/port/mixins/entities.py +10 -10
  3. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/defaults/common.py +1 -0
  4. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/defaults/initialize.py +1 -1
  5. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/entities_state_applier/port/applier.py +14 -20
  6. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/port_app_config/models.py +13 -4
  7. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/integrations/mixins/sync.py +1 -1
  8. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/integrations/mixins/sync_raw.py +1 -1
  9. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/models.py +6 -2
  10. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/utils/utils.py +10 -2
  11. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/clients/port/mixins/test_entities.py +2 -1
  12. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/core/conftest.py +2 -1
  13. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/core/handlers/entities_state_applier/test_applier.py +92 -0
  14. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/core/handlers/entity_processor/test_jq_entity_processor.py +1 -1
  15. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/core/handlers/mixins/test_sync_raw.py +24 -0
  16. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/core/handlers/port_app_config/test_base.py +82 -0
  17. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/core/utils/test_resolve_entities_diff.py +52 -0
  18. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/helpers/fixtures.py +2 -3
  19. {port_ocean-0.22.0 → port_ocean-0.22.2}/pyproject.toml +2 -1
  20. {port_ocean-0.22.0 → port_ocean-0.22.2}/LICENSE.md +0 -0
  21. {port_ocean-0.22.0 → port_ocean-0.22.2}/README.md +0 -0
  22. {port_ocean-0.22.0 → port_ocean-0.22.2}/integrations/_infra/Dockerfile.Deb +0 -0
  23. {port_ocean-0.22.0 → port_ocean-0.22.2}/integrations/_infra/Dockerfile.alpine +0 -0
  24. {port_ocean-0.22.0 → port_ocean-0.22.2}/integrations/_infra/Dockerfile.base.builder +0 -0
  25. {port_ocean-0.22.0 → port_ocean-0.22.2}/integrations/_infra/Dockerfile.base.runner +0 -0
  26. {port_ocean-0.22.0 → port_ocean-0.22.2}/integrations/_infra/Dockerfile.dockerignore +0 -0
  27. {port_ocean-0.22.0 → port_ocean-0.22.2}/integrations/_infra/Makefile +0 -0
  28. {port_ocean-0.22.0 → port_ocean-0.22.2}/integrations/_infra/grpcio.sh +0 -0
  29. {port_ocean-0.22.0 → port_ocean-0.22.2}/integrations/_infra/init.sh +0 -0
  30. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/__init__.py +0 -0
  31. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/bootstrap.py +0 -0
  32. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/__init__.py +0 -0
  33. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cli.py +0 -0
  34. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/commands/__init__.py +0 -0
  35. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/commands/defaults/__init___.py +0 -0
  36. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/commands/defaults/clean.py +0 -0
  37. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/commands/defaults/dock.py +0 -0
  38. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/commands/defaults/group.py +0 -0
  39. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/commands/list_integrations.py +0 -0
  40. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/commands/main.py +0 -0
  41. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/commands/new.py +0 -0
  42. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/commands/pull.py +0 -0
  43. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/commands/sail.py +0 -0
  44. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/commands/version.py +0 -0
  45. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/__init__.py +0 -0
  46. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/cookiecutter.json +0 -0
  47. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/extensions.py +0 -0
  48. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/hooks/post_gen_project.py +0 -0
  49. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.env.example +0 -0
  50. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.gitignore +0 -0
  51. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/.gitignore +0 -0
  52. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/blueprints.json +0 -0
  53. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/port-app-config.yml +0 -0
  54. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/spec.yaml +0 -0
  55. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CHANGELOG.md +0 -0
  56. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CONTRIBUTING.md +0 -0
  57. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/README.md +0 -0
  58. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/changelog/.gitignore +0 -0
  59. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/debug.py +0 -0
  60. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/main.py +0 -0
  61. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/poetry.toml +0 -0
  62. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/pyproject.toml +0 -0
  63. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/sonar-project.properties +0 -0
  64. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/tests/__init__.py +0 -0
  65. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/tests/test_sample.py +0 -0
  66. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/cli/utils.py +0 -0
  67. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/clients/__init__.py +0 -0
  68. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/clients/auth/__init__.py +0 -0
  69. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/clients/auth/auth_client.py +0 -0
  70. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/clients/auth/oauth_client.py +0 -0
  71. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/clients/port/__init__.py +0 -0
  72. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/clients/port/authentication.py +0 -0
  73. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/clients/port/client.py +0 -0
  74. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/clients/port/mixins/__init__.py +0 -0
  75. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/clients/port/mixins/blueprints.py +0 -0
  76. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/clients/port/mixins/integrations.py +0 -0
  77. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/clients/port/mixins/migrations.py +0 -0
  78. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/clients/port/mixins/organization.py +0 -0
  79. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/clients/port/retry_transport.py +0 -0
  80. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/clients/port/types.py +0 -0
  81. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/clients/port/utils.py +0 -0
  82. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/config/__init__.py +0 -0
  83. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/config/base.py +0 -0
  84. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/config/dynamic.py +0 -0
  85. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/config/settings.py +0 -0
  86. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/consumers/__init__.py +0 -0
  87. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/consumers/kafka_consumer.py +0 -0
  88. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/context/__init__.py +0 -0
  89. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/context/event.py +0 -0
  90. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/context/ocean.py +0 -0
  91. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/context/resource.py +0 -0
  92. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/__init__.py +0 -0
  93. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/defaults/__init__.py +0 -0
  94. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/defaults/clean.py +0 -0
  95. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/event_listener/__init__.py +0 -0
  96. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/event_listener/base.py +0 -0
  97. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/event_listener/factory.py +0 -0
  98. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/event_listener/http.py +0 -0
  99. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/event_listener/kafka.py +0 -0
  100. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/event_listener/once.py +0 -0
  101. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/event_listener/polling.py +0 -0
  102. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/event_listener/webhooks_only.py +0 -0
  103. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/__init__.py +0 -0
  104. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/base.py +0 -0
  105. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/entities_state_applier/__init__.py +0 -0
  106. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/entities_state_applier/base.py +0 -0
  107. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/entities_state_applier/port/__init__.py +0 -0
  108. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/entities_state_applier/port/get_related_entities.py +0 -0
  109. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/entities_state_applier/port/order_by_entities_dependencies.py +0 -0
  110. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/entity_processor/__init__.py +0 -0
  111. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/entity_processor/base.py +0 -0
  112. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/entity_processor/jq_entity_processor.py +0 -0
  113. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/port_app_config/__init__.py +0 -0
  114. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/port_app_config/api.py +0 -0
  115. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/port_app_config/base.py +0 -0
  116. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/queue/__init__.py +0 -0
  117. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/queue/abstract_queue.py +0 -0
  118. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/queue/local_queue.py +0 -0
  119. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/resync_state_updater/__init__.py +0 -0
  120. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/resync_state_updater/updater.py +0 -0
  121. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/webhook/__init__.py +0 -0
  122. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/webhook/abstract_webhook_processor.py +0 -0
  123. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/webhook/processor_manager.py +0 -0
  124. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/handlers/webhook/webhook_event.py +0 -0
  125. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/integrations/__init__.py +0 -0
  126. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/integrations/base.py +0 -0
  127. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/integrations/mixins/__init__.py +0 -0
  128. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/integrations/mixins/events.py +0 -0
  129. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/integrations/mixins/handler.py +0 -0
  130. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/integrations/mixins/live_events.py +0 -0
  131. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/integrations/mixins/utils.py +0 -0
  132. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/ocean_types.py +0 -0
  133. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/core/utils/entity_topological_sorter.py +0 -0
  134. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/debug_cli.py +0 -0
  135. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/exceptions/__init__.py +0 -0
  136. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/exceptions/api.py +0 -0
  137. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/exceptions/base.py +0 -0
  138. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/exceptions/clients.py +0 -0
  139. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/exceptions/context.py +0 -0
  140. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/exceptions/core.py +0 -0
  141. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/exceptions/port_defaults.py +0 -0
  142. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/exceptions/utils.py +0 -0
  143. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/exceptions/webhook_processor.py +0 -0
  144. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/helpers/__init__.py +0 -0
  145. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/helpers/async_client.py +0 -0
  146. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/helpers/metric/metric.py +0 -0
  147. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/helpers/metric/utils.py +0 -0
  148. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/helpers/retry.py +0 -0
  149. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/log/__init__.py +0 -0
  150. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/log/handlers.py +0 -0
  151. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/log/logger_setup.py +0 -0
  152. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/log/sensetive.py +0 -0
  153. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/middlewares.py +0 -0
  154. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/ocean.py +0 -0
  155. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/py.typed +0 -0
  156. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/run.py +0 -0
  157. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/sonar-project.properties +0 -0
  158. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/__init__.py +0 -0
  159. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/clients/__init__.py +0 -0
  160. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/clients/oauth/__init__.py +0 -0
  161. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/clients/oauth/test_oauth_client.py +0 -0
  162. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/clients/port/mixins/test_organization_mixin.py +0 -0
  163. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/conftest.py +0 -0
  164. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/core/defaults/test_common.py +0 -0
  165. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/core/handlers/mixins/test_live_events.py +0 -0
  166. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/core/handlers/port_app_config/test_api.py +0 -0
  167. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/core/handlers/queue/test_local_queue.py +0 -0
  168. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/core/handlers/webhook/test_abstract_webhook_processor.py +0 -0
  169. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/core/handlers/webhook/test_processor_manager.py +0 -0
  170. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/core/handlers/webhook/test_webhook_event.py +0 -0
  171. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/core/test_utils.py +0 -0
  172. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/core/utils/test_entity_topological_sorter.py +0 -0
  173. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/helpers/__init__.py +0 -0
  174. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/helpers/fake_port_api.py +0 -0
  175. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/helpers/integration.py +0 -0
  176. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/helpers/ocean_app.py +0 -0
  177. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/helpers/port_client.py +0 -0
  178. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/helpers/smoke_test.py +0 -0
  179. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/log/test_handlers.py +0 -0
  180. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/test_metric.py +0 -0
  181. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/test_ocean.py +0 -0
  182. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/test_smoke.py +0 -0
  183. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/utils/test_async_iterators.py +0 -0
  184. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/tests/utils/test_cache.py +0 -0
  185. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/utils/__init__.py +0 -0
  186. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/utils/async_http.py +0 -0
  187. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/utils/async_iterators.py +0 -0
  188. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/utils/cache.py +0 -0
  189. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/utils/misc.py +0 -0
  190. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/utils/queue_utils.py +0 -0
  191. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/utils/repeat.py +0 -0
  192. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/utils/signal.py +0 -0
  193. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/utils/time.py +0 -0
  194. {port_ocean-0.22.0 → port_ocean-0.22.2}/port_ocean/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: port-ocean
3
- Version: 0.22.0
3
+ Version: 0.22.2
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
@@ -35,6 +35,7 @@ Requires-Dist: prometheus-client (>=0.21.1,<0.22.0)
35
35
  Requires-Dist: pydantic[dotenv] (>=1.10.8,<2.0.0)
36
36
  Requires-Dist: pydispatcher (>=2.0.7,<3.0.0)
37
37
  Requires-Dist: pyhumps (>=3.8.0,<4.0.0)
38
+ Requires-Dist: pytest-cov (>=6.0.0,<7.0.0)
38
39
  Requires-Dist: python-dateutil (>=2.9.0.post0,<3.0.0)
39
40
  Requires-Dist: pyyaml (>=6.0,<7.0)
40
41
  Requires-Dist: rich (>=13.4.1,<14.0.0) ; extra == "cli"
@@ -133,7 +133,7 @@ class EntityClientMixin:
133
133
  request_options: RequestOptions,
134
134
  user_agent_type: UserAgentType | None = None,
135
135
  should_raise: bool = True,
136
- ) -> list[Entity]:
136
+ ) -> list[tuple[bool, Entity]]:
137
137
  modified_entities_results = await asyncio.gather(
138
138
  *(
139
139
  self.upsert_entity(
@@ -146,17 +146,17 @@ class EntityClientMixin:
146
146
  ),
147
147
  return_exceptions=True,
148
148
  )
149
- entity_results = [
150
- entity for entity in modified_entities_results if isinstance(entity, Entity)
151
- ]
152
- if not should_raise:
153
- return entity_results
154
149
 
155
- for entity_result in modified_entities_results:
156
- if isinstance(entity_result, Exception):
157
- raise entity_result
150
+ entities_results: list[tuple[bool, Entity]] = []
151
+ for original_entity, result in zip(entities, modified_entities_results):
152
+ if isinstance(result, Exception) and should_raise:
153
+ raise result
154
+ elif isinstance(result, Entity):
155
+ entities_results.append((True, result))
156
+ elif result is False:
157
+ entities_results.append((False, original_entity))
158
158
 
159
- return entity_results
159
+ return entities_results
160
160
 
161
161
  async def delete_entity(
162
162
  self,
@@ -68,6 +68,7 @@ def deconstruct_blueprints_to_creation_steps(
68
68
  with_relations.append(blueprint.copy())
69
69
 
70
70
  blueprint.pop("teamInheritance", {})
71
+ blueprint.pop("ownership", {})
71
72
  blueprint.pop("relations", {})
72
73
  bare_blueprint.append(blueprint)
73
74
 
@@ -42,8 +42,8 @@ def deconstruct_blueprints_to_creation_steps(
42
42
  blueprint.pop("mirrorProperties", {})
43
43
  blueprint.pop("aggregationProperties", {})
44
44
  with_relations.append(blueprint.copy())
45
-
46
45
  blueprint.pop("teamInheritance", {})
46
+ blueprint.pop("ownership", {})
47
47
  blueprint.pop("relations", {})
48
48
  bare_blueprint.append(blueprint)
49
49
 
@@ -121,26 +121,20 @@ class HttpEntitiesStateApplier(BaseEntitiesStateApplier):
121
121
  ) -> list[Entity]:
122
122
  logger.info(f"Upserting {len(entities)} entities")
123
123
  modified_entities: list[Entity] = []
124
- if event.port_app_config.create_missing_related_entities:
125
- modified_entities = await self.context.port_client.batch_upsert_entities(
126
- entities,
127
- event.port_app_config.get_port_request_options(),
128
- user_agent_type,
129
- should_raise=False,
130
- )
131
- else:
132
- for entity in entities:
133
- upsertedEntity = await self.context.port_client.upsert_entity(
134
- entity,
135
- event.port_app_config.get_port_request_options(),
136
- user_agent_type,
137
- should_raise=False,
138
- )
139
- if upsertedEntity:
140
- modified_entities.append(upsertedEntity)
141
- # condition to false to differentiate from `result_entity.is_using_search_identifier`
142
- if upsertedEntity is False:
143
- event.entity_topological_sorter.register_entity(entity)
124
+ upserted_entities: list[tuple[bool, Entity]] = []
125
+
126
+ upserted_entities = await self.context.port_client.batch_upsert_entities(
127
+ entities,
128
+ event.port_app_config.get_port_request_options(),
129
+ user_agent_type,
130
+ should_raise=False,
131
+ )
132
+
133
+ for is_upserted, entity in upserted_entities:
134
+ if is_upserted:
135
+ modified_entities.append(entity)
136
+ else:
137
+ event.entity_topological_sorter.register_entity(entity)
144
138
  return modified_entities
145
139
 
146
140
  async def delete(
@@ -22,7 +22,7 @@ class EntityMapping(BaseModel):
22
22
  identifier: str | IngestSearchQuery
23
23
  title: str | None
24
24
  blueprint: str
25
- team: str | None
25
+ team: str | IngestSearchQuery | None
26
26
  properties: dict[str, str] = Field(default_factory=dict)
27
27
  relations: dict[str, str | IngestSearchQuery] = Field(default_factory=dict)
28
28
 
@@ -51,6 +51,7 @@ class ResourceConfig(BaseModel):
51
51
 
52
52
 
53
53
  class PortAppConfig(BaseModel):
54
+ _default_entity_deletion_threshold: float = 0.9
54
55
  enable_merge_entity: bool = Field(alias="enableMergeEntity", default=True)
55
56
  delete_dependent_entities: bool = Field(
56
57
  alias="deleteDependentEntities", default=True
@@ -58,8 +59,8 @@ class PortAppConfig(BaseModel):
58
59
  create_missing_related_entities: bool = Field(
59
60
  alias="createMissingRelatedEntities", default=True
60
61
  )
61
- entity_deletion_threshold: float = Field(
62
- alias="entityDeletionThreshold", default=0.9
62
+ entity_deletion_threshold: float | None = Field(
63
+ alias="entityDeletionThreshold", default=None
63
64
  )
64
65
  resources: list[ResourceConfig] = Field(default_factory=list)
65
66
 
@@ -71,8 +72,13 @@ class PortAppConfig(BaseModel):
71
72
  "validation_only": False,
72
73
  }
73
74
 
75
+ def get_entity_deletion_threshold(self) -> float | None:
76
+ if self.entity_deletion_threshold is not None:
77
+ return self.entity_deletion_threshold
78
+ return self._default_entity_deletion_threshold
79
+
74
80
  def to_request(self) -> dict[str, Any]:
75
- return {
81
+ mapping = {
76
82
  "deleteDependentEntities": self.delete_dependent_entities,
77
83
  "createMissingRelatedEntities": self.create_missing_related_entities,
78
84
  "enableMergeEntity": self.enable_merge_entity,
@@ -81,6 +87,9 @@ class PortAppConfig(BaseModel):
81
87
  for resource in self.resources
82
88
  ],
83
89
  }
90
+ if self.entity_deletion_threshold is not None:
91
+ mapping["entityDeletionThreshold"] = self.entity_deletion_threshold
92
+ return mapping
84
93
 
85
94
  class Config:
86
95
  allow_population_by_field_name = True
@@ -102,7 +102,7 @@ class SyncMixin(HandlerMixin):
102
102
  entities, user_agent_type
103
103
  )
104
104
  await self.entities_state_applier.delete_diff(
105
- {"before": entities_at_port, "after": modified_entities}, user_agent_type, app_config.entity_deletion_threshold
105
+ {"before": entities_at_port, "after": modified_entities}, user_agent_type, app_config.get_entity_deletion_threshold()
106
106
  )
107
107
 
108
108
  logger.info("Finished syncing change")
@@ -671,7 +671,7 @@ class SyncRawMixin(HandlerMixin, EventsMixin):
671
671
  )
672
672
  await self.entities_state_applier.delete_diff(
673
673
  {"before": entities_at_port, "after": generated_entities},
674
- user_agent_type, app_config.entity_deletion_threshold
674
+ user_agent_type, app_config.get_entity_deletion_threshold()
675
675
  )
676
676
 
677
677
  logger.info("Resync finished successfully")
@@ -40,7 +40,7 @@ class Entity(BaseModel):
40
40
  identifier: Any
41
41
  blueprint: Any
42
42
  title: Any
43
- team: str | None | list[Any] = []
43
+ team: str | None | list[Any] | dict[str, Any] = []
44
44
  properties: dict[str, Any] = {}
45
45
  relations: dict[str, Any] = {}
46
46
 
@@ -50,7 +50,11 @@ class Entity(BaseModel):
50
50
 
51
51
  @property
52
52
  def is_using_search_relation(self) -> bool:
53
- return any(isinstance(relation, dict) for relation in self.relations.values())
53
+ return any(
54
+ isinstance(relation, dict) for relation in self.relations.values()
55
+ ) or (
56
+ self.team is not None and any(isinstance(team, dict) for team in self.team)
57
+ )
54
58
 
55
59
 
56
60
  class BlueprintRelation(BaseModel):
@@ -110,7 +110,8 @@ def get_port_diff(before: Iterable[Entity], after: Iterable[Entity]) -> EntityPo
110
110
 
111
111
 
112
112
  def are_teams_different(
113
- first_team: str | None | list[Any], second_team: str | None | list[Any]
113
+ first_team: str | None | list[Any] | dict[str, Any],
114
+ second_team: str | None | list[Any] | dict[str, Any],
114
115
  ) -> bool:
115
116
  if isinstance(first_team, list) and isinstance(second_team, list):
116
117
  return sorted(first_team) != sorted(second_team)
@@ -122,6 +123,7 @@ def are_entities_fields_equal(
122
123
  ) -> bool:
123
124
  """
124
125
  Compare two entity fields by serializing them to JSON and comparing their SHA-256 hashes.
126
+ Removes keys with None values before comparison if the corresponding key doesn't exist in the other dict.
125
127
 
126
128
  Args:
127
129
  first_entity_field: First entity field dictionary to compare
@@ -130,7 +132,13 @@ def are_entities_fields_equal(
130
132
  Returns:
131
133
  bool: True if the entity fields have identical content
132
134
  """
133
- first_props = json.dumps(first_entity_field, sort_keys=True)
135
+ first_entity_field_copy = first_entity_field.copy()
136
+
137
+ for key in list(first_entity_field.keys()):
138
+ if first_entity_field[key] is None and key not in second_entity_field:
139
+ del first_entity_field_copy[key]
140
+
141
+ first_props = json.dumps(first_entity_field_copy, sort_keys=True)
134
142
  second_props = json.dumps(second_entity_field, sort_keys=True)
135
143
  first_hash = hashlib.sha256(first_props.encode()).hexdigest()
136
144
  second_hash = hashlib.sha256(second_props.encode()).hexdigest()
@@ -41,8 +41,9 @@ async def test_batch_upsert_entities_read_timeout_should_raise_false(
41
41
  result_entities = await entity_client.batch_upsert_entities(
42
42
  entities=all_entities, request_options=MagicMock(), should_raise=False
43
43
  )
44
+ entities_only = [entity for _, entity in result_entities]
44
45
 
45
- assert result_entities == expected_result_entities
46
+ assert entities_only == expected_result_entities
46
47
 
47
48
 
48
49
  async def test_batch_upsert_entities_read_timeout_should_raise_true(
@@ -177,10 +177,11 @@ def create_entity(
177
177
  blueprint: str,
178
178
  relation: dict[str, str] | None = None,
179
179
  is_to_fail: bool = False,
180
+ team: str | list[str] | dict[str, Any] | None = None,
180
181
  ) -> Entity:
181
182
  if relation is None:
182
183
  relation = {}
183
- entity = Entity(identifier=id, blueprint=blueprint)
184
+ entity = Entity(identifier=id, blueprint=blueprint, team=team)
184
185
  entity.relations = relation
185
186
  entity.properties = {"mock_is_to_fail": is_to_fail}
186
187
  return entity
@@ -95,6 +95,30 @@ async def test_delete_diff_custom_threshold_above_threshold_not_deleted(
95
95
  mock_safe_delete.assert_not_called()
96
96
 
97
97
 
98
+ @pytest.mark.asyncio
99
+ async def test_delete_diff_custom_threshold_0_not_deleted(
100
+ mock_context: PortOceanContext,
101
+ ) -> None:
102
+ applier = HttpEntitiesStateApplier(mock_context)
103
+ entities = EntityDiff(
104
+ before=[
105
+ Entity(identifier="1", blueprint="test"),
106
+ Entity(identifier="2", blueprint="test"),
107
+ ],
108
+ after=[
109
+ Entity(identifier="2", blueprint="test"),
110
+ Entity(identifier="3", blueprint="test"),
111
+ ],
112
+ )
113
+
114
+ with patch.object(applier, "_safe_delete") as mock_safe_delete:
115
+ await applier.delete_diff(
116
+ entities, UserAgentType.exporter, entity_deletion_threshold=0
117
+ )
118
+
119
+ mock_safe_delete.assert_not_called()
120
+
121
+
98
122
  @pytest.mark.asyncio
99
123
  async def test_applier_with_mock_context(
100
124
  mock_ocean: Ocean,
@@ -130,6 +154,74 @@ async def test_applier_with_mock_context(
130
154
  assert result[0].identifier == "test_entity"
131
155
 
132
156
 
157
+ @pytest.mark.asyncio
158
+ async def test_applier_one_not_upserted(
159
+ mock_ocean: Ocean,
160
+ mock_context: PortOceanContext,
161
+ mock_port_app_config: PortAppConfig,
162
+ ) -> None:
163
+ # Create an applier using the mock_context fixture
164
+ applier = HttpEntitiesStateApplier(mock_context)
165
+
166
+ # Create test entities
167
+ entity = Entity(identifier="test_entity", blueprint="test_blueprint")
168
+
169
+ async with event_context(EventType.RESYNC, trigger_type="machine") as event:
170
+ # Mock the register_entity method
171
+ event.entity_topological_sorter.register_entity = Mock() # type: ignore
172
+ event.port_app_config = mock_port_app_config
173
+
174
+ # Test the upsert method with mocked client
175
+ with patch.object(mock_ocean.port_client.client, "post") as mock_post:
176
+ mock_post.return_value = Mock(
177
+ status_code=404,
178
+ json=lambda: {"ok": False, "error": "not_found"},
179
+ )
180
+
181
+ result = await applier.upsert([entity], UserAgentType.exporter)
182
+
183
+ # Assert that the post method was called
184
+ mock_post.assert_called_once()
185
+ assert len(result) == 0
186
+ event.entity_topological_sorter.register_entity.assert_called_once_with(
187
+ entity
188
+ )
189
+
190
+
191
+ @pytest.mark.asyncio
192
+ async def test_applier_error_upserting(
193
+ mock_ocean: Ocean,
194
+ mock_context: PortOceanContext,
195
+ mock_port_app_config: PortAppConfig,
196
+ ) -> None:
197
+ # Create an applier using the mock_context fixture
198
+ applier = HttpEntitiesStateApplier(mock_context)
199
+
200
+ # Create test entities
201
+ entity = Entity(identifier="test_entity", blueprint="test_blueprint")
202
+
203
+ async with event_context(EventType.RESYNC, trigger_type="machine") as event:
204
+ # Mock the register_entity method
205
+ event.entity_topological_sorter.register_entity = Mock() # type: ignore
206
+ event.port_app_config = mock_port_app_config
207
+
208
+ # Test the upsert method with mocked client
209
+ with patch.object(mock_ocean.port_client.client, "post") as mock_post:
210
+ mock_post.return_value = Mock(
211
+ status_code=404,
212
+ json=lambda: {"ok": False, "error": "not_found"},
213
+ )
214
+
215
+ result = await applier.upsert([entity], UserAgentType.exporter)
216
+
217
+ # Assert that the post method was called
218
+ mock_post.assert_called_once()
219
+ assert len(result) == 0
220
+ event.entity_topological_sorter.register_entity.assert_called_once_with(
221
+ entity
222
+ )
223
+
224
+
133
225
  @pytest.mark.asyncio
134
226
  async def test_using_create_entity_helper(
135
227
  mock_ocean: Ocean,
@@ -249,7 +249,7 @@ class TestJQEntityProcessor:
249
249
  result = await mocked_processor._search(data, pattern)
250
250
  assert result == "bar"
251
251
 
252
- @pytest.mark.timeout(15)
252
+ @pytest.mark.timeout(30)
253
253
  async def test_parse_items_performance_10000(
254
254
  self, mocked_processor: JQEntityProcessor
255
255
  ) -> None:
@@ -417,6 +417,30 @@ async def test_map_entities_compared_with_port_no_port_entities_all_entities_are
417
417
  assert "entity_2" in [e.identifier for e in changed_entities]
418
418
 
419
419
 
420
+ @pytest.mark.asyncio
421
+ async def test_map_entities_compared_with_port_returns_original_entities_when_using_team_search_query(
422
+ mock_sync_raw_mixin: SyncRawMixin,
423
+ mock_resource_config: ResourceConfig,
424
+ ) -> None:
425
+
426
+ team_search_query = {
427
+ "combinator": "and",
428
+ "rules": [{"property": "$team", "operator": "=", "value": "my-team"}],
429
+ }
430
+
431
+ entities = [
432
+ create_entity("entity_1", "service", {}, False, team=team_search_query),
433
+ create_entity("entity_2", "service", {}, False, team=team_search_query),
434
+ ]
435
+
436
+ changed_entities = await mock_sync_raw_mixin._map_entities_compared_with_port(
437
+ entities, mock_resource_config, UserAgentType.exporter
438
+ )
439
+
440
+ assert len(changed_entities) == 2
441
+ assert changed_entities == entities
442
+
443
+
420
444
  @pytest.mark.asyncio
421
445
  async def test_map_entities_compared_with_port_with_existing_entities_only_changed_third_party_entities_are_mapped(
422
446
  mock_sync_raw_mixin: SyncRawMixin,
@@ -78,6 +78,88 @@ async def test_get_port_app_config_success(
78
78
  result.resources[0].port.entity.mappings.properties["defaultBranch"]
79
79
  == ".default_branch"
80
80
  )
81
+ assert result.entity_deletion_threshold is None
82
+ port_app_config_handler.mock_get_port_app_config.assert_called_once()
83
+
84
+
85
+ @pytest.mark.asyncio
86
+ async def test_get_port_app_config_get_entity_deletion_threshold_with_flag_defined(
87
+ port_app_config_handler: MockPortAppConfig,
88
+ ) -> None:
89
+ # Arrange
90
+ valid_config = {
91
+ "entityDeletionThreshold": 0.1,
92
+ "resources": [
93
+ {
94
+ "kind": "repository",
95
+ "selector": {"query": "true"},
96
+ "port": {
97
+ "entity": {
98
+ "mappings": {
99
+ "identifier": ".name",
100
+ "title": ".name",
101
+ "blueprint": '"service"',
102
+ "properties": {
103
+ "description": ".description",
104
+ "url": ".html_url",
105
+ "defaultBranch": ".default_branch",
106
+ },
107
+ }
108
+ }
109
+ },
110
+ }
111
+ ],
112
+ }
113
+ port_app_config_handler.mock_get_port_app_config.return_value = valid_config
114
+
115
+ # Act
116
+ async with event_context(EventType.RESYNC, trigger_type="machine"):
117
+ result = await port_app_config_handler.get_port_app_config()
118
+ deletion_threshold = result.get_entity_deletion_threshold()
119
+
120
+ # Assert
121
+ assert isinstance(result, PortAppConfig)
122
+ assert deletion_threshold == 0.1
123
+ port_app_config_handler.mock_get_port_app_config.assert_called_once()
124
+
125
+
126
+ @pytest.mark.asyncio
127
+ async def test_get_port_app_config_get_entity_deletion_threshold_with_flag_not_defined(
128
+ port_app_config_handler: MockPortAppConfig,
129
+ ) -> None:
130
+ # Arrange
131
+ valid_config = {
132
+ "resources": [
133
+ {
134
+ "kind": "repository",
135
+ "selector": {"query": "true"},
136
+ "port": {
137
+ "entity": {
138
+ "mappings": {
139
+ "identifier": ".name",
140
+ "title": ".name",
141
+ "blueprint": '"service"',
142
+ "properties": {
143
+ "description": ".description",
144
+ "url": ".html_url",
145
+ "defaultBranch": ".default_branch",
146
+ },
147
+ }
148
+ }
149
+ },
150
+ }
151
+ ]
152
+ }
153
+ port_app_config_handler.mock_get_port_app_config.return_value = valid_config
154
+
155
+ # Act
156
+ async with event_context(EventType.RESYNC, trigger_type="machine"):
157
+ result = await port_app_config_handler.get_port_app_config()
158
+ deletion_threshold = result.get_entity_deletion_threshold()
159
+
160
+ # Assert
161
+ assert isinstance(result, PortAppConfig)
162
+ assert deletion_threshold == result._default_entity_deletion_threshold
81
163
  port_app_config_handler.mock_get_port_app_config.assert_called_once()
82
164
 
83
165
 
@@ -246,6 +246,58 @@ def test_are_entities_fields_equal_different_nested_relations_should_be_false()
246
246
  )
247
247
 
248
248
 
249
+ def test_are_entities_fields_equal_null_properties_should_be_true() -> None:
250
+ assert (
251
+ are_entities_fields_equal(
252
+ {
253
+ "team": None,
254
+ "members": ["user1", "user2"],
255
+ "metadata": {"role": "admin"},
256
+ },
257
+ {"members": ["user1", "user2"], "metadata": {"role": "admin"}},
258
+ )
259
+ is True
260
+ )
261
+
262
+
263
+ def test_are_entities_fields_equal_null_properties_and_real_data_in_other_entity_should_be_false() -> (
264
+ None
265
+ ):
266
+ assert (
267
+ are_entities_fields_equal(
268
+ {
269
+ "team": None,
270
+ "members": ["user1", "user2"],
271
+ "metadata": {"role": "admin"},
272
+ },
273
+ {
274
+ "team": "team_id1",
275
+ "members": ["user1", "user2"],
276
+ "metadata": {"role": "admin"},
277
+ },
278
+ )
279
+ is False
280
+ )
281
+
282
+
283
+ def test_are_entities_fields_equal_null_properties_in_both_should_be_true() -> None:
284
+ assert (
285
+ are_entities_fields_equal(
286
+ {
287
+ "team": None,
288
+ "members": ["user1", "user2"],
289
+ "metadata": {"role": "admin"},
290
+ },
291
+ {
292
+ "team": None,
293
+ "members": ["user1", "user2"],
294
+ "metadata": {"role": "admin"},
295
+ },
296
+ )
297
+ is True
298
+ )
299
+
300
+
249
301
  def test_are_entities_different_identical_entities_should_be_false() -> None:
250
302
  entity1 = create_test_entity(
251
303
  "",
@@ -2,7 +2,6 @@ from os import path
2
2
  from typing import Any, Callable, Dict, List, Tuple, Union
3
3
 
4
4
  import pytest
5
- import pytest_asyncio
6
5
 
7
6
  from port_ocean.clients.port.client import PortClient
8
7
  from port_ocean.core.handlers.port_app_config.models import ResourceConfig
@@ -26,7 +25,7 @@ def port_client_for_fake_integration() -> Tuple[SmokeTestDetails, PortClient]:
26
25
  return smoke_test_details, port_client
27
26
 
28
27
 
29
- @pytest_asyncio.fixture
28
+ @pytest.fixture
30
29
  def get_mocked_ocean_app(request: Any) -> Callable[[], Ocean]:
31
30
  test_dir = path.join(path.dirname(request.module.__file__), "..")
32
31
 
@@ -36,7 +35,7 @@ def get_mocked_ocean_app(request: Any) -> Callable[[], Ocean]:
36
35
  return get_ocean_app
37
36
 
38
37
 
39
- @pytest_asyncio.fixture
38
+ @pytest.fixture
40
39
  def get_mock_ocean_resource_configs(request: Any) -> Callable[[], List[ResourceConfig]]:
41
40
  module_dir = path.join(path.dirname(request.module.__file__), "..")
42
41
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "port-ocean"
3
- version = "0.22.0"
3
+ version = "0.22.2"
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"
@@ -63,6 +63,7 @@ rich = { version = "^13.4.1", optional = true }
63
63
  cookiecutter = { version = "^2.1.1", optional = true }
64
64
  jinja2-time = { version = "^0.2.0", optional = true }
65
65
  prometheus-client = "^0.21.1"
66
+ pytest-cov = "^6.0.0"
66
67
 
67
68
  [tool.poetry.extras]
68
69
  cli = ["click", "rich", "cookiecutter", "jinja2-time"]
File without changes
File without changes