port-ocean 0.28.15__tar.gz → 0.28.17__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.
- {port_ocean-0.28.15 → port_ocean-0.28.17}/PKG-INFO +1 -1
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/clients/port/mixins/entities.py +79 -44
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/helpers/retry.py +8 -2
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/clients/port/mixins/test_entities.py +71 -5
- port_ocean-0.28.17/port_ocean/tests/helpers/test_retry.py +931 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/pyproject.toml +1 -1
- port_ocean-0.28.15/port_ocean/tests/helpers/test_retry.py +0 -309
- {port_ocean-0.28.15 → port_ocean-0.28.17}/LICENSE.md +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/README.md +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/integrations/_infra/Dockerfile.Deb +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/integrations/_infra/Dockerfile.alpine +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/integrations/_infra/Dockerfile.base.builder +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/integrations/_infra/Dockerfile.base.runner +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/integrations/_infra/Dockerfile.dockerignore +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/integrations/_infra/Dockerfile.local +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/integrations/_infra/Makefile +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/integrations/_infra/README.md +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/integrations/_infra/entry_local.sh +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/integrations/_infra/grpcio.sh +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/integrations/_infra/init.sh +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/bootstrap.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cache/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cache/base.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cache/disk.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cache/errors.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cache/memory.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cli.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/commands/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/commands/defaults/__init___.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/commands/defaults/clean.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/commands/defaults/dock.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/commands/defaults/group.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/commands/list_integrations.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/commands/main.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/commands/new.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/commands/pull.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/commands/sail.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/commands/version.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/cookiecutter.json +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/extensions.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/hooks/post_gen_project.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.env.example +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.gitignore +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/.gitignore +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/blueprints.json +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/port-app-config.yml +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/spec.yaml +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CHANGELOG.md +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/CONTRIBUTING.md +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/README.md +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/changelog/.gitignore +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/debug.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/main.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/poetry.toml +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/pyproject.toml +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/sonar-project.properties +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/tests/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/tests/test_sample.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/cli/utils.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/clients/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/clients/auth/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/clients/auth/auth_client.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/clients/auth/oauth_client.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/clients/port/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/clients/port/authentication.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/clients/port/client.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/clients/port/mixins/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/clients/port/mixins/blueprints.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/clients/port/mixins/integrations.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/clients/port/mixins/migrations.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/clients/port/mixins/organization.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/clients/port/retry_transport.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/clients/port/types.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/clients/port/utils.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/config/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/config/base.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/config/dynamic.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/config/settings.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/consumers/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/consumers/kafka_consumer.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/context/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/context/event.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/context/metric_resource.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/context/ocean.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/context/resource.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/defaults/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/defaults/clean.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/defaults/common.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/defaults/initialize.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/event_listener/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/event_listener/base.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/event_listener/factory.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/event_listener/http.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/event_listener/kafka.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/event_listener/once.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/event_listener/polling.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/event_listener/webhooks_only.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/base.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/entities_state_applier/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/entities_state_applier/base.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/entities_state_applier/port/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/entities_state_applier/port/applier.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/entities_state_applier/port/get_related_entities.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/entities_state_applier/port/order_by_entities_dependencies.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/entity_processor/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/entity_processor/base.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/entity_processor/jq_entity_processor.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/entity_processor/jq_input_evaluator.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/port_app_config/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/port_app_config/api.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/port_app_config/base.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/port_app_config/models.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/queue/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/queue/abstract_queue.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/queue/group_queue.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/queue/local_queue.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/resync_state_updater/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/resync_state_updater/updater.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/webhook/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/webhook/abstract_webhook_processor.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/webhook/processor_manager.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/handlers/webhook/webhook_event.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/integrations/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/integrations/base.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/integrations/mixins/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/integrations/mixins/events.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/integrations/mixins/handler.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/integrations/mixins/live_events.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/integrations/mixins/sync.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/integrations/mixins/sync_raw.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/integrations/mixins/utils.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/models.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/ocean_types.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/utils/entity_topological_sorter.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/core/utils/utils.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/debug_cli.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/exceptions/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/exceptions/api.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/exceptions/base.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/exceptions/clients.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/exceptions/context.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/exceptions/core.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/exceptions/port_defaults.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/exceptions/utils.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/exceptions/webhook_processor.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/helpers/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/helpers/async_client.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/helpers/metric/metric.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/helpers/metric/utils.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/helpers/stream.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/log/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/log/handlers.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/log/logger_setup.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/log/sensetive.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/middlewares.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/ocean.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/py.typed +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/run.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/sonar-project.properties +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/cache/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/cache/test_disk_cache.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/cache/test_memory_cache.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/clients/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/clients/oauth/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/clients/oauth/test_oauth_client.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/clients/port/mixins/test_integrations.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/clients/port/mixins/test_organization_mixin.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/config/test_config.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/conftest.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/core/conftest.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/core/defaults/test_common.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/core/event_listener/test_kafka.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/core/handlers/entities_state_applier/test_applier.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/core/handlers/entity_processor/test_jq_entity_processor.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/core/handlers/entity_processor/test_jq_input_evaluator.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/core/handlers/mixins/test_live_events.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/core/handlers/mixins/test_sync_raw.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/core/handlers/port_app_config/test_api.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/core/handlers/port_app_config/test_base.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/core/handlers/queue/test_group_queue.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/core/handlers/queue/test_local_queue.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/core/handlers/webhook/test_abstract_webhook_processor.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/core/handlers/webhook/test_processor_manager.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/core/handlers/webhook/test_webhook_event.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/core/test_utils.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/core/utils/test_entity_topological_sorter.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/core/utils/test_get_port_diff.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/core/utils/test_resolve_entities_diff.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/helpers/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/helpers/fake_port_api.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/helpers/fixtures.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/helpers/integration.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/helpers/ocean_app.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/helpers/port_client.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/helpers/smoke_test.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/log/test_handlers.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/test_metric.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/test_ocean.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/test_smoke.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/utils/test_async_iterators.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/utils/test_cache.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/utils/__init__.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/utils/async_http.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/utils/async_iterators.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/utils/cache.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/utils/ipc.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/utils/misc.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/utils/queue_utils.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/utils/repeat.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/utils/signal.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/utils/time.py +0 -0
- {port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/version.py +0 -0
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import json
|
|
2
3
|
from typing import Any, Literal
|
|
3
4
|
from urllib.parse import quote_plus
|
|
4
|
-
import json
|
|
5
5
|
|
|
6
6
|
import httpx
|
|
7
7
|
from loguru import logger
|
|
8
|
-
from
|
|
8
|
+
from starlette import status
|
|
9
|
+
|
|
9
10
|
from port_ocean.clients.port.authentication import PortAuthentication
|
|
10
11
|
from port_ocean.clients.port.types import RequestOptions, UserAgentType
|
|
11
12
|
from port_ocean.clients.port.utils import (
|
|
12
|
-
handle_port_status_code,
|
|
13
13
|
PORT_HTTP_MAX_CONNECTIONS_LIMIT,
|
|
14
|
+
handle_port_status_code,
|
|
14
15
|
)
|
|
16
|
+
from port_ocean.context.ocean import ocean
|
|
15
17
|
from port_ocean.core.models import (
|
|
16
18
|
BulkUpsertResponse,
|
|
17
19
|
Entity,
|
|
18
20
|
PortAPIErrorMessage,
|
|
19
21
|
)
|
|
20
|
-
from starlette import status
|
|
21
|
-
|
|
22
22
|
from port_ocean.helpers.metric.metric import MetricPhase, MetricType
|
|
23
23
|
|
|
24
24
|
ENTITIES_BULK_SAMPLES_SIZE = 10
|
|
@@ -484,54 +484,89 @@ class EntityClientMixin:
|
|
|
484
484
|
parameters_to_include: list[str] | None = None,
|
|
485
485
|
) -> list[Entity]:
|
|
486
486
|
if query is None:
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
487
|
+
return await self._search_entities_by_datasource_paginated(user_agent_type)
|
|
488
|
+
|
|
489
|
+
return await self._search_entities_by_query(
|
|
490
|
+
user_agent_type=user_agent_type,
|
|
491
|
+
query=query,
|
|
492
|
+
parameters_to_include=parameters_to_include,
|
|
493
|
+
)
|
|
494
|
+
|
|
495
|
+
async def _search_entities_by_datasource_paginated(
|
|
496
|
+
self, user_agent_type: UserAgentType
|
|
497
|
+
) -> list[Entity]:
|
|
498
|
+
datasource_prefix = f"port-ocean/{self.auth.integration_type}/"
|
|
499
|
+
datasource_suffix = (
|
|
500
|
+
f"/{self.auth.integration_identifier}/{user_agent_type.value}"
|
|
501
|
+
)
|
|
502
|
+
logger.info(
|
|
503
|
+
f"Searching entities with datasource prefix: {datasource_prefix} and suffix: {datasource_suffix}"
|
|
504
|
+
)
|
|
505
|
+
|
|
506
|
+
next_from: str | None = None
|
|
507
|
+
aggregated_entities: list[Entity] = []
|
|
508
|
+
while True:
|
|
509
|
+
request_body: dict[str, Any] = {
|
|
510
|
+
"datasource_prefix": datasource_prefix,
|
|
511
|
+
"datasource_suffix": datasource_suffix,
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
if next_from:
|
|
515
|
+
request_body["from"] = next_from
|
|
494
516
|
|
|
495
517
|
response = await self.client.post(
|
|
496
518
|
f"{self.auth.api_url}/blueprints/entities/datasource-entities",
|
|
497
|
-
json=
|
|
498
|
-
"datasource_prefix": datasource_prefix,
|
|
499
|
-
"datasource_suffix": datasource_suffix,
|
|
500
|
-
},
|
|
519
|
+
json=request_body,
|
|
501
520
|
headers=await self.auth.headers(user_agent_type),
|
|
502
521
|
extensions={"retryable": True},
|
|
503
522
|
)
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
"
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
},
|
|
513
|
-
{
|
|
514
|
-
"property": "$datasource",
|
|
515
|
-
"operator": "contains",
|
|
516
|
-
"value": f"/{self.auth.integration_identifier}/{user_agent_type.value}",
|
|
517
|
-
},
|
|
518
|
-
],
|
|
519
|
-
}
|
|
523
|
+
handle_port_status_code(response)
|
|
524
|
+
response_json = response.json()
|
|
525
|
+
aggregated_entities.extend(
|
|
526
|
+
Entity.parse_obj(result) for result in response_json.get("entities", [])
|
|
527
|
+
)
|
|
528
|
+
next_from = response_json.get("next")
|
|
529
|
+
if not next_from:
|
|
530
|
+
break
|
|
520
531
|
|
|
521
|
-
|
|
522
|
-
query["rules"].extend(default_query["rules"])
|
|
532
|
+
return aggregated_entities
|
|
523
533
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
534
|
+
async def _search_entities_by_query(
|
|
535
|
+
self,
|
|
536
|
+
user_agent_type: UserAgentType,
|
|
537
|
+
query: dict[Any, Any],
|
|
538
|
+
parameters_to_include: list[str] | None,
|
|
539
|
+
) -> list[Entity]:
|
|
540
|
+
default_query = {
|
|
541
|
+
"combinator": "and",
|
|
542
|
+
"rules": [
|
|
543
|
+
{
|
|
544
|
+
"property": "$datasource",
|
|
545
|
+
"operator": "contains",
|
|
546
|
+
"value": f"port-ocean/{self.auth.integration_type}/",
|
|
532
547
|
},
|
|
533
|
-
|
|
534
|
-
|
|
548
|
+
{
|
|
549
|
+
"property": "$datasource",
|
|
550
|
+
"operator": "contains",
|
|
551
|
+
"value": f"/{self.auth.integration_identifier}/{user_agent_type.value}",
|
|
552
|
+
},
|
|
553
|
+
],
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
if query.get("rules"):
|
|
557
|
+
query["rules"].extend(default_query["rules"])
|
|
558
|
+
|
|
559
|
+
logger.info(f"Searching entities with custom query: {query}")
|
|
560
|
+
response = await self.client.post(
|
|
561
|
+
f"{self.auth.api_url}/entities/search",
|
|
562
|
+
json=query,
|
|
563
|
+
headers=await self.auth.headers(user_agent_type),
|
|
564
|
+
params={
|
|
565
|
+
"exclude_calculated_properties": "true",
|
|
566
|
+
"include": parameters_to_include or ["blueprint", "identifier"],
|
|
567
|
+
},
|
|
568
|
+
extensions={"retryable": True},
|
|
569
|
+
)
|
|
535
570
|
|
|
536
571
|
handle_port_status_code(response)
|
|
537
572
|
return [Entity.parse_obj(result) for result in response.json()["entities"]]
|
|
@@ -359,8 +359,11 @@ class RetryTransport(httpx.AsyncBaseTransport, httpx.BaseTransport):
|
|
|
359
359
|
else:
|
|
360
360
|
# If no Content-Length header, try to get actual content size
|
|
361
361
|
try:
|
|
362
|
-
|
|
362
|
+
content = await response.aread()
|
|
363
|
+
actual_size = len(content)
|
|
363
364
|
size_info = actual_size
|
|
365
|
+
# Restore the cached body so downstream code can still use .json()/.text/.content
|
|
366
|
+
response._content = content # httpx convention
|
|
364
367
|
except Exception as e:
|
|
365
368
|
cast(logging.Logger, self._logger).error(
|
|
366
369
|
f"Error getting response size: {e}"
|
|
@@ -383,8 +386,11 @@ class RetryTransport(httpx.AsyncBaseTransport, httpx.BaseTransport):
|
|
|
383
386
|
else:
|
|
384
387
|
# If no Content-Length header, try to get actual content size
|
|
385
388
|
try:
|
|
386
|
-
|
|
389
|
+
content = response.read()
|
|
390
|
+
actual_size = len(content)
|
|
387
391
|
size_info = actual_size
|
|
392
|
+
# Restore the cached body so downstream code can still use .json()/.text/.content
|
|
393
|
+
response._content = content # httpx convention
|
|
388
394
|
except Exception as e:
|
|
389
395
|
cast(logging.Logger, self._logger).error(
|
|
390
396
|
f"Error getting response size: {e}"
|
{port_ocean-0.28.15 → port_ocean-0.28.17}/port_ocean/tests/clients/port/mixins/test_entities.py
RENAMED
|
@@ -179,7 +179,7 @@ async def test_search_entities_uses_datasource_route_when_query_is_none(
|
|
|
179
179
|
) -> None:
|
|
180
180
|
"""Test that search_entities uses datasource route when query is None"""
|
|
181
181
|
mock_response = MagicMock()
|
|
182
|
-
mock_response.json.return_value = {"entities": []}
|
|
182
|
+
mock_response.json.return_value = {"entities": [], "next": None}
|
|
183
183
|
mock_response.is_error = False
|
|
184
184
|
mock_response.status_code = 200
|
|
185
185
|
mock_response.headers = {}
|
|
@@ -208,8 +208,74 @@ async def test_search_entities_uses_datasource_route_when_query_is_none(
|
|
|
208
208
|
== "https://api.getport.io/v1/blueprints/entities/datasource-entities"
|
|
209
209
|
)
|
|
210
210
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
211
|
+
sent_json = call_args[1]["json"]
|
|
212
|
+
assert sent_json["datasource_prefix"] == "port-ocean/test-integration/"
|
|
213
|
+
assert sent_json["datasource_suffix"] == "/test-identifier/sync"
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
async def test_search_entities_uses_datasource_route_when_query_is_none_two_pages(
|
|
217
|
+
entity_client: EntityClientMixin,
|
|
218
|
+
) -> None:
|
|
219
|
+
"""Test that search_entities uses datasource route when query is None"""
|
|
220
|
+
# First response with pagination token
|
|
221
|
+
mock_response_first = MagicMock()
|
|
222
|
+
mock_response_first.json.return_value = {
|
|
223
|
+
"entities": [
|
|
224
|
+
Entity(identifier="entity_1", blueprint="entity_1"),
|
|
225
|
+
Entity(identifier="entity_2", blueprint="entity_2"),
|
|
226
|
+
],
|
|
227
|
+
"next": "next_page_token",
|
|
228
|
+
}
|
|
229
|
+
mock_response_first.is_error = False
|
|
230
|
+
mock_response_first.status_code = 200
|
|
231
|
+
mock_response_first.headers = {}
|
|
232
|
+
|
|
233
|
+
# Second response without pagination token (end of pagination)
|
|
234
|
+
mock_response_second = MagicMock()
|
|
235
|
+
mock_response_second.json.return_value = {
|
|
236
|
+
"entities": [Entity(identifier="entity_3", blueprint="entity_3")],
|
|
237
|
+
"next": None,
|
|
214
238
|
}
|
|
215
|
-
|
|
239
|
+
mock_response_second.is_error = False
|
|
240
|
+
mock_response_second.status_code = 200
|
|
241
|
+
mock_response_second.headers = {}
|
|
242
|
+
|
|
243
|
+
# Mock the client to return different responses for each call
|
|
244
|
+
entity_client.client.post = AsyncMock(side_effect=[mock_response_first, mock_response_second]) # type: ignore
|
|
245
|
+
entity_client.auth.headers = AsyncMock(return_value={"Authorization": "Bearer test"}) # type: ignore
|
|
246
|
+
|
|
247
|
+
entity_client.auth.integration_type = "test-integration"
|
|
248
|
+
entity_client.auth.integration_identifier = "test-identifier"
|
|
249
|
+
entity_client.auth.api_url = "https://api.getport.io/v1"
|
|
250
|
+
|
|
251
|
+
mock_user_agent_type = MagicMock()
|
|
252
|
+
mock_user_agent_type.value = "sync"
|
|
253
|
+
|
|
254
|
+
entities = await entity_client.search_entities(
|
|
255
|
+
user_agent_type=mock_user_agent_type,
|
|
256
|
+
query=None,
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
# Should call the datasource-entities endpoint exactly twice for pagination
|
|
260
|
+
assert entity_client.client.post.await_count == 2
|
|
261
|
+
assert len(entities) == 3
|
|
262
|
+
|
|
263
|
+
# Check first call
|
|
264
|
+
first_call_args = entity_client.client.post.call_args_list[0]
|
|
265
|
+
assert (
|
|
266
|
+
first_call_args[0][0]
|
|
267
|
+
== "https://api.getport.io/v1/blueprints/entities/datasource-entities"
|
|
268
|
+
)
|
|
269
|
+
first_sent_json = first_call_args[1]["json"]
|
|
270
|
+
assert first_sent_json["datasource_prefix"] == "port-ocean/test-integration/"
|
|
271
|
+
assert first_sent_json["datasource_suffix"] == "/test-identifier/sync"
|
|
272
|
+
|
|
273
|
+
# Check second call
|
|
274
|
+
second_call_args = entity_client.client.post.call_args_list[1]
|
|
275
|
+
assert (
|
|
276
|
+
second_call_args[0][0]
|
|
277
|
+
== "https://api.getport.io/v1/blueprints/entities/datasource-entities"
|
|
278
|
+
)
|
|
279
|
+
second_sent_json = second_call_args[1]["json"]
|
|
280
|
+
assert second_sent_json["datasource_prefix"] == "port-ocean/test-integration/"
|
|
281
|
+
assert second_sent_json["datasource_suffix"] == "/test-identifier/sync"
|