port-ocean 0.15.1__py3-none-any.whl → 0.15.3__py3-none-any.whl

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.

@@ -77,18 +77,15 @@ def new(path: str, is_private_integration: bool) -> None:
77
77
  )
78
78
  console.print("Here are your next steps:\n", style="bold")
79
79
  console.print(
80
- "⚓️ Install necessary packages: Run [bold][blue]make install[/blue][/bold] to install all required packages for your project.\n"
81
- f"▶️ [bold][blue]cd {path}/{name} && make install && . .venv/bin/activate[/blue][/bold]\n"
80
+ f"⚓️ Install necessary packages: Run [bold][blue]cd {path}/{name} && make install && . .venv/bin/activate[/blue][/bold] to install all required packages for your project."
82
81
  )
83
82
  console.print(
84
- f"⚓️ Copy example env file: Run [bold][blue]cp {path}/{name}.env.example {path}/{name}/.env [/blue][/bold] and set your port credentials in the created file.\n"
83
+ "⚓️ Copy example env file: Run [bold][blue]cp .env.example .env [/blue][/bold] and update your integration's configuration in the .env file."
85
84
  )
86
85
  console.print(
87
- "⚓️ Set sail with [blue]Ocean[/blue]: Run [bold][blue]ocean sail[/blue] <path_to_integration>[/bold] to run the project using Ocean.\n"
88
- f"▶️ [bold][blue]ocean sail {path}/{name}[/blue][/bold] \n"
86
+ "⚓️ Set sail with [blue]Ocean[/blue]: Run [bold][blue]ocean sail[/blue][/bold] to run the project using Ocean."
89
87
  )
90
88
  if not final_private_integration:
91
89
  console.print(
92
- "⚓️ Smooth sailing with [blue]Make[/blue]: Alternatively, you can run [bold][blue]make run[/blue][/bold] to launch your project using Make. \n"
93
- f"▶️ [bold][blue]make run {path}/{name}[/blue][/bold]"
90
+ f"⚓️ Smooth sailing with [blue]Make[/blue]: Alternatively, you can run [bold][blue]make run {path}/{name}[/blue][/bold] to launch your project using Make."
94
91
  )
@@ -6,6 +6,9 @@
6
6
  "email": "Your address email <you@example.com>",
7
7
  "release_date": "{% now 'local' %}",
8
8
  "is_private_integration": true,
9
+ "port_client_id": "you can find it using: https://docs.getport.io/build-your-software-catalog/custom-integration/api/#find-your-port-credentials",
10
+ "port_client_secret": "you can find it using: https://docs.getport.io/build-your-software-catalog/custom-integration/api/#find-your-port-credentials",
11
+ "is_us_region": false,
9
12
  "_extensions": [
10
13
  "jinja2_time.TimeExtension",
11
14
  "extensions.VersionExtension"
@@ -1,2 +1,6 @@
1
- OCEAN__PORT__CLIENT_ID="<port-client-id>"
2
- OCEAN__PORT__CLIENT_SECRET="<port-client-secret>"
1
+ OCEAN__PORT__CLIENT_ID={{ cookiecutter.port_client_id }}
2
+ OCEAN__PORT__CLIENT_SECRET={{ cookiecutter.port_client_secret }}
3
+ OCEAN__INTEGRATION__IDENTIFIER={{ cookiecutter.integration_slug }}
4
+ OCEAN__PORT__BASE_URL={% if cookiecutter.is_us_region %}https://api.us.getport.io{% else %}https://api.getport.io{% endif %}
5
+ OCEAN__EVENT_LISTENER__TYPE=POLLING
6
+ OCEAN__INITIALIZE_PORT_RESOURCES=true
port_ocean/core/models.py CHANGED
@@ -8,12 +8,23 @@ from pydantic.fields import Field
8
8
 
9
9
  class Runtime(Enum):
10
10
  Saas = "Saas"
11
- SaasOauth2 = "SaasOauth2"
12
11
  OnPrem = "OnPrem"
13
12
 
14
13
  @property
15
14
  def is_saas_runtime(self) -> bool:
16
- return self in [Runtime.Saas, Runtime.SaasOauth2]
15
+ return self in [Runtime.Saas]
16
+
17
+ def is_installation_type_compatible(self, installation_type: str) -> bool:
18
+ """
19
+ Check if the installation type is compatible with the runtime
20
+
21
+ if the runtime is Saas, the installation type should start with Saas
22
+ else the installation type should be OnPrem
23
+ """
24
+ return (
25
+ self.value == Runtime.Saas.value
26
+ and installation_type.startswith(self.value)
27
+ ) or installation_type == self.value
17
28
 
18
29
 
19
30
  class Entity(BaseModel):
port_ocean/core/utils.py CHANGED
@@ -42,10 +42,12 @@ async def validate_integration_runtime(
42
42
  current_integration = await port_client.get_current_integration(
43
43
  should_raise=False, should_log=False
44
44
  )
45
- current_runtime = current_integration.get("installationType", "OnPrem")
46
- if current_integration and current_runtime != requested_runtime.value:
45
+ current_installation_type = current_integration.get("installationType", "OnPrem")
46
+ if current_integration and not requested_runtime.is_installation_type_compatible(
47
+ current_installation_type
48
+ ):
47
49
  raise IntegrationRuntimeException(
48
- f"Invalid Runtime! Requested to run existing {current_runtime} integration in {requested_runtime} runtime."
50
+ f"Invalid Runtime! Requested to run existing {current_installation_type} integration in {requested_runtime} runtime."
49
51
  )
50
52
 
51
53
 
@@ -0,0 +1,5 @@
1
+ from port_ocean.cli.commands.main import cli_start
2
+
3
+
4
+ if __name__ == "__main__":
5
+ cli_start()
@@ -0,0 +1,73 @@
1
+ from unittest.mock import AsyncMock, patch
2
+
3
+ import pytest
4
+
5
+ from port_ocean.core.utils import validate_integration_runtime
6
+ from port_ocean.clients.port.client import PortClient
7
+ from port_ocean.core.models import Runtime
8
+ from port_ocean.tests.helpers.port_client import get_port_client_for_integration
9
+ from port_ocean.exceptions.core import IntegrationRuntimeException
10
+
11
+
12
+ class TestValidateIntegrationRuntime:
13
+
14
+ @pytest.mark.asyncio
15
+ @pytest.mark.parametrize(
16
+ "requested_runtime, installation_type, should_raise",
17
+ [
18
+ (Runtime.Saas, "Saas", False),
19
+ (Runtime.Saas, "SaasOauth2", False),
20
+ (Runtime.Saas, "OnPrem", True),
21
+ (Runtime.OnPrem, "OnPrem", False),
22
+ (Runtime.OnPrem, "SaasOauth2", True),
23
+ ],
24
+ )
25
+ @patch.object(PortClient, "get_current_integration", new_callable=AsyncMock)
26
+ async def test_validate_integration_runtime(
27
+ self,
28
+ mock_get_current_integration: AsyncMock,
29
+ requested_runtime: Runtime,
30
+ installation_type: str,
31
+ should_raise: bool,
32
+ ) -> None:
33
+ # Arrange
34
+ port_client = get_port_client_for_integration(
35
+ client_id="mock-client-id",
36
+ client_secret="mock-client-secret",
37
+ integration_identifier="mock-integration-identifier",
38
+ integration_type="mock-integration-type",
39
+ integration_version="mock-integration-version",
40
+ base_url="mock-base-url",
41
+ )
42
+
43
+ # Mock the return value of get_current_integration
44
+ mock_get_current_integration.return_value = {
45
+ "installationType": installation_type
46
+ }
47
+
48
+ # Act & Assert
49
+ if should_raise:
50
+ with pytest.raises(IntegrationRuntimeException):
51
+ await validate_integration_runtime(port_client, requested_runtime)
52
+ else:
53
+ await validate_integration_runtime(port_client, requested_runtime)
54
+
55
+ # Verify that get_current_integration was called once
56
+ mock_get_current_integration.assert_called_once()
57
+
58
+ @pytest.mark.parametrize(
59
+ "requested_runtime, installation_type, expected",
60
+ [
61
+ (Runtime.Saas, "SaasOauth2", True),
62
+ (Runtime.Saas, "OnPrem", False),
63
+ (Runtime.OnPrem, "OnPrem", True),
64
+ (Runtime.OnPrem, "SaasCloud", False),
65
+ ],
66
+ )
67
+ def test_runtime_installation_compatibility(
68
+ self, requested_runtime: Runtime, installation_type: str, expected: bool
69
+ ) -> None:
70
+ assert (
71
+ requested_runtime.is_installation_type_compatible(installation_type)
72
+ == expected
73
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: port-ocean
3
- Version: 0.15.1
3
+ Version: 0.15.3
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
@@ -17,15 +17,15 @@ port_ocean/cli/commands/defaults/dock.py,sha256=pFtHrU_LTvb5Ddrzj09Wxy-jg1Ym10wB
17
17
  port_ocean/cli/commands/defaults/group.py,sha256=hii_4CYoQ7jSMePbnP4AmruO_RKWCUcoV7dXXBlZafc,115
18
18
  port_ocean/cli/commands/list_integrations.py,sha256=DVVioFruGUE-_v6UUHlcemWNN6RlWwCrf1X4HmAXsf8,1134
19
19
  port_ocean/cli/commands/main.py,sha256=gj0lmuLep2XeLNuabB7Wk0UVYPT7_CD_rAw5AoUQWSE,1057
20
- port_ocean/cli/commands/new.py,sha256=39_RnEZHoY0pWf59z_oXrLXAyVwzmFY0XcpCJrtZINI,3496
20
+ port_ocean/cli/commands/new.py,sha256=qJ6fQG1t95U574Cvx5pMRgxabrmdB6kxEI0bwuTryb8,3262
21
21
  port_ocean/cli/commands/pull.py,sha256=VvrRjLNlfPuLIf7KzeIcbzzdi98Z0M9wCRpXC3QPxdI,2306
22
22
  port_ocean/cli/commands/sail.py,sha256=rY7rEMjfy_KXiWvtL0T72TTLgeQ3HW4SOzKkz9wL9nI,2282
23
23
  port_ocean/cli/commands/version.py,sha256=hEuIEIcm6Zkamz41Z9nxeSM_4g3oNlAgWwQyDGboh-E,536
24
24
  port_ocean/cli/cookiecutter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- port_ocean/cli/cookiecutter/cookiecutter.json,sha256=N5UrAP2e5JbgEDz_WTQFIZlzSveME6x32sHeA7idjh0,481
25
+ port_ocean/cli/cookiecutter/cookiecutter.json,sha256=ie-LJjg-ek3lP2RRosY2u_q2W4y2TykXm_Gynjjt6Es,814
26
26
  port_ocean/cli/cookiecutter/extensions.py,sha256=eQNjZvy2enDkJpvMbBGil77Xk9-38f862wfnmCjdoBc,446
27
27
  port_ocean/cli/cookiecutter/hooks/post_gen_project.py,sha256=tFqtsjSbu7HMN32WIiFO37S1a_dfHezvdPwmM6MmNJk,1182
28
- port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.env.example,sha256=LnNPRe3RnzjWPL4tNLYEQiMvFEZHSy3ceqwQEapcpwE,92
28
+ port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.env.example,sha256=ywAmZto6YBGXyhEmpG1uYsgaHr2N1ZBRjdtRNt6Vkpw,388
29
29
  port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.gitignore,sha256=32p1lDW_g5hyBz486GWfDeR9m7ikFlASVri5a8vmNoo,2698
30
30
  port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/.gitignore,sha256=kCpRPdl3S_jqYYZaOrc0-xa6-l3KqVjNRXc6jCkd_-Q,12
31
31
  port_ocean/cli/cookiecutter/{{cookiecutter.integration_slug}}/.port/resources/blueprints.json,sha256=9kf5gY4YjP78vEPfd9j7347sV6wiqeHzmBz7UJkvmDg,1187
@@ -102,9 +102,10 @@ port_ocean/core/integrations/mixins/handler.py,sha256=mZ7-0UlG3LcrwJttFbMe-R4xcO
102
102
  port_ocean/core/integrations/mixins/sync.py,sha256=B9fEs8faaYLLikH9GBjE_E61vo0bQDjIGQsQ1SRXOlA,3931
103
103
  port_ocean/core/integrations/mixins/sync_raw.py,sha256=BGS5EnZ2N3ifcAi94Wo-ZassSJ-_Se9eFJMpBDT7pNY,18841
104
104
  port_ocean/core/integrations/mixins/utils.py,sha256=7y1rGETZIjOQadyIjFJXIHKkQFKx_SwiP-TrAIsyyLY,2303
105
- port_ocean/core/models.py,sha256=YWLy-b3N3VnMjD__BTytHqXG78lNjVqnIuhvcVLSlrs,1484
105
+ port_ocean/core/models.py,sha256=71QIFHl-p401h2HnSDQ-aaLXhu6z3iHTwCBI0TewJos,1902
106
106
  port_ocean/core/ocean_types.py,sha256=3_d8-n626f1kWLQ_Jxw194LEyrOVupz05qs_Y1pvB-A,990
107
- port_ocean/core/utils.py,sha256=40UjRauRJO47WDSNn9bkCRD2bfhfB3e-dnOLULnuVzE,3631
107
+ port_ocean/core/utils.py,sha256=QSRuF9wlhbOw6cELlDlek_UIX6ciIuKWml8QhBmHU_k,3703
108
+ port_ocean/debug_cli.py,sha256=gHrv-Ey3cImKOcGZpjoHlo4pa_zfmyOl6TUM4o9VtcA,96
108
109
  port_ocean/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
109
110
  port_ocean/exceptions/api.py,sha256=TLmTMqn4uHGaHgZK8PMIJ0TVJlPB4iP7xl9rx7GtCyY,426
110
111
  port_ocean/exceptions/base.py,sha256=uY4DX7fIITDFfemCJDWpaZi3bD51lcANc5swpoNvMJA,46
@@ -130,6 +131,7 @@ port_ocean/tests/clients/port/mixins/test_entities.py,sha256=A9myrnkLhKSQrnOLv1Z
130
131
  port_ocean/tests/conftest.py,sha256=JXASSS0IY0nnR6bxBflhzxS25kf4iNaABmThyZ0mZt8,101
131
132
  port_ocean/tests/core/defaults/test_common.py,sha256=sR7RqB3ZYV6Xn6NIg-c8k5K6JcGsYZ2SCe_PYX5vLYM,5560
132
133
  port_ocean/tests/core/handlers/entity_processor/test_jq_entity_processor.py,sha256=Yv03P-LDcJCKZ21exiTFrcT1eu0zn6Z954dilxrb52Y,10842
134
+ port_ocean/tests/core/test_utils.py,sha256=94940TerN38jy81ebLJ2Fzf5JJUaV9krnce75APCwmM,2641
133
135
  port_ocean/tests/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
134
136
  port_ocean/tests/helpers/fake_port_api.py,sha256=9rtjC6iTQMfzWK6WipkDzzG0b1IIaRmvdJLOyV613vE,6479
135
137
  port_ocean/tests/helpers/fixtures.py,sha256=IQEplbHhRgjrAsZlnXrgSYA5YQEn25I9HgO3_Fjibxg,1481
@@ -151,8 +153,8 @@ port_ocean/utils/repeat.py,sha256=0EFWM9d8lLXAhZmAyczY20LAnijw6UbIECf5lpGbOas,32
151
153
  port_ocean/utils/signal.py,sha256=K-6kKFQTltcmKDhtyZAcn0IMa3sUpOHGOAUdWKgx0_E,1369
152
154
  port_ocean/utils/time.py,sha256=pufAOH5ZQI7gXvOvJoQXZXZJV-Dqktoj9Qp9eiRwmJ4,1939
153
155
  port_ocean/version.py,sha256=UsuJdvdQlazzKGD3Hd5-U7N69STh8Dq9ggJzQFnu9fU,177
154
- port_ocean-0.15.1.dist-info/LICENSE.md,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
155
- port_ocean-0.15.1.dist-info/METADATA,sha256=1TN3ywl0FoNAvU1dTww8197vioantB9hlQO2hQnMP04,6673
156
- port_ocean-0.15.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
157
- port_ocean-0.15.1.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
158
- port_ocean-0.15.1.dist-info/RECORD,,
156
+ port_ocean-0.15.3.dist-info/LICENSE.md,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
157
+ port_ocean-0.15.3.dist-info/METADATA,sha256=97A1rlQ3w2zUQl6-OKN_6n_yJvMquXcJWwsJ3bNJ3hg,6673
158
+ port_ocean-0.15.3.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
159
+ port_ocean-0.15.3.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
160
+ port_ocean-0.15.3.dist-info/RECORD,,