omnata-plugin-runtime 0.5.7a152__tar.gz → 0.5.7a154__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omnata-plugin-runtime
3
- Version: 0.5.7a152
3
+ Version: 0.5.7a154
4
4
  Summary: Classes and common runtime components for building and running Omnata Plugins
5
5
  Author: James Weakley
6
6
  Author-email: james.weakley@omnata.com
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "omnata-plugin-runtime"
3
- version = "0.5.7-a152"
3
+ version = "0.5.7-a154"
4
4
  description = "Classes and common runtime components for building and running Omnata Plugins"
5
5
  authors = ["James Weakley <james.weakley@omnata.com>"]
6
6
  readme = "README.md"
@@ -39,7 +39,6 @@ import jinja2
39
39
  import pandas
40
40
  from pydantic_core import to_jsonable_python
41
41
  from pydantic import Field, TypeAdapter, ValidationError, create_model, root_validator, BaseModel
42
- from pydantic.dataclasses import dataclass
43
42
  from dateutil.parser import parse
44
43
  from jinja2 import Environment
45
44
  from snowflake.connector.pandas_tools import write_pandas
@@ -128,6 +127,8 @@ class PluginInfo(BaseModel):
128
127
  Setting this to 'partner' means that the plugin was developed and distributed by a partner.
129
128
  All other values only carry meaning for Omnata plugins, to indicate which iconography to apply within the application.
130
129
  :param str package_source: Whether the plugin is packaged as a function or a stage
130
+ :param List[UDFDefinition] consumer_udfs: A list of UDFs that the plugin exposes to consumers
131
+ :param List[UDTFDefinition] consumer_udtfs: A list of UDTFs that the plugin exposes to consumers
131
132
  """
132
133
 
133
134
  manifest: PluginManifest
@@ -140,6 +141,8 @@ class PluginInfo(BaseModel):
140
141
  plugin_devkit_version: str = 'unknown'
141
142
  tier: str
142
143
  package_source: Literal["function", "stage"]
144
+ consumer_udfs: List[UDFDefinition] = Field(default_factory=list)
145
+ consumer_udtfs: List[UDTFDefinition] = Field(default_factory=list)
143
146
 
144
147
 
145
148
  def jinja_filter(func):
@@ -2231,8 +2234,7 @@ def get_nested_value(nested_dict:Dict, keys:List[str]):
2231
2234
  return reduce(lambda d, key: d.get(key) if isinstance(d, dict) else None, keys, nested_dict)
2232
2235
 
2233
2236
 
2234
- @dataclass
2235
- class SnowflakeFunctionParameter:
2237
+ class SnowflakeFunctionParameter(BaseModel):
2236
2238
  """
2237
2239
  Represents a parameter for a Snowflake UDF or UDTF
2238
2240
  """
@@ -2246,8 +2248,7 @@ class SnowflakeFunctionParameter:
2246
2248
  return f"{self.name} {self.data_type} default {self.default_value_clause}"
2247
2249
  return f"{self.name} {self.data_type}"
2248
2250
 
2249
- @dataclass
2250
- class SnowflakeUDTFResultColumn:
2251
+ class SnowflakeUDTFResultColumn(BaseModel):
2251
2252
  """
2252
2253
  Represents a result column for a Snowflake UDTF
2253
2254
  """
@@ -2256,49 +2257,21 @@ class SnowflakeUDTFResultColumn:
2256
2257
  def __str__(self):
2257
2258
  return f"{self.name} {self.data_type}"
2258
2259
 
2259
- @dataclass
2260
- class PythonUDTFDefinition:
2260
+ class UDTFDefinition(BaseModel):
2261
2261
  """
2262
2262
  The information needed by the plugin uploader to put a Python UDTF definition into the setup script.
2263
2263
  Do not use this class directly in plugins, instead use the omnata_udtf decorator.
2264
2264
  """
2265
- name: str
2266
- description: str
2267
- params: List[SnowflakeFunctionParameter]
2268
- result_columns: List[SnowflakeUDTFResultColumn]
2269
- handler: str
2270
- expose_to_consumer: bool
2271
- packages: Optional[List[str]] = None
2272
-
2273
- def __str__(self):
2274
- param_str = ', '.join([str(param) for param in self.params])
2275
- table_result_columns = ', '.join([f"{col.name} {col.data_type}" for col in self.result_columns])
2276
- packages_str = ', '.join([f"'{p}'" for p in self.packages])
2277
- return f"""CREATE OR REPLACE FUNCTION UDFS.{self.name}({param_str})
2278
- RETURNS TABLE({table_result_columns})
2279
- LANGUAGE PYTHON
2280
- RUNTIME_VERSION=3.10
2281
- COMMENT = $${self.description}$$
2282
- PACKAGES = ({packages_str})
2283
- IMPORTS = ('/app.zip')
2284
- HANDLER='{self.handler}';
2285
- """
2286
-
2287
- @dataclass
2288
- class JavaUDTFDefinition:
2289
- """
2290
- The information needed by the plugin uploader to put a Java UDTF definition into the setup script.
2291
- These are created directly in python, since we don't want the omnata cli to need to do any Java reflection.
2292
- Any .jar files placed in the udf_direct_imports directory will be uploaded to the stage and can be
2293
- added to the imports parameter as (e.g.) '/my_jar.jar'.
2294
- """
2295
- name: str
2296
- description: str
2297
- params: List[SnowflakeFunctionParameter]
2298
- result_columns: List[SnowflakeUDTFResultColumn]
2299
- packages: List[str]
2300
- imports: List[str]
2301
- handler: str
2265
+ name: str = Field(..., title="The name of the UDTF")
2266
+ language: Literal['python','java'] = Field(..., title="The language of the UDF")
2267
+ runtime_version: str = Field(..., title="The runtime version of the UDF (language dependent)")
2268
+ description: str = Field(..., title="A description of the UDTF")
2269
+ params: List[SnowflakeFunctionParameter] = Field(..., title="The parameters of the UDTF")
2270
+ result_columns: List[SnowflakeUDTFResultColumn] = Field(..., title="The result columns of the UDTF")
2271
+ handler: str = Field(..., title="The handler class/function for the UDTF")
2272
+ expose_to_consumer: bool = Field(..., title="Whether the UDTF should be exposed to consumers")
2273
+ imports: Optional[List[str]] = Field(None, title="A list of imports required by the UDF")
2274
+ packages: Optional[List[str]] = Field(None, title="A list of packages required by the UDTF")
2302
2275
 
2303
2276
  def __str__(self):
2304
2277
  param_str = ', '.join([str(param) for param in self.params])
@@ -2307,54 +2280,29 @@ class JavaUDTFDefinition:
2307
2280
  imports_str = ', '.join([f"'{i}'" for i in self.imports])
2308
2281
  return f"""CREATE OR REPLACE FUNCTION UDFS.{self.name}({param_str})
2309
2282
  RETURNS TABLE({table_result_columns})
2310
- LANGUAGE PYTHON
2311
- RUNTIME_VERSION=3.10
2283
+ LANGUAGE {self.language.upper()}
2284
+ RUNTIME_VERSION={self.runtime_version}
2312
2285
  COMMENT = $${self.description}$$
2313
2286
  PACKAGES = ({packages_str})
2314
2287
  IMPORTS = ({imports_str})
2315
2288
  HANDLER='{self.handler}';
2316
2289
  """
2317
2290
 
2318
- @dataclass
2319
- class PythonUDFDefinition:
2291
+ class UDFDefinition(BaseModel):
2320
2292
  """
2321
2293
  The information needed by the plugin uploader to put a Python UDF definition into the setup script.
2322
2294
  Do not use this class directly in plugins, instead use the omnata_udf decorator.
2323
2295
  """
2324
- name: str
2325
- description: str
2326
- params: List[SnowflakeFunctionParameter]
2327
- result_data_type: str
2328
- handler: str
2329
- expose_to_consumer: bool
2330
- packages: Optional[List[str]] = None
2331
-
2332
- def __str__(self):
2333
- param_str = ', '.join([str(param) for param in self.params])
2334
- packages_str = ', '.join([f"'{p}'" for p in self.packages])
2335
- return f"""CREATE OR REPLACE FUNCTION UDFS.{self.name}({param_str})
2336
- RETURNS {self.result_data_type}
2337
- LANGUAGE PYTHON
2338
- RUNTIME_VERSION=3.10
2339
- COMMENT = $${self.description}$$
2340
- PACKAGES = ({packages_str})
2341
- IMPORTS = ('/app.zip')
2342
- HANDLER='{self.handler}';
2343
- """
2344
-
2345
- @dataclass
2346
- class JavaUDFDefinition:
2347
- """
2348
- The information needed by the plugin uploader to put a java UDF definition into the setup script.
2349
- """
2350
- name: str
2351
- description: str
2352
- params: List[SnowflakeFunctionParameter]
2353
- result_data_type: str
2354
- packages: List[str]
2355
- imports: List[str]
2356
- handler: str
2357
- expose_to_consumer: bool
2296
+ name: str = Field(..., title="The name of the UDF")
2297
+ language: Literal['python','java'] = Field(..., title="The language of the UDF")
2298
+ runtime_version: str = Field(..., title="The runtime version of the UDF (language dependent)")
2299
+ description: str = Field(..., title="A description of the UDF")
2300
+ params: List[SnowflakeFunctionParameter] = Field(..., title="The parameters of the UDF")
2301
+ result_data_type: str = Field(..., title="The data type returned by the UDF")
2302
+ handler: str = Field(..., title="The handler class/function for the UDF")
2303
+ expose_to_consumer: bool = Field(..., title="Whether the UDF should be exposed to consumers")
2304
+ imports: Optional[List[str]] = Field(None, title="A list of imports required by the UDF")
2305
+ packages: Optional[List[str]] = Field(None, title="A list of packages required by the UDF")
2358
2306
 
2359
2307
  def __str__(self):
2360
2308
  param_str = ', '.join([str(param) for param in self.params])
@@ -2362,8 +2310,8 @@ class JavaUDFDefinition:
2362
2310
  imports_str = ', '.join([f"'{i}'" for i in self.imports])
2363
2311
  return f"""CREATE OR REPLACE FUNCTION UDFS.{self.name}({param_str})
2364
2312
  RETURNS {self.result_data_type}
2365
- LANGUAGE PYTHON
2366
- RUNTIME_VERSION=3.10
2313
+ LANGUAGE {self.language.upper()}
2314
+ RUNTIME_VERSION={self.runtime_version}
2367
2315
  COMMENT = $${self.description}$$
2368
2316
  PACKAGES = ({packages_str})
2369
2317
  IMPORTS = ({imports_str})
@@ -2447,7 +2395,7 @@ def omnata_udtf(
2447
2395
 
2448
2396
  return class_decorator
2449
2397
 
2450
- def find_udtf_classes(path:str = '.') -> List[PythonUDTFDefinition | JavaUDTFDefinition]:
2398
+ def find_udtf_classes(path:str = '.') -> List[UDTFDefinition]:
2451
2399
  """
2452
2400
  Finds all classes in the specified directory which have the 'omnata_udtf' decorator applied
2453
2401
  """
@@ -2466,15 +2414,16 @@ def find_udtf_classes(path:str = '.') -> List[PythonUDTFDefinition | JavaUDTFDef
2466
2414
  for name, obj in inspect.getmembers(module, inspect.isclass):
2467
2415
  # Check if the class has the specified attribute
2468
2416
  if hasattr(obj, '_is_omnata_udtf'):
2469
- matching_classes.append(PythonUDTFDefinition(
2417
+ matching_classes.append(UDTFDefinition(
2470
2418
  name=obj._omnata_udtf_name,
2419
+
2471
2420
  description=obj._omnata_udtf_description,
2472
2421
  params=obj._omnata_udtf_params,
2473
2422
  result_columns=obj._omnata_udtf_result_columns,
2474
2423
  expose_to_consumer=obj._omnata_udtf_expose_to_consumer,
2475
2424
  handler=obj.__module__+'.'+obj.__name__
2476
2425
  ))
2477
- elif isinstance(obj, JavaUDTFDefinition):
2426
+ elif isinstance(obj, UDTFDefinition) and cast(UDTFDefinition,obj).language == 'java':
2478
2427
  matching_classes.append(obj)
2479
2428
 
2480
2429
  return matching_classes
@@ -2547,7 +2496,7 @@ def omnata_udf(
2547
2496
 
2548
2497
  return decorator
2549
2498
 
2550
- def find_udf_functions(path:str = '.') -> List[PythonUDFDefinition | JavaUDFDefinition]:
2499
+ def find_udf_functions(path:str = '.') -> List[UDFDefinition]:
2551
2500
  """
2552
2501
  Finds all functions in the specified directory which have the 'omnata_udf' decorator applied
2553
2502
  """
@@ -2566,8 +2515,11 @@ def find_udf_functions(path:str = '.') -> List[PythonUDFDefinition | JavaUDFDefi
2566
2515
  for name, obj in inspect.getmembers(module, inspect.isfunction):
2567
2516
  # Check if the class has the specified attribute
2568
2517
  if hasattr(obj, '_is_omnata_udf'):
2569
- matching_classes.append(PythonUDFDefinition(
2518
+ matching_classes.append(UDFDefinition(
2570
2519
  name=obj._omnata_udf_name,
2520
+ language='python',
2521
+ runtime_version='3.10',
2522
+ imports=['/app.zip'],
2571
2523
  description=obj._omnata_udf_description,
2572
2524
  params=obj._omnata_udf_params,
2573
2525
  result_data_type=obj._omnata_udf_result_data_type,
@@ -2575,7 +2527,7 @@ def find_udf_functions(path:str = '.') -> List[PythonUDFDefinition | JavaUDFDefi
2575
2527
  packages=[],
2576
2528
  handler=obj.__module__+'.'+obj.__name__
2577
2529
  ))
2578
- elif isinstance(obj, JavaUDFDefinition):
2530
+ elif isinstance(obj, UDFDefinition) and cast(UDFDefinition,obj).language == 'java':
2579
2531
  matching_classes.append(obj)
2580
2532
 
2581
2533
  return matching_classes