omnata-plugin-runtime 0.5.0a113__tar.gz → 0.5.2__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {omnata_plugin_runtime-0.5.0a113 → omnata_plugin_runtime-0.5.2}/PKG-INFO +1 -1
- {omnata_plugin_runtime-0.5.0a113 → omnata_plugin_runtime-0.5.2}/pyproject.toml +1 -1
- {omnata_plugin_runtime-0.5.0a113 → omnata_plugin_runtime-0.5.2}/src/omnata_plugin_runtime/configuration.py +56 -58
- {omnata_plugin_runtime-0.5.0a113 → omnata_plugin_runtime-0.5.2}/src/omnata_plugin_runtime/forms.py +89 -89
- {omnata_plugin_runtime-0.5.0a113 → omnata_plugin_runtime-0.5.2}/src/omnata_plugin_runtime/plugin_entrypoints.py +13 -12
- {omnata_plugin_runtime-0.5.0a113 → omnata_plugin_runtime-0.5.2}/src/omnata_plugin_runtime/rate_limiting.py +5 -4
- {omnata_plugin_runtime-0.5.0a113 → omnata_plugin_runtime-0.5.2}/LICENSE +0 -0
- {omnata_plugin_runtime-0.5.0a113 → omnata_plugin_runtime-0.5.2}/README.md +0 -0
- {omnata_plugin_runtime-0.5.0a113 → omnata_plugin_runtime-0.5.2}/src/omnata_plugin_runtime/__init__.py +0 -0
- {omnata_plugin_runtime-0.5.0a113 → omnata_plugin_runtime-0.5.2}/src/omnata_plugin_runtime/api.py +0 -0
- {omnata_plugin_runtime-0.5.0a113 → omnata_plugin_runtime-0.5.2}/src/omnata_plugin_runtime/logging.py +0 -0
- {omnata_plugin_runtime-0.5.0a113 → omnata_plugin_runtime-0.5.2}/src/omnata_plugin_runtime/omnata_plugin.py +0 -0
@@ -8,7 +8,7 @@ from typing import Any, List, Dict, Literal, Union, Optional
|
|
8
8
|
from enum import Enum
|
9
9
|
|
10
10
|
from abc import ABC
|
11
|
-
from pydantic import BaseModel, Field, PrivateAttr, validator # pylint: disable=no-name-in-module
|
11
|
+
from pydantic import BaseModel, Field, PrivateAttr, SerializationInfo, model_serializer, validator # pylint: disable=no-name-in-module
|
12
12
|
|
13
13
|
if tuple(sys.version_info[:2]) >= (3, 9):
|
14
14
|
# Python 3.9 and above
|
@@ -110,16 +110,18 @@ class OutboundSyncAction(SubscriptableBaseModel, ABC):
|
|
110
110
|
**STANDARD_OUTBOUND_SYNC_ACTIONS[data["action_name"]]().__dict__,
|
111
111
|
}
|
112
112
|
super().__init__(**data)
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
113
|
+
|
114
|
+
@model_serializer(mode='wrap')
|
115
|
+
def ser_model(self,handler,info:SerializationInfo) -> Dict[str, Any]:
|
116
|
+
serialized:Dict[str,Any] = handler(self)
|
117
|
+
if not self.custom_action and (info.exclude_none is None or info.exclude_none == False):
|
118
|
+
return {k:v for k,v in serialized.items() if k not in [
|
119
|
+
"description"]}
|
120
|
+
return serialized
|
121
|
+
|
122
|
+
def model_dump_no_trim(self) -> Dict[str, Any]:
|
123
|
+
# we use our own special include value to signal not to trim
|
124
|
+
return self.model_dump(exclude_none=True)
|
123
125
|
|
124
126
|
|
125
127
|
class CreateSyncAction(OutboundSyncAction):
|
@@ -221,13 +223,13 @@ class OutboundSyncStrategy(SubscriptableBaseModel, ABC):
|
|
221
223
|
name: str
|
222
224
|
description: str
|
223
225
|
icon_source: str = ICON_URL_CODE
|
224
|
-
action_on_record_create: Optional[OutboundSyncAction] = None
|
225
|
-
action_on_record_update: Optional[OutboundSyncAction] = None
|
226
|
-
action_on_record_delete: Optional[OutboundSyncAction] = None
|
227
|
-
action_on_record_unchanged: Optional[OutboundSyncAction] = None
|
226
|
+
action_on_record_create: Optional[OutboundSyncAction] = Field(default=None)
|
227
|
+
action_on_record_update: Optional[OutboundSyncAction] = Field(default=None)
|
228
|
+
action_on_record_delete: Optional[OutboundSyncAction] = Field(default=None)
|
229
|
+
action_on_record_unchanged: Optional[OutboundSyncAction] = Field(default=None)
|
228
230
|
custom_strategy: bool = True
|
229
231
|
|
230
|
-
def __eq__(self, other):
|
232
|
+
def __eq__(self, other:OutboundSyncStrategy):
|
231
233
|
if hasattr(other, 'custom_strategy') and hasattr(other, 'name'):
|
232
234
|
return (
|
233
235
|
self.custom_strategy == other.custom_strategy
|
@@ -251,27 +253,23 @@ class OutboundSyncStrategy(SubscriptableBaseModel, ABC):
|
|
251
253
|
}
|
252
254
|
super().__init__(**data)
|
253
255
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
"""
|
261
|
-
excluded_fields = (
|
262
|
-
{}
|
263
|
-
if not trim or self.custom_strategy
|
264
|
-
else {
|
256
|
+
@model_serializer(mode='wrap')
|
257
|
+
def ser_model(self,handler,info:SerializationInfo) -> Dict[str, Any]:
|
258
|
+
serialized:Dict[str,Any] = handler(self)
|
259
|
+
if not self.custom_strategy and (info.exclude_none is None or info.exclude_none == False):
|
260
|
+
return {k:v for k,v in serialized.items() if k not in [
|
265
261
|
"description",
|
266
262
|
"icon_source",
|
267
263
|
"action_on_record_create",
|
268
264
|
"action_on_record_update",
|
269
265
|
"action_on_record_delete",
|
270
|
-
"action_on_record_unchanged"
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
266
|
+
"action_on_record_unchanged"]}
|
267
|
+
return serialized
|
268
|
+
|
269
|
+
def model_dump_no_trim(self) -> Dict[str, Any]:
|
270
|
+
# we use our own special include value to signal not to trim
|
271
|
+
return self.model_dump(exclude_none=True)
|
272
|
+
|
275
273
|
|
276
274
|
class CreateSyncStrategy(OutboundSyncStrategy):
|
277
275
|
"""
|
@@ -424,8 +422,8 @@ class InboundSyncStreamsConfiguration(SubscriptableBaseModel):
|
|
424
422
|
"""
|
425
423
|
|
426
424
|
include_new_streams: bool
|
427
|
-
new_stream_sync_strategy: Optional[InboundSyncStrategy] = None
|
428
|
-
new_stream_storage_behaviour: Optional[InboundStorageBehaviour] = None
|
425
|
+
new_stream_sync_strategy: Optional[InboundSyncStrategy] = Field(default=None)
|
426
|
+
new_stream_storage_behaviour: Optional[InboundStorageBehaviour] = Field(default=None)
|
429
427
|
included_streams: Dict[str, StoredStreamConfiguration]
|
430
428
|
excluded_streams: List[str]
|
431
429
|
bulk_configuration: InboundSyncBulkConfiguration = InboundSyncBulkConfiguration.CUSTOMIZE
|
@@ -532,10 +530,10 @@ class ConnectionConfigurationParameters(SubscriptableBaseModel):
|
|
532
530
|
"""
|
533
531
|
|
534
532
|
connection_method: str
|
535
|
-
connection_parameters: Dict[str, StoredConfigurationValue] = None
|
536
|
-
connection_secrets: Dict[str, StoredConfigurationValue] = None
|
537
|
-
ngrok_tunnel_settings: Optional[NgrokTunnelSettings] = None
|
538
|
-
access_token_secret_name: Optional[str] = None
|
533
|
+
connection_parameters: Optional[Dict[str, StoredConfigurationValue]] = Field(default=None)
|
534
|
+
connection_secrets: Optional[Dict[str, StoredConfigurationValue]] = Field(default=None)
|
535
|
+
ngrok_tunnel_settings: Optional[NgrokTunnelSettings] = Field(default=None)
|
536
|
+
access_token_secret_name: Optional[str] = Field(default=None)
|
539
537
|
|
540
538
|
_snowflake: Optional[Any] = PrivateAttr( # or use Any to annotate the type and use Field to initialize
|
541
539
|
default=None
|
@@ -608,10 +606,10 @@ class SyncConfigurationParameters(ConnectionConfigurationParameters):
|
|
608
606
|
"""
|
609
607
|
|
610
608
|
connection_method: str
|
611
|
-
connection_parameters: Dict[str, StoredConfigurationValue] = None
|
612
|
-
connection_secrets: Dict[str, StoredConfigurationValue] = None
|
613
|
-
sync_parameters: Dict[str, StoredConfigurationValue] = None
|
614
|
-
current_form_parameters: Dict[str, StoredConfigurationValue] = None
|
609
|
+
connection_parameters: Optional[Dict[str, StoredConfigurationValue]] = Field(default=None)
|
610
|
+
connection_secrets: Optional[Dict[str, StoredConfigurationValue]] = Field(default=None)
|
611
|
+
sync_parameters: Optional[Dict[str, StoredConfigurationValue]] = Field(default=None)
|
612
|
+
current_form_parameters: Optional[Dict[str, StoredConfigurationValue]] = Field(default=None)
|
615
613
|
|
616
614
|
def sync_parameter_exists(self, parameter_name: str) -> bool:
|
617
615
|
"""
|
@@ -688,12 +686,12 @@ class OutboundSyncConfigurationParameters(SyncConfigurationParameters):
|
|
688
686
|
"""
|
689
687
|
|
690
688
|
connection_method: str
|
691
|
-
connection_parameters: Dict[str, StoredConfigurationValue] = None
|
692
|
-
connection_secrets: Dict[str, StoredConfigurationValue] = None
|
693
|
-
sync_parameters: Dict[str, StoredConfigurationValue] = None
|
694
|
-
current_form_parameters: Dict[str, StoredConfigurationValue] = None
|
695
|
-
sync_strategy: OutboundSyncStrategy = None
|
696
|
-
field_mappings: StoredMappingValue = None
|
689
|
+
connection_parameters: Optional[Dict[str, StoredConfigurationValue]] = Field(default=None)
|
690
|
+
connection_secrets: Optional[Dict[str, StoredConfigurationValue]] = Field(default=None)
|
691
|
+
sync_parameters: Optional[Dict[str, StoredConfigurationValue]] = Field(default=None)
|
692
|
+
current_form_parameters: Optional[Dict[str, StoredConfigurationValue]] = Field(default=None)
|
693
|
+
sync_strategy: Optional[OutboundSyncStrategy] = Field(default=None)
|
694
|
+
field_mappings: Optional[StoredMappingValue] = Field(default=None)
|
697
695
|
|
698
696
|
|
699
697
|
class InboundSyncConfigurationParameters(SyncConfigurationParameters):
|
@@ -708,11 +706,11 @@ class InboundSyncConfigurationParameters(SyncConfigurationParameters):
|
|
708
706
|
"""
|
709
707
|
|
710
708
|
connection_method: str
|
711
|
-
connection_parameters: Dict[str, StoredConfigurationValue] = None
|
712
|
-
connection_secrets: Dict[str, StoredConfigurationValue] = None
|
713
|
-
sync_parameters: Dict[str, StoredConfigurationValue] = None
|
714
|
-
current_form_parameters: Dict[str, StoredConfigurationValue] = None
|
715
|
-
currently_selected_streams: List[str] = None
|
709
|
+
connection_parameters: Optional[Dict[str, StoredConfigurationValue]] = Field(default=None)
|
710
|
+
connection_secrets: Optional[Dict[str, StoredConfigurationValue]] = Field(default=None)
|
711
|
+
sync_parameters: Optional[Dict[str, StoredConfigurationValue]] = Field(default=None)
|
712
|
+
current_form_parameters: Optional[Dict[str, StoredConfigurationValue]] = Field(default=None)
|
713
|
+
currently_selected_streams: Optional[List[str]] = Field(default=None)
|
716
714
|
|
717
715
|
|
718
716
|
class StoredJinjaTemplate(SubscriptableBaseModel):
|
@@ -722,7 +720,7 @@ class StoredJinjaTemplate(SubscriptableBaseModel):
|
|
722
720
|
"""
|
723
721
|
|
724
722
|
mapper_type: Literal["jinja_template"] = "jinja_template"
|
725
|
-
additional_column_expressions: Dict[str, str] = {}
|
723
|
+
additional_column_expressions: Dict[str, str] = Field(default={})
|
726
724
|
jinja_template: str
|
727
725
|
|
728
726
|
|
@@ -759,11 +757,11 @@ class SyncScheduleSnowflakeTask(SubscriptableBaseModel):
|
|
759
757
|
mode: Literal["snowflake_task"] = "snowflake_task"
|
760
758
|
sync_frequency: str
|
761
759
|
sync_frequency_name: Literal["1 min", "5 mins", "15 mins", "Hourly", "Daily","Custom"]
|
762
|
-
warehouse: str = None
|
760
|
+
warehouse: Optional[str] = Field(default=None)
|
763
761
|
time_limit_mins: int = 60 * 4
|
764
|
-
daily_hour: Optional[int] = None
|
765
|
-
daily_minute: Optional[int] = None
|
766
|
-
minute_of_hour: Optional[int] = None
|
762
|
+
daily_hour: Optional[int] = Field(default=None)
|
763
|
+
daily_minute: Optional[int] = Field(default=None)
|
764
|
+
minute_of_hour: Optional[int] = Field(default=None)
|
767
765
|
|
768
766
|
|
769
767
|
class SyncScheduleDbt(SubscriptableBaseModel):
|
{omnata_plugin_runtime-0.5.0a113 → omnata_plugin_runtime-0.5.2}/src/omnata_plugin_runtime/forms.py
RENAMED
@@ -41,10 +41,10 @@ class FormOption(SubscriptableBaseModel):
|
|
41
41
|
value: str
|
42
42
|
label: str
|
43
43
|
metadata: dict = Field(default_factory=dict)
|
44
|
-
required: bool = False
|
45
|
-
unique: bool = False
|
46
|
-
default: bool = False
|
47
|
-
disabled: bool = False
|
44
|
+
required: bool = Field(default=False)
|
45
|
+
unique: bool = Field(default=False)
|
46
|
+
default: bool = Field(default=False)
|
47
|
+
disabled: bool = Field(default=False)
|
48
48
|
data_type_icon: str = "unknown"
|
49
49
|
|
50
50
|
|
@@ -55,12 +55,12 @@ class FormInputField(SubscriptableBaseModel):
|
|
55
55
|
|
56
56
|
name: str
|
57
57
|
label: str
|
58
|
-
default_value: Union[str, bool] = ""
|
59
|
-
required: bool = False
|
60
|
-
depends_on: Optional[str] = None
|
61
|
-
help_text: str = ""
|
62
|
-
reload_on_change: bool = False
|
63
|
-
secret: bool = False
|
58
|
+
default_value: Union[str, bool] = Field(default="")
|
59
|
+
required: bool = Field(default=False)
|
60
|
+
depends_on: Optional[str] = Field(default=None)
|
61
|
+
help_text: str = Field(default="")
|
62
|
+
reload_on_change: bool = Field(default=False)
|
63
|
+
secret: bool = Field(default=False)
|
64
64
|
type: Literal["input"] = "input"
|
65
65
|
|
66
66
|
|
@@ -81,15 +81,15 @@ class FormTextAreaField(SubscriptableBaseModel):
|
|
81
81
|
|
82
82
|
name: str
|
83
83
|
label: str
|
84
|
-
default_value: str = ""
|
85
|
-
secret: bool = False
|
86
|
-
required: bool = False
|
87
|
-
depends_on: Optional[str] = None
|
88
|
-
help_text: str = ""
|
89
|
-
reload_on_change: bool = False
|
84
|
+
default_value: str = Field(default="")
|
85
|
+
secret: bool = Field(default=False)
|
86
|
+
required: bool = Field(default=False)
|
87
|
+
depends_on: Optional[str] = Field(default=None)
|
88
|
+
help_text: str = Field(default="")
|
89
|
+
reload_on_change: bool = Field(default=False)
|
90
90
|
type: Literal["textarea"] = "textarea"
|
91
91
|
|
92
|
-
variables: bool = False
|
92
|
+
variables: bool = Field(default=False)
|
93
93
|
|
94
94
|
class InformationField(SubscriptableBaseModel):
|
95
95
|
"""
|
@@ -101,10 +101,10 @@ class InformationField(SubscriptableBaseModel):
|
|
101
101
|
"""
|
102
102
|
name: str
|
103
103
|
markdown_content: str
|
104
|
-
depends_on: Optional[str] = None
|
104
|
+
depends_on: Optional[str] = Field(default=None)
|
105
105
|
type: Literal["information"] = "information"
|
106
|
-
reload_on_change: bool = False
|
107
|
-
secret: bool = False
|
106
|
+
reload_on_change: bool = Field(default=False)
|
107
|
+
secret: bool = Field(default=False)
|
108
108
|
|
109
109
|
class InformationBoxField(SubscriptableBaseModel):
|
110
110
|
"""
|
@@ -119,12 +119,12 @@ class InformationBoxField(SubscriptableBaseModel):
|
|
119
119
|
"""
|
120
120
|
name: str
|
121
121
|
markdown_content: str
|
122
|
-
depends_on: Optional[str] = None
|
122
|
+
depends_on: Optional[str] = Field(default=None)
|
123
123
|
type: Literal["information_box"] = "information_box"
|
124
|
-
reload_on_change: bool = False
|
124
|
+
reload_on_change: bool = Field(default=False)
|
125
125
|
box_type: Literal["info", "warning", "error"] = "info"
|
126
|
-
box_icon: Optional[str] = None
|
127
|
-
secret: bool = False
|
126
|
+
box_icon: Optional[str] = Field(default=None)
|
127
|
+
secret: bool = Field(default=False)
|
128
128
|
|
129
129
|
class FormSshKeypair(SubscriptableBaseModel):
|
130
130
|
"""
|
@@ -132,21 +132,21 @@ class FormSshKeypair(SubscriptableBaseModel):
|
|
132
132
|
"""
|
133
133
|
name: str
|
134
134
|
label: str
|
135
|
-
default_value: Optional[str] = None
|
136
|
-
required: bool = False
|
137
|
-
depends_on: Optional[str] = None
|
138
|
-
help_text: str = ""
|
135
|
+
default_value: Optional[str] = Field(default=None)
|
136
|
+
required: bool = Field(default=False)
|
137
|
+
depends_on: Optional[str] = Field(default=None)
|
138
|
+
help_text: str = Field(default="")
|
139
139
|
local_side: Literal["public", "private"] = "public"
|
140
140
|
"""
|
141
141
|
The side of the keypair which belongs to Snowflake. This value will be stored as the secret value, and the other side
|
142
142
|
can be copied/downloaded only during the connection process.
|
143
143
|
"""
|
144
|
-
allow_user_provided: bool = True
|
144
|
+
allow_user_provided: bool = Field(default=True)
|
145
145
|
"""
|
146
146
|
Allows the user to provide Snowflake's side of the keypair, for cases where one is generated on the outside
|
147
147
|
"""
|
148
148
|
type: Literal["ssh_keypair"] = "ssh_keypair"
|
149
|
-
secret: bool = True
|
149
|
+
secret: bool = Field(default=True)
|
150
150
|
|
151
151
|
class FormX509Certificate(SubscriptableBaseModel):
|
152
152
|
"""
|
@@ -155,12 +155,12 @@ class FormX509Certificate(SubscriptableBaseModel):
|
|
155
155
|
"""
|
156
156
|
name: str
|
157
157
|
label: str
|
158
|
-
default_value: Optional[str] = None
|
159
|
-
required: bool = False
|
160
|
-
depends_on: Optional[str] = None
|
161
|
-
help_text: str = ""
|
158
|
+
default_value: Optional[str] = Field(default=None)
|
159
|
+
required: bool = Field(default=False)
|
160
|
+
depends_on: Optional[str] = Field(default=None)
|
161
|
+
help_text: str = Field(default="")
|
162
162
|
type: Literal["x509_certificate"] = "x509_certificate"
|
163
|
-
secret: bool = True
|
163
|
+
secret: bool = Field(default=True)
|
164
164
|
|
165
165
|
class FormGpgKeypair(SubscriptableBaseModel):
|
166
166
|
"""
|
@@ -169,21 +169,21 @@ class FormGpgKeypair(SubscriptableBaseModel):
|
|
169
169
|
|
170
170
|
name: str
|
171
171
|
label: str
|
172
|
-
default_value: Optional[str] = None
|
173
|
-
required: bool = False
|
174
|
-
depends_on: Optional[str] = None
|
175
|
-
help_text: str = ""
|
172
|
+
default_value: Optional[str] = Field(default=None)
|
173
|
+
required: bool = Field(default=False)
|
174
|
+
depends_on: Optional[str] = Field(default=None)
|
175
|
+
help_text: str = Field(default="")
|
176
176
|
local_side: Literal["public", "private"] = "public"
|
177
177
|
"""
|
178
178
|
The side of the keypair which belongs to Snowflake. This value will be stored as the secret value, and the other side
|
179
179
|
can be copied/downloaded only during the connection process.
|
180
180
|
"""
|
181
|
-
allow_user_provided: bool = True
|
181
|
+
allow_user_provided: bool = Field(default=True)
|
182
182
|
"""
|
183
183
|
Allows the user to provide Snowflake's side of the keypair, for cases where one is generated on the outside
|
184
184
|
"""
|
185
185
|
type: Literal["gpg_keypair"] = "gpg_keypair"
|
186
|
-
secret: bool = True
|
186
|
+
secret: bool = Field(default=True)
|
187
187
|
|
188
188
|
|
189
189
|
class FormCheckboxField(SubscriptableBaseModel):
|
@@ -193,12 +193,12 @@ class FormCheckboxField(SubscriptableBaseModel):
|
|
193
193
|
|
194
194
|
name: str
|
195
195
|
label: str
|
196
|
-
default_value: bool = False
|
197
|
-
required: bool = False
|
198
|
-
secret: bool = False
|
199
|
-
depends_on: Optional[str] = None
|
200
|
-
help_text: str = ""
|
201
|
-
reload_on_change: bool = False
|
196
|
+
default_value: bool = Field(default=False)
|
197
|
+
required: bool = Field(default=False)
|
198
|
+
secret: bool = Field(default=False)
|
199
|
+
depends_on: Optional[str] = Field(default=None)
|
200
|
+
help_text: str = Field(default="")
|
201
|
+
reload_on_change: bool = Field(default=False)
|
202
202
|
type: Literal["checkbox"] = "checkbox"
|
203
203
|
|
204
204
|
|
@@ -209,17 +209,17 @@ class FormSliderField(SubscriptableBaseModel):
|
|
209
209
|
|
210
210
|
name: str
|
211
211
|
label: str
|
212
|
-
default_value: Optional[str] = None
|
213
|
-
secret: bool = False
|
214
|
-
required: bool = False
|
215
|
-
depends_on: Optional[str] = None
|
216
|
-
help_text: str = ""
|
217
|
-
reload_on_change: bool = False
|
212
|
+
default_value: Optional[str] = Field(default=None)
|
213
|
+
secret: bool = Field(default=False)
|
214
|
+
required: bool = Field(default=False)
|
215
|
+
depends_on: Optional[str] = Field(default=None)
|
216
|
+
help_text: str = Field(default="")
|
217
|
+
reload_on_change: bool = Field(default=False)
|
218
218
|
type: Literal["slider"] = "slider"
|
219
219
|
|
220
|
-
min_value: int = 0
|
221
|
-
max_value: int = 100
|
222
|
-
step_size: int = 1
|
220
|
+
min_value: int = Field(default=0)
|
221
|
+
max_value: int = Field(default=100)
|
222
|
+
step_size: int = Field(default=1)
|
223
223
|
|
224
224
|
|
225
225
|
class FormJinjaTemplate(SubscriptableBaseModel):
|
@@ -229,7 +229,7 @@ class FormJinjaTemplate(SubscriptableBaseModel):
|
|
229
229
|
|
230
230
|
mapper_type: Literal["jinja_template"] = "jinja_template"
|
231
231
|
label: str = "Jinja Template"
|
232
|
-
depends_on: Optional[str] = None
|
232
|
+
depends_on: Optional[str] = Field(default=None)
|
233
233
|
|
234
234
|
|
235
235
|
# ----------------------------------------------------------------------------
|
@@ -249,7 +249,7 @@ class StaticFormOptionsDataSource(SubscriptableBaseModel):
|
|
249
249
|
"""
|
250
250
|
|
251
251
|
values: List[FormOption] = Field(default_factory=list)
|
252
|
-
new_option_creator: Optional[NewOptionCreator] = None
|
252
|
+
new_option_creator: Optional[NewOptionCreator] = Field(default=None)
|
253
253
|
type: Literal["static"] = "static"
|
254
254
|
|
255
255
|
|
@@ -261,7 +261,7 @@ class DynamicFormOptionsDataSource(SubscriptableBaseModel):
|
|
261
261
|
source_function: Union[
|
262
262
|
Callable[[SyncConfigurationParameters], List[FormOption]], str
|
263
263
|
]
|
264
|
-
new_option_creator: Optional[NewOptionCreator] = None
|
264
|
+
new_option_creator: Optional[NewOptionCreator] = Field(default=None)
|
265
265
|
type: Literal["dynamic"] = "dynamic"
|
266
266
|
|
267
267
|
@validator("source_function", always=True)
|
@@ -299,12 +299,12 @@ class FormRadioField(FormFieldWithDataSource, BaseModel):
|
|
299
299
|
|
300
300
|
name: str
|
301
301
|
label: str
|
302
|
-
default_value: Optional[str] = None
|
303
|
-
required: bool = False
|
304
|
-
secret: bool = False
|
305
|
-
depends_on: Optional[str] = None
|
306
|
-
help_text: str = ""
|
307
|
-
reload_on_change: bool = False
|
302
|
+
default_value: Optional[str] = Field(default=None)
|
303
|
+
required: bool = Field(default=False)
|
304
|
+
secret: bool = Field(default=False)
|
305
|
+
depends_on: Optional[str] = Field(default=None)
|
306
|
+
help_text: str = Field(default="")
|
307
|
+
reload_on_change: bool = Field(default=False)
|
308
308
|
type: Literal["radio"] = "radio"
|
309
309
|
|
310
310
|
|
@@ -316,15 +316,15 @@ class FormDropdownField(FormFieldWithDataSource, BaseModel):
|
|
316
316
|
|
317
317
|
name: str
|
318
318
|
label: str
|
319
|
-
default_value: Optional[str] = None
|
320
|
-
required: bool = False
|
321
|
-
secret: bool = False
|
322
|
-
depends_on: Optional[str] = None
|
323
|
-
help_text: str = ""
|
324
|
-
reload_on_change: bool = False
|
319
|
+
default_value: Optional[str] = Field(default=None)
|
320
|
+
required: bool = Field(default=False)
|
321
|
+
secret: bool = Field(default=False)
|
322
|
+
depends_on: Optional[str] = Field(default=None)
|
323
|
+
help_text: str = Field(default="")
|
324
|
+
reload_on_change: bool = Field(default=False)
|
325
325
|
type: Literal["dropdown"] = "dropdown"
|
326
326
|
|
327
|
-
multi_select: bool = False
|
327
|
+
multi_select: bool = Field(default=False)
|
328
328
|
|
329
329
|
|
330
330
|
FormFieldBase = Annotated[
|
@@ -374,7 +374,7 @@ class NewOptionCreator(SubscriptableBaseModel):
|
|
374
374
|
construct_form_option: Union[
|
375
375
|
Callable[[StoredConfigurationValue], FormOption], str
|
376
376
|
]
|
377
|
-
allow_create: bool = True
|
377
|
+
allow_create: bool = Field(default=True)
|
378
378
|
|
379
379
|
@validator("creation_form_function", always=True)
|
380
380
|
def function_name_convertor(cls, v) -> str:
|
@@ -404,7 +404,7 @@ class FormFieldMappingSelector(FormFieldWithDataSource, BaseModel):
|
|
404
404
|
|
405
405
|
mapper_type: Literal["field_mapping_selector"] = "field_mapping_selector"
|
406
406
|
label: str = "Field Mappings"
|
407
|
-
depends_on: Optional[str] = None
|
407
|
+
depends_on: Optional[str] = Field(default=None)
|
408
408
|
|
409
409
|
|
410
410
|
Mapper = Annotated[
|
@@ -420,7 +420,7 @@ class OutboundSyncConfigurationForm(ConfigurationFormBase):
|
|
420
420
|
to map Snowflake columns to app fields/payloads.
|
421
421
|
"""
|
422
422
|
|
423
|
-
mapper: Optional[Mapper] = None
|
423
|
+
mapper: Optional[Mapper] = Field(default=None)
|
424
424
|
|
425
425
|
|
426
426
|
class InboundSyncConfigurationForm(ConfigurationFormBase):
|
@@ -436,24 +436,24 @@ class SecurityIntegrationTemplateAuthorizationCode(BaseModel):
|
|
436
436
|
Provides values used to populate a security integration instructions template, which
|
437
437
|
in turn allows the customer to create an OAuth based secret object
|
438
438
|
"""
|
439
|
-
oauth_docs_url: Optional[str] = None
|
439
|
+
oauth_docs_url: Optional[str] = Field(default=None)
|
440
440
|
oauth_grant: Literal["authorization_code"] = "authorization_code"
|
441
|
-
oauth_client_id: str = '<client id>'
|
442
|
-
oauth_client_secret: str = '<client secret>'
|
443
|
-
oauth_token_endpoint: str = '<token endpoint>'
|
444
|
-
oauth_authorization_endpoint: str = '<authorization endpoint>'
|
445
|
-
oauth_allowed_scopes: List[str] = []
|
441
|
+
oauth_client_id: str = Field(default='<client id>')
|
442
|
+
oauth_client_secret: str = Field(default='<client secret>')
|
443
|
+
oauth_token_endpoint: str = Field(default='<token endpoint>')
|
444
|
+
oauth_authorization_endpoint: str = Field(default='<authorization endpoint>')
|
445
|
+
oauth_allowed_scopes: List[str] = Field(default=[])
|
446
446
|
|
447
447
|
class SecurityIntegrationTemplateClientCredentials(BaseModel):
|
448
448
|
"""
|
449
449
|
Provides values used to populate a security integration instructions template, which
|
450
450
|
in turn allows the customer to create an OAuth based secret object
|
451
451
|
"""
|
452
|
-
oauth_docs_url: Optional[str] = None
|
452
|
+
oauth_docs_url: Optional[str] = Field(default=None)
|
453
453
|
oauth_grant: Literal["client_credentials"] = "client_credentials"
|
454
|
-
oauth_client_id: str = '<client id>'
|
455
|
-
oauth_client_secret: str = '<client secret>'
|
456
|
-
oauth_token_endpoint: str = '<token endpoint>'
|
454
|
+
oauth_client_id: str = Field(default='<client id>')
|
455
|
+
oauth_client_secret: str = Field(default='<client secret>')
|
456
|
+
oauth_token_endpoint: str = Field(default='<token endpoint>')
|
457
457
|
oauth_allowed_scopes: List[str] = []
|
458
458
|
|
459
459
|
SecurityIntegrationTemplate = Annotated[
|
@@ -465,7 +465,7 @@ class NGrokMTLSTunnel(SubscriptableBaseModel):
|
|
465
465
|
"""
|
466
466
|
Designates a ConnectionMethod as connecting via an ngrok tunnel.
|
467
467
|
"""
|
468
|
-
SupportEdgeTermination: bool = True
|
468
|
+
SupportEdgeTermination: bool = Field(default=True)
|
469
469
|
post_tunnel_fields_function: Union[
|
470
470
|
Callable[[ConnectionConfigurationParameters], List[FormFieldBase]], str
|
471
471
|
]
|
@@ -488,6 +488,6 @@ class ConnectionMethod(SubscriptableBaseModel):
|
|
488
488
|
|
489
489
|
name: str
|
490
490
|
fields: List[FormFieldBase]
|
491
|
-
oauth_template: Optional[SecurityIntegrationTemplate] = None
|
492
|
-
ngrok_tunnel_configuration: Optional[NGrokMTLSTunnel] = None
|
493
|
-
description: str = ""
|
491
|
+
oauth_template: Optional[SecurityIntegrationTemplate] = Field(default=None)
|
492
|
+
ngrok_tunnel_configuration: Optional[NGrokMTLSTunnel] = Field(default=None)
|
493
|
+
description: str = Field(default="")
|
@@ -32,6 +32,7 @@ from .omnata_plugin import (
|
|
32
32
|
OutboundSyncRequest,
|
33
33
|
DeadlineReachedException,
|
34
34
|
)
|
35
|
+
from pydantic import TypeAdapter
|
35
36
|
from .rate_limiting import ApiLimits, RateLimitState
|
36
37
|
|
37
38
|
# set the logger class to our custom logger so that pydantic errors are handled correctly
|
@@ -233,7 +234,7 @@ class PluginEntrypoint:
|
|
233
234
|
stream_errors=omnata_log_handler.stream_global_errors,
|
234
235
|
total_records_estimate=inbound_sync_request._total_records_estimate
|
235
236
|
)
|
236
|
-
return_dict["final_progress_update"] = final_progress_update.
|
237
|
+
return_dict["final_progress_update"] = final_progress_update.model_dump()
|
237
238
|
if inbound_sync_request.deadline_reached:
|
238
239
|
# if we actually hit the deadline, this is flagged by the cancellation checking worker and the cancellation
|
239
240
|
# token is set. We throw it here as an error since that's currently how it flows back to the engine with a DELAYED state
|
@@ -305,10 +306,10 @@ class PluginEntrypoint:
|
|
305
306
|
)
|
306
307
|
script_result = the_function(parameters)
|
307
308
|
if isinstance(script_result, BaseModel):
|
308
|
-
script_result = script_result.
|
309
|
+
script_result = script_result.model_dump()
|
309
310
|
elif isinstance(script_result, List):
|
310
311
|
if len(script_result) > 0 and isinstance(script_result[0], BaseModel):
|
311
|
-
script_result = [r.
|
312
|
+
script_result = [r.model_dump() for r in script_result]
|
312
313
|
return script_result
|
313
314
|
|
314
315
|
def inbound_list_streams(
|
@@ -341,10 +342,10 @@ class PluginEntrypoint:
|
|
341
342
|
|
342
343
|
script_result = self._plugin_instance.inbound_stream_list(parameters)
|
343
344
|
if isinstance(script_result, BaseModel):
|
344
|
-
script_result = script_result.
|
345
|
+
script_result = script_result.model_dump()
|
345
346
|
elif isinstance(script_result, List):
|
346
347
|
if len(script_result) > 0 and isinstance(script_result[0], BaseModel):
|
347
|
-
script_result = [r.
|
348
|
+
script_result = [r.model_dump() for r in script_result]
|
348
349
|
return script_result
|
349
350
|
|
350
351
|
|
@@ -365,17 +366,17 @@ class PluginEntrypoint:
|
|
365
366
|
script_result = the_function(stored_value)
|
366
367
|
if not isinstance(script_result, FormOption):
|
367
368
|
raise ValueError(f"Expected a FormOption from function {function_name}, got {type(script_result)}")
|
368
|
-
results.append(script_result.
|
369
|
+
results.append(script_result.model_dump())
|
369
370
|
return results
|
370
371
|
|
371
372
|
def connection_form(self):
|
372
373
|
logger.info("Entered connection_form method")
|
373
374
|
form: List[ConnectionMethod] = self._plugin_instance.connection_form()
|
374
|
-
return [f.
|
375
|
+
return [f.model_dump() for f in form]
|
375
376
|
|
376
377
|
def create_billing_events(self, session, event_request: Dict):
|
377
378
|
logger.info("Entered create_billing_events method")
|
378
|
-
request = BillingEventRequest.
|
379
|
+
request = TypeAdapter(BillingEventRequest).validate_python(event_request)
|
379
380
|
events: List[SnowflakeBillingEvent] = self._plugin_instance.create_billing_events(
|
380
381
|
request
|
381
382
|
)
|
@@ -408,7 +409,7 @@ class PluginEntrypoint:
|
|
408
409
|
logger.warn('Billing event creation failed due to running internally to Omnata')
|
409
410
|
else:
|
410
411
|
raise e
|
411
|
-
return [e.
|
412
|
+
return [e.model_dump() for e in events]
|
412
413
|
|
413
414
|
def get_secrets(
|
414
415
|
self, oauth_secret_name: Optional[str], other_secrets_name: Optional[str]
|
@@ -461,7 +462,7 @@ class PluginEntrypoint:
|
|
461
462
|
script_result = the_function(parameters)
|
462
463
|
if isinstance(script_result, List):
|
463
464
|
if len(script_result) > 0 and isinstance(script_result[0], BaseModel):
|
464
|
-
script_result = [r.
|
465
|
+
script_result = [r.model_dump() for r in script_result]
|
465
466
|
else:
|
466
467
|
raise ValueError(f"Expected a List from function {function_name}, got {type(script_result)}")
|
467
468
|
return script_result
|
@@ -531,7 +532,7 @@ class PluginEntrypoint:
|
|
531
532
|
f"alter network rule {network_rule_name} set value_list = ({rule_values_string})"
|
532
533
|
).collect()
|
533
534
|
|
534
|
-
return connect_response.
|
535
|
+
return connect_response.model_dump()
|
535
536
|
|
536
537
|
def api_limits(self,
|
537
538
|
method:str,
|
@@ -564,7 +565,7 @@ class PluginEntrypoint:
|
|
564
565
|
# There's a bit of parsing here that could possibly be done outside of the handler function, but this shouldn't be too expensive
|
565
566
|
sync_parameters: Dict[str, StoredConfigurationValue] = TypeAdapter(
|
566
567
|
Dict[str, StoredConfigurationValue]).validate_python(sync_parameters)
|
567
|
-
field_mappings: StoredMappingValue = StoredMappingValue.
|
568
|
+
field_mappings: StoredMappingValue = TypeAdapter(StoredMappingValue).validate_python(field_mappings)
|
568
569
|
return self._plugin_instance.outbound_record_validator(
|
569
570
|
sync_parameters, field_mappings, transformed_record, source_types
|
570
571
|
)
|
@@ -178,10 +178,9 @@ class RateLimitState(SubscriptableBaseModel):
|
|
178
178
|
[],
|
179
179
|
description="A list of timestamps where previous requests have been made, used to calculate the next request time",
|
180
180
|
)
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
)
|
181
|
+
# can't set this as a class variable because it's not serializable
|
182
|
+
# TODO: probably shouldn't mix models with functionality like this
|
183
|
+
_request_timestamps_lock: Optional[threading.Lock] = None
|
185
184
|
|
186
185
|
@field_serializer('wait_until',when_used='always')
|
187
186
|
def serialize_wait_until(self, value:Optional[datetime.datetime]) -> Optional[int]:
|
@@ -253,6 +252,8 @@ class RateLimitState(SubscriptableBaseModel):
|
|
253
252
|
You only need to use this if your HTTP requests are not automatically being
|
254
253
|
registered, which happens if http.client.HTTPConnection is not being used.
|
255
254
|
"""
|
255
|
+
if self._request_timestamps_lock is None:
|
256
|
+
self._request_timestamps_lock = threading.Lock()
|
256
257
|
with self._request_timestamps_lock:
|
257
258
|
append_time = datetime.datetime.now(datetime.timezone.utc)
|
258
259
|
if self.previous_request_timestamps is None:
|
File without changes
|
File without changes
|
File without changes
|
{omnata_plugin_runtime-0.5.0a113 → omnata_plugin_runtime-0.5.2}/src/omnata_plugin_runtime/api.py
RENAMED
File without changes
|
{omnata_plugin_runtime-0.5.0a113 → omnata_plugin_runtime-0.5.2}/src/omnata_plugin_runtime/logging.py
RENAMED
File without changes
|
File without changes
|