From 555926f71c7ce47102f7362b1e96fed9f64ccfce Mon Sep 17 00:00:00 2001 From: Emanuele Lanuti Date: Tue, 20 May 2025 16:27:52 +0200 Subject: [PATCH 1/6] Refactor CLI functions to match Nubia fork base class Signed-off-by: Emanuele Lanuti --- suzieq/cli/sq_nubia_context.py | 26 +++++++++++++------------- suzieq/cli/sqcmds/context_commands.py | 15 ++++++++------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/suzieq/cli/sq_nubia_context.py b/suzieq/cli/sq_nubia_context.py index eed39d3570..82fd8e7e30 100644 --- a/suzieq/cli/sq_nubia_context.py +++ b/suzieq/cli/sq_nubia_context.py @@ -1,8 +1,5 @@ import sys - -from nubia import context -from nubia import exceptions -from nubia import eventbus +from nubia import context, exceptions, eventbus from suzieq.shared.utils import load_sq_config, print_version from suzieq.shared.schema import Schema @@ -16,13 +13,12 @@ def __init__(self): self.ctxt = None super().__init__() - def on_connected(self, *args, **kwargs): + async def on_connected(self, *args, **kwargs): if self._args.V: print_version() sys.exit(0) if self._args.config: - cfg = load_sq_config(validate=True, - config_file=self._args.config) + cfg = load_sq_config(validate=True, config_file=self._args.config) else: cfg = load_sq_config(validate=True) @@ -31,22 +27,26 @@ def on_connected(self, *args, **kwargs): print('Create a suzieq-cfg.yml under the homedir or current dir') print('OR pass a path to the config file via -c argument') sys.exit(1) + self.ctxt = SqContext(cfg=cfg) self.ctxt.schemas = Schema(self.ctxt.cfg["schema-directory"]) - def on_cli(self, cmd, args): - # dispatch the on connected message - self.registry.dispatch_message(eventbus.Message.CONNECTED) + async def on_cli(self, cmd, args): + await self.registry.dispatch_message(eventbus.Message.CONNECTED) + + async def on_interactive(self, args): + cmd = self._registry.find_command("connect") + if not cmd: + raise exceptions.CommandError("Connect command not found") - def on_interactive(self, args): - ret = self._registry.find_command("connect").run_cli(args) + ret = await cmd.run_cli(args) if ret: raise exceptions.CommandError("Failed starting interactive mode") # dispatch the on connected message def change_engine(self, engine: str): '''Change the backend engine''' - if engine == self.ctxt.engine: + if self.ctxt and engine == self.ctxt.engine: return self.ctxt.engine = engine diff --git a/suzieq/cli/sqcmds/context_commands.py b/suzieq/cli/sqcmds/context_commands.py index dc174a7fb5..a4f5149c42 100644 --- a/suzieq/cli/sqcmds/context_commands.py +++ b/suzieq/cli/sqcmds/context_commands.py @@ -197,14 +197,14 @@ def __init__(self): super().__init__() self._allcmds = self._sqcmds = None - def run_interactive(self, cmd, args, raw): + async def run_interactive(self, cmd, args, raw): arglist = args.split() - return self._help_cmd(*arglist) + return await self._help_cmd(*arglist) def get_command_names(self): return self.thiscmd - def add_arguments(self, parser): + async def add_arguments(self, parser): parser.add_parser("help") def get_help(self, cmd, *args): @@ -236,11 +236,11 @@ def get_completions(self, cmd, document, complete_event): if x.startswith(verb)] return completions - def _help_cmd(self, *args): + async def _help_cmd(self, *args): """Show help for a service""" if len(args) == 0: helpcmd = HelpCommand() - helpcmd.run_interactive('', '', '') + await helpcmd.run_interactive('', '', '') cprint( "Use " f"{colored('help []', 'cyan')}" @@ -258,10 +258,11 @@ def _help_cmd(self, *args): self._build_cmd_verb_list() if service in self._sqcmds: if verb: - self._allcmds[service].run_interactive( + await self._allcmds[service].run_interactive( service, f'help command={verb}', '') else: - self._allcmds[service].run_interactive(service, 'help', '') + await self._allcmds[service].run_interactive(service, + 'help', '') def _build_cmd_verb_list(self): if not self._allcmds: From 4d9c1d3628af76fa4673c0c0073598af7866c9c8 Mon Sep 17 00:00:00 2001 From: Emanuele Lanuti Date: Tue, 20 May 2025 16:29:00 +0200 Subject: [PATCH 2/6] Add autocompletion definitions file Signed-off-by: Emanuele Lanuti --- suzieq/cli/sqcmds/sq_completions.py | 421 ++++++++++++++++++++++++++++ 1 file changed, 421 insertions(+) create mode 100644 suzieq/cli/sqcmds/sq_completions.py diff --git a/suzieq/cli/sqcmds/sq_completions.py b/suzieq/cli/sqcmds/sq_completions.py new file mode 100644 index 0000000000..552bbf131c --- /dev/null +++ b/suzieq/cli/sqcmds/sq_completions.py @@ -0,0 +1,421 @@ +from typing import List, Dict, Optional, Tuple, Set +import pandas as pd + +from nubia.internal import context +from suzieq.shared.context import SqContext +from suzieq.sqobjects import get_sqobject, get_tables +from suzieq.shared.utils import timed_lru_cache, lru_cache + + +virt_tbl_cmd_mapping: Dict[str, str] = { + 'endpoint': 'device', + 'path': 'device', + 'topology': 'device', + 'namespace': 'device', + 'route': 'routes', + 'mac': 'macs', + 'interface': 'interfaces', + 'assert': 'device', # only for namespace/hostname + 'query': 'device', # only for namespace/hostname +} + + +@timed_lru_cache(60) +def completion_get_data(cmd: str, column: str, + **kwargs) -> Set[str]: + '''Caching enabled dataframe retrieval''' + + result = set() + nubia_ctxt = context.get_context() + if not nubia_ctxt: + return result + + ctxt: SqContext = nubia_ctxt.ctxt + + # kwargs are passed with values as tuples, not lists which + # causes a bunch of problems in asserts. So, convert tuples + # to lists again + for k, v in kwargs.items(): + if isinstance(v, tuple): + kwargs[k] = list(v) + + if cmd in ["assert", "query"]: + df = get_sqobject(cmd)(context=ctxt).get(columns=[column], **kwargs) + if not df.empty and 'error' not in df.columns: + result = set(df[column].unique()) + elif cmd == "extdb": + result = set() + # TODO: implement autocompletion with external tables + # ext_table = kwargs.pop('ext_table', None) + # return get_sqobject(cmd)(ext_table=ext_table, context=ctxt) + else: + df = get_sqobject(cmd)(context=ctxt).unique(columns=[column], **kwargs) + if not df.empty and 'error'not in df.columns: + result = set(df[column]) + + return result + + +@timed_lru_cache(60) +def get_assert_query_completions(cmd: str, column: str, + **kwargs) -> pd.DataFrame: + '''Get completion for assert/query which return a dict''' + + nubia_ctxt = context.get_context() + if not nubia_ctxt: + return pd.DataFrame({column: []}) + + ctxt: SqContext = nubia_ctxt.ctxt + + # kwargs are passed with values as tuples, not lists which + # causes a bunch of problems in asserts. So, convert tuples + # to lists again + for k, v in kwargs.items(): + if isinstance(v, tuple): + kwargs[k] = list(v) + try: + df = get_sqobject(cmd)(context=ctxt) \ + .get(columns=[column], **kwargs) + return df + except Exception: + return pd.DataFrame({column: []}) + + +@lru_cache +def completion_get_columns(cmd: str, component: Optional[str] = None + ) -> List[str]: + '''Return columns associated with a table for unique/top/assert''' + ctxt: SqContext = context.get_context().ctxt + sqobj = None + + if cmd == 'sqlog' and component: + sqobj = get_sqobject(cmd)(component=component, context=ctxt) + elif cmd != 'sqlog': + sqobj = get_sqobject(cmd)(context=ctxt) + if sqobj and sqobj.schema: + return sorted(sqobj.schema.get_user_visible_fields()) + return [] + + +def get_kwargs_so_far(raw_cmd: str, keywords: List[str]) -> Dict: + '''Parse the raw_cmd and return kwargs for requested keywords''' + + kwargs: Dict[str, Tuple] = {} + for keyword in keywords: + kwargs[keyword] = tuple() + if f' {keyword}=' in raw_cmd: + val_str = raw_cmd.split(f' {keyword}=')[-1] + if val_str: + kwargs[keyword] = tuple([val_str.split()[0]]) + + return kwargs + + +def return_completions(cmd, column, val_so_far, quote_result=False, + **kwargs) -> List[str]: + '''Given a cmd and column, return valid completion list''' + + result = [] + try: + valid_set = completion_get_data(cmd, column, **kwargs) + except Exception: + valid_set = [] + + if val_so_far: + result = sorted( + [x for x in valid_set if str(x).startswith(val_so_far)]) + else: + result = sorted(list(valid_set)) + + if quote_result: + result = [f'"{x}"' for x in result] + + return result + + +def namespace_completer(_cmd: str, _: str, last_token: str, + _raw_cmd: str) -> List[str]: + '''Provide dynamic completion list for namespace''' + + ns_so_far: Optional[str] = None + + if isinstance(last_token, str): + ns_so_far = last_token.split('=')[-1] + + return return_completions('device', 'namespace', ns_so_far, + ignore_neverpoll=True) + + +def vrf_completer(cmd: str, _subcmd: str, last_token: str, + raw_cmd: str) -> List[str]: + '''Dynamic completion of hostname''' + + vrf_so_far = None + + if isinstance(last_token, str): + vrf_so_far = last_token.split('=')[-1] + + kwargs = get_kwargs_so_far(raw_cmd, ['namespace', 'hostname']) + + if cmd in ['path', 'topology', 'endpoint']: + cmd = 'address' + + return return_completions(cmd, 'vrf', vrf_so_far, **kwargs) + + +def hostname_completer(cmd: str, _subcmd: str, last_token: str, + raw_cmd: str) -> List[str]: + '''Dynamic completion of hostname''' + + hostname_so_far: Optional[str] = None + + if isinstance(last_token, str): + hostname_so_far = last_token.split('=')[-1] + + kwargs = get_kwargs_so_far(raw_cmd, ['namespace']) + + cmd = virt_tbl_cmd_mapping.get(cmd, cmd) + + return return_completions('device', 'hostname', hostname_so_far, **kwargs) + + +def assert_name_completer(_cmd: str, _: str, + last_token: str, + raw_cmd: str) -> List[str]: + '''Return the completion for asserts''' + + asrt_so_far = None + + if isinstance(last_token, str): + asrt_so_far = last_token.split('=')[-1] + + kwargs = get_kwargs_so_far(raw_cmd, ['workflow']) + + return return_completions('assert', 'name', asrt_so_far, **kwargs) + + +def assert_vars_name_completer(_cmd: str, _: str, + last_token: str, + _raw_cmd: str) -> List[str]: + """assert_vars completition""" + vars_so_far = None + + if isinstance(last_token, str): + vars_so_far = last_token.split('=')[-1] + + kwargs = {'assert_vars': tuple(['*'])} + + return return_completions('assert', 'name', vars_so_far, **kwargs) + + +def query_vars_name_completer(_cmd: str, _: str, last_token: str, + _raw_cmd: str) -> List[str]: + """query_vars completitions""" + vars_so_far: Optional[str] = None + + if isinstance(last_token, str): + vars_so_far = last_token.split('=')[-1] + + kwargs = {'query_vars': tuple(['*'])} + + return return_completions('query', 'name', vars_so_far, **kwargs) + + +def workflow_name_completer(_cmd: str, _subcmd: str, last_token: str, + _raw_cmd: str) -> List[str]: + '''Return the completion for workflows''' + + wf_so_far = None + + if isinstance(last_token, str): + wf_so_far = last_token.split('=')[-1] + + kwargs = {'workflow': tuple(['*'])} + + return return_completions('assert', 'name', wf_so_far, **kwargs) + + +def column_name_completer(cmd: str, subcmd: str, last_token: str, + raw_cmd: str) -> List[str]: + '''Return completions for column name''' + col_so_far = None + + if isinstance(last_token, str): + col_so_far = last_token.split('=')[-1] + + if cmd == "sqlog": + component = get_kwargs_so_far(raw_cmd, ['component']) + kwargs = { + 'component': (component.get('component', [None]) or + [None])[0] + } + else: + ext_table = get_kwargs_so_far(raw_cmd, ['table']) + kwargs = {'ext_table': (ext_table.get('table', [None]) or [None])[0]} + + if (subcmd in ['unique', 'top', 'assert'] + and cmd not in ["endpoint", "assert"]): + fields = completion_get_columns(cmd, **kwargs) + else: + fields = [] + + if fields: + if col_so_far: + return sorted([f for f in fields if f.startswith(col_so_far)]) + + return sorted(fields) + + +def route_proto_completer(cmd: str, _subcmd: str, last_token: str, + raw_cmd: str) -> List[str]: + '''Dynamic completion of protocol field in routing table''' + + if isinstance(last_token, str): + proto_so_far = last_token.split('=')[-1] + else: + proto_so_far = '' + + kwargs = get_kwargs_so_far(raw_cmd, ['namespace', 'hostname']) + + return return_completions(cmd, 'protocol', proto_so_far, **kwargs) + + +def service_completer(_cmd: str, _subcmd: str, last_token: str, + _raw_cmd: str) -> List[str]: + '''Dynamic completion of service names in sqpoller table''' + + svc_so_far = None + + if isinstance(last_token, str): + svc_so_far = last_token.split('=')[-1] + + svcs = set({x for x in get_tables() + if x not in ['path', 'topology', 'namespace', 'endpoint', + 'topcpu', 'topmem', 'assert', 'query', + 'extdb']}) + if svcs: + if svc_so_far: + return sorted([x for x in svcs if x.startswith(svc_so_far)]) + else: + return sorted(svcs) + + return [] + + +def query_completer(_cmd: str, _subcmd: str, last_token: str, + _raw_cmd: str) -> List[str]: + '''Dynamic completion of service names in sqpoller table''' + + q_so_far = None + + if isinstance(last_token, str): + q_so_far = last_token.split('=')[-1] + + queries = [x for x in completion_get_data('query', 'name') + if x] + if queries: + if q_so_far: + return sorted([x for x in queries if x.startswith(q_so_far)]) + else: + return sorted(queries) + + return [] + + +def vlan_completer(cmd: str, _subcmd: str, last_token: str, + raw_cmd: str) -> List[str]: + '''Dynamic completion of VLAN''' + + vlan_so_far = None + + if isinstance(last_token, str): + vlan_so_far = last_token.split('=')[-1] + + kwargs = get_kwargs_so_far(raw_cmd, ['namespace']) + + return return_completions(cmd, 'vlan', vlan_so_far, **kwargs) + + +def vni_completer(cmd: str, _subcmd: str, last_token: str, + raw_cmd: str) -> List[str]: + '''Dynamic completion of VLAN''' + + vni_so_far = None + + if isinstance(last_token, str): + vni_so_far = last_token.split('=')[-1] + + kwargs = get_kwargs_so_far(raw_cmd, ['namespace']) + + return return_completions(cmd, 'vni', vni_so_far, **kwargs) + + +def bridgeid_completer(cmd: str, _subcmd: str, last_token: str, + raw_cmd: str) -> List[str]: + '''Dynamic completion of STP bridgeId''' + + bridge_id_so_far = None + + if isinstance(last_token, str): + bridge_id_so_far = last_token.split('=')[-1] + + kwargs = get_kwargs_so_far(raw_cmd, ['namespace']) + + return return_completions(cmd, 'bridgeId', bridge_id_so_far, **kwargs) + + +def stp_vlan_completer(cmd: str, _subcmd: str, last_token: str, + raw_cmd: str) -> List[str]: + '''Dynamic completion of STP VLANID for PVST+''' + + vlan_so_far = None + + if isinstance(last_token, str): + vlan_so_far = last_token.split('=')[-1] + + kwargs = get_kwargs_so_far(raw_cmd, ['namespace']) + + return return_completions(cmd, 'instanceId', vlan_so_far, **kwargs) + + +def instanceId_completer(cmd: str, _subcmd: str, last_token: str, + raw_cmd: str) -> List[str]: + '''Dynamic completion of STP instanceId''' + + instance_id_so_far = None + + if isinstance(last_token, str): + instance_id_so_far = last_token.split('=')[-1] + + kwargs = get_kwargs_so_far(raw_cmd, ['namespace']) + + return return_completions(cmd, 'instanceId', instance_id_so_far, **kwargs) + + +def inv_type_completer(cmd: str, _subcmd: str, last_token: str, + raw_cmd: str) -> List[str]: + '''Dynamic completion of inventory type''' + + inv_type_so_far = None + + if isinstance(last_token, str): + inv_type_so_far = last_token.split('=')[-1] + + kwargs = get_kwargs_so_far(raw_cmd, ['namespace']) + + return return_completions(cmd, 'type', inv_type_so_far, **kwargs) + + +def license_name_completer(cmd: str, _subcmd: str, last_token: str, + raw_cmd: str) -> List[str]: + '''Dynamic completion of device license name''' + + lic_so_far = None + + if isinstance(last_token, str): + lic_so_far = last_token.split('=')[-1] + + kwargs = get_kwargs_so_far(raw_cmd, ['namespace']) + + return return_completions(cmd, 'name', lic_so_far, quote_result=True, + **kwargs) From f4e6e50f6d7ab5f8007e939895ba3c374c38b3df Mon Sep 17 00:00:00 2001 From: Emanuele Lanuti Date: Tue, 20 May 2025 16:29:39 +0200 Subject: [PATCH 3/6] Add helper function for CLI autocompletion Signed-off-by: Emanuele Lanuti --- suzieq/shared/schema.py | 7 +++++++ suzieq/shared/utils.py | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/suzieq/shared/schema.py b/suzieq/shared/schema.py index 71aae96377..0ae51d4243 100644 --- a/suzieq/shared/schema.py +++ b/suzieq/shared/schema.py @@ -314,3 +314,10 @@ def get_arrow_schema(self) -> pa.Schema: def get_parent_fields(self, field) -> List[str]: '''Get dependent fields for a given augmented field in table''' return self._all_schemas.get_parent_fields(self._table, field) + + def get_user_visible_fields(self) -> List[str]: + '''Return the list of fields that are not suppressed + ''' + # type: ignore + return [f['name'] for f in self.get_raw_schema() + if 'suppress' not in f] diff --git a/suzieq/shared/utils.py b/suzieq/shared/utils.py index 626792ebef..f5931319a6 100644 --- a/suzieq/shared/utils.py +++ b/suzieq/shared/utils.py @@ -7,15 +7,16 @@ import platform import re import sys -from datetime import datetime +from datetime import datetime, timezone, timedelta from enum import Enum +from functools import lru_cache, wraps from importlib.util import find_spec from ipaddress import ip_network from itertools import groupby from logging.handlers import RotatingFileHandler from os import getenv from time import time -from typing import Any, Dict, List, Optional, Union, Tuple +from typing import Any, Dict, List, Optional, Tuple, Union import pandas as pd import psutil @@ -1255,3 +1256,33 @@ def set_rest_engine(cfg: Dict[str, Any]) -> Tuple[str, str, str, str]: rest_api_key = restcfg.get('API_KEY', '') return rest_server_ip, rest_server_port, rest_transport, rest_api_key + + +# timed_lru_cache copied from +# https://realpython.com/lru-cache-python/#evicting-cache-entries-based-on-both-time-and-space +def timed_lru_cache(seconds: int, maxsize: int = 128): + """lru_cache that also expires entries with time + + This is from realpython.com. In many situations, we need memoization + with timed expiry. For example, if we memoize dataframes, we need to + refresh them after a while, or we'll be left with stale data until the + entry is evicted due to unuse which is unpredictable and could be forever. + + Args: + seconds: time to live for an entry, in seconds + maxsize: maximum cache size, 128 default + """ + + def wrapper_cache(func): + func = lru_cache(maxsize=maxsize)(func) + func.lifetime = timedelta(seconds=seconds) + func.expiration = datetime.now(tz=timezone.utc) + func.lifetime + + @wraps(func) + def wrapped_func(*args, **kwargs): + if datetime.now(tz=timezone.utc) >= func.expiration: + func.cache_clear() + func.expiration = datetime.now(tz=timezone.utc) + func.lifetime + return func(*args, **kwargs) + return wrapped_func + return wrapper_cache From 358b0ef386b0425675dd34ce68de03f97f1ab013 Mon Sep 17 00:00:00 2001 From: Emanuele Lanuti Date: Tue, 20 May 2025 16:30:35 +0200 Subject: [PATCH 4/6] Update nubia fork Signed-off-by: Emanuele Lanuti --- poetry.lock | 511 +++++++++++++++++-------------------------------- pyproject.toml | 6 +- 2 files changed, 182 insertions(+), 335 deletions(-) diff --git a/poetry.lock b/poetry.lock index 14b34a6986..842e07fab1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# This file is automatically @generated by Poetry and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. [[package]] name = "aiofiles" version = "23.1.0" description = "File support for asyncio." -category = "main" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -16,7 +15,6 @@ files = [ name = "aiohttp" version = "3.9.5" description = "Async http client/server framework (asyncio)" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -113,7 +111,6 @@ speedups = ["Brotli", "aiodns", "brotlicffi"] name = "aiosignal" version = "1.3.1" description = "aiosignal: a list of registered asynchronous callbacks" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -128,7 +125,6 @@ frozenlist = ">=1.1.0" name = "alabaster" version = "0.7.13" description = "A configurable sidebar-enabled Sphinx theme" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -140,7 +136,6 @@ files = [ name = "altair" version = "4.2.2" description = "Altair: A declarative statistical visualization library for Python." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -163,7 +158,6 @@ dev = ["black", "docutils", "flake8", "ipython", "m2r", "mistune (<2.0.0)", "pyt name = "anyio" version = "3.7.1" description = "High level compatibility layer for multiple asynchronous event loop implementations" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -185,7 +179,6 @@ trio = ["trio (<0.22)"] name = "appdirs" version = "1.4.4" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" optional = false python-versions = "*" files = [ @@ -197,7 +190,6 @@ files = [ name = "appnope" version = "0.1.3" description = "Disable App Nap on macOS >= 10.9" -category = "main" optional = false python-versions = "*" files = [ @@ -209,7 +201,6 @@ files = [ name = "argon2-cffi" version = "21.3.0" description = "The secure Argon2 password hashing algorithm." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -229,7 +220,6 @@ tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pytest"] name = "argon2-cffi-bindings" version = "21.2.0" description = "Low-level CFFI bindings for Argon2" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -267,7 +257,6 @@ tests = ["pytest"] name = "asgiref" version = "3.7.2" description = "ASGI specs, helper code, and adapters" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -285,7 +274,6 @@ tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] name = "astroid" version = "2.15.6" description = "An abstract syntax tree for Python with inference support." -category = "dev" optional = false python-versions = ">=3.7.2" files = [ @@ -302,7 +290,6 @@ wrapt = {version = ">=1.11,<2", markers = "python_version < \"3.11\""} name = "asttokens" version = "2.2.1" description = "Annotate AST trees with source code positions" -category = "main" optional = false python-versions = "*" files = [ @@ -320,7 +307,6 @@ test = ["astroid", "pytest"] name = "async-timeout" version = "4.0.3" description = "Timeout context manager for asyncio programs" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -332,7 +318,6 @@ files = [ name = "asyncssh" version = "2.14.2" description = "AsyncSSH: Asynchronous SSHv2 client and server library" -category = "main" optional = false python-versions = ">= 3.6" files = [ @@ -357,7 +342,6 @@ pywin32 = ["pywin32 (>=227)"] name = "attrs" version = "23.1.0" description = "Classes Without Boilerplate" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -376,7 +360,6 @@ tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pyte name = "autopep8" version = "2.0.2" description = "A tool that automatically formats Python code to conform to the PEP 8 style guide" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -392,7 +375,6 @@ tomli = {version = "*", markers = "python_version < \"3.11\""} name = "babel" version = "2.12.1" description = "Internationalization utilities" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -407,7 +389,6 @@ pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} name = "backcall" version = "0.2.0" description = "Specifications for callback functions passed in to an API" -category = "main" optional = false python-versions = "*" files = [ @@ -419,7 +400,6 @@ files = [ name = "bandit" version = "1.7.5" description = "Security oriented static analyser for python code." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -443,7 +423,6 @@ yaml = ["PyYAML"] name = "beautifulsoup4" version = "4.12.2" description = "Screen-scraping library" -category = "main" optional = false python-versions = ">=3.6.0" files = [ @@ -462,7 +441,6 @@ lxml = ["lxml"] name = "bidict" version = "0.22.1" description = "The bidirectional mapping library for Python." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -479,7 +457,6 @@ test = ["hypothesis", "pytest", "pytest-benchmark[histogram]", "pytest-cov", "py name = "bleach" version = "6.0.0" description = "An easy safelist-based HTML-sanitizing tool." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -498,7 +475,6 @@ css = ["tinycss2 (>=1.1.0,<1.2)"] name = "blinker" version = "1.6.2" description = "Fast, simple object-to-object and broadcast signaling" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -510,7 +486,6 @@ files = [ name = "cachetools" version = "5.3.1" description = "Extensible memoizing collections and decorators" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -522,7 +497,6 @@ files = [ name = "certifi" version = "2023.5.7" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -534,7 +508,6 @@ files = [ name = "cffi" version = "1.15.1" description = "Foreign Function Interface for Python calling C code." -category = "main" optional = false python-versions = "*" files = [ @@ -611,7 +584,6 @@ pycparser = "*" name = "cfgv" version = "3.3.1" description = "Validate configuration and produce human readable error messages." -category = "dev" optional = false python-versions = ">=3.6.1" files = [ @@ -623,7 +595,6 @@ files = [ name = "charset-normalizer" version = "3.2.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -708,7 +679,6 @@ files = [ name = "ciscoconfparse" version = "1.6.52" description = "Parse, Audit, Query, Build, and Modify Cisco IOS-style and JunOS-style configurations" -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -726,7 +696,6 @@ toml = "0.10.2" name = "click" version = "8.1.5" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -741,7 +710,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -753,7 +721,6 @@ files = [ name = "comm" version = "0.1.3" description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -773,7 +740,6 @@ typing = ["mypy (>=0.990)"] name = "configargparse" version = "0.15.2" description = "A drop-in replacement for argparse that allows options to also be set via config files and/or environment variables." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -787,7 +753,6 @@ yaml = ["PyYAML"] name = "contourpy" version = "1.1.0" description = "Python library for calculating contours of 2D quadrilateral grids" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -850,7 +815,6 @@ test-no-images = ["pytest", "pytest-cov", "wurlitzer"] name = "coverage" version = "7.2.7" description = "Code coverage measurement for Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -926,7 +890,6 @@ toml = ["tomli"] name = "cryptography" version = "41.0.2" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -972,7 +935,6 @@ test-randomorder = ["pytest-randomly"] name = "cycler" version = "0.11.0" description = "Composable style cycles" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -984,7 +946,6 @@ files = [ name = "dateparser" version = "1.1.8" description = "Date parsing library designed to parse dates from HTML pages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1007,7 +968,6 @@ langdetect = ["langdetect"] name = "debugpy" version = "1.6.7" description = "An implementation of the Debug Adapter Protocol for Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1035,7 +995,6 @@ files = [ name = "decorator" version = "5.1.1" description = "Decorators for Humans" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1047,7 +1006,6 @@ files = [ name = "defusedxml" version = "0.7.1" description = "XML bomb protection for Python stdlib modules" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -1059,7 +1017,6 @@ files = [ name = "dill" version = "0.3.6" description = "serialize all of python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1074,7 +1031,6 @@ graph = ["objgraph (>=1.7.2)"] name = "distlib" version = "0.3.6" description = "Distribution utilities" -category = "dev" optional = false python-versions = "*" files = [ @@ -1086,7 +1042,6 @@ files = [ name = "dnspython" version = "2.4.0" description = "DNS toolkit" -category = "main" optional = false python-versions = ">=3.8,<4.0" files = [ @@ -1110,7 +1065,6 @@ wmi = ["wmi (>=1.5.1,<2.0.0)"] name = "docutils" version = "0.20.1" description = "Docutils -- Python Documentation Utilities" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1122,7 +1076,6 @@ files = [ name = "entrypoints" version = "0.4" description = "Discover and load entry points from installed packages." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1134,7 +1087,6 @@ files = [ name = "exceptiongroup" version = "1.1.2" description = "Backport of PEP 654 (exception groups)" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1149,7 +1101,6 @@ test = ["pytest (>=6)"] name = "execnet" version = "2.0.2" description = "execnet: rapid multi-Python deployment" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1164,7 +1115,6 @@ testing = ["hatch", "pre-commit", "pytest", "tox"] name = "executing" version = "1.2.0" description = "Get the currently executing AST node of a frame, and other information" -category = "main" optional = false python-versions = "*" files = [ @@ -1179,7 +1129,6 @@ tests = ["asttokens", "littleutils", "pytest", "rich"] name = "faker" version = "4.18.0" description = "Faker is a Python package that generates fake data for you." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1195,7 +1144,6 @@ text-unidecode = "1.3" name = "fastapi" version = "0.95.2" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1217,7 +1165,6 @@ test = ["anyio[trio] (>=3.2.1,<4.0.0)", "black (==23.1.0)", "coverage[toml] (>=6 name = "fastjsonschema" version = "2.17.1" description = "Fastest Python implementation of JSON schema" -category = "main" optional = false python-versions = "*" files = [ @@ -1232,7 +1179,6 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc name = "filelock" version = "3.12.2" description = "A platform independent file lock." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1248,7 +1194,6 @@ testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "p name = "flake8" version = "6.0.0" description = "the modular source code checker: pep8 pyflakes and co" -category = "dev" optional = false python-versions = ">=3.8.1" files = [ @@ -1265,7 +1210,6 @@ pyflakes = ">=3.0.0,<3.1.0" name = "fonttools" version = "4.41.0" description = "Tools to manipulate font files" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1323,7 +1267,6 @@ woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] name = "frozenlist" version = "1.4.1" description = "A list-like structure which implements collections.abc.MutableSequence" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1410,7 +1353,6 @@ files = [ name = "future" version = "0.18.3" description = "Clean single-source support for Python 3 and 2" -category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -1421,7 +1363,6 @@ files = [ name = "future-fstrings" version = "1.2.0" description = "A backport of fstrings to python<3.6" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1436,7 +1377,6 @@ rewrite = ["tokenize-rt (>=3)"] name = "gitdb" version = "4.0.10" description = "Git Object Database" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1451,7 +1391,6 @@ smmap = ">=3.0.1,<6" name = "gitpython" version = "3.1.32" description = "GitPython is a Python library used to interact with Git repositories" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1466,7 +1405,6 @@ gitdb = ">=4.0.1,<5" name = "graphviz" version = "0.15" description = "Simple Python interface for Graphviz" -category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*" files = [ @@ -1483,7 +1421,6 @@ test = ["mock (>=3)", "pytest (>=4)", "pytest-cov", "pytest-mock (>=2)"] name = "h11" version = "0.14.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1495,7 +1432,6 @@ files = [ name = "httpcore" version = "0.17.3" description = "A minimal low-level HTTP client." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1507,17 +1443,16 @@ files = [ anyio = ">=3.0,<5.0" certifi = "*" h11 = ">=0.13,<0.15" -sniffio = ">=1.0.0,<2.0.0" +sniffio = "==1.*" [package.extras] http2 = ["h2 (>=3,<5)"] -socks = ["socksio (>=1.0.0,<2.0.0)"] +socks = ["socksio (==1.*)"] [[package]] name = "httpx" version = "0.24.1" description = "The next generation HTTP client." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1533,15 +1468,14 @@ sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] -cli = ["click (>=8.0.0,<9.0.0)", "pygments (>=2.0.0,<3.0.0)", "rich (>=10,<14)"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] -socks = ["socksio (>=1.0.0,<2.0.0)"] +socks = ["socksio (==1.*)"] [[package]] name = "icdiff" version = "2.0.6" description = "improved colored diff" -category = "dev" optional = false python-versions = "*" files = [ @@ -1552,7 +1486,6 @@ files = [ name = "identify" version = "2.5.24" description = "File identification library for Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1567,7 +1500,6 @@ license = ["ukkonen"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1579,7 +1511,6 @@ files = [ name = "imagesize" version = "1.4.1" description = "Getting image size from png/jpeg/jpeg2000/gif file" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1591,7 +1522,6 @@ files = [ name = "importlib-metadata" version = "6.8.0" description = "Read metadata from Python packages" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1611,7 +1541,6 @@ testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs name = "importlib-resources" version = "6.0.0" description = "Read resources from Python packages" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1630,7 +1559,6 @@ testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1642,7 +1570,6 @@ files = [ name = "ipaddress" version = "1.0.23" description = "IPv4/IPv6 manipulation library" -category = "main" optional = false python-versions = "*" files = [ @@ -1654,7 +1581,6 @@ files = [ name = "ipdb" version = "0.13.13" description = "IPython-enabled pdb" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1671,7 +1597,6 @@ tomli = {version = "*", markers = "python_version > \"3.6\" and python_version < name = "ipykernel" version = "6.24.0" description = "IPython Kernel for Jupyter" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1685,7 +1610,7 @@ comm = ">=0.1.1" debugpy = ">=1.6.5" ipython = ">=7.23.1" jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" matplotlib-inline = ">=0.1" nest-asyncio = "*" packaging = "*" @@ -1705,7 +1630,6 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" name = "ipython" version = "8.12.2" description = "IPython: Productive Interactive Computing" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1745,7 +1669,6 @@ test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pa name = "ipython-genutils" version = "0.2.0" description = "Vestigial utilities from IPython" -category = "main" optional = false python-versions = "*" files = [ @@ -1757,7 +1680,6 @@ files = [ name = "isort" version = "5.12.0" description = "A Python utility / library to sort Python imports." -category = "dev" optional = false python-versions = ">=3.8.0" files = [ @@ -1775,7 +1697,6 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"] name = "jedi" version = "0.17.2" description = "An autocompletion tool for Python that can be used for text editors." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -1792,35 +1713,90 @@ testing = ["Django (<3.1)", "colorama", "docopt", "pytest (>=3.9.0,<5.0.0)"] [[package]] name = "jellyfish" -version = "0.10.0" -description = "a library for doing approximate and phonetic matching of strings." -category = "main" -optional = false -python-versions = ">3.6" -files = [ - {file = "jellyfish-0.10.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:184aa2f3d88105c020b4fdc9659b7fb2939a2d33b2afed68e8a686046a260ddc"}, - {file = "jellyfish-0.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cd15db9c65658c2bbb4814f8446944faabd73171acaa9febcb29fea7e23d0b6"}, - {file = "jellyfish-0.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:215d03d4f53a49b64e9f210d5a2f3adcbd6754e83e3cc47e23fd0b6e17910bb2"}, - {file = "jellyfish-0.10.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:087572c9be6a3a3e2192b8d32364e4ab03a7ed50d9bbea223725c8403203ab5a"}, - {file = "jellyfish-0.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:834d1e1526f966c8e2f90ace36fe15b40f240469282dfceb19edfb0114d77c30"}, - {file = "jellyfish-0.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:e083553d9b4a9f69f1ea454287ab878a2149e3a922b5a71c305dc83c966bb8ce"}, - {file = "jellyfish-0.10.0-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:dfe4636e5c6f5ee8b56398845268e651ec958715a4148b0bad450f757c5b60b3"}, - {file = "jellyfish-0.10.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5563983cc01990fc5f29f803a140a87ac93762e10f4ed695d9ecce2769788276"}, - {file = "jellyfish-0.10.0-cp37-cp37m-win_amd64.whl", hash = "sha256:7504aaf29f6a54ddf35fcdb165cd7aac6c0cdc012331bc510a86030893484e0a"}, - {file = "jellyfish-0.10.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:6bed4c8938decbbdae61120c52bde9da9aa98e25a112a0a6bcae02be3845430c"}, - {file = "jellyfish-0.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b14199a698cb8e4386cf722bd00ae094723b3c3b4c7f42fe08659f2c0d8a278"}, - {file = "jellyfish-0.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:84cf3f25d2c3578a4f182c14f6462cb497a87269fef95e3ebda44cd8bb0b8eea"}, - {file = "jellyfish-0.10.0-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:3905d8b2d563ee19b5af8da6aad1f61bb69c9eecc22167e3872d72ecf9325280"}, - {file = "jellyfish-0.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63001fabcf7b166b86e2cdc1181137a80b35f08d1eab49fbd1107120d090752c"}, - {file = "jellyfish-0.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:8b4180769ff3172e7da79f9acf7cabbfc04467cf64e640fba4fb4e6367e28309"}, - {file = "jellyfish-0.10.0.tar.gz", hash = "sha256:c58d221cca1b91fe9afe8cf30a721904054533add4482075c9980c809f7d05bd"}, +version = "1.0.4" +description = "Approximate and phonetic matching of strings." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jellyfish-1.0.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:f2cfa648575d1e8197cd61a1936929913916173aee8ee66210eb6a08b1a2fa11"}, + {file = "jellyfish-1.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3c915ce23a518d2289c63a502064bf970b9748d9e4164e21e36ebba40c07ad37"}, + {file = "jellyfish-1.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a001b0794aa84bcab311f6019289904ddf417b47ffe2b4796b41a8314bae3c1c"}, + {file = "jellyfish-1.0.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ffe094f4d5b1de72ed1e8bb3e729ada8915f096bc04c344aabb4327a669f272e"}, + {file = "jellyfish-1.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:481689f6e1a695ddf44b7fe9250d0f86839d98ab5418115d8e52886d488fd259"}, + {file = "jellyfish-1.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:30ccf4b1e6a6f9a54f60250f5d65898746186b93aceebfd0dc7159cbe5554db3"}, + {file = "jellyfish-1.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0459f8dc1d63a165f3848ed9f756107cff0d4990e3dffbaed839228073b628b7"}, + {file = "jellyfish-1.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1830f125dc2f41babd0101b2d67a325972f79e991af1e0a135d9efe2c890bbbc"}, + {file = "jellyfish-1.0.4-cp310-none-win32.whl", hash = "sha256:169634dc62f7bb9b93c03d3d7b5da327426023d47d58bd8b424c61aaaa33085c"}, + {file = "jellyfish-1.0.4-cp310-none-win_amd64.whl", hash = "sha256:5b87fca57f6240fe4658810587a0ff49f261a6a49943ad003bbc109c358cec2e"}, + {file = "jellyfish-1.0.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:1561cd0d1687113a5b1e4c4f0e1ab373fbc851af0c9c769a486f94f9ede27cd5"}, + {file = "jellyfish-1.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0d60ab87c542659bd71ed952fbc9c4186293e49016dd92ca79156fee6574a17d"}, + {file = "jellyfish-1.0.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ceba547f96de1f58d29f87c816aab4ec02cbeb6606a48fcad1dcf35c1f06042"}, + {file = "jellyfish-1.0.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b1457d3de969f652d6396cb0329cae3f8d75e0851b335f106624bc991c63c80b"}, + {file = "jellyfish-1.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90384f8b4446a84682bb18051cdc17a069963fff1d0af03ccd2b044b62af6d44"}, + {file = "jellyfish-1.0.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:896552560dcba125db074b980ccc17e123e9444593b272edb82254e4b30f0bd1"}, + {file = "jellyfish-1.0.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:47b0914f375be24976f26ff1436f22dc9fa1ecf9513dbe7ebbee6af5f85409a2"}, + {file = "jellyfish-1.0.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1529a9f1627acffda79ab490ca3f67d35ee1e15c2d30b3f9f93be895b212c4c5"}, + {file = "jellyfish-1.0.4-cp311-none-win32.whl", hash = "sha256:4a47daa243798db689f8b1f3e6c811032075fd434e2af9dfea35a1553152e34e"}, + {file = "jellyfish-1.0.4-cp311-none-win_amd64.whl", hash = "sha256:1d42fdf67a34a346d906b0ab8d56db9cc68bf6497382650d4581ec0fc8eef342"}, + {file = "jellyfish-1.0.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:81f68a8ba074ef3630fab6e635d542708c6e7b5c504a546257b796835b28a5d5"}, + {file = "jellyfish-1.0.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:535a7e99c2b6d456b06d160c950379f18cb72effeb856069eae5d024e09b4afd"}, + {file = "jellyfish-1.0.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76b7936b69687d788aabb86875c0780d6a77dbac9d1738503b0091af744ff79b"}, + {file = "jellyfish-1.0.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:015997043c3eecbf686a71838028180d885f0dc4f7e99daf7194e1787ecd5909"}, + {file = "jellyfish-1.0.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66c7c6113565bcd3771882ff1c6a31573ef3ce755f882e1bf27b233c44a24f35"}, + {file = "jellyfish-1.0.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:069d406850c68a43513a4ddbbf4191e83a2b8fb08119d708086a21c2cf6c406e"}, + {file = "jellyfish-1.0.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:642dde8453ae45235c377ad3ce6cc990bf90fe9c4222896ab3f0f6c5609089a4"}, + {file = "jellyfish-1.0.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:967723d8a1321327b3d6e9eada2db95659ff27ab6de8bb8dc82eefe1ce993333"}, + {file = "jellyfish-1.0.4-cp312-none-win32.whl", hash = "sha256:bd33becfa61956c8ebd12bcb7227d48156d7e4c289780bcccf06e55acde12bf6"}, + {file = "jellyfish-1.0.4-cp312-none-win_amd64.whl", hash = "sha256:c3addb4eebadd7cd4f6cdbff55a4a28caf2448333131b20661d4ff342f53e8a4"}, + {file = "jellyfish-1.0.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:b365ef28bed2673fffec38775aae36fd9d692ff3e2c6f331ed1898c00cd1f388"}, + {file = "jellyfish-1.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44329a7fa570a167144ef20d8d57dff7c59028ecc392cccd9385d23c321aa784"}, + {file = "jellyfish-1.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59f4d263d15d868372c2dcfe12007707d3448a9253a1d912230f213b456ca697"}, + {file = "jellyfish-1.0.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5dca33ca59163445c8afdedff7f47d7f27f0a88fabedfde4ea7197698adc6335"}, + {file = "jellyfish-1.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42056f50f5c604132ca50088253122c8a0bdbf8f37959b60f4fd75026396be3c"}, + {file = "jellyfish-1.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2c001b7cfb14216108dcc851ac39fb428ed82138dabcd6a20e051a2ec5cd6f9e"}, + {file = "jellyfish-1.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c9c713fb0012db4468c2aff8e3a6b6dbd63908563bec0f0ed508d280f0fc4937"}, + {file = "jellyfish-1.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d78874364780b2a6ec248c3d92fb5343cdc5dadaa552cc564eebe7941678303c"}, + {file = "jellyfish-1.0.4-cp38-none-win32.whl", hash = "sha256:363562fa5d99bc688a187ede4c05a9e220baf296a450fe1a24e2c02a65d0077c"}, + {file = "jellyfish-1.0.4-cp38-none-win_amd64.whl", hash = "sha256:27f51df4818fc3eea3ed32c9f50883c011c9e1f972cc2b04cef614d24179f427"}, + {file = "jellyfish-1.0.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:651f8c75bf4352427f1160c2b1d9e994862cc86a9ce2106e9c0c2d87e973ca88"}, + {file = "jellyfish-1.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a9fd3409238012c3d153b5d3ec5f3fe32648ceb6a86f67d42434f0f5f2447a28"}, + {file = "jellyfish-1.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e003e5db6607b46d7f1e321628a0a04e8f56adcbdd8aadfb6b61ec6764bc028a"}, + {file = "jellyfish-1.0.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2d443734829b7e38a4e4525cc572e6ff6e0588254ae346a11c976b935efdbc54"}, + {file = "jellyfish-1.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:984e6307ed255224dc38370b953b48e6f13950209d76489ade582dedc66a001a"}, + {file = "jellyfish-1.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:00e23fb1e87c8b99008fe0a9c00f509754cf0e1a74d9a975fc3737790e756679"}, + {file = "jellyfish-1.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f6f5aaa4f4326feb6754878f3875ee39c5df2e650abe04f9da28c80c3e341728"}, + {file = "jellyfish-1.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d40c3ebd4a00a55845b5653e4a5a8784a032a68e91ca3713163e446b48168887"}, + {file = "jellyfish-1.0.4-cp39-none-win32.whl", hash = "sha256:ce7a7c6ab717d7b8961d234a60c0e12f80a24b4b0ec213a2272f4cdba013b5f8"}, + {file = "jellyfish-1.0.4-cp39-none-win_amd64.whl", hash = "sha256:73e0789d20eda3923a6531693aca1ca6231bec12b9b7c6d7c2ed37b1889f40c1"}, + {file = "jellyfish-1.0.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89f6db50049492c49b622e8e8c04c5494d4c96c92f0ae573288eefb809d60d1f"}, + {file = "jellyfish-1.0.4-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f5af807b15db3c7d08c30911fbe82266ff1089f28ba5a682e87e3145943936cd"}, + {file = "jellyfish-1.0.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17c7822dcb9e70b682604941852f6bba78b047b60d41d2df0e6a75a5d2b1bb78"}, + {file = "jellyfish-1.0.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f581b0184ce7a000f38941b2c81a4480b5fd52cdeb5672f9f682d9e3adb8db84"}, + {file = "jellyfish-1.0.4-pp310-pypy310_pp73-musllinux_1_1_i686.whl", hash = "sha256:f5bc5e05616155306756abe2afda23caefb766b59c849d88285f67bcdcf5a5bb"}, + {file = "jellyfish-1.0.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:4de7c4e7245a2fa9d24bb75dd66aaf77b3521b2377883af0b6008740024ce598"}, + {file = "jellyfish-1.0.4-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e94d594b4b4902a5278346852227f9be281a4aa61907ecd00091451bce8279be"}, + {file = "jellyfish-1.0.4-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:91dc251d02dee6686a1dc31a30a0ea7d8f49781556272b1044cb1a942db75a40"}, + {file = "jellyfish-1.0.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:359aa8c0a55560bd0e6d17e2098b96428d91f066120a708ad889a729801a78b9"}, + {file = "jellyfish-1.0.4-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:02525584cb1d09f3b5b784685a63ba6e889bce240acef12161d7a6f428ea6c2e"}, + {file = "jellyfish-1.0.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9f9d82531af35123632bd02a4394c8783a6f81d89b5c1711bd4c1a6c800a8dc"}, + {file = "jellyfish-1.0.4-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c54255f79a5d00a8261c48e75b483bf1ba2aa87655bd69d4cff805eab758c0f4"}, + {file = "jellyfish-1.0.4-pp38-pypy38_pp73-musllinux_1_1_i686.whl", hash = "sha256:209ccfbc135d150f6af2db9d3c13764f690aa6196fb74ecffd5394c367ed4938"}, + {file = "jellyfish-1.0.4-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3ee641c1c68e0458cac4b9c8c4432d535de1bdd66e8514e541939094622b55cc"}, + {file = "jellyfish-1.0.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d9552ac0478d3015f93161e7d7e1a388b3204fac2a1a22aaf30d67c3670eb6f2"}, + {file = "jellyfish-1.0.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:2cc0a11166cb1cea0700585de63fa46252a5efa46bc31bc4d869b71e3c666ded"}, + {file = "jellyfish-1.0.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6285981622d31c11994f2abcd0d35ec7661cba842538e59bfb735fbedf7b6531"}, + {file = "jellyfish-1.0.4-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07e10f5ab014a626048ff7cd78a6a52c81845f89d94902371278c4be66d91909"}, + {file = "jellyfish-1.0.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8eaa4f2cf78f34cfd41270968954b3bc1eed433b6e7d124786b8064021c110a5"}, + {file = "jellyfish-1.0.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:83e3c4b446da02926b382f8eb8b931e266927e82162adf4c57f0c55c2bf95b35"}, + {file = "jellyfish-1.0.4-pp39-pypy39_pp73-musllinux_1_1_i686.whl", hash = "sha256:d88f47c5c3d97f40b4aa42b83d7ca03707bd6bebd945c9532da6e25515bbeea4"}, + {file = "jellyfish-1.0.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:a4b717a510e64773c4f882b373d4aeda7d2b2b8ffae87c16a906426b7cd02d55"}, + {file = "jellyfish-1.0.4.tar.gz", hash = "sha256:72aabb3bedd513cdd20712242fd51173b59972c0b146b7a0b9c6f32f1656293f"}, ] [[package]] name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1838,7 +1814,6 @@ i18n = ["Babel (>=2.7)"] name = "jsonpath-ng" version = "1.6.1" description = "A final implementation of JSONPath for Python that aims to be standard compliant, including arithmetic and binary comparison operators and providing clear AST for metaprogramming." -category = "main" optional = false python-versions = "*" files = [ @@ -1853,7 +1828,6 @@ ply = "*" name = "jsonschema" version = "4.18.3" description = "An implementation of JSON Schema validation for Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1877,7 +1851,6 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- name = "jsonschema-specifications" version = "2023.6.1" description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1893,7 +1866,6 @@ referencing = ">=0.28.0" name = "jupyter-client" version = "8.3.0" description = "Jupyter protocol implementation and client libraries" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1903,7 +1875,7 @@ files = [ [package.dependencies] importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" python-dateutil = ">=2.8.2" pyzmq = ">=23.0" tornado = ">=6.2" @@ -1917,7 +1889,6 @@ test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pyt name = "jupyter-core" version = "5.3.1" description = "Jupyter core package. A base package on which Jupyter projects rely." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1938,7 +1909,6 @@ test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] name = "jupyterlab-pygments" version = "0.2.2" description = "Pygments theme using JupyterLab CSS variables" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1950,7 +1920,6 @@ files = [ name = "kiwisolver" version = "1.4.4" description = "A fast implementation of the Cassowary constraint solver" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2028,7 +1997,6 @@ files = [ name = "lazy-object-proxy" version = "1.9.0" description = "A fast and thorough lazy object proxy." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2074,7 +2042,6 @@ files = [ name = "loguru" version = "0.6.0" description = "Python logging made (stupidly) simple" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2093,7 +2060,6 @@ dev = ["Sphinx (>=4.1.1)", "black (>=19.10b0)", "colorama (>=0.3.4)", "docutils name = "markdown-it-py" version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2118,7 +2084,6 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "markupsafe" version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2186,53 +2151,58 @@ files = [ [[package]] name = "matplotlib" -version = "3.7.2" +version = "3.7.5" description = "Python plotting package" -category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "matplotlib-3.7.2-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:2699f7e73a76d4c110f4f25be9d2496d6ab4f17345307738557d345f099e07de"}, - {file = "matplotlib-3.7.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a8035ba590658bae7562786c9cc6ea1a84aa49d3afab157e414c9e2ea74f496d"}, - {file = "matplotlib-3.7.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f8e4a49493add46ad4a8c92f63e19d548b2b6ebbed75c6b4c7f46f57d36cdd1"}, - {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71667eb2ccca4c3537d9414b1bc00554cb7f91527c17ee4ec38027201f8f1603"}, - {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:152ee0b569a37630d8628534c628456b28686e085d51394da6b71ef84c4da201"}, - {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:070f8dddd1f5939e60aacb8fa08f19551f4b0140fab16a3669d5cd6e9cb28fc8"}, - {file = "matplotlib-3.7.2-cp310-cp310-win32.whl", hash = "sha256:fdbb46fad4fb47443b5b8ac76904b2e7a66556844f33370861b4788db0f8816a"}, - {file = "matplotlib-3.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:23fb1750934e5f0128f9423db27c474aa32534cec21f7b2153262b066a581fd1"}, - {file = "matplotlib-3.7.2-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:30e1409b857aa8a747c5d4f85f63a79e479835f8dffc52992ac1f3f25837b544"}, - {file = "matplotlib-3.7.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:50e0a55ec74bf2d7a0ebf50ac580a209582c2dd0f7ab51bc270f1b4a0027454e"}, - {file = "matplotlib-3.7.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ac60daa1dc83e8821eed155796b0f7888b6b916cf61d620a4ddd8200ac70cd64"}, - {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:305e3da477dc8607336ba10bac96986d6308d614706cae2efe7d3ffa60465b24"}, - {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c308b255efb9b06b23874236ec0f10f026673ad6515f602027cc8ac7805352d"}, - {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60c521e21031632aa0d87ca5ba0c1c05f3daacadb34c093585a0be6780f698e4"}, - {file = "matplotlib-3.7.2-cp311-cp311-win32.whl", hash = "sha256:26bede320d77e469fdf1bde212de0ec889169b04f7f1179b8930d66f82b30cbc"}, - {file = "matplotlib-3.7.2-cp311-cp311-win_amd64.whl", hash = "sha256:af4860132c8c05261a5f5f8467f1b269bf1c7c23902d75f2be57c4a7f2394b3e"}, - {file = "matplotlib-3.7.2-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:a1733b8e84e7e40a9853e505fe68cc54339f97273bdfe6f3ed980095f769ddc7"}, - {file = "matplotlib-3.7.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d9881356dc48e58910c53af82b57183879129fa30492be69058c5b0d9fddf391"}, - {file = "matplotlib-3.7.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f081c03f413f59390a80b3e351cc2b2ea0205839714dbc364519bcf51f4b56ca"}, - {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1cd120fca3407a225168238b790bd5c528f0fafde6172b140a2f3ab7a4ea63e9"}, - {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a2c1590b90aa7bd741b54c62b78de05d4186271e34e2377e0289d943b3522273"}, - {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d2ff3c984b8a569bc1383cd468fc06b70d7b59d5c2854ca39f1436ae8394117"}, - {file = "matplotlib-3.7.2-cp38-cp38-win32.whl", hash = "sha256:5dea00b62d28654b71ca92463656d80646675628d0828e08a5f3b57e12869e13"}, - {file = "matplotlib-3.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:0f506a1776ee94f9e131af1ac6efa6e5bc7cb606a3e389b0ccb6e657f60bb676"}, - {file = "matplotlib-3.7.2-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:6515e878f91894c2e4340d81f0911857998ccaf04dbc1bba781e3d89cbf70608"}, - {file = "matplotlib-3.7.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:71f7a8c6b124e904db550f5b9fe483d28b896d4135e45c4ea381ad3b8a0e3256"}, - {file = "matplotlib-3.7.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12f01b92ecd518e0697da4d97d163b2b3aa55eb3eb4e2c98235b3396d7dad55f"}, - {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7e28d6396563955f7af437894a36bf2b279462239a41028323e04b85179058b"}, - {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbcf59334ff645e6a67cd5f78b4b2cdb76384cdf587fa0d2dc85f634a72e1a3e"}, - {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:318c89edde72ff95d8df67d82aca03861240512994a597a435a1011ba18dbc7f"}, - {file = "matplotlib-3.7.2-cp39-cp39-win32.whl", hash = "sha256:ce55289d5659b5b12b3db4dc9b7075b70cef5631e56530f14b2945e8836f2d20"}, - {file = "matplotlib-3.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:2ecb5be2b2815431c81dc115667e33da0f5a1bcf6143980d180d09a717c4a12e"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fdcd28360dbb6203fb5219b1a5658df226ac9bebc2542a9e8f457de959d713d0"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c3cca3e842b11b55b52c6fb8bd6a4088693829acbfcdb3e815fa9b7d5c92c1b"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebf577c7a6744e9e1bd3fee45fc74a02710b214f94e2bde344912d85e0c9af7c"}, - {file = "matplotlib-3.7.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:936bba394682049919dda062d33435b3be211dc3dcaa011e09634f060ec878b2"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bc221ffbc2150458b1cd71cdd9ddd5bb37962b036e41b8be258280b5b01da1dd"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35d74ebdb3f71f112b36c2629cf32323adfbf42679e2751252acd468f5001c07"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:717157e61b3a71d3d26ad4e1770dc85156c9af435659a25ee6407dc866cb258d"}, - {file = "matplotlib-3.7.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:20f844d6be031948148ba49605c8b96dfe7d3711d1b63592830d650622458c11"}, - {file = "matplotlib-3.7.2.tar.gz", hash = "sha256:a8cdb91dddb04436bd2f098b8fdf4b81352e68cf4d2c6756fcc414791076569b"}, + {file = "matplotlib-3.7.5-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:4a87b69cb1cb20943010f63feb0b2901c17a3b435f75349fd9865713bfa63925"}, + {file = "matplotlib-3.7.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d3ce45010fefb028359accebb852ca0c21bd77ec0f281952831d235228f15810"}, + {file = "matplotlib-3.7.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fbea1e762b28400393d71be1a02144aa16692a3c4c676ba0178ce83fc2928fdd"}, + {file = "matplotlib-3.7.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec0e1adc0ad70ba8227e957551e25a9d2995e319c29f94a97575bb90fa1d4469"}, + {file = "matplotlib-3.7.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6738c89a635ced486c8a20e20111d33f6398a9cbebce1ced59c211e12cd61455"}, + {file = "matplotlib-3.7.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1210b7919b4ed94b5573870f316bca26de3e3b07ffdb563e79327dc0e6bba515"}, + {file = "matplotlib-3.7.5-cp310-cp310-win32.whl", hash = "sha256:068ebcc59c072781d9dcdb82f0d3f1458271c2de7ca9c78f5bd672141091e9e1"}, + {file = "matplotlib-3.7.5-cp310-cp310-win_amd64.whl", hash = "sha256:f098ffbaab9df1e3ef04e5a5586a1e6b1791380698e84938d8640961c79b1fc0"}, + {file = "matplotlib-3.7.5-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:f65342c147572673f02a4abec2d5a23ad9c3898167df9b47c149f32ce61ca078"}, + {file = "matplotlib-3.7.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4ddf7fc0e0dc553891a117aa083039088d8a07686d4c93fb8a810adca68810af"}, + {file = "matplotlib-3.7.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0ccb830fc29442360d91be48527809f23a5dcaee8da5f4d9b2d5b867c1b087b8"}, + {file = "matplotlib-3.7.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efc6bb28178e844d1f408dd4d6341ee8a2e906fc9e0fa3dae497da4e0cab775d"}, + {file = "matplotlib-3.7.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b15c4c2d374f249f324f46e883340d494c01768dd5287f8bc00b65b625ab56c"}, + {file = "matplotlib-3.7.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d028555421912307845e59e3de328260b26d055c5dac9b182cc9783854e98fb"}, + {file = "matplotlib-3.7.5-cp311-cp311-win32.whl", hash = "sha256:fe184b4625b4052fa88ef350b815559dd90cc6cc8e97b62f966e1ca84074aafa"}, + {file = "matplotlib-3.7.5-cp311-cp311-win_amd64.whl", hash = "sha256:084f1f0f2f1010868c6f1f50b4e1c6f2fb201c58475494f1e5b66fed66093647"}, + {file = "matplotlib-3.7.5-cp312-cp312-macosx_10_12_universal2.whl", hash = "sha256:34bceb9d8ddb142055ff27cd7135f539f2f01be2ce0bafbace4117abe58f8fe4"}, + {file = "matplotlib-3.7.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:c5a2134162273eb8cdfd320ae907bf84d171de948e62180fa372a3ca7cf0f433"}, + {file = "matplotlib-3.7.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:039ad54683a814002ff37bf7981aa1faa40b91f4ff84149beb53d1eb64617980"}, + {file = "matplotlib-3.7.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d742ccd1b09e863b4ca58291728db645b51dab343eebb08d5d4b31b308296ce"}, + {file = "matplotlib-3.7.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:743b1c488ca6a2bc7f56079d282e44d236bf375968bfd1b7ba701fd4d0fa32d6"}, + {file = "matplotlib-3.7.5-cp312-cp312-win_amd64.whl", hash = "sha256:fbf730fca3e1f23713bc1fae0a57db386e39dc81ea57dc305c67f628c1d7a342"}, + {file = "matplotlib-3.7.5-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:cfff9b838531698ee40e40ea1a8a9dc2c01edb400b27d38de6ba44c1f9a8e3d2"}, + {file = "matplotlib-3.7.5-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:1dbcca4508bca7847fe2d64a05b237a3dcaec1f959aedb756d5b1c67b770c5ee"}, + {file = "matplotlib-3.7.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4cdf4ef46c2a1609a50411b66940b31778db1e4b73d4ecc2eaa40bd588979b13"}, + {file = "matplotlib-3.7.5-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:167200ccfefd1674b60e957186dfd9baf58b324562ad1a28e5d0a6b3bea77905"}, + {file = "matplotlib-3.7.5-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:53e64522934df6e1818b25fd48cf3b645b11740d78e6ef765fbb5fa5ce080d02"}, + {file = "matplotlib-3.7.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3e3bc79b2d7d615067bd010caff9243ead1fc95cf735c16e4b2583173f717eb"}, + {file = "matplotlib-3.7.5-cp38-cp38-win32.whl", hash = "sha256:6b641b48c6819726ed47c55835cdd330e53747d4efff574109fd79b2d8a13748"}, + {file = "matplotlib-3.7.5-cp38-cp38-win_amd64.whl", hash = "sha256:f0b60993ed3488b4532ec6b697059897891927cbfc2b8d458a891b60ec03d9d7"}, + {file = "matplotlib-3.7.5-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:090964d0afaff9c90e4d8de7836757e72ecfb252fb02884016d809239f715651"}, + {file = "matplotlib-3.7.5-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:9fc6fcfbc55cd719bc0bfa60bde248eb68cf43876d4c22864603bdd23962ba25"}, + {file = "matplotlib-3.7.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7cc3078b019bb863752b8b60e8b269423000f1603cb2299608231996bd9d54"}, + {file = "matplotlib-3.7.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e4e9a868e8163abaaa8259842d85f949a919e1ead17644fb77a60427c90473c"}, + {file = "matplotlib-3.7.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa7ebc995a7d747dacf0a717d0eb3aa0f0c6a0e9ea88b0194d3a3cd241a1500f"}, + {file = "matplotlib-3.7.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3785bfd83b05fc0e0c2ae4c4a90034fe693ef96c679634756c50fe6efcc09856"}, + {file = "matplotlib-3.7.5-cp39-cp39-win32.whl", hash = "sha256:29b058738c104d0ca8806395f1c9089dfe4d4f0f78ea765c6c704469f3fffc81"}, + {file = "matplotlib-3.7.5-cp39-cp39-win_amd64.whl", hash = "sha256:fd4028d570fa4b31b7b165d4a685942ae9cdc669f33741e388c01857d9723eab"}, + {file = "matplotlib-3.7.5-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2a9a3f4d6a7f88a62a6a18c7e6a84aedcaf4faf0708b4ca46d87b19f1b526f88"}, + {file = "matplotlib-3.7.5-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b9b3fd853d4a7f008a938df909b96db0b454225f935d3917520305b90680579c"}, + {file = "matplotlib-3.7.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0ad550da9f160737d7890217c5eeed4337d07e83ca1b2ca6535078f354e7675"}, + {file = "matplotlib-3.7.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:20da7924a08306a861b3f2d1da0d1aa9a6678e480cf8eacffe18b565af2813e7"}, + {file = "matplotlib-3.7.5-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b45c9798ea6bb920cb77eb7306409756a7fab9db9b463e462618e0559aecb30e"}, + {file = "matplotlib-3.7.5-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a99866267da1e561c7776fe12bf4442174b79aac1a47bd7e627c7e4d077ebd83"}, + {file = "matplotlib-3.7.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b6aa62adb6c268fc87d80f963aca39c64615c31830b02697743c95590ce3fbb"}, + {file = "matplotlib-3.7.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e530ab6a0afd082d2e9c17eb1eb064a63c5b09bb607b2b74fa41adbe3e162286"}, + {file = "matplotlib-3.7.5.tar.gz", hash = "sha256:1e5c971558ebc811aa07f54c7b7c677d78aa518ef4c390e14673a09e0860184a"}, ] [package.dependencies] @@ -2241,17 +2211,16 @@ cycler = ">=0.10" fonttools = ">=4.22.0" importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""} kiwisolver = ">=1.0.1" -numpy = ">=1.20" +numpy = ">=1.20,<2" packaging = ">=20.0" pillow = ">=6.2.0" -pyparsing = ">=2.3.1,<3.1" +pyparsing = ">=2.3.1" python-dateutil = ">=2.7" [[package]] name = "matplotlib-inline" version = "0.1.6" description = "Inline Matplotlib backend for Jupyter" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2266,7 +2235,6 @@ traitlets = "*" name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -2278,7 +2246,6 @@ files = [ name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2290,7 +2257,6 @@ files = [ name = "mistune" version = "3.0.1" description = "A sane and fast Markdown parser with useful plugins and renderers" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2302,7 +2268,6 @@ files = [ name = "mock" version = "5.1.0" description = "Rolling backport of unittest.mock for all Pythons" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -2319,7 +2284,6 @@ test = ["pytest", "pytest-cov"] name = "multidict" version = "6.0.4" description = "multidict implementation" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2403,7 +2367,6 @@ files = [ name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2415,7 +2378,6 @@ files = [ name = "natsort" version = "8.4.0" description = "Simple yet flexible natural sorting in Python." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2431,7 +2393,6 @@ icu = ["PyICU (>=1.0.0)"] name = "nbclient" version = "0.8.0" description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." -category = "main" optional = false python-versions = ">=3.8.0" files = [ @@ -2441,7 +2402,7 @@ files = [ [package.dependencies] jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" nbformat = ">=5.1" traitlets = ">=5.4" @@ -2454,7 +2415,6 @@ test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>= name = "nbconvert" version = "7.6.0" description = "Converting Jupyter Notebooks" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2493,7 +2453,6 @@ webpdf = ["pyppeteer (>=1,<1.1)"] name = "nbformat" version = "5.9.1" description = "The Jupyter Notebook format" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2515,7 +2474,6 @@ test = ["pep440", "pre-commit", "pytest", "testpath"] name = "nest-asyncio" version = "1.5.6" description = "Patch asyncio to allow nested event loops" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2527,7 +2485,6 @@ files = [ name = "netconan" version = "0.11.3" description = "Netconan network configuration anonymization utilities" -category = "main" optional = false python-versions = "*" files = [ @@ -2550,7 +2507,6 @@ test = ["pytest (>=4.6.0,<5.0.0)", "pytest-cov (<3.0.0)", "requests-mock (<2.0.0 name = "networkx" version = "2.4" description = "Python package for creating and manipulating graphs and networks" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2578,7 +2534,6 @@ scipy = ["scipy"] name = "nodeenv" version = "1.8.0" description = "Node.js virtual environment builder" -category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" files = [ @@ -2593,7 +2548,6 @@ setuptools = "*" name = "notebook" version = "6.4.12" description = "A web-based notebook environment for interactive computing" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2623,11 +2577,31 @@ docs = ["myst-parser", "nbsphinx", "sphinx", "sphinx-rtd-theme", "sphinxcontrib- json-logging = ["json-logging"] test = ["coverage", "nbval", "pytest", "pytest-cov", "requests", "requests-unixsocket", "selenium", "testpath"] +[[package]] +name = "nubia-cli" +version = "0.2.5" +description = "A fork of Meta's nubia, a framework for building beautiful shells." +optional = false +python-versions = ">=3.8.1,<3.12" +files = [ + {file = "nubia_cli-0.2.5-py3-none-any.whl", hash = "sha256:ec3d6c2acbea9afa6d051bdeb00e37773331366afecedd2fdc48c9818e9bd95e"}, + {file = "nubia_cli-0.2.5.tar.gz", hash = "sha256:0cdf68b31143a1e81c3e31432e6659b2e8877760ffe373796d3192a2dfaf0ced"}, +] + +[package.dependencies] +jellyfish = ">=1.0,<1.1" +prettytable = ">=2.4.0,<3.0.0" +prompt-toolkit = ">=3.0.23,<4.0.0" +Pygments = ">=2.10.0,<3.0.0" +pyparsing = ">=3.1,<3.2" +termcolor = ">=1.1.0,<2.0.0" +typing-inspect = ">=0.7.1,<0.8.0" +wcwidth = ">=0.2.5,<0.3.0" + [[package]] name = "numpy" version = "1.20.3" description = "NumPy is the fundamental package for array computing with Python." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2661,7 +2635,6 @@ files = [ name = "packaging" version = "21.3" description = "Core utilities for Python packages" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2676,7 +2649,6 @@ pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" name = "pandas" version = "1.5.3" description = "Powerful data structures for data analysis, time series, and statistics" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2721,7 +2693,6 @@ test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] name = "pandocfilters" version = "1.5.0" description = "Utilities for writing pandoc filters in python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2733,7 +2704,6 @@ files = [ name = "parso" version = "0.7.1" description = "A Python Parser" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2748,7 +2718,6 @@ testing = ["docopt", "pytest (>=3.0.7)"] name = "passlib" version = "1.7.4" description = "comprehensive password hashing framework supporting over 30 schemes" -category = "main" optional = false python-versions = "*" files = [ @@ -2766,7 +2735,6 @@ totp = ["cryptography"] name = "pbr" version = "5.11.1" description = "Python Build Reasonableness" -category = "dev" optional = false python-versions = ">=2.6" files = [ @@ -2778,7 +2746,6 @@ files = [ name = "pexpect" version = "4.8.0" description = "Pexpect allows easy control of interactive console applications." -category = "main" optional = false python-versions = "*" files = [ @@ -2793,7 +2760,6 @@ ptyprocess = ">=0.5" name = "pickleshare" version = "0.7.5" description = "Tiny 'shelve'-like database with concurrency support" -category = "main" optional = false python-versions = "*" files = [ @@ -2805,7 +2771,6 @@ files = [ name = "pillow" version = "10.0.0" description = "Python Imaging Library (Fork)" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2875,7 +2840,6 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa name = "pkgutil-resolve-name" version = "1.3.10" description = "Resolve a name to an object." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2887,7 +2851,6 @@ files = [ name = "platformdirs" version = "3.9.1" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2903,7 +2866,6 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest- name = "pluggy" version = "1.2.0" description = "plugin and hook calling mechanisms for python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2919,7 +2881,6 @@ testing = ["pytest", "pytest-benchmark"] name = "ply" version = "3.11" description = "Python Lex & Yacc" -category = "main" optional = false python-versions = "*" files = [ @@ -2931,7 +2892,6 @@ files = [ name = "pprintpp" version = "0.4.0" description = "A drop-in replacement for pprint that's actually pretty" -category = "dev" optional = false python-versions = "*" files = [ @@ -2943,7 +2903,6 @@ files = [ name = "pre-commit" version = "2.21.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2960,14 +2919,13 @@ virtualenv = ">=20.10.0" [[package]] name = "prettytable" -version = "3.8.0" +version = "2.5.0" description = "A simple Python library for easily displaying tabular data in a visually appealing ASCII table format" -category = "main" optional = false -python-versions = ">=3.8" +python-versions = ">=3.6" files = [ - {file = "prettytable-3.8.0-py3-none-any.whl", hash = "sha256:03481bca25ae0c28958c8cd6ac5165c159ce89f7ccde04d5c899b24b68bb13b7"}, - {file = "prettytable-3.8.0.tar.gz", hash = "sha256:031eae6a9102017e8c7c7906460d150b7ed78b20fd1d8c8be4edaf88556c07ce"}, + {file = "prettytable-2.5.0-py3-none-any.whl", hash = "sha256:1411c65d21dca9eaa505ba1d041bed75a6d629ae22f5109a923f4e719cfecba4"}, + {file = "prettytable-2.5.0.tar.gz", hash = "sha256:f7da57ba63d55116d65e5acb147bfdfa60dceccabf0d607d6817ee2888a05f2c"}, ] [package.dependencies] @@ -2980,7 +2938,6 @@ tests = ["pytest", "pytest-cov", "pytest-lazy-fixture"] name = "prometheus-client" version = "0.17.1" description = "Python client for the Prometheus monitoring system." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2995,7 +2952,6 @@ twisted = ["twisted"] name = "prompt-toolkit" version = "3.0.39" description = "Library for building powerful interactive command lines in Python" -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -3010,7 +2966,6 @@ wcwidth = "*" name = "protobuf" version = "3.20.3" description = "Protocol Buffers" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3042,7 +2997,6 @@ files = [ name = "psutil" version = "5.9.5" description = "Cross-platform lib for process and system monitoring in Python." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -3069,7 +3023,6 @@ test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] name = "ptyprocess" version = "0.7.0" description = "Run a subprocess in a pseudo terminal" -category = "main" optional = false python-versions = "*" files = [ @@ -3081,7 +3034,6 @@ files = [ name = "pure-eval" version = "0.2.2" description = "Safely evaluate AST nodes without side effects" -category = "main" optional = false python-versions = "*" files = [ @@ -3096,7 +3048,6 @@ tests = ["pytest"] name = "pyarrow" version = "11.0.0" description = "Python library for Apache Arrow" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3134,7 +3085,6 @@ numpy = ">=1.16.6" name = "pycodestyle" version = "2.10.0" description = "Python style guide checker" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -3146,7 +3096,6 @@ files = [ name = "pycparser" version = "2.21" description = "C parser in Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -3158,7 +3107,6 @@ files = [ name = "pycscope" version = "1.2.1" description = "Generates a cscope index of Python source trees" -category = "dev" optional = false python-versions = "*" files = [ @@ -3169,7 +3117,6 @@ files = [ name = "pydantic" version = "1.10.11" description = "Data validation and settings management using python type hints" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3222,7 +3169,6 @@ email = ["email-validator (>=1.0.3)"] name = "pydeck" version = "0.8.1b0" description = "Widget for deck.gl maps" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3242,7 +3188,6 @@ jupyter = ["ipykernel (>=5.1.2)", "ipython (>=5.8.0)", "ipywidgets (>=7,<8)", "t name = "pyflakes" version = "3.0.1" description = "passive checker of Python programs" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -3254,7 +3199,6 @@ files = [ name = "pygments" version = "2.15.1" description = "Pygments is a syntax highlighting package written in Python." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3269,7 +3213,6 @@ plugins = ["importlib-metadata"] name = "pylint" version = "2.17.4" description = "python code static checker" -category = "dev" optional = false python-versions = ">=3.7.2" files = [ @@ -3296,7 +3239,6 @@ testutils = ["gitpython (>3)"] name = "pympler" version = "1.0.1" description = "A development tool to measure, monitor and analyze the memory behavior of Python objects." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3306,21 +3248,22 @@ files = [ [[package]] name = "pyparsing" -version = "2.4.7" -description = "Python parsing module" -category = "main" +version = "3.1.4" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = ">=3.6.8" files = [ - {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, - {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, + {file = "pyparsing-3.1.4-py3-none-any.whl", hash = "sha256:a6a7ee4235a3f944aa1fa2249307708f893fe5717dc603503c6c7969c070fb7c"}, + {file = "pyparsing-3.1.4.tar.gz", hash = "sha256:f86ec8d1a83f11977c9a6ea7598e8c27fc5cddfa5b07ea2241edbbde1d7bc032"}, ] +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + [[package]] name = "pytest" version = "7.2.2" description = "pytest: simple powerful testing with Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3344,7 +3287,6 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2. name = "pytest-asyncio" version = "0.21.1" description = "Pytest support for asyncio" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3363,7 +3305,6 @@ testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy name = "pytest-cov" version = "4.1.0" description = "Pytest plugin for measuring coverage." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3382,7 +3323,6 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale name = "pytest-depends" version = "1.0.1" description = "Tests that depend on other tests" -category = "dev" optional = false python-versions = "*" files = [ @@ -3400,7 +3340,6 @@ pytest = ">=3" name = "pytest-icdiff" version = "0.6" description = "use icdiff for better error messages in pytest assertions" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -3417,7 +3356,6 @@ pytest = "*" name = "pytest-mock" version = "3.11.1" description = "Thin-wrapper around the mock package for easier use with pytest" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3435,7 +3373,6 @@ dev = ["pre-commit", "pytest-asyncio", "tox"] name = "pytest-xdist" version = "3.3.1" description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3456,7 +3393,6 @@ testing = ["filelock"] name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -3471,7 +3407,6 @@ six = ">=1.5" name = "python-dotenv" version = "0.19.2" description = "Read key-value pairs from a .env file and set them as environment variables" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -3482,33 +3417,10 @@ files = [ [package.extras] cli = ["click (>=5.0)"] -[[package]] -name = "python-nubia" -version = "0.2b5" -description = "A framework for building beautiful shells" -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "python-nubia-0.2b5.tar.gz", hash = "sha256:051931c7a67bbfef9e30ba5b08fa96b35d699621ac0c0030e069caa2475456bd"}, - {file = "python_nubia-0.2b5-py3-none-any.whl", hash = "sha256:2cc39c82e1bb76127689e4bc71c52e3d533a48c84e3c745a4c01891ba0aa650a"}, -] - -[package.dependencies] -jellyfish = "*" -prettytable = "*" -prompt-toolkit = ">=2" -Pygments = "*" -pyparsing = ">=2.2.0" -termcolor = "*" -typing-inspect = "*" -wcwidth = "*" - [[package]] name = "pytoolconfig" version = "1.2.2" description = "Python tool configuration" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3531,7 +3443,6 @@ validation = ["pydantic (>=1.7.4)"] name = "pytz" version = "2023.3" description = "World timezone definitions, modern and historical" -category = "main" optional = false python-versions = "*" files = [ @@ -3543,7 +3454,6 @@ files = [ name = "pyvmomi" version = "8.0.2.0.1" description = "VMware vSphere Python SDK" -category = "main" optional = false python-versions = ">=2.7.9, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -3560,7 +3470,6 @@ sso = ["lxml", "pyOpenSSL", "pywin32"] name = "pywin32" version = "306" description = "Python for Window Extensions" -category = "main" optional = false python-versions = "*" files = [ @@ -3584,7 +3493,6 @@ files = [ name = "pywinpty" version = "2.0.11" description = "Pseudo terminal support for Windows from Python." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3599,7 +3507,6 @@ files = [ name = "pyyaml" version = "6.0" description = "YAML parser and emitter for Python" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3649,7 +3556,6 @@ files = [ name = "pyzmq" version = "25.1.0" description = "Python bindings for 0MQ" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3739,7 +3645,6 @@ cffi = {version = "*", markers = "implementation_name == \"pypy\""} name = "referencing" version = "0.29.1" description = "JSON Referencing + Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3755,7 +3660,6 @@ rpds-py = ">=0.7.0" name = "regex" version = "2023.6.3" description = "Alternative regular expression module, to replace re." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3853,7 +3757,6 @@ files = [ name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3875,7 +3778,6 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "rich" version = "13.4.2" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -3895,7 +3797,6 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] name = "rope" version = "1.9.0" description = "a python refactoring library..." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3915,7 +3816,6 @@ release = ["pip-tools (>=6.12.1)", "toml (>=0.10.2)", "twine (>=4.0.2)"] name = "rpds-py" version = "0.8.10" description = "Python bindings to Rust's persistent data structures (rpds)" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4022,7 +3922,6 @@ files = [ name = "semver" version = "3.0.1" description = "Python helper for Semantic Versioning (https://semver.org)" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4034,7 +3933,6 @@ files = [ name = "send2trash" version = "1.8.2" description = "Send file to trash natively under Mac OS X, Windows and Linux" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" files = [ @@ -4051,7 +3949,6 @@ win32 = ["pywin32"] name = "setuptools" version = "68.0.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -4068,7 +3965,6 @@ testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs ( name = "simplejson" version = "3.19.1" description = "Simple, fast, extensible JSON encoder/decoder for Python" -category = "main" optional = false python-versions = ">=2.5, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -4163,7 +4059,6 @@ files = [ name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -4175,7 +4070,6 @@ files = [ name = "smmap" version = "5.0.0" description = "A pure Python implementation of a sliding window memory map manager" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -4187,7 +4081,6 @@ files = [ name = "sniffio" version = "1.3.0" description = "Sniff out which async library your code is running under" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4199,7 +4092,6 @@ files = [ name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -category = "dev" optional = false python-versions = "*" files = [ @@ -4211,7 +4103,6 @@ files = [ name = "soupsieve" version = "2.4.1" description = "A modern CSS selector implementation for Beautiful Soup." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4223,7 +4114,6 @@ files = [ name = "sphinx" version = "7.0.1" description = "Python documentation generator" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -4259,7 +4149,6 @@ test = ["cython", "filelock", "html5lib", "pytest (>=4.6)"] name = "sphinx-autodoc-typehints" version = "1.23.3" description = "Type hints (PEP 484) support for the Sphinx autodoc extension" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -4280,7 +4169,6 @@ type-comment = ["typed-ast (>=1.5.4)"] name = "sphinxcontrib-applehelp" version = "1.0.4" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -4296,7 +4184,6 @@ test = ["pytest"] name = "sphinxcontrib-devhelp" version = "1.0.2" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -4312,7 +4199,6 @@ test = ["pytest"] name = "sphinxcontrib-htmlhelp" version = "2.0.1" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -4328,7 +4214,6 @@ test = ["html5lib", "pytest"] name = "sphinxcontrib-jsmath" version = "1.0.1" description = "A sphinx extension which renders display math in HTML via JavaScript" -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -4343,7 +4228,6 @@ test = ["flake8", "mypy", "pytest"] name = "sphinxcontrib-qthelp" version = "1.0.3" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -4359,7 +4243,6 @@ test = ["pytest"] name = "sphinxcontrib-serializinghtml" version = "1.1.5" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -4375,7 +4258,6 @@ test = ["pytest"] name = "stack-data" version = "0.6.2" description = "Extract data from python stack frames and tracebacks for informative displays" -category = "main" optional = false python-versions = "*" files = [ @@ -4395,7 +4277,6 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] name = "starlette" version = "0.27.0" description = "The little ASGI library that shines." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4414,7 +4295,6 @@ full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyam name = "stevedore" version = "5.1.0" description = "Manage dynamic plugins for Python applications" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -4429,7 +4309,6 @@ pbr = ">=2.0.0,<2.1.0 || >2.1.0" name = "streamlit" version = "1.11.1" description = "The fastest way to build data apps in Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4468,7 +4347,6 @@ watchdog = {version = "*", markers = "platform_system != \"Darwin\""} name = "streamlit-aggrid" version = "0.2.3.post2" description = "Streamlit component implementation of ag-grid" -category = "main" optional = false python-versions = ">=3.7.1,<4.0" files = [ @@ -4486,7 +4364,6 @@ streamlit = ">=0.87.0" name = "tabulate" version = "0.8.10" description = "Pretty-print tabular data" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -4499,24 +4376,18 @@ widechars = ["wcwidth"] [[package]] name = "termcolor" -version = "2.3.0" -description = "ANSI color formatting for output in terminal" -category = "main" +version = "1.1.0" +description = "ANSII Color formatting for output in terminal." optional = false -python-versions = ">=3.7" +python-versions = "*" files = [ - {file = "termcolor-2.3.0-py3-none-any.whl", hash = "sha256:3afb05607b89aed0ffe25202399ee0867ad4d3cb4180d98aaf8eefa6a5f7d475"}, - {file = "termcolor-2.3.0.tar.gz", hash = "sha256:b5b08f68937f138fe92f6c089b99f1e2da0ae56c52b78bf7075fd95420fd9a5a"}, + {file = "termcolor-1.1.0.tar.gz", hash = "sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b"}, ] -[package.extras] -tests = ["pytest", "pytest-cov"] - [[package]] name = "terminado" version = "0.17.1" description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4537,7 +4408,6 @@ test = ["pre-commit", "pytest (>=7.0)", "pytest-timeout"] name = "text-unidecode" version = "1.3" description = "The most basic Text::Unidecode port" -category = "main" optional = false python-versions = "*" files = [ @@ -4549,7 +4419,6 @@ files = [ name = "textfsm" version = "1.1.3" description = "Python module for parsing semi-structured text into python tables." -category = "main" optional = false python-versions = "*" files = [ @@ -4565,7 +4434,6 @@ six = "*" name = "tinycss2" version = "1.2.1" description = "A tiny CSS parser" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4584,7 +4452,6 @@ test = ["flake8", "isort", "pytest"] name = "toml" version = "0.10.2" description = "Python Library for Tom's Obvious, Minimal Language" -category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -4596,7 +4463,6 @@ files = [ name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -4608,7 +4474,6 @@ files = [ name = "tomlkit" version = "0.11.8" description = "Style preserving TOML library" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -4620,7 +4485,6 @@ files = [ name = "toolz" version = "0.12.0" description = "List processing tools and functional utilities" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -4632,7 +4496,6 @@ files = [ name = "tornado" version = "6.3.2" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." -category = "main" optional = false python-versions = ">= 3.8" files = [ @@ -4653,7 +4516,6 @@ files = [ name = "traitlets" version = "5.9.0" description = "Traitlets Python configuration system" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4669,7 +4531,6 @@ test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] name = "typing-extensions" version = "4.7.1" description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4679,14 +4540,14 @@ files = [ [[package]] name = "typing-inspect" -version = "0.9.0" +version = "0.7.1" description = "Runtime inspection utilities for typing module." -category = "main" optional = false python-versions = "*" files = [ - {file = "typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f"}, - {file = "typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78"}, + {file = "typing_inspect-0.7.1-py2-none-any.whl", hash = "sha256:b1f56c0783ef0f25fb064a01be6e5407e54cf4a4bf4f3ba3fe51e0bd6dcea9e5"}, + {file = "typing_inspect-0.7.1-py3-none-any.whl", hash = "sha256:3cd7d4563e997719a710a3bfe7ffb544c6b72069b6812a02e9b414a8fa3aaa6b"}, + {file = "typing_inspect-0.7.1.tar.gz", hash = "sha256:047d4097d9b17f46531bf6f014356111a1b6fb821a24fe7ac909853ca2a782aa"}, ] [package.dependencies] @@ -4697,7 +4558,6 @@ typing-extensions = ">=3.7.4" name = "tzlocal" version = "2.1" description = "tzinfo object for the local timezone" -category = "main" optional = false python-versions = "*" files = [ @@ -4712,7 +4572,6 @@ pytz = "*" name = "urllib3" version = "1.26.16" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -4729,7 +4588,6 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] name = "uvicorn" version = "0.15.0" description = "The lightning-fast ASGI server." -category = "main" optional = false python-versions = "*" files = [ @@ -4743,13 +4601,12 @@ click = ">=7.0" h11 = ">=0.8" [package.extras] -standard = ["PyYAML (>=5.1)", "colorama (>=0.4)", "httptools (>=0.2.0,<0.3.0)", "python-dotenv (>=0.13)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchgod (>=0.6)", "websockets (>=9.1)"] +standard = ["PyYAML (>=5.1)", "colorama (>=0.4)", "httptools (==0.2.*)", "python-dotenv (>=0.13)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchgod (>=0.6)", "websockets (>=9.1)"] [[package]] name = "uvloop" version = "0.17.0" description = "Fast implementation of asyncio event loop on top of libuv" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4794,7 +4651,6 @@ test = ["Cython (>=0.29.32,<0.30.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "my name = "validators" version = "0.20.0" description = "Python Data Validation for Humans™." -category = "main" optional = false python-versions = ">=3.4" files = [ @@ -4811,7 +4667,6 @@ test = ["flake8 (>=2.4.0)", "isort (>=4.2.2)", "pytest (>=2.2.3)"] name = "virtualenv" version = "20.24.0" description = "Virtual Python Environment builder" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -4832,7 +4687,6 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess name = "watchdog" version = "3.0.0" description = "Filesystem events monitoring" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4872,7 +4726,6 @@ watchmedo = ["PyYAML (>=3.10)"] name = "wcwidth" version = "0.2.6" description = "Measures the displayed width of unicode strings in a terminal" -category = "main" optional = false python-versions = "*" files = [ @@ -4884,7 +4737,6 @@ files = [ name = "webencodings" version = "0.5.1" description = "Character encoding aliases for legacy web content" -category = "main" optional = false python-versions = "*" files = [ @@ -4896,7 +4748,6 @@ files = [ name = "win32-setctime" version = "1.1.0" description = "A small Python utility to set file creation time on Windows" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -4911,7 +4762,6 @@ dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"] name = "wrapt" version = "1.15.0" description = "Module for decorators, wrappers and monkey patching." -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" files = [ @@ -4996,7 +4846,6 @@ files = [ name = "xmltodict" version = "0.12.0" description = "Makes working with XML feel like you are working with JSON" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -5008,7 +4857,6 @@ files = [ name = "yarl" version = "1.9.2" description = "Yet another URL library" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5096,7 +4944,6 @@ multidict = ">=4.0" name = "zipp" version = "3.16.2" description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -5111,4 +4958,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">3.8.1, < 3.10" -content-hash = "52baef73e079105051f17534c6fd05f66e760560dcf44b6f4541d625687a2bdc" +content-hash = "5413e29b0dd184fd416875317942407f7f01161efae6b97433c0201494591d53" diff --git a/pyproject.toml b/pyproject.toml index 816702e187..3db8f1cf96 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,6 @@ prompt-toolkit = ">2" pyarrow = "~11.0" pandas = "~1.5" PyYAML = "*" -python-nubia = "0.2b5" uvloop = "*" networkx = "~2.4" matplotlib = "~3.7" @@ -42,7 +41,7 @@ dateparser = "~1.1" natsort = "^8.0.0" colorama = "^0.4.4" tzlocal = "< 3.0" -pyparsing = ">=2.2.0, <3.0" +pyparsing = ">=3.1, <3.2" xmltodict = "~0.12.0" streamlit-aggrid = "~0.2.2" ciscoconfparse = "~1.6.21" @@ -50,11 +49,12 @@ notebook = "6.4.12" urllib3 = "~1.26.12" packaging = "~21.3" psutil = "~5.9.4" -jellyfish = "~0.10" +jellyfish = ">=1.0,<1.1" altair = '>3.2, <5.0' pydantic = '< 2.0' numpy = '~1.20' pyvmomi = "^8.0.2.0.1" +nubia-cli = "^0.2.5" [tool.poetry.dev-dependencies] pylint = "*" From 9054bacd4adf7b1bd8354df53d785ff2a049eecf Mon Sep 17 00:00:00 2001 From: Emanuele Lanuti Date: Tue, 20 May 2025 16:31:59 +0200 Subject: [PATCH 5/6] Add autocompletion support to specific CLI commands Signed-off-by: Emanuele Lanuti --- suzieq/cli/sqcmds/AddressCmd.py | 4 ++- suzieq/cli/sqcmds/BgpCmd.py | 6 ++-- suzieq/cli/sqcmds/EvpnVniCmd.py | 7 +++-- suzieq/cli/sqcmds/InterfaceCmd.py | 11 +++++--- suzieq/cli/sqcmds/InventoryCmd.py | 9 ++++-- suzieq/cli/sqcmds/MacCmd.py | 4 ++- suzieq/cli/sqcmds/OspfCmd.py | 6 ++-- suzieq/cli/sqcmds/PathCmd.py | 6 ++-- suzieq/cli/sqcmds/RouteCmd.py | 13 +++++---- suzieq/cli/sqcmds/SqPollerCmd.py | 6 ++-- suzieq/cli/sqcmds/TopologyCmd.py | 12 ++++---- suzieq/cli/sqcmds/VlanCmd.py | 6 ++-- suzieq/cli/sqcmds/command.py | 47 ++++++++++++++++--------------- 13 files changed, 84 insertions(+), 53 deletions(-) diff --git a/suzieq/cli/sqcmds/AddressCmd.py b/suzieq/cli/sqcmds/AddressCmd.py index cf01b0fa3d..406240ee9b 100644 --- a/suzieq/cli/sqcmds/AddressCmd.py +++ b/suzieq/cli/sqcmds/AddressCmd.py @@ -3,10 +3,12 @@ from suzieq.cli.sqcmds.command import SqTableCommand from suzieq.sqobjects.address import AddressObj +import suzieq.cli.sqcmds.sq_completions as completitions @argument("vrf", - description="VRF(s), space separated") + description="VRF(s), space separated", + choices=completitions.vrf_completer) @argument("type", description="Interface type(s), space separated") @argument("ifname", description="Interface name(s), space separated") @argument("ipvers", diff --git a/suzieq/cli/sqcmds/BgpCmd.py b/suzieq/cli/sqcmds/BgpCmd.py index 2f7f6226bf..7ea6148966 100644 --- a/suzieq/cli/sqcmds/BgpCmd.py +++ b/suzieq/cli/sqcmds/BgpCmd.py @@ -1,16 +1,18 @@ import time from datetime import timedelta -from nubia import command import pandas as pd +from nubia import command +import suzieq.cli.sqcmds.sq_completions as completitions from suzieq.cli.nubia_patch import argument from suzieq.cli.sqcmds.command import SqTableCommand from suzieq.sqobjects.bgp import BgpObj @command("bgp", help="Act on BGP data") -@argument("vrf", description="VRF(s), space separated") +@argument("vrf", description="VRF(s), space separated", + choices=completitions.vrf_completer) @argument("state", description="status of the session to match", choices=["Established", "NotEstd", "dynamic"]) @argument("peer", diff --git a/suzieq/cli/sqcmds/EvpnVniCmd.py b/suzieq/cli/sqcmds/EvpnVniCmd.py index 127a5218b1..c49f4adbdf 100644 --- a/suzieq/cli/sqcmds/EvpnVniCmd.py +++ b/suzieq/cli/sqcmds/EvpnVniCmd.py @@ -1,13 +1,16 @@ import time + from nubia import command -from suzieq.cli.nubia_patch import argument +import suzieq.cli.sqcmds.sq_completions as completitions +from suzieq.cli.nubia_patch import argument from suzieq.cli.sqcmds.command import SqTableCommand from suzieq.sqobjects.evpnVni import EvpnvniObj @command("evpnVni", help="Act on EVPN VNI data") -@argument("vni", description="VNI ID(s), space separated") +@argument("vni", description="VNI ID(s), space separated", + choices=completitions.vni_completer) @argument("priVtepIp", description="Primary VTEP IP(s), space separated") class EvpnVniCmd(SqTableCommand): """EVPN information such as VNI/VLAN mapping, VTEP IPs etc.""" diff --git a/suzieq/cli/sqcmds/InterfaceCmd.py b/suzieq/cli/sqcmds/InterfaceCmd.py index 0132a4642b..a348d7b730 100644 --- a/suzieq/cli/sqcmds/InterfaceCmd.py +++ b/suzieq/cli/sqcmds/InterfaceCmd.py @@ -1,11 +1,12 @@ import time -from nubia import command import pandas as pd +from nubia import command +import suzieq.cli.sqcmds.sq_completions as completitions from suzieq.cli.nubia_patch import argument -from suzieq.sqobjects import get_sqobject from suzieq.cli.sqcmds.command import SqTableCommand +from suzieq.sqobjects import get_sqobject @command("interface", help="Act on Interface data") @@ -14,7 +15,8 @@ @argument("vrf", description="VRF(s), space separated") @argument("portmode", description="Portmode(s), space separated") @argument("vlan", description="Vlan(s), space separated") -@argument("vrf", description="VRF(s), space separated") +@argument("vrf", description="VRF(s), space separated", + choices=completitions.vrf_completer) @argument("state", description="interface state to qualify show", choices=["up", "down", "notConnected", "!up", "!down", "!notConnected"]) @@ -77,7 +79,8 @@ def __init__( @argument( "what", description="What do you want to assert", - choices=["mtu-value"], + # choices=["mtu-value"], + choices=completitions.column_name_completer ) @argument("value", description="Value to match against") @argument("result", description="Show only assert that matches this value", diff --git a/suzieq/cli/sqcmds/InventoryCmd.py b/suzieq/cli/sqcmds/InventoryCmd.py index 3728b3fdb7..b88b8546d5 100644 --- a/suzieq/cli/sqcmds/InventoryCmd.py +++ b/suzieq/cli/sqcmds/InventoryCmd.py @@ -1,15 +1,18 @@ import re + from nubia import command -from suzieq.cli.nubia_patch import argument +import suzieq.cli.sqcmds.sq_completions as completitions +from suzieq.cli.nubia_patch import argument from suzieq.cli.sqcmds.command import SqTableCommand from suzieq.sqobjects.inventory import InventoryObj @command("inventory", help="Act on inventory data") @argument("type", description="Filter by type", - choices=["fan", "power", "xcvr", "supervisor", "port-adapter", - "linecard", "fabric", "midplane", "mx-cb"]) + # choices=["fan", "power", "xcvr", "supervisor", "port-adapter", + # "linecard", "fabric", "midplane", "mx-cb"] + choices=completitions.inv_type_completer) @argument("status", description="Filter by status", choices=['present', 'absent']) @argument("model", description="Filter by model") diff --git a/suzieq/cli/sqcmds/MacCmd.py b/suzieq/cli/sqcmds/MacCmd.py index 37d5619d02..9b8e136b1b 100644 --- a/suzieq/cli/sqcmds/MacCmd.py +++ b/suzieq/cli/sqcmds/MacCmd.py @@ -3,10 +3,12 @@ from suzieq.cli.sqcmds.command import SqTableCommand from suzieq.sqobjects.macs import MacsObj +import suzieq.cli.sqcmds.sq_completions as completitions @command("mac", help="Act on MAC Table data") -@argument("vlan", description="VLAN(s). space separated") +@argument("vlan", description="VLAN(s). space separated", + choices=completitions.vlan_completer) @argument("macaddr", description="MAC address(es), in quotes, space separated") @argument("remoteVtepIp", diff --git a/suzieq/cli/sqcmds/OspfCmd.py b/suzieq/cli/sqcmds/OspfCmd.py index 42a76fff25..204e0fa4a8 100644 --- a/suzieq/cli/sqcmds/OspfCmd.py +++ b/suzieq/cli/sqcmds/OspfCmd.py @@ -1,8 +1,9 @@ import time -from nubia import command import pandas as pd +from nubia import command +import suzieq.cli.sqcmds.sq_completions as completitions from suzieq.cli.nubia_patch import argument from suzieq.cli.sqcmds.command import SqTableCommand from suzieq.sqobjects.ospf import OspfObj @@ -13,7 +14,8 @@ "ifname", description="Interface name(s), space separated" ) -@argument("vrf", description="VRF(s), space separated") +@argument("vrf", description="VRF(s), space separated", + choices=completitions.vrf_completer) @argument("area", description="Area(s), space separated") @argument("state", description="Select view based on OSPF state", choices=["full", "other", "passive", "!full", "!passive", diff --git a/suzieq/cli/sqcmds/PathCmd.py b/suzieq/cli/sqcmds/PathCmd.py index 2c6aaf2aed..e274e05729 100644 --- a/suzieq/cli/sqcmds/PathCmd.py +++ b/suzieq/cli/sqcmds/PathCmd.py @@ -1,6 +1,7 @@ from nubia import command -from suzieq.cli.nubia_patch import argument +import suzieq.cli.sqcmds.sq_completions as completitions +from suzieq.cli.nubia_patch import argument from suzieq.cli.sqcmds.command import SqTableCommand from suzieq.sqobjects.path import PathObj @@ -8,7 +9,8 @@ @command("path", help="build and act on path data") @argument("src", description="Source IP address, in quotes") @argument("dest", description="Destination IP address, in quotes") -@argument("vrf", description="VRF to trace path in") +@argument("vrf", description="VRF to trace path in", + choices=completitions.vrf_completer) class PathCmd(SqTableCommand): """Path trace information including overlay and underlay""" diff --git a/suzieq/cli/sqcmds/RouteCmd.py b/suzieq/cli/sqcmds/RouteCmd.py index ec83f2d12c..0f379dbe25 100644 --- a/suzieq/cli/sqcmds/RouteCmd.py +++ b/suzieq/cli/sqcmds/RouteCmd.py @@ -1,17 +1,20 @@ -import time import ipaddress -import pandas as pd +import time +import pandas as pd from nubia import command -from suzieq.cli.nubia_patch import argument +import suzieq.cli.sqcmds.sq_completions as completitions +from suzieq.cli.nubia_patch import argument from suzieq.cli.sqcmds.command import SqTableCommand from suzieq.sqobjects.routes import RoutesObj @command("route", help="Act on Routes") -@argument("vrf", description="VRF(s), space separated") -@argument("protocol", description="Routing protocol(s), space separated") +@argument("vrf", description="VRF(s), space separated", + choices=completitions.vrf_completer) +@argument("protocol", description="Routing protocol(s), space separated", + choices=completitions.route_proto_completer) @argument("prefix", description="Prefix(es), in quotes, space separated") @argument("prefixlen", description="must be of the form " "[<|<=|>=|>|!] length") diff --git a/suzieq/cli/sqcmds/SqPollerCmd.py b/suzieq/cli/sqcmds/SqPollerCmd.py index 7aaaefe8f8..6f900f0397 100644 --- a/suzieq/cli/sqcmds/SqPollerCmd.py +++ b/suzieq/cli/sqcmds/SqPollerCmd.py @@ -1,12 +1,14 @@ from nubia import command -from suzieq.cli.nubia_patch import argument +import suzieq.cli.sqcmds.sq_completions as completitions +from suzieq.cli.nubia_patch import argument from suzieq.cli.sqcmds.command import SqTableCommand from suzieq.sqobjects.sqPoller import SqPollerObj @command("sqPoller", help="Act on SqPoller data") -@argument("service", description="Service(s), space separated") +@argument("service", description="Service(s), space separated", + choices=completitions.service_completer) @argument("status", description="status of service to match", choices=["all", "pass", "fail"]) @argument('poll_period_exceeded', diff --git a/suzieq/cli/sqcmds/TopologyCmd.py b/suzieq/cli/sqcmds/TopologyCmd.py index 8c2d2bca65..7a1a748bd2 100644 --- a/suzieq/cli/sqcmds/TopologyCmd.py +++ b/suzieq/cli/sqcmds/TopologyCmd.py @@ -1,6 +1,7 @@ from nubia import command -from suzieq.cli.nubia_patch import argument +import suzieq.cli.sqcmds.sq_completions as completitions +from suzieq.cli.nubia_patch import argument from suzieq.cli.sqcmds.command import SqTableCommand from suzieq.sqobjects.topology import TopologyObj @@ -12,13 +13,14 @@ @argument("via", description="Protocol(s) via which nodes are connected, " "space separated") -@argument("vrf", description="VRF(s), space separated") +@argument("vrf", description="VRF(s), space separated", + choices=completitions.vrf_completer) @argument("asn", description="BGP ASN(s), space separated") @argument("area", description="OSPF Area(s), space separated") @argument("afiSafi", description="BGP AFI SAFI lens to filter the topology") -@ argument("peerHostname", - description="Peer hostname(s), space separated, " - "space separated") +@argument("peerHostname", + description="Peer hostname(s), space separated, " + "space separated") class TopologyCmd(SqTableCommand): """Information about the topology constructed from various protocols""" diff --git a/suzieq/cli/sqcmds/VlanCmd.py b/suzieq/cli/sqcmds/VlanCmd.py index 0b4ebf467c..8eca136b3c 100644 --- a/suzieq/cli/sqcmds/VlanCmd.py +++ b/suzieq/cli/sqcmds/VlanCmd.py @@ -1,6 +1,7 @@ from nubia import command -from suzieq.cli.nubia_patch import argument +import suzieq.cli.sqcmds.sq_completions as completitions +from suzieq.cli.nubia_patch import argument from suzieq.cli.sqcmds.command import SqTableCommand from suzieq.sqobjects.vlan import VlanObj @@ -9,7 +10,8 @@ @argument("state", description="State of VLAN to query", choices=['active', 'suspended']) @argument("vlan", - description="VLAN(s), space separated, can use <, >, <=, >=, !") + description="VLAN(s), space separated, can use <, >, <=, >=, !", + choices=completitions.vlan_completer) @argument('vlanName', description="VLAN name(s), space separated") class VlanCmd(SqTableCommand): diff --git a/suzieq/cli/sqcmds/command.py b/suzieq/cli/sqcmds/command.py index acbca836cb..f01f7e08db 100644 --- a/suzieq/cli/sqcmds/command.py +++ b/suzieq/cli/sqcmds/command.py @@ -1,24 +1,23 @@ -import time import ast import inspect -from io import StringIO import shutil +import time +from io import StringIO from typing import List import numpy as np import pandas as pd +from colorama import Fore, Style +from natsort import natsort_keygen from nubia import command, context - - from prompt_toolkit import prompt -from natsort import natsort_keygen -from colorama import Fore, Style +from termcolor import colored, cprint -from termcolor import cprint, colored +import suzieq.cli.sqcmds.sq_completions as completitions from suzieq.cli.nubia_patch import argument -from suzieq.shared.sq_plugin import SqPlugin from suzieq.shared.exceptions import UserQueryError +from suzieq.shared.sq_plugin import SqPlugin from suzieq.shared.utils import (DATA_FORMATS, SUPPORTED_ENGINES, deprecated_command_warning) @@ -35,10 +34,12 @@ def colorize(x, color): choices=SUPPORTED_ENGINES, ) @argument( - "namespace", description="Namespace(s), space separated" + "namespace", description="Namespace(s), space separated", + choices=completitions.namespace_completer ) @argument("hostname", - description="Hostname(s), space separated") + description="Hostname(s), space separated", + choices=completitions.hostname_completer) @argument( "start_time", description="Start of time window, try natural language spec" ) @@ -50,7 +51,8 @@ def colorize(x, color): description="View all records or just the latest", choices=["all", "latest"], ) -@argument("columns", description="Space separated list of columns, * for all") +@argument("columns", description="Space separated list of columns, * for all", + choices=completitions.column_name_completer) @argument( "format", description="Select the pformat of the output", @@ -149,8 +151,8 @@ def schemas(self): '''Return the schemas''' return self._schemas - @ command("help", help="show help for a command") - @ argument("command", description="command to show help for") + @command("help", help="show help for a command") + @argument("command", description="command to show help for") # pylint: disable=redefined-outer-name def help(self, command: str = ''): """Show help for a command @@ -537,11 +539,12 @@ def unique(self, count='', **kwargs): df.sort_values(by=['numRows', df.columns[0]]), dont_strip_cols=True) - @ command("top", help="find the top n values for a field") - @ argument("count", description="number of rows to return") - @ argument("what", description="numeric field to get top values for") - @ argument("reverse", description="return bottom n values", - choices=['True', 'False']) + @command("top", help="find the top n values for a field") + @argument("count", description="number of rows to return") + @argument("what", description="numeric field to get top values for", + choices=completitions.column_name_completer) + @argument("reverse", description="return bottom n values", + choices=['True', 'False']) def top(self, count: int = 5, what: str = '', reverse: str = 'False', **kwargs) -> int: """Return the top n values for a field in a table @@ -576,10 +579,10 @@ def top(self, count: int = 5, what: str = '', reverse: str = 'False', else: return self._gen_output(df) - @ command("help", help="show help for a command") - @ argument("command", description="command to show help for", - choices=['show', 'unique', 'summarize', 'assert', 'describe', - 'top', "lpm"]) + @command("help", help="show help for a command") + @argument("command", description="command to show help for", + choices=['show', 'unique', 'summarize', 'assert', 'describe', + 'top', "lpm"]) # pylint: disable=redefined-outer-name def help(self, command: str = ''): return super().help(command) From 225dba8626f12c7a6b33ecfd73c0f89e2439256e Mon Sep 17 00:00:00 2001 From: Emanuele Lanuti Date: Wed, 21 May 2025 10:35:28 +0200 Subject: [PATCH 6/6] Remove unused data Signed-off-by: Emanuele Lanuti --- suzieq/cli/sqcmds/InterfaceCmd.py | 1 - suzieq/cli/sqcmds/InventoryCmd.py | 2 - suzieq/cli/sqcmds/sq_completions.py | 106 ++-------------------------- 3 files changed, 7 insertions(+), 102 deletions(-) diff --git a/suzieq/cli/sqcmds/InterfaceCmd.py b/suzieq/cli/sqcmds/InterfaceCmd.py index a348d7b730..1a484f1e93 100644 --- a/suzieq/cli/sqcmds/InterfaceCmd.py +++ b/suzieq/cli/sqcmds/InterfaceCmd.py @@ -79,7 +79,6 @@ def __init__( @argument( "what", description="What do you want to assert", - # choices=["mtu-value"], choices=completitions.column_name_completer ) @argument("value", description="Value to match against") diff --git a/suzieq/cli/sqcmds/InventoryCmd.py b/suzieq/cli/sqcmds/InventoryCmd.py index b88b8546d5..2842700b79 100644 --- a/suzieq/cli/sqcmds/InventoryCmd.py +++ b/suzieq/cli/sqcmds/InventoryCmd.py @@ -10,8 +10,6 @@ @command("inventory", help="Act on inventory data") @argument("type", description="Filter by type", - # choices=["fan", "power", "xcvr", "supervisor", "port-adapter", - # "linecard", "fabric", "midplane", "mx-cb"] choices=completitions.inv_type_completer) @argument("status", description="Filter by status", choices=['present', 'absent']) diff --git a/suzieq/cli/sqcmds/sq_completions.py b/suzieq/cli/sqcmds/sq_completions.py index 552bbf131c..cc8f62e3bf 100644 --- a/suzieq/cli/sqcmds/sq_completions.py +++ b/suzieq/cli/sqcmds/sq_completions.py @@ -1,11 +1,10 @@ -from typing import List, Dict, Optional, Tuple, Set -import pandas as pd +from typing import Dict, List, Optional, Set, Tuple from nubia.internal import context + from suzieq.shared.context import SqContext +from suzieq.shared.utils import lru_cache, timed_lru_cache from suzieq.sqobjects import get_sqobject, get_tables -from suzieq.shared.utils import timed_lru_cache, lru_cache - virt_tbl_cmd_mapping: Dict[str, str] = { 'endpoint': 'device', @@ -15,8 +14,6 @@ 'route': 'routes', 'mac': 'macs', 'interface': 'interfaces', - 'assert': 'device', # only for namespace/hostname - 'query': 'device', # only for namespace/hostname } @@ -39,11 +36,7 @@ def completion_get_data(cmd: str, column: str, if isinstance(v, tuple): kwargs[k] = list(v) - if cmd in ["assert", "query"]: - df = get_sqobject(cmd)(context=ctxt).get(columns=[column], **kwargs) - if not df.empty and 'error' not in df.columns: - result = set(df[column].unique()) - elif cmd == "extdb": + if cmd == "extdb": result = set() # TODO: implement autocompletion with external tables # ext_table = kwargs.pop('ext_table', None) @@ -56,33 +49,8 @@ def completion_get_data(cmd: str, column: str, return result -@timed_lru_cache(60) -def get_assert_query_completions(cmd: str, column: str, - **kwargs) -> pd.DataFrame: - '''Get completion for assert/query which return a dict''' - - nubia_ctxt = context.get_context() - if not nubia_ctxt: - return pd.DataFrame({column: []}) - - ctxt: SqContext = nubia_ctxt.ctxt - - # kwargs are passed with values as tuples, not lists which - # causes a bunch of problems in asserts. So, convert tuples - # to lists again - for k, v in kwargs.items(): - if isinstance(v, tuple): - kwargs[k] = list(v) - try: - df = get_sqobject(cmd)(context=ctxt) \ - .get(columns=[column], **kwargs) - return df - except Exception: - return pd.DataFrame({column: []}) - - @lru_cache -def completion_get_columns(cmd: str, component: Optional[str] = None +def completion_get_columns(cmd: str, component: Optional[str] = None, ) -> List[str]: '''Return columns associated with a table for unique/top/assert''' ctxt: SqContext = context.get_context().ctxt @@ -115,7 +83,6 @@ def return_completions(cmd, column, val_so_far, quote_result=False, **kwargs) -> List[str]: '''Given a cmd and column, return valid completion list''' - result = [] try: valid_set = completion_get_data(cmd, column, **kwargs) except Exception: @@ -174,67 +141,9 @@ def hostname_completer(cmd: str, _subcmd: str, last_token: str, kwargs = get_kwargs_so_far(raw_cmd, ['namespace']) - cmd = virt_tbl_cmd_mapping.get(cmd, cmd) - return return_completions('device', 'hostname', hostname_so_far, **kwargs) -def assert_name_completer(_cmd: str, _: str, - last_token: str, - raw_cmd: str) -> List[str]: - '''Return the completion for asserts''' - - asrt_so_far = None - - if isinstance(last_token, str): - asrt_so_far = last_token.split('=')[-1] - - kwargs = get_kwargs_so_far(raw_cmd, ['workflow']) - - return return_completions('assert', 'name', asrt_so_far, **kwargs) - - -def assert_vars_name_completer(_cmd: str, _: str, - last_token: str, - _raw_cmd: str) -> List[str]: - """assert_vars completition""" - vars_so_far = None - - if isinstance(last_token, str): - vars_so_far = last_token.split('=')[-1] - - kwargs = {'assert_vars': tuple(['*'])} - - return return_completions('assert', 'name', vars_so_far, **kwargs) - - -def query_vars_name_completer(_cmd: str, _: str, last_token: str, - _raw_cmd: str) -> List[str]: - """query_vars completitions""" - vars_so_far: Optional[str] = None - - if isinstance(last_token, str): - vars_so_far = last_token.split('=')[-1] - - kwargs = {'query_vars': tuple(['*'])} - - return return_completions('query', 'name', vars_so_far, **kwargs) - - -def workflow_name_completer(_cmd: str, _subcmd: str, last_token: str, - _raw_cmd: str) -> List[str]: - '''Return the completion for workflows''' - - wf_so_far = None - - if isinstance(last_token, str): - wf_so_far = last_token.split('=')[-1] - - kwargs = {'workflow': tuple(['*'])} - - return return_completions('assert', 'name', wf_so_far, **kwargs) - - def column_name_completer(cmd: str, subcmd: str, last_token: str, raw_cmd: str) -> List[str]: '''Return completions for column name''' @@ -250,8 +159,7 @@ def column_name_completer(cmd: str, subcmd: str, last_token: str, [None])[0] } else: - ext_table = get_kwargs_so_far(raw_cmd, ['table']) - kwargs = {'ext_table': (ext_table.get('table', [None]) or [None])[0]} + kwargs = {} if (subcmd in ['unique', 'top', 'assert'] and cmd not in ["endpoint", "assert"]): @@ -291,7 +199,7 @@ def service_completer(_cmd: str, _subcmd: str, last_token: str, svcs = set({x for x in get_tables() if x not in ['path', 'topology', 'namespace', 'endpoint', - 'topcpu', 'topmem', 'assert', 'query', + 'topcpu', 'topmem', 'extdb']}) if svcs: if svc_so_far: