omnata-plugin-runtime 0.5.0a113__py3-none-any.whl → 0.5.2__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.
- omnata_plugin_runtime/configuration.py +56 -58
- omnata_plugin_runtime/forms.py +89 -89
- omnata_plugin_runtime/plugin_entrypoints.py +13 -12
- omnata_plugin_runtime/rate_limiting.py +5 -4
- {omnata_plugin_runtime-0.5.0a113.dist-info → omnata_plugin_runtime-0.5.2.dist-info}/METADATA +1 -1
- omnata_plugin_runtime-0.5.2.dist-info/RECORD +12 -0
- omnata_plugin_runtime-0.5.0a113.dist-info/RECORD +0 -12
- {omnata_plugin_runtime-0.5.0a113.dist-info → omnata_plugin_runtime-0.5.2.dist-info}/LICENSE +0 -0
- {omnata_plugin_runtime-0.5.0a113.dist-info → omnata_plugin_runtime-0.5.2.dist-info}/WHEEL +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/forms.py
CHANGED
@@ -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:
|
@@ -0,0 +1,12 @@
|
|
1
|
+
omnata_plugin_runtime/__init__.py,sha256=MS9d1whnfT_B3-ThqZ7l63QeC_8OEKTuaYV5wTwRpBA,1576
|
2
|
+
omnata_plugin_runtime/api.py,sha256=FxzTqri4no8ClkOm7vZADG8aD47jcGBCTTQDEORmOJM,6326
|
3
|
+
omnata_plugin_runtime/configuration.py,sha256=4eKYhw6_l-RUVUwNU5NlTpPwL7xZRs6VLaCKf8OIKuY,36420
|
4
|
+
omnata_plugin_runtime/forms.py,sha256=42o3DJnnxJ-W92pNaF5MuawvDPUK5O0azvn80HDxTZM,19744
|
5
|
+
omnata_plugin_runtime/logging.py,sha256=bn7eKoNWvtuyTk7RTwBS9UARMtqkiICtgMtzq3KA2V0,3272
|
6
|
+
omnata_plugin_runtime/omnata_plugin.py,sha256=zIk8dS5m4pXsVy_2im-Cd-t1uQV9hf1seosb1T2jGGs,110880
|
7
|
+
omnata_plugin_runtime/plugin_entrypoints.py,sha256=JirYUbPBaN0UMh9t_uAHDdhaQZ7NUhdMJ11eHRKOoNY,29302
|
8
|
+
omnata_plugin_runtime/rate_limiting.py,sha256=DVQ_bc-mVLBkrU1PTns1MWXhHiLpSB5HkWCcdePtJ2A,25611
|
9
|
+
omnata_plugin_runtime-0.5.2.dist-info/LICENSE,sha256=IMF9i4xIpgCADf0U-V1cuf9HBmqWQd3qtI3FSuyW4zE,26526
|
10
|
+
omnata_plugin_runtime-0.5.2.dist-info/METADATA,sha256=RlhKCVUmdUudXbUqZTcZnN1n4Ta2tSQrc9Gt6Yh1yTY,1884
|
11
|
+
omnata_plugin_runtime-0.5.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
12
|
+
omnata_plugin_runtime-0.5.2.dist-info/RECORD,,
|
@@ -1,12 +0,0 @@
|
|
1
|
-
omnata_plugin_runtime/__init__.py,sha256=MS9d1whnfT_B3-ThqZ7l63QeC_8OEKTuaYV5wTwRpBA,1576
|
2
|
-
omnata_plugin_runtime/api.py,sha256=FxzTqri4no8ClkOm7vZADG8aD47jcGBCTTQDEORmOJM,6326
|
3
|
-
omnata_plugin_runtime/configuration.py,sha256=LvQVIKwo8XlfHf-9Jkj1GDH0U6sOKDKi3IMDyAwAnHE,35781
|
4
|
-
omnata_plugin_runtime/forms.py,sha256=hV6jVaizex20Pb9NxPx11TBPK-Yy8pREAnTtCxHo4Qo,18409
|
5
|
-
omnata_plugin_runtime/logging.py,sha256=bn7eKoNWvtuyTk7RTwBS9UARMtqkiICtgMtzq3KA2V0,3272
|
6
|
-
omnata_plugin_runtime/omnata_plugin.py,sha256=zIk8dS5m4pXsVy_2im-Cd-t1uQV9hf1seosb1T2jGGs,110880
|
7
|
-
omnata_plugin_runtime/plugin_entrypoints.py,sha256=xlPTI25N5G3l0bRFSkga98TIHM44NRaN2g7T5jSsqX0,29181
|
8
|
-
omnata_plugin_runtime/rate_limiting.py,sha256=BzN8CkI8dxel1PERDpuSZek7vo6QeCHwbZEtcO21IR4,25479
|
9
|
-
omnata_plugin_runtime-0.5.0a113.dist-info/LICENSE,sha256=IMF9i4xIpgCADf0U-V1cuf9HBmqWQd3qtI3FSuyW4zE,26526
|
10
|
-
omnata_plugin_runtime-0.5.0a113.dist-info/METADATA,sha256=Y5WpUCj7G4AHMfwIkzlFqgk9OEHdesZ4tWREqMKfGYQ,1888
|
11
|
-
omnata_plugin_runtime-0.5.0a113.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
12
|
-
omnata_plugin_runtime-0.5.0a113.dist-info/RECORD,,
|
File without changes
|
File without changes
|