nextmv 0.18.0__py3-none-any.whl → 1.0.0.dev2__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.
- nextmv/__about__.py +1 -1
- nextmv/__entrypoint__.py +8 -13
- nextmv/__init__.py +53 -0
- nextmv/_serialization.py +96 -0
- nextmv/base_model.py +54 -9
- nextmv/cli/CONTRIBUTING.md +511 -0
- nextmv/cli/__init__.py +0 -0
- nextmv/cli/cloud/__init__.py +47 -0
- nextmv/cli/cloud/acceptance/__init__.py +27 -0
- nextmv/cli/cloud/acceptance/create.py +393 -0
- nextmv/cli/cloud/acceptance/delete.py +68 -0
- nextmv/cli/cloud/acceptance/get.py +104 -0
- nextmv/cli/cloud/acceptance/list.py +62 -0
- nextmv/cli/cloud/acceptance/update.py +95 -0
- nextmv/cli/cloud/account/__init__.py +28 -0
- nextmv/cli/cloud/account/create.py +83 -0
- nextmv/cli/cloud/account/delete.py +60 -0
- nextmv/cli/cloud/account/get.py +66 -0
- nextmv/cli/cloud/account/update.py +70 -0
- nextmv/cli/cloud/app/__init__.py +35 -0
- nextmv/cli/cloud/app/create.py +141 -0
- nextmv/cli/cloud/app/delete.py +58 -0
- nextmv/cli/cloud/app/exists.py +44 -0
- nextmv/cli/cloud/app/get.py +66 -0
- nextmv/cli/cloud/app/list.py +61 -0
- nextmv/cli/cloud/app/push.py +137 -0
- nextmv/cli/cloud/app/update.py +124 -0
- nextmv/cli/cloud/batch/__init__.py +29 -0
- nextmv/cli/cloud/batch/create.py +454 -0
- nextmv/cli/cloud/batch/delete.py +68 -0
- nextmv/cli/cloud/batch/get.py +104 -0
- nextmv/cli/cloud/batch/list.py +63 -0
- nextmv/cli/cloud/batch/metadata.py +66 -0
- nextmv/cli/cloud/batch/update.py +95 -0
- nextmv/cli/cloud/data/__init__.py +26 -0
- nextmv/cli/cloud/data/upload.py +162 -0
- nextmv/cli/cloud/ensemble/__init__.py +31 -0
- nextmv/cli/cloud/ensemble/create.py +414 -0
- nextmv/cli/cloud/ensemble/delete.py +67 -0
- nextmv/cli/cloud/ensemble/get.py +65 -0
- nextmv/cli/cloud/ensemble/update.py +103 -0
- nextmv/cli/cloud/input_set/__init__.py +30 -0
- nextmv/cli/cloud/input_set/create.py +170 -0
- nextmv/cli/cloud/input_set/get.py +63 -0
- nextmv/cli/cloud/input_set/list.py +63 -0
- nextmv/cli/cloud/input_set/update.py +123 -0
- nextmv/cli/cloud/instance/__init__.py +35 -0
- nextmv/cli/cloud/instance/create.py +290 -0
- nextmv/cli/cloud/instance/delete.py +62 -0
- nextmv/cli/cloud/instance/exists.py +39 -0
- nextmv/cli/cloud/instance/get.py +62 -0
- nextmv/cli/cloud/instance/list.py +60 -0
- nextmv/cli/cloud/instance/update.py +216 -0
- nextmv/cli/cloud/managed_input/__init__.py +31 -0
- nextmv/cli/cloud/managed_input/create.py +146 -0
- nextmv/cli/cloud/managed_input/delete.py +65 -0
- nextmv/cli/cloud/managed_input/get.py +63 -0
- nextmv/cli/cloud/managed_input/list.py +60 -0
- nextmv/cli/cloud/managed_input/update.py +97 -0
- nextmv/cli/cloud/run/__init__.py +37 -0
- nextmv/cli/cloud/run/cancel.py +37 -0
- nextmv/cli/cloud/run/create.py +530 -0
- nextmv/cli/cloud/run/get.py +199 -0
- nextmv/cli/cloud/run/input.py +86 -0
- nextmv/cli/cloud/run/list.py +80 -0
- nextmv/cli/cloud/run/logs.py +167 -0
- nextmv/cli/cloud/run/metadata.py +67 -0
- nextmv/cli/cloud/run/track.py +501 -0
- nextmv/cli/cloud/scenario/__init__.py +29 -0
- nextmv/cli/cloud/scenario/create.py +451 -0
- nextmv/cli/cloud/scenario/delete.py +65 -0
- nextmv/cli/cloud/scenario/get.py +102 -0
- nextmv/cli/cloud/scenario/list.py +63 -0
- nextmv/cli/cloud/scenario/metadata.py +67 -0
- nextmv/cli/cloud/scenario/update.py +93 -0
- nextmv/cli/cloud/secrets/__init__.py +33 -0
- nextmv/cli/cloud/secrets/create.py +206 -0
- nextmv/cli/cloud/secrets/delete.py +67 -0
- nextmv/cli/cloud/secrets/get.py +66 -0
- nextmv/cli/cloud/secrets/list.py +60 -0
- nextmv/cli/cloud/secrets/update.py +147 -0
- nextmv/cli/cloud/shadow/__init__.py +33 -0
- nextmv/cli/cloud/shadow/create.py +184 -0
- nextmv/cli/cloud/shadow/delete.py +68 -0
- nextmv/cli/cloud/shadow/get.py +61 -0
- nextmv/cli/cloud/shadow/list.py +63 -0
- nextmv/cli/cloud/shadow/metadata.py +66 -0
- nextmv/cli/cloud/shadow/start.py +43 -0
- nextmv/cli/cloud/shadow/stop.py +43 -0
- nextmv/cli/cloud/shadow/update.py +95 -0
- nextmv/cli/cloud/upload/__init__.py +22 -0
- nextmv/cli/cloud/upload/create.py +39 -0
- nextmv/cli/cloud/version/__init__.py +33 -0
- nextmv/cli/cloud/version/create.py +97 -0
- nextmv/cli/cloud/version/delete.py +62 -0
- nextmv/cli/cloud/version/exists.py +39 -0
- nextmv/cli/cloud/version/get.py +62 -0
- nextmv/cli/cloud/version/list.py +60 -0
- nextmv/cli/cloud/version/update.py +92 -0
- nextmv/cli/community/__init__.py +24 -0
- nextmv/cli/community/clone.py +270 -0
- nextmv/cli/community/list.py +265 -0
- nextmv/cli/configuration/__init__.py +23 -0
- nextmv/cli/configuration/config.py +195 -0
- nextmv/cli/configuration/create.py +94 -0
- nextmv/cli/configuration/delete.py +67 -0
- nextmv/cli/configuration/list.py +77 -0
- nextmv/cli/main.py +188 -0
- nextmv/cli/message.py +153 -0
- nextmv/cli/options.py +206 -0
- nextmv/cli/version.py +38 -0
- nextmv/cloud/__init__.py +71 -17
- nextmv/cloud/acceptance_test.py +757 -51
- nextmv/cloud/account.py +406 -17
- nextmv/cloud/application/__init__.py +957 -0
- nextmv/cloud/application/_acceptance.py +419 -0
- nextmv/cloud/application/_batch_scenario.py +860 -0
- nextmv/cloud/application/_ensemble.py +251 -0
- nextmv/cloud/application/_input_set.py +227 -0
- nextmv/cloud/application/_instance.py +289 -0
- nextmv/cloud/application/_managed_input.py +227 -0
- nextmv/cloud/application/_run.py +1393 -0
- nextmv/cloud/application/_secrets.py +294 -0
- nextmv/cloud/application/_shadow.py +314 -0
- nextmv/cloud/application/_utils.py +54 -0
- nextmv/cloud/application/_version.py +303 -0
- nextmv/cloud/assets.py +48 -0
- nextmv/cloud/batch_experiment.py +294 -33
- nextmv/cloud/client.py +307 -66
- nextmv/cloud/ensemble.py +247 -0
- nextmv/cloud/input_set.py +120 -2
- nextmv/cloud/instance.py +133 -8
- nextmv/cloud/integration.py +533 -0
- nextmv/cloud/package.py +168 -53
- nextmv/cloud/scenario.py +410 -0
- nextmv/cloud/secrets.py +234 -0
- nextmv/cloud/shadow.py +190 -0
- nextmv/cloud/url.py +73 -0
- nextmv/cloud/version.py +132 -4
- nextmv/default_app/.gitignore +1 -0
- nextmv/default_app/README.md +32 -0
- nextmv/default_app/app.yaml +12 -0
- nextmv/default_app/input.json +5 -0
- nextmv/default_app/main.py +37 -0
- nextmv/default_app/requirements.txt +2 -0
- nextmv/default_app/src/__init__.py +0 -0
- nextmv/default_app/src/visuals.py +36 -0
- nextmv/deprecated.py +47 -0
- nextmv/input.py +861 -90
- nextmv/local/__init__.py +5 -0
- nextmv/local/application.py +1251 -0
- nextmv/local/executor.py +1042 -0
- nextmv/local/geojson_handler.py +323 -0
- nextmv/local/local.py +97 -0
- nextmv/local/plotly_handler.py +61 -0
- nextmv/local/runner.py +274 -0
- nextmv/logger.py +80 -9
- nextmv/manifest.py +1466 -0
- nextmv/model.py +241 -66
- nextmv/options.py +708 -115
- nextmv/output.py +1301 -274
- nextmv/polling.py +325 -0
- nextmv/run.py +1702 -0
- nextmv/safe.py +145 -0
- nextmv/status.py +122 -0
- nextmv-1.0.0.dev2.dist-info/METADATA +311 -0
- nextmv-1.0.0.dev2.dist-info/RECORD +170 -0
- {nextmv-0.18.0.dist-info → nextmv-1.0.0.dev2.dist-info}/WHEEL +1 -1
- nextmv-1.0.0.dev2.dist-info/entry_points.txt +2 -0
- nextmv/cloud/application.py +0 -1405
- nextmv/cloud/manifest.py +0 -234
- nextmv/cloud/status.py +0 -29
- nextmv-0.18.0.dist-info/METADATA +0 -770
- nextmv-0.18.0.dist-info/RECORD +0 -25
- {nextmv-0.18.0.dist-info → nextmv-1.0.0.dev2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Integration module for interacting with Nextmv Cloud integrations.
|
|
3
|
+
|
|
4
|
+
This module provides functionality to interact with integrations in Nextmv
|
|
5
|
+
Cloud, including integration management.
|
|
6
|
+
|
|
7
|
+
Classes
|
|
8
|
+
-------
|
|
9
|
+
IntegrationType
|
|
10
|
+
Enum representing the type of an integration.
|
|
11
|
+
IntegrationProvider
|
|
12
|
+
Enum representing the provider of an integration.
|
|
13
|
+
Integration
|
|
14
|
+
Class representing an integration in Nextmv Cloud.
|
|
15
|
+
|
|
16
|
+
Functions
|
|
17
|
+
---------
|
|
18
|
+
list_integrations
|
|
19
|
+
Function to list all integrations in Nextmv Cloud.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from datetime import datetime
|
|
23
|
+
from enum import Enum
|
|
24
|
+
from typing import Any
|
|
25
|
+
|
|
26
|
+
from pydantic import AliasChoices, Field
|
|
27
|
+
|
|
28
|
+
from nextmv.base_model import BaseModel
|
|
29
|
+
from nextmv.cloud.client import Client
|
|
30
|
+
from nextmv.manifest import ManifestType
|
|
31
|
+
from nextmv.safe import safe_id
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class IntegrationType(str, Enum):
|
|
35
|
+
"""
|
|
36
|
+
The type of an integration.
|
|
37
|
+
|
|
38
|
+
You can import the `IntegrationType` class directly from `cloud`:
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from nextmv.cloud import IntegrationType
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Attributes
|
|
45
|
+
----------
|
|
46
|
+
RUNTIME : str
|
|
47
|
+
Indicates a runtime integration.
|
|
48
|
+
DATA : str
|
|
49
|
+
Indicates a data integration.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
RUNTIME = "runtime"
|
|
53
|
+
"""Indicates a runtime integration."""
|
|
54
|
+
DATA = "data"
|
|
55
|
+
"""Indicates a data integration."""
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class IntegrationProvider(str, Enum):
|
|
59
|
+
"""
|
|
60
|
+
The provider of an integration.
|
|
61
|
+
|
|
62
|
+
You can import the `IntegrationProvider` class directly from `cloud`:
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from nextmv.cloud import IntegrationProvider
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Attributes
|
|
69
|
+
----------
|
|
70
|
+
DBX : str
|
|
71
|
+
Indicates a Databricks integration.
|
|
72
|
+
UNKNOWN : str
|
|
73
|
+
Indicates an unknown integration provider.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
DBX = "dbx"
|
|
77
|
+
"""Indicates a Databricks integration."""
|
|
78
|
+
UNKNOWN = "unknown"
|
|
79
|
+
"""Indicates an unknown integration provider."""
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class Integration(BaseModel):
|
|
83
|
+
"""
|
|
84
|
+
Represents an integration in Nextmv Cloud. An integration allows Nextmv
|
|
85
|
+
Cloud to communicate with external systems or services.
|
|
86
|
+
|
|
87
|
+
You can import the `Integration` class directly from `cloud`:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from nextmv.cloud import Integration
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
You can use the `Integration.get` class method to retrieve an existing
|
|
94
|
+
integration from Nextmv Cloud, to ensure that all fields are properly
|
|
95
|
+
populated.
|
|
96
|
+
|
|
97
|
+
Parameters
|
|
98
|
+
----------
|
|
99
|
+
integration_id : str
|
|
100
|
+
The unique identifier of the integration.
|
|
101
|
+
client : Client
|
|
102
|
+
Client to use for interacting with the Nextmv Cloud API.
|
|
103
|
+
name : str, optional
|
|
104
|
+
The name of the integration.
|
|
105
|
+
description : str, optional
|
|
106
|
+
An optional description of the integration.
|
|
107
|
+
is_global : bool, optional
|
|
108
|
+
Indicates whether the integration is global (available to all
|
|
109
|
+
applications in the account).
|
|
110
|
+
application_ids : list[str], optional
|
|
111
|
+
List of application IDs that have access to this integration.
|
|
112
|
+
integration_type : IntegrationType, optional
|
|
113
|
+
The type of the integration (runtime or data).
|
|
114
|
+
exec_types : list[ManifestType], optional
|
|
115
|
+
List of execution types supported by the integration.
|
|
116
|
+
provider : IntegrationProvider, optional
|
|
117
|
+
The provider of the integration.
|
|
118
|
+
provider_config : dict[str, Any], optional
|
|
119
|
+
Configuration specific to the integration provider.
|
|
120
|
+
created_at : datetime, optional
|
|
121
|
+
The timestamp when the integration was created.
|
|
122
|
+
updated_at : datetime, optional
|
|
123
|
+
The timestamp when the integration was last updated.
|
|
124
|
+
"""
|
|
125
|
+
|
|
126
|
+
integration_id: str = Field(
|
|
127
|
+
serialization_alias="id",
|
|
128
|
+
validation_alias=AliasChoices("id", "integration_id"),
|
|
129
|
+
)
|
|
130
|
+
"""The unique identifier of the integration."""
|
|
131
|
+
client: Client = Field(exclude=True)
|
|
132
|
+
"""Client to use for interacting with the Nextmv Cloud API."""
|
|
133
|
+
|
|
134
|
+
name: str | None = None
|
|
135
|
+
"""The name of the integration."""
|
|
136
|
+
description: str | None = None
|
|
137
|
+
"""An optional description of the integration."""
|
|
138
|
+
is_global: bool = Field(
|
|
139
|
+
serialization_alias="global",
|
|
140
|
+
validation_alias=AliasChoices("global", "is_global"),
|
|
141
|
+
default=False,
|
|
142
|
+
)
|
|
143
|
+
"""
|
|
144
|
+
Indicates whether the integration is global (available to all
|
|
145
|
+
applications in the account).
|
|
146
|
+
"""
|
|
147
|
+
application_ids: list[str] | None = None
|
|
148
|
+
"""
|
|
149
|
+
List of application IDs that have access to this integration.
|
|
150
|
+
"""
|
|
151
|
+
integration_type: IntegrationType | None = Field(
|
|
152
|
+
serialization_alias="type",
|
|
153
|
+
validation_alias=AliasChoices("type", "integration_type"),
|
|
154
|
+
default=None,
|
|
155
|
+
)
|
|
156
|
+
"""The type of the integration (runtime or data)."""
|
|
157
|
+
exec_types: list[ManifestType] | None = None
|
|
158
|
+
"""List of execution types supported by the integration."""
|
|
159
|
+
provider: IntegrationProvider | None = None
|
|
160
|
+
"""The provider of the integration."""
|
|
161
|
+
provider_config: dict[str, Any] | None = None
|
|
162
|
+
"""Configuration specific to the integration provider."""
|
|
163
|
+
created_at: datetime | None = None
|
|
164
|
+
"""The timestamp when the integration was created."""
|
|
165
|
+
updated_at: datetime | None = None
|
|
166
|
+
"""The timestamp when the integration was last updated."""
|
|
167
|
+
endpoint: str = Field(
|
|
168
|
+
exclude=True,
|
|
169
|
+
default="v1/integrations/{id}",
|
|
170
|
+
)
|
|
171
|
+
"""Base endpoint for the integration."""
|
|
172
|
+
|
|
173
|
+
def model_post_init(self, __context) -> None:
|
|
174
|
+
"""
|
|
175
|
+
Validations done after model initialization.
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
self.endpoint = self.endpoint.format(id=self.integration_id)
|
|
179
|
+
|
|
180
|
+
@classmethod
|
|
181
|
+
def get(cls, client: Client, integration_id: str) -> "Integration":
|
|
182
|
+
"""
|
|
183
|
+
Retrieve an existing integration from Nextmv Cloud.
|
|
184
|
+
|
|
185
|
+
This method should be used for validating that the integration exists,
|
|
186
|
+
and not rely simply on instantiating the `Integration` class. Using
|
|
187
|
+
this method ensures that all the fields of the `Integration` class are
|
|
188
|
+
properly populated.
|
|
189
|
+
|
|
190
|
+
Parameters
|
|
191
|
+
----------
|
|
192
|
+
client : Client
|
|
193
|
+
Client to use for interacting with the Nextmv Cloud API.
|
|
194
|
+
integration_id : str
|
|
195
|
+
The unique identifier of the integration to retrieve.
|
|
196
|
+
|
|
197
|
+
Returns
|
|
198
|
+
-------
|
|
199
|
+
Integration
|
|
200
|
+
The retrieved integration instance.
|
|
201
|
+
|
|
202
|
+
Raises
|
|
203
|
+
------
|
|
204
|
+
requests.HTTPError
|
|
205
|
+
If the response status code is not 2xx.
|
|
206
|
+
|
|
207
|
+
Examples
|
|
208
|
+
--------
|
|
209
|
+
>>> from nextmv.cloud import Client, Integration
|
|
210
|
+
>>> client = Client(api_key="your_api_key")
|
|
211
|
+
>>> integration = Integration.get(client=client, integration_id="your_integration_id")
|
|
212
|
+
>>> print(integration.to_dict())
|
|
213
|
+
"""
|
|
214
|
+
|
|
215
|
+
response = client.request(
|
|
216
|
+
method="GET",
|
|
217
|
+
endpoint=f"v1/integrations/{integration_id}",
|
|
218
|
+
)
|
|
219
|
+
response_dict = response.json()
|
|
220
|
+
response_dict["client"] = client
|
|
221
|
+
|
|
222
|
+
return cls.from_dict(response_dict)
|
|
223
|
+
|
|
224
|
+
@classmethod
|
|
225
|
+
def new( # noqa: C901
|
|
226
|
+
cls,
|
|
227
|
+
client: Client,
|
|
228
|
+
name: str,
|
|
229
|
+
integration_type: IntegrationType | str,
|
|
230
|
+
exec_types: list[ManifestType | str],
|
|
231
|
+
provider: IntegrationProvider | str,
|
|
232
|
+
provider_config: dict[str, Any],
|
|
233
|
+
integration_id: str | None = None,
|
|
234
|
+
description: str | None = None,
|
|
235
|
+
is_global: bool = False,
|
|
236
|
+
application_ids: list[str] | None = None,
|
|
237
|
+
exist_ok: bool = False,
|
|
238
|
+
) -> "Integration":
|
|
239
|
+
"""
|
|
240
|
+
Create a new integration directly in Nextmv Cloud.
|
|
241
|
+
|
|
242
|
+
Parameters
|
|
243
|
+
----------
|
|
244
|
+
client : Client
|
|
245
|
+
Client to use for interacting with the Nextmv Cloud API.
|
|
246
|
+
name : str
|
|
247
|
+
The name of the integration.
|
|
248
|
+
integration_type : IntegrationType | str
|
|
249
|
+
The type of the integration. Please refer to the `IntegrationType`
|
|
250
|
+
enum for possible values.
|
|
251
|
+
exec_types : list[ManifestType | str]
|
|
252
|
+
List of execution types supported by the integration. Please refer
|
|
253
|
+
to the `ManifestType` enum for possible values.
|
|
254
|
+
provider : IntegrationProvider | str
|
|
255
|
+
The provider of the integration. Please refer to the
|
|
256
|
+
`IntegrationProvider` enum for possible values.
|
|
257
|
+
provider_config : dict[str, Any]
|
|
258
|
+
Configuration specific to the integration provider.
|
|
259
|
+
integration_id : str, optional
|
|
260
|
+
The unique identifier of the integration. If not provided,
|
|
261
|
+
it will be generated automatically.
|
|
262
|
+
description : str, optional
|
|
263
|
+
An optional description of the integration.
|
|
264
|
+
is_global : bool, optional, default=False
|
|
265
|
+
Indicates whether the integration is global (available to all
|
|
266
|
+
applications in the account). Default is False.
|
|
267
|
+
application_ids : list[str], optional
|
|
268
|
+
List of application IDs that have access to this integration.
|
|
269
|
+
exist_ok : bool, default=False
|
|
270
|
+
If True and an integration with the same ID already exists,
|
|
271
|
+
return the existing integration instead of creating a new one.
|
|
272
|
+
|
|
273
|
+
Returns
|
|
274
|
+
-------
|
|
275
|
+
Integration
|
|
276
|
+
The created integration instance.
|
|
277
|
+
|
|
278
|
+
Raises
|
|
279
|
+
------
|
|
280
|
+
requests.HTTPError
|
|
281
|
+
If the response status code is not 2xx.
|
|
282
|
+
ValueError
|
|
283
|
+
If both `is_global` is True and `application_ids` is provided.
|
|
284
|
+
|
|
285
|
+
Examples
|
|
286
|
+
--------
|
|
287
|
+
>>> from nextmv.cloud import Client, Integration, IntegrationType, IntegrationProvider, ManifestType
|
|
288
|
+
>>> client = Client(api_key="your_api_key")
|
|
289
|
+
>>> integration = Integration.new(
|
|
290
|
+
... client=client,
|
|
291
|
+
... name="my_integration",
|
|
292
|
+
... integration_type=IntegrationType.RUNTIME,
|
|
293
|
+
... exec_types=[ManifestType.PYTHON],
|
|
294
|
+
... provider=IntegrationProvider.DBX,
|
|
295
|
+
... provider_config={"config_key": "config_value"},
|
|
296
|
+
... )
|
|
297
|
+
>>> print(integration.to_dict())
|
|
298
|
+
"""
|
|
299
|
+
|
|
300
|
+
if is_global and application_ids is not None:
|
|
301
|
+
raise ValueError("An integration cannot be global and have specific application IDs.")
|
|
302
|
+
elif not is_global and application_ids is None:
|
|
303
|
+
raise ValueError("A non-global integration must have specific application IDs.")
|
|
304
|
+
|
|
305
|
+
if integration_id is None:
|
|
306
|
+
integration_id = safe_id("integration")
|
|
307
|
+
|
|
308
|
+
if exist_ok:
|
|
309
|
+
try:
|
|
310
|
+
integration = cls.get(client=client, integration_id=integration_id)
|
|
311
|
+
return integration
|
|
312
|
+
except Exception:
|
|
313
|
+
pass
|
|
314
|
+
|
|
315
|
+
if not isinstance(integration_type, IntegrationType):
|
|
316
|
+
integration_type = IntegrationType(integration_type)
|
|
317
|
+
|
|
318
|
+
if not all(isinstance(exec_type, ManifestType) for exec_type in exec_types):
|
|
319
|
+
exec_types = [ManifestType(exec_type) for exec_type in exec_types]
|
|
320
|
+
|
|
321
|
+
if not isinstance(provider, IntegrationProvider):
|
|
322
|
+
provider = IntegrationProvider(provider)
|
|
323
|
+
|
|
324
|
+
payload = {
|
|
325
|
+
"id": integration_id,
|
|
326
|
+
"name": name,
|
|
327
|
+
"global": is_global,
|
|
328
|
+
"type": integration_type.value,
|
|
329
|
+
"exec_types": [exec_type.value for exec_type in exec_types],
|
|
330
|
+
"provider": provider.value,
|
|
331
|
+
"provider_config": provider_config,
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if description is not None:
|
|
335
|
+
payload["description"] = description
|
|
336
|
+
|
|
337
|
+
if application_ids is not None:
|
|
338
|
+
payload["application_ids"] = application_ids
|
|
339
|
+
|
|
340
|
+
response = client.request(
|
|
341
|
+
method="POST",
|
|
342
|
+
endpoint="v1/integrations",
|
|
343
|
+
payload=payload,
|
|
344
|
+
)
|
|
345
|
+
response_dict = response.json()
|
|
346
|
+
response_dict["client"] = client
|
|
347
|
+
integration = cls.from_dict(response_dict)
|
|
348
|
+
|
|
349
|
+
return integration
|
|
350
|
+
|
|
351
|
+
def delete(self) -> None:
|
|
352
|
+
"""
|
|
353
|
+
Deletes the integration from Nextmv Cloud.
|
|
354
|
+
|
|
355
|
+
Raises
|
|
356
|
+
------
|
|
357
|
+
requests.HTTPError
|
|
358
|
+
If the response status code is not 2xx.
|
|
359
|
+
|
|
360
|
+
Examples
|
|
361
|
+
--------
|
|
362
|
+
>>> from nextmv.cloud import Client, Integration
|
|
363
|
+
>>> client = Client(api_key="your_api_key")
|
|
364
|
+
>>> integration = Integration.get(client=client, integration_id="your_integration_id")
|
|
365
|
+
>>> integration.delete()
|
|
366
|
+
"""
|
|
367
|
+
|
|
368
|
+
_ = self.client.request(
|
|
369
|
+
method="DELETE",
|
|
370
|
+
endpoint=self.endpoint,
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
def update( # noqa: C901
|
|
374
|
+
self,
|
|
375
|
+
name: str | None = None,
|
|
376
|
+
integration_type: IntegrationType | str | None = None,
|
|
377
|
+
exec_types: list[ManifestType | str] | None = None,
|
|
378
|
+
provider: IntegrationProvider | str | None = None,
|
|
379
|
+
provider_config: dict[str, Any] | None = None,
|
|
380
|
+
description: str | None = None,
|
|
381
|
+
is_global: bool | None = None,
|
|
382
|
+
application_ids: list[str] | None = None,
|
|
383
|
+
) -> "Integration":
|
|
384
|
+
"""
|
|
385
|
+
Updates the integration in Nextmv Cloud.
|
|
386
|
+
|
|
387
|
+
Parameters
|
|
388
|
+
----------
|
|
389
|
+
name : str, optional
|
|
390
|
+
The new name of the integration.
|
|
391
|
+
integration_type : IntegrationType | str, optional
|
|
392
|
+
The new type of the integration. Please refer to the `IntegrationType`
|
|
393
|
+
enum for possible values.
|
|
394
|
+
exec_types : list[ManifestType | str], optional
|
|
395
|
+
New list of execution types supported by the integration. Please refer
|
|
396
|
+
to the `ManifestType` enum for possible values.
|
|
397
|
+
provider : IntegrationProvider | str, optional
|
|
398
|
+
The new provider of the integration. Please refer to the
|
|
399
|
+
`IntegrationProvider` enum for possible values.
|
|
400
|
+
provider_config : dict[str, Any], optional
|
|
401
|
+
New configuration specific to the integration provider.
|
|
402
|
+
description : str, optional
|
|
403
|
+
The new description of the integration.
|
|
404
|
+
is_global : bool, optional
|
|
405
|
+
Indicates whether the integration is global (available to all
|
|
406
|
+
applications in the account). If not provided, the current value
|
|
407
|
+
is preserved.
|
|
408
|
+
application_ids : list[str], optional
|
|
409
|
+
New list of application IDs that have access to this integration.
|
|
410
|
+
|
|
411
|
+
Returns
|
|
412
|
+
-------
|
|
413
|
+
Integration
|
|
414
|
+
The updated integration instance.
|
|
415
|
+
|
|
416
|
+
Raises
|
|
417
|
+
------
|
|
418
|
+
requests.HTTPError
|
|
419
|
+
If the response status code is not 2xx.
|
|
420
|
+
|
|
421
|
+
Examples
|
|
422
|
+
--------
|
|
423
|
+
>>> from nextmv.cloud import Client, Integration
|
|
424
|
+
>>> client = Client(api_key="your_api_key")
|
|
425
|
+
>>> integration = Integration.get(client=client, integration_id="your_integration_id")
|
|
426
|
+
>>> updated_integration = integration.update(name="new_name")
|
|
427
|
+
>>> print(updated_integration.to_dict())
|
|
428
|
+
"""
|
|
429
|
+
|
|
430
|
+
integration = self.get(client=self.client, integration_id=self.integration_id)
|
|
431
|
+
integration_dict = integration.to_dict()
|
|
432
|
+
payload = integration_dict.copy()
|
|
433
|
+
|
|
434
|
+
if name is not None:
|
|
435
|
+
payload["name"] = name
|
|
436
|
+
|
|
437
|
+
if integration_type is not None:
|
|
438
|
+
if not isinstance(integration_type, IntegrationType):
|
|
439
|
+
integration_type = IntegrationType(integration_type)
|
|
440
|
+
payload["type"] = integration_type.value
|
|
441
|
+
|
|
442
|
+
if exec_types is not None:
|
|
443
|
+
if not all(isinstance(exec_type, ManifestType) for exec_type in exec_types):
|
|
444
|
+
exec_types = [ManifestType(exec_type) for exec_type in exec_types]
|
|
445
|
+
payload["exec_types"] = [exec_type.value for exec_type in exec_types]
|
|
446
|
+
|
|
447
|
+
if provider is not None:
|
|
448
|
+
if not isinstance(provider, IntegrationProvider):
|
|
449
|
+
provider = IntegrationProvider(provider)
|
|
450
|
+
payload["provider"] = provider.value
|
|
451
|
+
|
|
452
|
+
if provider_config is not None:
|
|
453
|
+
payload["provider_config"] = provider_config
|
|
454
|
+
|
|
455
|
+
if description is not None:
|
|
456
|
+
payload["description"] = description
|
|
457
|
+
|
|
458
|
+
if is_global is not None:
|
|
459
|
+
payload["global"] = is_global
|
|
460
|
+
|
|
461
|
+
if application_ids is not None:
|
|
462
|
+
payload["application_ids"] = application_ids
|
|
463
|
+
|
|
464
|
+
# Final validation: ensure invariants are met.
|
|
465
|
+
if payload["global"] is True and payload.get("application_ids"):
|
|
466
|
+
raise ValueError(
|
|
467
|
+
"An integration cannot be global and have application_ids. "
|
|
468
|
+
"To make an integration global, call update(is_global=True, application_ids=[])."
|
|
469
|
+
)
|
|
470
|
+
if payload["global"] is False and not payload.get("application_ids"):
|
|
471
|
+
raise ValueError(
|
|
472
|
+
"A non-global integration must have specific application IDs. "
|
|
473
|
+
"Provide application_ids with at least one ID, or set is_global=True."
|
|
474
|
+
)
|
|
475
|
+
|
|
476
|
+
response = self.client.request(
|
|
477
|
+
method="PUT",
|
|
478
|
+
endpoint=self.endpoint,
|
|
479
|
+
payload=payload,
|
|
480
|
+
)
|
|
481
|
+
response_dict = response.json()
|
|
482
|
+
response_dict["client"] = self.client
|
|
483
|
+
integration = self.from_dict(response_dict)
|
|
484
|
+
|
|
485
|
+
return integration
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
def list_integrations(client: Client) -> list[Integration]:
|
|
489
|
+
"""
|
|
490
|
+
List all integrations in Nextmv Cloud for the given client.
|
|
491
|
+
|
|
492
|
+
You can import the `list_integrations` method directly from `cloud`:
|
|
493
|
+
|
|
494
|
+
```python
|
|
495
|
+
from nextmv.cloud import list_integrations
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
Parameters
|
|
499
|
+
----------
|
|
500
|
+
client : Client
|
|
501
|
+
Client to use for interacting with the Nextmv Cloud API.
|
|
502
|
+
|
|
503
|
+
Returns
|
|
504
|
+
-------
|
|
505
|
+
list[Integration]
|
|
506
|
+
List of integrations.
|
|
507
|
+
|
|
508
|
+
Raises
|
|
509
|
+
------
|
|
510
|
+
requests.HTTPError
|
|
511
|
+
If the response status code is not 2xx.
|
|
512
|
+
|
|
513
|
+
Examples
|
|
514
|
+
--------
|
|
515
|
+
>>> from nextmv.cloud import Client, list_integrations
|
|
516
|
+
>>> client = Client(api_key="your_api_key")
|
|
517
|
+
>>> integrations = list_integrations(client=client)
|
|
518
|
+
>>> for integration in integrations:
|
|
519
|
+
... print(integration.to_dict())
|
|
520
|
+
"""
|
|
521
|
+
|
|
522
|
+
response = client.request(
|
|
523
|
+
method="GET",
|
|
524
|
+
endpoint="v1/integrations",
|
|
525
|
+
)
|
|
526
|
+
response_dict = response.json()
|
|
527
|
+
integrations = []
|
|
528
|
+
for integration_data in response_dict.get("items", []):
|
|
529
|
+
integration_data["client"] = client
|
|
530
|
+
integration = Integration.from_dict(integration_data)
|
|
531
|
+
integrations.append(integration)
|
|
532
|
+
|
|
533
|
+
return integrations
|