omnata-plugin-runtime 0.3.23a68__tar.gz → 0.3.24__tar.gz
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-0.3.23a68 → omnata_plugin_runtime-0.3.24}/PKG-INFO +1 -1
- {omnata_plugin_runtime-0.3.23a68 → omnata_plugin_runtime-0.3.24}/pyproject.toml +1 -1
- {omnata_plugin_runtime-0.3.23a68 → omnata_plugin_runtime-0.3.24}/src/omnata_plugin_runtime/omnata_plugin.py +46 -37
- {omnata_plugin_runtime-0.3.23a68 → omnata_plugin_runtime-0.3.24}/LICENSE +0 -0
- {omnata_plugin_runtime-0.3.23a68 → omnata_plugin_runtime-0.3.24}/README.md +0 -0
- {omnata_plugin_runtime-0.3.23a68 → omnata_plugin_runtime-0.3.24}/src/omnata_plugin_runtime/__init__.py +0 -0
- {omnata_plugin_runtime-0.3.23a68 → omnata_plugin_runtime-0.3.24}/src/omnata_plugin_runtime/api.py +0 -0
- {omnata_plugin_runtime-0.3.23a68 → omnata_plugin_runtime-0.3.24}/src/omnata_plugin_runtime/configuration.py +0 -0
- {omnata_plugin_runtime-0.3.23a68 → omnata_plugin_runtime-0.3.24}/src/omnata_plugin_runtime/forms.py +0 -0
- {omnata_plugin_runtime-0.3.23a68 → omnata_plugin_runtime-0.3.24}/src/omnata_plugin_runtime/logging.py +0 -0
- {omnata_plugin_runtime-0.3.23a68 → omnata_plugin_runtime-0.3.24}/src/omnata_plugin_runtime/plugin_entrypoints.py +0 -0
- {omnata_plugin_runtime-0.3.23a68 → omnata_plugin_runtime-0.3.24}/src/omnata_plugin_runtime/rate_limiting.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "omnata-plugin-runtime"
|
3
|
-
version = "0.3.
|
3
|
+
version = "0.3.24"
|
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"
|
@@ -1261,7 +1261,7 @@ class InboundSyncRequest(SyncRequest):
|
|
1261
1261
|
)
|
1262
1262
|
]
|
1263
1263
|
|
1264
|
-
def get_hash(keys:List[str]) -> str:
|
1264
|
+
def get_hash(self, keys:List[str]) -> str:
|
1265
1265
|
"""
|
1266
1266
|
Creates a hash from a list of keys.
|
1267
1267
|
The function will join the keys with an underscore and then create a
|
@@ -1823,30 +1823,40 @@ def managed_outbound_processing(concurrency: int, batch_size: int):
|
|
1823
1823
|
def actual_decorator(method):
|
1824
1824
|
@wraps(method)
|
1825
1825
|
def _impl(self: OmnataPlugin, *method_args, **method_kwargs):
|
1826
|
+
logger.info(f"managed_outbound_processing invoked with {len(method_args)} positional arguments and {len(method_kwargs)} named arguments ({','.join(method_kwargs.keys())})")
|
1826
1827
|
if self._sync_request is None: # pylint: disable=protected-access
|
1827
1828
|
raise ValueError(
|
1828
1829
|
"To use the managed_outbound_processing decorator, you must attach a sync request to the plugin instance (via the _sync_request property)"
|
1829
1830
|
)
|
1830
|
-
# if self._sync_request.api_limits is None:
|
1831
|
-
# raise ValueError('To use the managed_outbound_processing decorator, API constraints must be defined. These can be provided in the response to the connect method')
|
1832
1831
|
logger.info(f"Batch size: {batch_size}. Concurrency: {concurrency}")
|
1833
|
-
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
1839
|
-
|
1840
|
-
|
1841
|
-
|
1842
|
-
|
1843
|
-
|
1844
|
-
|
1845
|
-
|
1846
|
-
)
|
1832
|
+
|
1833
|
+
dataframe_arg = None
|
1834
|
+
if 'dataframe' in method_kwargs:
|
1835
|
+
dataframe_arg = method_kwargs['dataframe']
|
1836
|
+
del method_kwargs['dataframe']
|
1837
|
+
if dataframe_arg.__class__.__name__ != "DataFrame":
|
1838
|
+
raise ValueError(
|
1839
|
+
f"The 'dataframe' named argument to the @managed_outbound_processing must be a DataFrame. Instead, a {dataframe_arg.__class__.__name__} was provided."
|
1840
|
+
)
|
1841
|
+
|
1842
|
+
elif 'dataframe_generator' in method_kwargs:
|
1843
|
+
dataframe_arg = method_kwargs['dataframe_generator']
|
1844
|
+
del method_kwargs['dataframe_generator']
|
1845
|
+
if not hasattr(dataframe_arg, "__next__"):
|
1846
|
+
raise ValueError(
|
1847
|
+
f"The 'dataframe_generator' named argument to the @managed_outbound_processing must be an iterator function. Instead, a {dataframe_arg.__class__.__name__} was provided."
|
1848
|
+
)
|
1849
|
+
# if the dataframe was provided as the first argument, we'll use that
|
1850
|
+
if dataframe_arg is None and len(method_args) > 0:
|
1851
|
+
dataframe_arg = method_args[0]
|
1852
|
+
if dataframe_arg.__class__.__name__ != "DataFrame" and not hasattr(dataframe_arg, "__next__"):
|
1853
|
+
raise ValueError(
|
1854
|
+
f"The first argument to a @managed_outbound_processing method must be a DataFrame or DataFrame generator (from outbound_sync_request.get_records). Instead, a {first_arg.__class__.__name__} was provided. Alternatively, you can provide these via the 'dataframe' or 'dataframe_generator' named arguments."
|
1855
|
+
)
|
1856
|
+
method_args = method_args[1:]
|
1847
1857
|
|
1848
1858
|
# put the record iterator on the queue, ready for the first task to read it
|
1849
|
-
fixed_size_generator = FixedSizeGenerator(
|
1859
|
+
fixed_size_generator = FixedSizeGenerator(dataframe_arg, batch_size=batch_size)
|
1850
1860
|
tasks:List[threading.Thread] = []
|
1851
1861
|
logger.info(f"Creating {concurrency} worker(s) for applying records")
|
1852
1862
|
# just in case
|
@@ -1862,7 +1872,7 @@ def managed_outbound_processing(concurrency: int, batch_size: int):
|
|
1862
1872
|
i,
|
1863
1873
|
fixed_size_generator,
|
1864
1874
|
self._sync_request._thread_cancellation_token,
|
1865
|
-
method_args
|
1875
|
+
method_args,
|
1866
1876
|
method_kwargs,
|
1867
1877
|
),
|
1868
1878
|
)
|
@@ -1923,7 +1933,7 @@ def __managed_inbound_processing_worker(
|
|
1923
1933
|
while not cancellation_token.is_set():
|
1924
1934
|
# Get our generator object out of the queue
|
1925
1935
|
logger.info(
|
1926
|
-
f"worker {worker_index} processing. Cancelled: {cancellation_token.is_set()}"
|
1936
|
+
f"worker {worker_index} processing. Cancelled: {cancellation_token.is_set()}. Method args: {len(method_args)}. Method kwargs: {len(method_kwargs.keys())} ({','.join(method_kwargs.keys())})"
|
1927
1937
|
)
|
1928
1938
|
try:
|
1929
1939
|
stream: StoredStreamConfiguration = streams_queue.get_nowait()
|
@@ -1982,27 +1992,26 @@ def managed_inbound_processing(concurrency: int):
|
|
1982
1992
|
raise ValueError(
|
1983
1993
|
"To use the managed_inbound_processing decorator, you must attach an apply request to the plugin instance (via the _sync_request property)"
|
1984
1994
|
)
|
1985
|
-
|
1995
|
+
logger.info(f"managed_inbound_processing invoked with {len(method_args)} positional arguments and {len(method_kwargs)} named arguments ({','.join(method_kwargs.keys())})")
|
1986
1996
|
if self._sync_request.development_mode is True:
|
1987
1997
|
concurrency_to_use = 1 # disable concurrency when running in development mode, it interferes with pyvcr
|
1988
1998
|
else:
|
1989
1999
|
concurrency_to_use = concurrency
|
1990
|
-
|
1991
|
-
|
1992
|
-
|
1993
|
-
|
1994
|
-
|
1995
|
-
)
|
1996
|
-
|
1997
|
-
|
1998
|
-
|
1999
|
-
|
2000
|
-
|
2001
|
-
|
2002
|
-
|
2003
|
-
)
|
2000
|
+
stream_list_arg: List[StoredStreamConfiguration] = None
|
2001
|
+
if 'streams' in method_kwargs:
|
2002
|
+
stream_list_arg = cast(List[StoredStreamConfiguration],method_kwargs['streams'])
|
2003
|
+
del method_kwargs['streams']
|
2004
|
+
if stream_list_arg is None and len(method_args) > 0:
|
2005
|
+
stream_list_arg = cast(List[StoredStreamConfiguration],method_args[0])
|
2006
|
+
if stream_list_arg.__class__.__name__ != "list":
|
2007
|
+
raise ValueError(
|
2008
|
+
f"The first argument to a @managed_inbound_processing method must be a list of StoredStreamConfigurations if the 'streams' named argument is not provided. Instead, a {stream_list_arg.__class__.__name__} was provided."
|
2009
|
+
)
|
2010
|
+
method_args = method_args[1:]
|
2011
|
+
if stream_list_arg is None:
|
2012
|
+
raise ValueError("You must provide a list of StoredStreamConfiguration objects to the method, either as the first argument or as a named argument 'streams'")
|
2004
2013
|
|
2005
|
-
streams_list
|
2014
|
+
streams_list = stream_list_arg
|
2006
2015
|
# create a queue full of all the streams to process
|
2007
2016
|
streams_queue = queue.Queue()
|
2008
2017
|
for stream in streams_list:
|
@@ -2022,7 +2031,7 @@ def managed_inbound_processing(concurrency: int):
|
|
2022
2031
|
i,
|
2023
2032
|
streams_queue,
|
2024
2033
|
self._sync_request._thread_cancellation_token,
|
2025
|
-
method_args
|
2034
|
+
method_args,
|
2026
2035
|
method_kwargs,
|
2027
2036
|
),
|
2028
2037
|
)
|
File without changes
|
File without changes
|
File without changes
|
{omnata_plugin_runtime-0.3.23a68 → omnata_plugin_runtime-0.3.24}/src/omnata_plugin_runtime/api.py
RENAMED
File without changes
|
File without changes
|
{omnata_plugin_runtime-0.3.23a68 → omnata_plugin_runtime-0.3.24}/src/omnata_plugin_runtime/forms.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|