port-ocean 0.29.9__tar.gz → 0.29.10__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 (225) hide show
  1. {port_ocean-0.29.9 → port_ocean-0.29.10}/PKG-INFO +1 -1
  2. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/entity_processor/jq_input_evaluator.py +30 -10
  3. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/helpers/metric/metric.py +1 -0
  4. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/handlers/entity_processor/test_jq_entity_processor.py +8 -8
  5. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/handlers/entity_processor/test_jq_input_evaluator.py +10 -10
  6. port_ocean-0.29.10/port_ocean/tests/test_metrics_endpoints.py +53 -0
  7. {port_ocean-0.29.9 → port_ocean-0.29.10}/pyproject.toml +1 -1
  8. {port_ocean-0.29.9 → port_ocean-0.29.10}/LICENSE.md +0 -0
  9. {port_ocean-0.29.9 → port_ocean-0.29.10}/README.md +0 -0
  10. {port_ocean-0.29.9 → port_ocean-0.29.10}/integrations/_infra/Dockerfile.Deb +0 -0
  11. {port_ocean-0.29.9 → port_ocean-0.29.10}/integrations/_infra/Dockerfile.alpine +0 -0
  12. {port_ocean-0.29.9 → port_ocean-0.29.10}/integrations/_infra/Dockerfile.base.builder +0 -0
  13. {port_ocean-0.29.9 → port_ocean-0.29.10}/integrations/_infra/Dockerfile.base.runner +0 -0
  14. {port_ocean-0.29.9 → port_ocean-0.29.10}/integrations/_infra/Dockerfile.dockerignore +0 -0
  15. {port_ocean-0.29.9 → port_ocean-0.29.10}/integrations/_infra/Dockerfile.local +0 -0
  16. {port_ocean-0.29.9 → port_ocean-0.29.10}/integrations/_infra/Makefile +0 -0
  17. {port_ocean-0.29.9 → port_ocean-0.29.10}/integrations/_infra/README.md +0 -0
  18. {port_ocean-0.29.9 → port_ocean-0.29.10}/integrations/_infra/entry_local.sh +0 -0
  19. {port_ocean-0.29.9 → port_ocean-0.29.10}/integrations/_infra/grpcio.sh +0 -0
  20. {port_ocean-0.29.9 → port_ocean-0.29.10}/integrations/_infra/init.sh +0 -0
  21. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/__init__.py +0 -0
  22. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/bootstrap.py +0 -0
  23. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cache/__init__.py +0 -0
  24. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cache/base.py +0 -0
  25. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cache/disk.py +0 -0
  26. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cache/errors.py +0 -0
  27. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cache/memory.py +0 -0
  28. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/__init__.py +0 -0
  29. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cli.py +0 -0
  30. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/commands/__init__.py +0 -0
  31. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/commands/defaults/__init___.py +0 -0
  32. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/commands/defaults/clean.py +0 -0
  33. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/commands/defaults/dock.py +0 -0
  34. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/commands/defaults/group.py +0 -0
  35. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/commands/list_integrations.py +0 -0
  36. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/commands/main.py +0 -0
  37. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/commands/new.py +0 -0
  38. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/commands/pull.py +0 -0
  39. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/commands/sail.py +0 -0
  40. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/commands/version.py +0 -0
  41. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/__init__.py +0 -0
  42. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/cookiecutter.json +0 -0
  43. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/extensions.py +0 -0
  44. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/hooks/post_gen_project.py +0 -0
  45. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.env.example +0 -0
  46. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.gitignore +0 -0
  47. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/.gitignore +0 -0
  48. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/blueprints.json +0 -0
  49. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/port-app-config.yml +0 -0
  50. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/spec.yaml +0 -0
  51. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CHANGELOG.md +0 -0
  52. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CONTRIBUTING.md +0 -0
  53. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/README.md +0 -0
  54. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/changelog/.gitignore +0 -0
  55. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/debug.py +0 -0
  56. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/main.py +0 -0
  57. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/poetry.toml +0 -0
  58. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/pyproject.toml +0 -0
  59. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/sonar-project.properties +0 -0
  60. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/tests/__init__.py +0 -0
  61. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/tests/test_sample.py +0 -0
  62. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/cli/utils.py +0 -0
  63. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/clients/__init__.py +0 -0
  64. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/clients/auth/__init__.py +0 -0
  65. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/clients/auth/auth_client.py +0 -0
  66. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/clients/auth/oauth_client.py +0 -0
  67. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/clients/port/__init__.py +0 -0
  68. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/clients/port/authentication.py +0 -0
  69. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/clients/port/client.py +0 -0
  70. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/clients/port/mixins/__init__.py +0 -0
  71. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/clients/port/mixins/actions.py +0 -0
  72. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/clients/port/mixins/blueprints.py +0 -0
  73. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/clients/port/mixins/entities.py +0 -0
  74. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/clients/port/mixins/integrations.py +0 -0
  75. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/clients/port/mixins/migrations.py +0 -0
  76. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/clients/port/mixins/organization.py +0 -0
  77. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/clients/port/retry_transport.py +0 -0
  78. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/clients/port/types.py +0 -0
  79. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/clients/port/utils.py +0 -0
  80. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/config/__init__.py +0 -0
  81. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/config/base.py +0 -0
  82. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/config/dynamic.py +0 -0
  83. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/config/settings.py +0 -0
  84. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/consumers/__init__.py +0 -0
  85. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/consumers/kafka_consumer.py +0 -0
  86. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/context/__init__.py +0 -0
  87. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/context/event.py +0 -0
  88. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/context/metric_resource.py +0 -0
  89. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/context/ocean.py +0 -0
  90. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/context/resource.py +0 -0
  91. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/__init__.py +0 -0
  92. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/defaults/__init__.py +0 -0
  93. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/defaults/clean.py +0 -0
  94. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/defaults/common.py +0 -0
  95. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/defaults/initialize.py +0 -0
  96. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/event_listener/__init__.py +0 -0
  97. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/event_listener/actions_only.py +0 -0
  98. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/event_listener/base.py +0 -0
  99. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/event_listener/factory.py +0 -0
  100. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/event_listener/http.py +0 -0
  101. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/event_listener/kafka.py +0 -0
  102. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/event_listener/once.py +0 -0
  103. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/event_listener/polling.py +0 -0
  104. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/event_listener/webhooks_only.py +0 -0
  105. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/__init__.py +0 -0
  106. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/actions/__init__.py +0 -0
  107. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/actions/abstract_executor.py +0 -0
  108. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/actions/execution_manager.py +0 -0
  109. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/base.py +0 -0
  110. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/entities_state_applier/__init__.py +0 -0
  111. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/entities_state_applier/base.py +0 -0
  112. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/entities_state_applier/port/__init__.py +0 -0
  113. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/entities_state_applier/port/applier.py +0 -0
  114. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/entities_state_applier/port/get_related_entities.py +0 -0
  115. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/entities_state_applier/port/order_by_entities_dependencies.py +0 -0
  116. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/entity_processor/__init__.py +0 -0
  117. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/entity_processor/base.py +0 -0
  118. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/entity_processor/jq_entity_processor.py +0 -0
  119. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/port_app_config/__init__.py +0 -0
  120. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/port_app_config/api.py +0 -0
  121. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/port_app_config/base.py +0 -0
  122. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/port_app_config/models.py +0 -0
  123. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/queue/__init__.py +0 -0
  124. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/queue/abstract_queue.py +0 -0
  125. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/queue/group_queue.py +0 -0
  126. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/queue/local_queue.py +0 -0
  127. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/resync_state_updater/__init__.py +0 -0
  128. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/resync_state_updater/updater.py +0 -0
  129. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/webhook/__init__.py +0 -0
  130. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/webhook/abstract_webhook_processor.py +0 -0
  131. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/webhook/processor_manager.py +0 -0
  132. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/handlers/webhook/webhook_event.py +0 -0
  133. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/integrations/__init__.py +0 -0
  134. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/integrations/base.py +0 -0
  135. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/integrations/mixins/__init__.py +0 -0
  136. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/integrations/mixins/events.py +0 -0
  137. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/integrations/mixins/handler.py +0 -0
  138. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/integrations/mixins/live_events.py +0 -0
  139. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/integrations/mixins/sync.py +0 -0
  140. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/integrations/mixins/sync_raw.py +0 -0
  141. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/integrations/mixins/utils.py +0 -0
  142. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/models.py +0 -0
  143. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/ocean_types.py +0 -0
  144. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/utils/entity_topological_sorter.py +0 -0
  145. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/core/utils/utils.py +0 -0
  146. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/debug_cli.py +0 -0
  147. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/exceptions/__init__.py +0 -0
  148. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/exceptions/api.py +0 -0
  149. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/exceptions/base.py +0 -0
  150. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/exceptions/clients.py +0 -0
  151. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/exceptions/context.py +0 -0
  152. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/exceptions/core.py +0 -0
  153. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/exceptions/execution_manager.py +0 -0
  154. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/exceptions/port_defaults.py +0 -0
  155. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/exceptions/utils.py +0 -0
  156. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/exceptions/webhook_processor.py +0 -0
  157. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/helpers/__init__.py +0 -0
  158. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/helpers/async_client.py +0 -0
  159. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/helpers/metric/utils.py +0 -0
  160. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/helpers/retry.py +0 -0
  161. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/helpers/stream.py +0 -0
  162. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/log/__init__.py +0 -0
  163. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/log/handlers.py +0 -0
  164. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/log/logger_setup.py +0 -0
  165. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/log/sensetive.py +0 -0
  166. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/middlewares.py +0 -0
  167. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/ocean.py +0 -0
  168. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/py.typed +0 -0
  169. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/run.py +0 -0
  170. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/sonar-project.properties +0 -0
  171. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/__init__.py +0 -0
  172. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/cache/__init__.py +0 -0
  173. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/cache/test_disk_cache.py +0 -0
  174. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/cache/test_memory_cache.py +0 -0
  175. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/clients/__init__.py +0 -0
  176. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/clients/oauth/__init__.py +0 -0
  177. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/clients/oauth/test_oauth_client.py +0 -0
  178. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/clients/port/mixins/test_entities.py +0 -0
  179. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/clients/port/mixins/test_integrations.py +0 -0
  180. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/clients/port/mixins/test_organization_mixin.py +0 -0
  181. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/config/test_config.py +0 -0
  182. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/conftest.py +0 -0
  183. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/conftest.py +0 -0
  184. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/defaults/test_common.py +0 -0
  185. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/event_listener/test_kafka.py +0 -0
  186. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/handlers/actions/test_execution_manager.py +0 -0
  187. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/handlers/entities_state_applier/test_applier.py +0 -0
  188. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/handlers/mixins/test_live_events.py +0 -0
  189. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/handlers/mixins/test_sync_raw.py +0 -0
  190. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/handlers/port_app_config/test_api.py +0 -0
  191. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/handlers/port_app_config/test_base.py +0 -0
  192. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/handlers/queue/test_group_queue.py +0 -0
  193. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/handlers/queue/test_local_queue.py +0 -0
  194. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/handlers/webhook/test_abstract_webhook_processor.py +0 -0
  195. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/handlers/webhook/test_processor_manager.py +0 -0
  196. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/handlers/webhook/test_webhook_event.py +0 -0
  197. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/test_utils.py +0 -0
  198. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/utils/test_entity_topological_sorter.py +0 -0
  199. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/utils/test_get_port_diff.py +0 -0
  200. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/core/utils/test_resolve_entities_diff.py +0 -0
  201. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/helpers/__init__.py +0 -0
  202. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/helpers/fake_port_api.py +0 -0
  203. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/helpers/fixtures.py +0 -0
  204. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/helpers/integration.py +0 -0
  205. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/helpers/ocean_app.py +0 -0
  206. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/helpers/port_client.py +0 -0
  207. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/helpers/smoke_test.py +0 -0
  208. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/helpers/test_retry.py +0 -0
  209. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/log/test_handlers.py +0 -0
  210. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/test_metric.py +0 -0
  211. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/test_ocean.py +0 -0
  212. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/test_smoke.py +0 -0
  213. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/utils/test_async_iterators.py +0 -0
  214. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/tests/utils/test_cache.py +0 -0
  215. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/utils/__init__.py +0 -0
  216. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/utils/async_http.py +0 -0
  217. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/utils/async_iterators.py +0 -0
  218. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/utils/cache.py +0 -0
  219. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/utils/ipc.py +0 -0
  220. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/utils/misc.py +0 -0
  221. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/utils/queue_utils.py +0 -0
  222. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/utils/repeat.py +0 -0
  223. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/utils/signal.py +0 -0
  224. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/utils/time.py +0 -0
  225. {port_ocean-0.29.9 → port_ocean-0.29.10}/port_ocean/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: port-ocean
3
- Version: 0.29.9
3
+ Version: 0.29.10
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
@@ -103,22 +103,42 @@ def can_expression_run_with_no_input(selector_query: str) -> bool:
103
103
 
104
104
  def _can_expression_run_on_single_item(expr: str, key: str) -> bool:
105
105
  """
106
- Detect `.key` outside of quotes, as a standalone path segment beginning
107
- after a non-word boundary (start, space, |, (, [, {, , or :) and not part
108
- of `.something.key`.
109
- assuming key = 'item'
110
- Examples:
111
- - .item.yaeli => true
112
- - map(.item.yaeli) => true
113
- - .body.item => false
106
+ Return True only if all top-level jq paths in the expression
107
+ reference `.key...` and nothing outside that tree.
114
108
  """
115
109
  if not key:
116
110
  return False
117
111
 
118
112
  masked = _mask_strings(expr)
119
113
  masked = _mask_numbers(masked)
120
- pattern = re.compile(rf"(?<![A-Za-z0-9_])\.{re.escape(key)}(?![A-Za-z0-9_])")
121
- return bool(pattern.search(masked))
114
+
115
+ # 🚫 Reject expressions that start from a root-level array, e.g. `.[] | ...` or `.[0] | ...`
116
+ # Top-level ".[" = a dot not preceded by [A-Za-z0-9_.])]
117
+ if re.search(r"(?<![A-Za-z0-9_.\]\)])\.\[", masked):
118
+ return False
119
+
120
+ # Match *top-level* paths only:
121
+ # - A dot NOT preceded by [A-Za-z0-9_.])]
122
+ # (so we don't treat `.field` in `.item.field[0].subfield` as a new root)
123
+ # - Followed by an identifier for the first segment
124
+ paths = re.findall(
125
+ r"(?<![A-Za-z0-9_.\]\)])\.[A-Za-z_][A-Za-z0-9_]*",
126
+ masked,
127
+ )
128
+
129
+ if not paths:
130
+ return False
131
+
132
+ allowed_root = f".{key}"
133
+
134
+ for p in paths:
135
+ if p == allowed_root or p.startswith(allowed_root + "."):
136
+ continue
137
+ else:
138
+ # Some other root field like .name, .body, .foo, etc.
139
+ return False
140
+
141
+ return True
122
142
 
123
143
 
124
144
  def classify_input(
@@ -266,6 +266,7 @@ class Metrics:
266
266
  router = APIRouter()
267
267
 
268
268
  @router.get("/", response_class=PlainTextResponse)
269
+ @router.get("", response_class=PlainTextResponse)
269
270
  async def prom_metrics() -> str:
270
271
  return self.generate_latest()
271
272
 
@@ -561,13 +561,13 @@ class TestJQEntityProcessor:
561
561
  "function_with_middle_pattern": "map(.body.item.field)", # Function with middle pattern - ALL
562
562
  "select_with_pattern": 'select(.item.status == "active")', # Select with pattern - SINGLE
563
563
  "select_with_middle_pattern": 'select(.data.item.status == "active")', # Select with middle pattern - ALL
564
- "pipe_with_pattern": ".[] | .item.field", # Pipe with pattern - SINGLE
564
+ "pipe_with_pattern": ".[] | .item.field", # Pipe with pattern - ALL
565
565
  "pipe_with_middle_pattern": ".[] | .body.item.field", # Pipe with middle pattern - ALL
566
566
  "array_with_pattern": "[.item.id, .item.name]", # Array with pattern - SINGLE
567
567
  "array_with_middle_pattern": "[.data.item.id, .body.item.name]", # Array with middle pattern - ALL
568
568
  "object_with_pattern": "{id: .item.id, name: .item.name}", # Object with pattern - SINGLE
569
569
  "object_with_middle_pattern": "{id: .data.item.id, name: .body.item.name}", # Object with middle pattern - ALL
570
- "nested_with_pattern": ".data.items[] | .item.field", # Nested with pattern - SINGLE
570
+ "nested_with_pattern": ".data.items[] | .item.field", # Nested with pattern - ALL
571
571
  "nested_with_middle_pattern": ".data.items[] | .body.item.field", # Nested with middle pattern - ALL
572
572
  "conditional_with_pattern": "if .item.exists then .item.value else null end", # Conditional with pattern - SINGLE
573
573
  "conditional_with_middle_pattern": "if .data.item.exists then .body.item.value else null end", # Conditional with middle pattern - ALL
@@ -597,10 +597,8 @@ class TestJQEntityProcessor:
597
597
  "special_chars": ".item.field[0]",
598
598
  "function_with_pattern": "map(.item.field)",
599
599
  "select_with_pattern": 'select(.item.status == "active")',
600
- "pipe_with_pattern": ".[] | .item.field",
601
600
  "array_with_pattern": "[.item.id, .item.name]",
602
601
  "object_with_pattern": "{id: .item.id, name: .item.name}",
603
- "nested_with_pattern": ".data.items[] | .item.field",
604
602
  "conditional_with_pattern": "if .item.exists then .item.value else null end",
605
603
  },
606
604
  "relations": {
@@ -620,9 +618,11 @@ class TestJQEntityProcessor:
620
618
  "function_with_middle_pattern": "map(.body.item.field)",
621
619
  "select_with_middle_pattern": 'select(.data.item.status == "active")',
622
620
  "item_in_string": 'select(.data.string == ".item")',
621
+ "pipe_with_pattern": ".[] | .item.field",
623
622
  "pipe_with_middle_pattern": ".[] | .body.item.field",
624
623
  "array_with_middle_pattern": "[.data.item.id, .body.item.name]",
625
624
  "object_with_middle_pattern": "{id: .data.item.id, name: .body.item.name}",
625
+ "nested_with_pattern": ".data.items[] | .item.field",
626
626
  "nested_with_middle_pattern": ".data.items[] | .body.item.field",
627
627
  "conditional_with_middle_pattern": "if .data.item.exists then .body.item.value else null end",
628
628
  "field_with_null_name": ".is_null",
@@ -664,10 +664,10 @@ class TestJQEntityProcessor:
664
664
  # JQ expressions with functions that contain .item
665
665
  "mapped_property": "map(.item.field)", # Contains .item but starts with map - SINGLE
666
666
  "selected_property": 'select(.item.status == "active")', # Contains .item but starts with select - SINGLE
667
- "filtered_property": '.[] | select(.item.type == "service")', # Contains .item in pipe - SINGLE
667
+ "filtered_property": '.[] | select(.item.type == "service")', # Main thread is based on the main object - ALL
668
668
  "array_literal": "[.item.id, .item.name]", # Contains .item in array - SINGLE
669
669
  "object_literal": "{id: .item.id, name: .item.name}", # Contains .item in object - SINGLE
670
- "nested_access": ".data.items[] | .item.field", # Contains .item in nested access - SINGLE
670
+ "nested_access": ".data.items[] | .item.field", # Contains .item in nested access - ALL
671
671
  "conditional": "if .item.exists then .item.value else null end", # Contains .item in conditional - SINGLE
672
672
  "function_call": "length(.item.array)", # Contains .item in function call - SINGLE
673
673
  "range_expression": "range(.item.start; .item.end)", # Contains .item in range - SINGLE
@@ -790,10 +790,8 @@ class TestJQEntityProcessor:
790
790
  "properties": {
791
791
  "mapped_property": "map(.item.field)",
792
792
  "selected_property": 'select(.item.status == "active")',
793
- "filtered_property": '.[] | select(.item.type == "service")',
794
793
  "array_literal": "[.item.id, .item.name]",
795
794
  "object_literal": "{id: .item.id, name: .item.name}",
796
- "nested_access": ".data.items[] | .item.field",
797
795
  "conditional": "if .item.exists then .item.value else null end",
798
796
  "function_call": "length(.item.array)",
799
797
  "range_expression": "range(.item.start; .item.end)",
@@ -892,6 +890,8 @@ class TestJQEntityProcessor:
892
890
  # ALL mappings - expressions with dots but not containing .item
893
891
  expected_all = {
894
892
  "properties": {
893
+ "filtered_property": '.[] | select(.item.type == "service")',
894
+ "nested_access": ".data.items[] | .item.field",
895
895
  "external_map": "map(.external.field)",
896
896
  "external_select": 'select(.external.status == "active")',
897
897
  "external_array": "[.external.id, .external.name]",
@@ -318,9 +318,13 @@ class TestCanExpressionRunOnSingleItem:
318
318
 
319
319
  def test_key_in_pipe(self) -> None:
320
320
  """Test key in pipe operations"""
321
- assert _can_expression_run_on_single_item(".[] | .item.field", "item") is True
321
+ assert _can_expression_run_on_single_item(".[] | .item.field", "item") is False
322
322
  assert (
323
- _can_expression_run_on_single_item(".data[] | .item.field", "item") is True
323
+ _can_expression_run_on_single_item(".data[] | .item.field", "item") is False
324
+ )
325
+ assert (
326
+ _can_expression_run_on_single_item("[1,2,3,4] | .item.field", "item")
327
+ is True
324
328
  )
325
329
 
326
330
  def test_key_in_array(self) -> None:
@@ -409,7 +413,7 @@ class TestCanExpressionRunOnSingleItem:
409
413
  """Test key in complex expressions"""
410
414
  assert (
411
415
  _can_expression_run_on_single_item(".data.items[] | .item.field", "item")
412
- is True
416
+ is False
413
417
  )
414
418
  assert (
415
419
  _can_expression_run_on_single_item(
@@ -473,9 +477,7 @@ class TestClassifyInput:
473
477
  classify_input("select(.item.status)", "item")
474
478
  == InputClassifyingResult.SINGLE
475
479
  )
476
- assert (
477
- classify_input(".[] | .item.field", "item") == InputClassifyingResult.SINGLE
478
- )
480
+ assert classify_input(".[] | .item.field", "item") == InputClassifyingResult.ALL
479
481
  assert (
480
482
  classify_input("[.item.id, .item.name]", "item")
481
483
  == InputClassifyingResult.SINGLE
@@ -538,7 +540,7 @@ class TestClassifyInput:
538
540
  # Complex single input expressions
539
541
  assert (
540
542
  classify_input(".data.items[] | .item.field", "item")
541
- == InputClassifyingResult.SINGLE
543
+ == InputClassifyingResult.ALL
542
544
  )
543
545
  assert (
544
546
  classify_input("reduce .item.items[] as $item (0; . + $item.value)", "item")
@@ -835,9 +837,7 @@ class TestIntegration:
835
837
  classify_input('select(.item.status == "active")', "item")
836
838
  == InputClassifyingResult.SINGLE
837
839
  )
838
- assert (
839
- classify_input(".[] | .item.field", "item") == InputClassifyingResult.SINGLE
840
- )
840
+ assert classify_input(".[] | .item.field", "item") == InputClassifyingResult.ALL
841
841
  assert (
842
842
  classify_input("[.item.id, .item.name]", "item")
843
843
  == InputClassifyingResult.SINGLE
@@ -0,0 +1,53 @@
1
+ from fastapi import FastAPI
2
+ from fastapi.testclient import TestClient
3
+ from unittest.mock import Mock
4
+ from port_ocean.helpers.metric.metric import Metrics
5
+
6
+
7
+ def test_metrics_endpoints() -> None:
8
+ """Test that both /metrics and /metrics/ endpoints work correctly."""
9
+ # Create mock settings
10
+ metrics_settings = Mock()
11
+ metrics_settings.enabled = True
12
+
13
+ integration_settings = Mock()
14
+ integration_settings.type = "test"
15
+ integration_settings.identifier = "test-integration"
16
+
17
+ port_client = Mock()
18
+
19
+ # Create metrics instance
20
+ metrics = Metrics(
21
+ metrics_settings=metrics_settings,
22
+ integration_configuration=integration_settings,
23
+ port_client=port_client,
24
+ multiprocessing_enabled=False,
25
+ )
26
+
27
+ # Create FastAPI app with the metrics router using the same pattern as Ocean
28
+ app = FastAPI()
29
+ app.include_router(metrics.create_mertic_router(), prefix="/metrics")
30
+
31
+ # Create test client
32
+ client = TestClient(app)
33
+
34
+ # Test both endpoints
35
+ response_no_slash = client.get("/metrics")
36
+ response_with_slash = client.get("/metrics/")
37
+
38
+ # Both should return 200
39
+ assert (
40
+ response_no_slash.status_code == 200
41
+ ), f"Expected 200, got {response_no_slash.status_code}"
42
+ assert (
43
+ response_with_slash.status_code == 200
44
+ ), f"Expected 200, got {response_with_slash.status_code}"
45
+
46
+ # Both should return the same content
47
+ assert (
48
+ response_no_slash.text == response_with_slash.text
49
+ ), "Endpoints should return identical content"
50
+
51
+ # Verify content type is text/plain (prometheus format)
52
+ assert response_no_slash.headers["content-type"] == "text/plain; charset=utf-8"
53
+ assert response_with_slash.headers["content-type"] == "text/plain; charset=utf-8"
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "port-ocean"
3
- version = "0.29.9"
3
+ version = "0.29.10"
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"
File without changes
File without changes