From 265b6e14ba1ad40317752521b8656d129f14a535 Mon Sep 17 00:00:00 2001 From: Jasmine Date: Sun, 10 Nov 2024 15:16:32 +0200 Subject: [PATCH 01/58] added alerts functionality --- .../common/clients/xsiam/xsiam_api_client.py | 129 +++++++++++++++--- 1 file changed, 113 insertions(+), 16 deletions(-) diff --git a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py index 66995ecd9f7..5b37a909d3d 100644 --- a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py +++ b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py @@ -32,10 +32,8 @@ def is_server_type(self) -> bool: self.get_ioc_rules() return True except ApiException as error: - logger.debug( # noqa: PLE1205 - "{}", - f"{self} is not {self.server_type} server, error: {error}", - ) + logger.debug( + f"{self} is not {self.server_type} server, error: {error}") return False @property @@ -46,6 +44,28 @@ def server_type(self) -> ServerType: def marketplace(self) -> MarketplaceVersions: return MarketplaceVersions.MarketplaceV2 + """ + ############################# + Helper methods + ############################# + """ + + def _process_response(self, response, status_code, expected_status=200): + """Process the HTTP response coming from the XSOAR client.""" # noqa: E999 + if status_code == expected_status: + if response: + try: + return json.loads(response) + except json.JSONDecodeError: + api_response = response.replace("'", '"').replace( + "False", "false").replace("True", "true").replace("None", "null") + return json.loads(api_response) + return {} + else: + error_message = f"Expected status {expected_status}, but got {status_code}. Response: {response}" + raise Exception(error_message) + + """ ############################# xsoar related methods @@ -60,7 +80,8 @@ def delete_incidents( response_type: str = "object", ): # if in the future it will be possible to delete incidents in XSIAM, implement this method - raise NotImplementedError("it is not possible to delete incidents in XSIAM") + raise NotImplementedError( + "it is not possible to delete incidents in XSIAM") """ ############################# @@ -76,7 +97,8 @@ def push_to_dataset( data_format: str = "json", ): if self.server_config.token: - endpoint = urljoin(self.server_config.base_api_url, "logs/v1/xsiam") + endpoint = urljoin( + self.server_config.base_api_url, "logs/v1/xsiam") additional_headers = { "authorization": self.server_config.token, "format": data_format, @@ -86,14 +108,13 @@ def push_to_dataset( } token_type = "xsiam_token" elif self.server_config.collector_token: - endpoint = urljoin(self.server_config.base_api_url, "logs/v1/event") + endpoint = urljoin( + self.server_config.base_api_url, "logs/v1/event") additional_headers = { "authorization": self.server_config.collector_token, - "content-type": ( - "application/json" - if data_format.casefold == "json" - else "text/plain" - ), + "content-type": "application/json" + if data_format.casefold == "json" + else "text/plain", "content-encoding": "gzip", } token_type = "collector_token" @@ -109,7 +130,8 @@ def push_to_dataset( ) try: data = response.json() - except requests.exceptions.JSONDecodeError: # type: ignore[attr-defined] + # type: ignore[attr-defined] + except requests.exceptions.JSONDecodeError: error = response.text err_msg = f"Failed to push using {token_type} - with status code {response.status_code}" err_msg += f"\n{error}" if error else "" @@ -167,7 +189,8 @@ def get_xql_query_result(self, execution_id: str, timeout: int = 300): self.server_config.base_api_url, "public_api/v1/xql/get_query_results/" ) logger.info(f"Getting xql query results: endpoint={endpoint}") - response = self._xdr_client.post(endpoint, data=payload, timeout=timeout) + response = self._xdr_client.post( + endpoint, data=payload, timeout=timeout) logger.debug("Request completed to get xql query results") data = response.json() logger.debug(pformat(data)) @@ -188,8 +211,7 @@ def get_xql_query_result(self, execution_id: str, timeout: int = 300): def get_ioc_rules(self): # /ioc-rules is only an endpoint in XSIAM. response, status_code, response_headers = self._xsoar_client.generic_request( - "/ioc-rules", "GET", response_type="object" - ) + "/ioc-rules", "GET", response_type="object") if ( "text/html" in response_headers.get("Content-Type") or status_code != requests.codes.ok @@ -199,3 +221,78 @@ def get_ioc_rules(self): ) return response + + # def connect_xdr(alerts): + # headers = { + # "Authorization": self.public_api_key.key, + # "x-xdr-auth-id": self.public_api_key.id, + # "Content-Type": "application/json", + # } + # alert_payload = {"request_data": {"alerts": alerts}} + # res = requests.post( + # url=f'https://api-{xsoar_host}/public_api/v1/alerts/insert_parsed_alerts/', headers=headers, json=alert_payload) + + """ + ############################# + Alerts related methods + ############################# + """ + + def create_alert_from_json(self, json_content: dict) -> int: + alert_payload = {"request_data": {"alert": json_content}} + res = requests.post(url=f'{self.base_url}/public_api/v1/alerts/create_alert', + headers=self._xdr_client.headers, json=alert_payload) + alert_data = self._process_response(res.content, res.status_code, 200) + return alert_data['reply'] + + def get_internal_alert_id(self, alert_external_id: str) -> int: + data = self.search_alerts(alert_external_id) + return data['alerts'][0]['alert_id'] + + def update_alert(self, alert_id: str | list[str], updated_data: dict): + """ + Args: + alert_id (str | list[str]): alert ids to edit. + updated_data (dict): The data to update the alerts with. https://cortex-panw.stoplight.io/docs/cortex-xsiam-1/rpt3p1ne2bwfe-update-alerts + """ + alert_payload = {"request_data": { + "update_data": updated_data, "alert_id_list": alert_id}} + res = requests.post(url=f'{self.base_url}/public_api/v1/alerts/update_alerts', + headers=self._xdr_client.headers, json=alert_payload) + alert_data = self._process_response(res.content, res.status_code, 200) + return alert_data + + def search_alerts(self, external_alert_id: str | list[str]): + body = { + "request_data": { + "filters": [ + { + "field": "external_id_list", + "operator": "in", + "value": external_alert_id if isinstance(external_alert_id, list) else [external_alert_id] + } + ] + } + } + res = requests.post(url=f'{self.base_url}/public_api/v1/alerts/get_alerts/', + headers=self._xdr_client.headers, json=body) + return self._process_response(res.content, res.status_code, 200)['reply'] + + """ + ############################# + Playbooks related methods + ############################# + """ + + def get_playbook_data(self, playbook_id: int) -> dict: + playbook_endpoint = f"/playbook/{playbook_id}" + + res = requests.get(url=f'{self.base_url}/public_api/v1{playbook_endpoint}', + headers=self._xdr_client.headers, json=body) + return self._process_response(res.content, res.status_code, 200) + + def update_playbook_input(self, playbook_id: str, new_inputs: dict): + saving_inputs_path = f"/playbook/inputs/{playbook_id}" + res = requests.post(url=f'{self.base_url}/public_api/v1{saving_inputs_path}', + headers=self._xdr_client.headers, json={"inputs":new_inputs}) + return self._process_response(res.content, res.status_code, 200) From 03a494e8f1b87ec0357bf42f7425ad05171f0c3b Mon Sep 17 00:00:00 2001 From: Jasmine Date: Sun, 10 Nov 2024 16:08:50 +0200 Subject: [PATCH 02/58] wip --- .../commands/common/clients/xsiam/xsiam_api_client.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py index 5b37a909d3d..2e4d879fbdb 100644 --- a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py +++ b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py @@ -287,12 +287,10 @@ def search_alerts(self, external_alert_id: str | list[str]): def get_playbook_data(self, playbook_id: int) -> dict: playbook_endpoint = f"/playbook/{playbook_id}" - res = requests.get(url=f'{self.base_url}/public_api/v1{playbook_endpoint}', - headers=self._xdr_client.headers, json=body) - return self._process_response(res.content, res.status_code, 200) + response, status_code, _ = self._xsoar_client.generic_request(playbook_endpoint, method='GET', accept='application/json') + return self._process_response(response, status_code, 200) def update_playbook_input(self, playbook_id: str, new_inputs: dict): saving_inputs_path = f"/playbook/inputs/{playbook_id}" - res = requests.post(url=f'{self.base_url}/public_api/v1{saving_inputs_path}', - headers=self._xdr_client.headers, json={"inputs":new_inputs}) - return self._process_response(res.content, res.status_code, 200) + response, status_code, _ = self._xsoar_client.generic_request(saving_inputs_path, method='POST', body={"inputs":new_inputs}) + return self._process_response(response, status_code, 200) From 30b9120cee3cd5c9519bd888f3da1bbb090fc4d6 Mon Sep 17 00:00:00 2001 From: Jasmine Date: Mon, 11 Nov 2024 14:34:57 +0200 Subject: [PATCH 03/58] wip --- demisto_sdk/__main__.py | 20 + demisto_sdk/commands/common/constants.py | 1 + .../run_playbook_flow_test.py | 1975 +++++++++++++++++ 3 files changed, 1996 insertions(+) create mode 100644 demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py diff --git a/demisto_sdk/__main__.py b/demisto_sdk/__main__.py index 5bfda94b65d..bb53c5cac68 100644 --- a/demisto_sdk/__main__.py +++ b/demisto_sdk/__main__.py @@ -68,6 +68,10 @@ ) from demisto_sdk.commands.setup_env.setup_environment import IDEType from demisto_sdk.commands.split.ymlsplitter import YmlSplitter +from demisto_sdk.commands.test_content.playbook_flow_test import ( + init_flow_test, + run_playbook_flow_test, +) from demisto_sdk.commands.test_content.test_modeling_rule import ( init_test_data, test_modeling_rule, @@ -3852,6 +3856,22 @@ def pre_commit( typer_click_object2 = typer.main.get_command(app_generate_modeling_rules) main.add_command(typer_click_object2, "generate-modeling-rules") +# ====================== playbook-flow test command group ====================== # +playbook_flow_app = typer.Typer( + name="playbook-flow-test", + hidden=True, + no_args_is_help=True, + context_settings={"help_option_names": ["-h", "--help"]}, +) +playbook_flow_app.command("test", no_args_is_help=True)( + run_playbook_flow_test.run_flow_test +) +playbook_flow_app.command("init", no_args_is_help=True)( + init_flow_test.create_new_flow_test +) +typer_click_object = typer.main.get_command(playbook_flow_app) +main.add_command(typer_click_object, "playbook-flow-test") + # ====================== graph command group ====================== # graph_cmd_group = typer.Typer( diff --git a/demisto_sdk/commands/common/constants.py b/demisto_sdk/commands/common/constants.py index 271412f42d2..b45fa634ff7 100644 --- a/demisto_sdk/commands/common/constants.py +++ b/demisto_sdk/commands/common/constants.py @@ -2212,3 +2212,4 @@ class PlaybookTaskType(StrEnum): # Test types: TEST_PLAYBOOKS = "TestPlaybooks" TEST_MODELING_RULES = "TestModelingRules" +PLAYBOOKS_FLOW_TEST = "PlaybookFlowTest" diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py new file mode 100644 index 00000000000..ee04a5fe4a0 --- /dev/null +++ b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py @@ -0,0 +1,1975 @@ +import logging +import os +from datetime import datetime +from pathlib import Path +from threading import Thread +from time import sleep +from typing import Any, Dict, List, Optional, Tuple, Union +from uuid import UUID + +import dateparser +import demisto_client +import pytest +import pytz +import requests +import typer +from google.cloud import storage # type: ignore[attr-defined] +from junitparser import Error, JUnitXml, TestCase, TestSuite +from junitparser.junitparser import Failure, Result, Skipped +from packaging.version import Version +from tabulate import tabulate +from tenacity import ( + Retrying, + before_sleep_log, + retry_if_exception_type, + stop_after_attempt, + wait_fixed, +) +from typer.main import get_command_from_info + +from demisto_sdk.commands.common.content_constant_paths import CONTENT_PATH +from demisto_sdk.commands.common.handlers import DEFAULT_JSON_HANDLER as json +from demisto_sdk.commands.common.logger import ( + handle_deprecated_args, + logger, + logging_setup, +) +from demisto_sdk.commands.common.tools import ( + get_file, + get_json_file, + is_epoch_datetime, + parse_int_or_default, + string_to_bool, +) +from demisto_sdk.commands.test_content.ParallelLoggingManager import ( + ParallelLoggingManager, +) +from demisto_sdk.commands.test_content.tools import get_ui_url +from demisto_sdk.commands.test_content.xsiam_tools.xsiam_client import ( + XsiamApiClient, + XsiamApiClientConfig, +) +from demisto_sdk.commands.upload.upload import upload_content_entity as upload_cmd +from demisto_sdk.utils.utils import get_containing_pack + +CI_PIPELINE_ID = os.environ.get("CI_PIPELINE_ID") +XSIAM_CLIENT_SLEEP_INTERVAL = 60 +XSIAM_CLIENT_RETRY_ATTEMPTS = 5 + +app = typer.Typer() + + +def get_utc_now() -> datetime: + """Get the current time in UTC, with timezone aware.""" + return datetime.now(tz=pytz.UTC) + + +def duration_since_start_time(start_time: datetime) -> float: + """Get the duration since the given start time, in seconds. + + Args: + start_time (datetime): Start time. + + Returns: + float: Duration since the given start time, in seconds. + """ + return (get_utc_now() - start_time).total_seconds() + + +def create_table(expected: Dict[str, Any], received: Dict[str, Any]) -> str: + """Create a table to display the expected and received values. + + Args: + expected: mapping of keys to expected values + received: mapping of keys to received values + + Returns: + String representation of a table, to display the expected and received values. + """ + data = [(key, str(val), str(received.get(key))) for key, val in expected.items()] + return tabulate( + data, + tablefmt="grid", + headers=["Model Field", "Expected Value", "Received Value"], + colalign=("left", "left", "left"), + ) + + +def day_suffix(day: int) -> str: + """ + Returns a suffix string base on the day of the month. + for 1, 21, 31 => st + for 2, 22 => nd + for 3, 23 => rd + for to all the others => th + + see here for more details: https://en.wikipedia.org/wiki/English_numerals#Ordinal_numbers + + Args: + day: The day of the month represented by a number. + + Returns: + suffix string (st, nd, rd, th). + """ + return "th" if 11 <= day <= 13 else {1: "st", 2: "nd", 3: "rd"}.get(day % 10, "th") + + +def get_relative_path_to_content(path: Path) -> str: + """Get the relative path to the content directory. + + Args: + path: The path to the content item. + + Returns: + Path: The relative path to the content directory. + """ + if path.is_absolute() and path.as_posix().startswith(CONTENT_PATH.as_posix()): + return path.as_posix().replace(f"{CONTENT_PATH.as_posix()}{os.path.sep}", "") + return path.as_posix() + + +def convert_epoch_time_to_string_time( + epoch_time: int, with_ms: bool = False, tenant_timezone: str = "UTC" +) -> str: + """ + Converts epoch time with milliseconds to string time with timezone delta. + + Args: + epoch_time: The received epoch time (with milliseconds). + with_ms: Whether to convert the epoch time with ms or not default is False. + tenant_timezone: The timezone of the XSIAM tenant. + + Returns: + The string time with timezone delta. + """ + datetime_object = datetime.fromtimestamp( + epoch_time / 1000, pytz.timezone(tenant_timezone) + ) + time_format = ( + f"%b %-d{day_suffix(datetime_object.day)} %Y %H:%M:%S{'.%f' if with_ms else ''}" + ) + return datetime_object.strftime(time_format) + + +def get_type_pretty_name(obj: Any) -> str: + """Get the pretty name of the type of the given object. + + Args: + obj (Any): The object to get the type name for. + + Returns: + str: The pretty name of the type of the given object. + """ + return { + type(None): "null", + list: "list", + dict: "dict", + tuple: "tuple", + set: "set", + UUID: "UUID", + str: "string", + int: "int", + float: "float", + bool: "boolean", + datetime: "datetime", + }.get(type(obj), str(type(obj))) + + +def sanitize_received_value_by_expected_type( + received_value: Any, expected_type: str +) -> Tuple[str, Any]: + """ + XSIAM returns numeric values from the API always as float, so we need to check if the expected type is int and if that's the + case and the value returned is a numeric without a floating point value, we can assume it's an int. + Args: + expected_type: The expected type of the object. + received_value: The object to get the type for. + + Returns: + The expected type of the object, and the object itself after being sanitized. + """ + received_value_type = get_type_pretty_name(received_value) + # The values returned from XSIAM for int/float are always float, so we need to check if the expected type is int. + if ( + expected_type == "int" + and received_value_type == "float" + and int(received_value) == received_value + ): + return "int", int(received_value) + return received_value_type, received_value + + +def create_retrying_caller(retry_attempts: int, sleep_interval: int) -> Retrying: + """Create a Retrying object with the given retry_attempts and sleep_interval.""" + sleep_interval = parse_int_or_default(sleep_interval, XSIAM_CLIENT_SLEEP_INTERVAL) + retry_attempts = parse_int_or_default(retry_attempts, XSIAM_CLIENT_RETRY_ATTEMPTS) + retry_params: Dict[str, Any] = { + "reraise": True, + "before_sleep": before_sleep_log(logger, logging.DEBUG), + "retry": retry_if_exception_type(requests.exceptions.RequestException), + "stop": stop_after_attempt(retry_attempts), + "wait": wait_fixed(sleep_interval), + } + return Retrying(**retry_params) + + +def xsiam_get_installed_packs(xsiam_client: XsiamApiClient) -> List[Dict[str, Any]]: + """Get the list of installed packs from the XSIAM tenant. + Wrapper for XsiamApiClient.get_installed_packs() with retry logic. + """ + return xsiam_client.installed_packs + + +def verify_results( + modeling_rule: ModelingRule, + tested_dataset: str, + results: List[dict], + test_data: TestData, +) -> List[TestCase]: + """Verify that the results of the XQL query match the expected values. + + Args: + modeling_rule: The modeling rule object parsed from the modeling rule file. + tested_dataset (str): The dataset to verify result for. + results (List[dict]): The results of the XQL query. + test_data (init_test_data.TestData): The data parsed from the test data file. + + Returns: + list[TestCase]: List of test cases for the results of the XQL query. + """ + + if not results: + logger.error( + f"[red]{SYNTAX_ERROR_IN_MODELING_RULE}[/red]", extra={"markup": True} + ) + test_case = TestCase( + f"Modeling rule - {modeling_rule.normalize_file_name()}", + classname="Modeling Rule Results", + ) + test_case.result += [Failure(SYNTAX_ERROR_IN_MODELING_RULE)] + test_case.system_err = SYNTAX_ERROR_IN_MODELING_RULE + return [test_case] + + rule_relevant_data = [ + data for data in test_data.data if data.dataset == tested_dataset + ] + if len(results) != len(rule_relevant_data): + err = ( + f"Expected {len(test_data.data)} results, got {len(results)}. Verify that the event" + " data used in your test data file meets the criteria of the modeling rule, e.g. the filter" + " condition." + ) + test_case = TestCase( + f"Modeling rule - {modeling_rule.normalize_file_name()}", + classname="Modeling Rule Results", + ) + test_case.result += [Failure(err)] + logger.error(f"[red]{err}[/red]", extra={"markup": True}) + return [test_case] + + test_cases = [] + for i, result in enumerate(results, start=1): + td_event_id = result.pop(f"{tested_dataset}.test_data_event_id") + msg = ( + f"Modeling rule - {get_relative_path_to_content(modeling_rule.path)} {i}/{len(results)}" + f" test_data_event_id:{td_event_id}" + ) + logger.info( + f"[cyan]{msg}[/cyan]", + extra={"markup": True}, + ) + result_test_case = TestCase( + msg, + classname=f"test_data_event_id:{td_event_id}", + ) + verify_results_against_test_data( + result_test_case, result, test_data, td_event_id + ) + + test_cases.append(result_test_case) + + return test_cases + + +def verify_results_against_test_data( + result_test_case: TestCase, + result: Dict[str, Any], + test_data: TestData, + td_event_id: str, +): + """Verify that the results of the XQL query match the expected values.""" + + result_test_case_system_out = [] + result_test_case_system_err = [] + result_test_case_results = [] + tenant_timezone: str = "" + expected_values = None + # Find the expected values for the given test data event ID. + for e in test_data.data: + if str(e.test_data_event_id) == td_event_id: + expected_values = e.expected_values + tenant_timezone = e.tenant_timezone + break + if not tenant_timezone: + result_test_case_system_out.append(TIME_ZONE_WARNING) + logger.warning(f"[yellow]{TIME_ZONE_WARNING}[/yellow]") + if expected_values: + if ( + expected_time_value := expected_values.get(SingleModelingRule.TIME_FIELD) + ) and (time_value := result.get(SingleModelingRule.TIME_FIELD)): + result[SingleModelingRule.TIME_FIELD] = convert_epoch_time_to_string_time( + time_value, "." in expected_time_value, tenant_timezone + ) + table_result = create_table(expected_values, result) + logger.info(f"\n{table_result}") + for expected_key, expected_value in expected_values.items(): + if expected_value: + received_value = result.get(expected_key) + expected_value_type = get_type_pretty_name(expected_value) + ( + received_value_type_sanitized, + received_value_sanitized, + ) = sanitize_received_value_by_expected_type( + received_value, expected_value_type + ) + out = ( + f"Checking for key {expected_key} - " + f"expected value:{expected_value} expected type:{expected_value_type} " + f"received value:{received_value_sanitized} received type:{received_value_type_sanitized} " + f"before sanitization - received value:{received_value} received type: " + f"{get_type_pretty_name(received_value)}" + ) + logger.debug(f"[cyan]{out}[/cyan]", extra={"markup": True}) + result_test_case_system_out.append(out) + if ( + received_value_sanitized == expected_value + and received_value_type_sanitized == expected_value_type + ): + out = f"Value:{received_value_sanitized} and Type:{received_value_type_sanitized} Matched for key {expected_key}" + result_test_case_system_out.append(out) + logger.debug(out) + else: + if received_value_type_sanitized == expected_value_type: + err = ( + f"Expected value does not match for key {expected_key}: - expected: {expected_value} - " + f"received: {received_value_sanitized} Types match:{received_value_type_sanitized}" + ) + logger.error( + f'[red][bold]{expected_key}[/bold] --- "{received_value_sanitized}" != "{expected_value}" ' + f"Types match:{received_value_type_sanitized}[/red]", + extra={"markup": True}, + ) + else: + # Types don't match, so values are not matching either, + # so it means that both do not match. + err = ( + f"Expected value and type do not match for key {expected_key}: - expected: {expected_value} - " + f"received: {received_value_sanitized} expected type: {expected_value_type} " + f"received type: {received_value_type_sanitized}" + ) + logger.error( + f'[red][bold]{expected_key}[/bold][red] --- "{received_value_sanitized}" != "{expected_value}"\n' + f' [bold]{expected_key}[/bold][red] --- Received value type: "{received_value_type_sanitized}" ' + f'!= Expected value type: "{expected_value_type}"[/red]', + extra={"markup": True}, + ) + result_test_case_system_err.append(err) + result_test_case_results.append(Failure(err)) + else: + err = f"No mapping for key {expected_key} - skipping checking match" + result_test_case_system_out.append(err) + result_test_case_results.append(Skipped(err)) # type:ignore[arg-type] + logger.debug(f"[cyan]{err}[/cyan]", extra={"markup": True}) + else: + err = f"No matching expected_values found for test_data_event_id={td_event_id} in test_data {test_data}" + logger.error(f"[red]{err}[/red]", extra={"markup": True}) + result_test_case_results.append(Failure(err)) + result_test_case.system_err = "\n".join(result_test_case_system_err) + result_test_case.system_out = "\n".join(result_test_case_system_out) + if result_test_case_results: + result_test_case.result += result_test_case_results + return result_test_case + + +def validate_expected_values( + xsiam_client: XsiamApiClient, + retrying_caller: Retrying, + modeling_rule: ModelingRule, + test_data: TestData, +) -> List[TestCase]: + """Validate the expected_values in the given test data file.""" + validate_expected_values_test_cases = [] + for rule in modeling_rule.rules: + validate_expected_values_test_case = TestCase( + f"Validate expected_values {modeling_rule.path} dataset:{rule.dataset} " + f"vendor:{rule.vendor} product:{rule.product}", + classname="Validate expected values query", + ) + query = generate_xql_query( + rule, + [ + str(d.test_data_event_id) + for d in test_data.data + if d.dataset == rule.dataset + ], + ) + query_info = f"Query for dataset {rule.dataset}:\n{query}" + logger.debug(query_info) + validate_expected_values_test_case_system_out = [query_info] + try: + results = retrying_caller(xsiam_execute_query, xsiam_client, query) + except requests.exceptions.RequestException: + logger.error( + f"[red]{XQL_QUERY_ERROR_EXPLANATION}[/red]", + extra={"markup": True}, + ) + validate_expected_values_test_case.system_err = XQL_QUERY_ERROR_EXPLANATION + validate_expected_values_test_case.result += [ + Error("Failed to execute XQL query") + ] + else: + verify_results_test_cases = verify_results( + modeling_rule, rule.dataset, results, test_data + ) + validate_expected_values_test_cases.extend(verify_results_test_cases) + validate_expected_values_test_case.system_out = "\n".join( + validate_expected_values_test_case_system_out + ) + validate_expected_values_test_cases.append(validate_expected_values_test_case) + + return validate_expected_values_test_cases + + +def validate_schema_aligned_with_test_data( + test_data: TestData, + schema: Dict, +) -> Tuple[bool, List[Result]]: + """ + Validates that the schema is aligned with the test-data types. + + Args: + test_data: the test data object. + schema: the content of the schema file. + Returns: + Tuple[bool, List[Result]]: if the schema is aligned with the test-data types and a list of the results. + """ + + # map each dataset from the schema to the correct events that has the same dataset + schema_dataset_to_events = { + dataset: [ + event_log for event_log in test_data.data if event_log.dataset == dataset + ] + for dataset in schema.keys() + } + + errors_occurred = False + results: List[Result] = [] + + for dataset, event_logs in schema_dataset_to_events.items(): + all_schema_dataset_mappings = schema[dataset] + test_data_mappings: Dict = {} + error_logs = set() + for event_log in event_logs: + for ( + event_key, + event_val, + ) in event_log.event_data.items(): # type:ignore[union-attr] + if ( + event_val is None + ): # if event_val is None, warn and continue looping. + info = f"{event_key=} is null on {event_log.test_data_event_id} event for {dataset=}, ignoring {event_key=}" + logger.warning(f"[yellow]{info}[/yellow]", extra={"markup": True}) + results.append(Skipped(info)) + # add the event key to the mapping to validate there isn't another key with a different type + test_data_mappings[event_key] = None + continue + + if schema_key_mappings := all_schema_dataset_mappings.get(event_key): + # we do not consider epochs as datetime in xsiam + if ( + isinstance(event_val, str) + and not is_epoch_datetime(event_val) + and dateparser.parse( + event_val, settings={"STRICT_PARSING": True} + ) + ): + event_val_type = datetime + else: + event_val_type = type(event_val) + + test_data_key_mappings = EXPECTED_SCHEMA_MAPPINGS[event_val_type] + + if ( + existing_testdata_key_mapping := test_data_mappings.get( + event_key + ) + ) and existing_testdata_key_mapping != test_data_key_mappings: + err = ( + f"The testdata contains events with the same {event_key=} " + f"that have different types for dataset {dataset}" + ) + error_logs.add(err) + results.append(Error(err)) # type:ignore[arg-type] + errors_occurred = True + continue + else: + test_data_mappings[event_key] = test_data_key_mappings + + if test_data_key_mappings != schema_key_mappings: + err = ( + f"The field {event_key} has mismatch on type or is_array in " + f"event ID {event_log.test_data_event_id} between testdata and schema --- " + f'TestData Mapping "{test_data_key_mappings}" != Schema Mapping "{schema_key_mappings}"' + ) + results.append(Error(err)) # type:ignore[arg-type] + error_logs.add( + f"[red][bold]the field {event_key} has mismatch on type or is_array in " + f"event ID {event_log.test_data_event_id} between testdata and schema[/bold][red] --- " + f'TestData Mapping "{test_data_key_mappings}" != Schema Mapping "{schema_key_mappings}"[/red]' + ) + errors_occurred = True + + if missing_test_data_keys := set(all_schema_dataset_mappings.keys()) - set( + test_data_mappings.keys() + ): + skipped = ( + f"The following fields {missing_test_data_keys} are in schema for dataset {dataset}, but not " + "in test-data, make sure to remove them from the schema or add them to test-data if necessary" + ) + logger.warning(f"[yellow]{skipped}[/yellow]", extra={"markup": True}) + results.append(Skipped(skipped)) + + if error_logs: + for _log in error_logs: + logger.error(_log, extra={"markup": True}) + else: + logger.info( + f"[green]Schema type mappings = Testdata type mappings for dataset {dataset}[/green]", + extra={"markup": True}, + ) + return not errors_occurred, results + + +def check_dataset_exists( + xsiam_client: XsiamApiClient, + retrying_caller: Retrying, + dataset: str, + init_sleep_time: int = 30, + print_errors: bool = True, +) -> TestCase: + """Check if the dataset in the test data file exists in the tenant. + + Args: + xsiam_client (XsiamApiClient): Xsiam API client. + retrying_caller (tenacity.Retrying): The retrying caller object. + dataset (str): The data set name. + init_sleep_time (int, optional): The number of seconds to wait for dataset installation. Defaults to 30. + print_errors (bool): Whether to print errors. + Returns: + TestCase: Test case for checking if the dataset exists in the tenant. + """ + process_failed = False + dataset_set_test_case = TestCase( + "Check if dataset exists in tenant", classname="Check dataset exists" + ) + dataset_set_test_case_start_time = get_utc_now() + test_case_results = [] + logger.debug( + f"Sleeping for {init_sleep_time} seconds before query for the dataset, to make sure the dataset was installed correctly." + ) + sleep(init_sleep_time) + start_time = get_utc_now() + results_exist = False + dataset_exist = False + logger.info( + f'[cyan]Checking if dataset "{dataset}" exists on the tenant...[/cyan]', + extra={"markup": True}, + ) + query = f"config timeframe = 10y | dataset = {dataset}" + try: + results = retrying_caller(xsiam_execute_query, xsiam_client, query) + + dataset_exist = True + if results: + logger.info( + f"[green]Dataset {dataset} exists[/green]", + extra={"markup": True}, + ) + results_exist = True + except requests.exceptions.RequestException: + results = [] + + # There are no results from the dataset, but it exists. + if not results: + err = ( + f"Dataset {dataset} exists but no results were returned. This could mean that your testdata " + "does not meet the criteria for an associated Parsing Rule and is therefore being dropped from " + "the dataset. Check to see if a Parsing Rule exists for your dataset and that your testdata " + "meets the criteria for that rule." + ) + test_case_results.append(Error(err)) + if print_errors: + logger.error(f"[red]{err}[/red]", extra={"markup": True}) + if not dataset_exist: + err = f"[red]Dataset {dataset} does not exist[/red]" + test_case_results.append(Error(err)) + if print_errors: + logger.error(f"[red]{err}[/red]", extra={"markup": True}) + + duration = duration_since_start_time(start_time) + logger.info(f"Processing Dataset {dataset} finished after {duration:.2f} seconds") + # OR statement between existence var and results of each data set, if at least one of dataset_exist or results_exist are False process_failed will be true. + process_failed |= not (dataset_exist and results_exist) + + if test_case_results: + dataset_set_test_case.result += test_case_results + dataset_set_test_case.time = duration_since_start_time( + dataset_set_test_case_start_time + ) + return dataset_set_test_case + + +def push_test_data_to_tenant( + xsiam_client: XsiamApiClient, + retrying_caller: Retrying, + mr: ModelingRule, + test_data: TestData, +) -> TestCase: + """Push the test data to the tenant. + + Args: + retrying_caller (tenacity.Retrying): The retrying caller object. + xsiam_client (XsiamApiClient): Xsiam API client. + mr (ModelingRule): Modeling rule object parsed from the modeling rule file. + test_data (init_test_data.TestData): Test data object parsed from the test data file. + Returns: + TestCase: Test case for pushing the test data to the tenant. + """ + push_test_data_test_case = TestCase( + f"Push test data to tenant {mr.path}", + classname="Push test data to tenant", + ) + push_test_data_test_case_start_time = get_utc_now() + system_errors = [] + for rule in mr.rules: + events_test_data = [ + { + **event_log.event_data, + "test_data_event_id": str(event_log.test_data_event_id), + } + for event_log in test_data.data + if isinstance(event_log.event_data, dict) + and event_log.dataset == rule.dataset + ] + logger.info( + f"[cyan]Pushing test data for {rule.dataset} to tenant...[/cyan]", + extra={"markup": True}, + ) + try: + retrying_caller(xsiam_push_to_dataset, xsiam_client, events_test_data, rule) + except requests.exceptions.RequestException: + system_err = ( + f"Failed pushing test data to tenant for dataset {rule.dataset}" + ) + system_errors.append(system_err) + logger.error(f"[red]{system_err}[/red]", extra={"markup": True}) + + if system_errors: + logger.error( + f"[red]{FAILURE_TO_PUSH_EXPLANATION}[/red]", + extra={"markup": True}, + ) + push_test_data_test_case.system_err = "\n".join(system_errors) + push_test_data_test_case.result += [Failure(FAILURE_TO_PUSH_EXPLANATION)] + else: + system_out = f"Test data pushed successfully for Modeling rule:{get_relative_path_to_content(mr.path)}" + push_test_data_test_case.system_out = system_out + logger.info(f"[green]{system_out}[/green]", extra={"markup": True}) + push_test_data_test_case.time = duration_since_start_time( + push_test_data_test_case_start_time + ) + return push_test_data_test_case + + +def verify_pack_exists_on_tenant( + xsiam_client: XsiamApiClient, + retrying_caller: Retrying, + mr: ModelingRule, + interactive: bool, +) -> bool: + """Verify that the pack containing the modeling rule exists on the tenant. + + Args: + retrying_caller (tenacity.Retrying): The retrying caller object. + xsiam_client (XsiamApiClient): Xsiam API client. + mr (ModelingRule): Modeling rule object parsed from the modeling rule file. + interactive (bool): Whether command is being run in interactive mode. + """ + logger.info( + "[cyan]Verifying pack installed on tenant[/cyan]", extra={"markup": True} + ) + containing_pack = get_containing_pack(mr) + containing_pack_id = containing_pack.id + installed_packs = retrying_caller(xsiam_get_installed_packs, xsiam_client) + if found_pack := next( + (pack for pack in installed_packs if containing_pack_id == pack.get("id")), + None, + ): + logger.debug( + f"[cyan]Found pack on tenant:\n{found_pack}[/cyan]", extra={"markup": True} + ) + else: + logger.error( + f"[red]Pack {containing_pack_id} was not found on tenant[/red]", + extra={"markup": True}, + ) + + upload_result = 0 + if interactive: + if typer.confirm( + f"Would you like to upload {containing_pack_id} to the tenant?" + ): + logger.info( + f'[cyan][underline]Upload "{containing_pack_id}"[/underline][/cyan]', + extra={"markup": True}, + ) + upload_kwargs = { + "zip": True, + "xsiam": True, + "input": containing_pack.path, + "keep_zip": None, + "insecure": False, + "input_config_file": None, + "skip_validation": False, + "reattach": True, + } + upload_result = upload_cmd(**upload_kwargs) + if upload_result != 0: + logger.error( + f"[red]Failed to upload pack {containing_pack_id} to tenant[/red]", + extra={"markup": True}, + ) + # wait for pack to finish installing + sleep(1) + else: + upload_result = 1 + if not interactive or upload_result != 0: + logger.error( + "[red]Pack does not exist on the tenant. Please install or upload the pack and try again[/red]", + extra={"markup": True}, + ) + logger.info( + f"\ndemisto-sdk upload -z -x -i {containing_pack.path}\ndemisto-sdk modeling-rules test {mr.path.parent}" + ) + return False + return True + + +def is_test_data_exists_on_server( + test_data_path: Path, +) -> Tuple[List[UUID], List[UUID]]: + """Verify that the test data exists and is valid. + + Args: + test_data_path (Path): Path to the test data file. + + Returns: + Tuple[List[str], List[str]]: Tuple of lists where the first list is test event + first list: ids that do not have example event data. + second list is test event ids that do not have expected_values to check. + """ + missing_event_data, missing_expected_values_data = [], [] + test_data = TestData.parse_file(test_data_path) + for event_log in test_data.data: + if not event_log.event_data: + missing_event_data.append(event_log.test_data_event_id) + if all(val is None for val in event_log.expected_values.values()): + missing_expected_values_data.append(event_log.test_data_event_id) + return missing_event_data, missing_expected_values_data + + +def verify_event_id_does_not_exist_on_tenant( + xsiam_client: XsiamApiClient, + modeling_rule: ModelingRule, + test_data: TestData, + retrying_caller: Retrying, +) -> List[TestCase]: + """ + Verify that the event ID does not exist on the tenant. + Args: + xsiam_client (XsiamApiClient): Xsiam API client. + modeling_rule (ModelingRule): Modeling rule object parsed from the modeling rule file. + test_data (init_test_data.TestData): Test data object parsed from the test data file. + retrying_caller (Retrying): The retrying caller object. + """ + logger.info( + "[cyan]Verifying that the event IDs does not exist on the tenant[/cyan]", + extra={"markup": True}, + ) + success_msg = "[green]The event IDs does not exists on the tenant[/green]" + error_msg = "The event id already exists in the tenant" + validate_expected_values_test_cases = [] + + for rule in modeling_rule.rules: + validate_event_id_does_not_exist_on_tenant_test_case = TestCase( + f"Validate event_id_does_not_exist_on_tenant {get_relative_path_to_content(modeling_rule.path)} dataset:{rule.dataset} " + f"vendor:{rule.vendor} product:{rule.product}", + classname="Validate event id does not exist query", + ) + test_data_event_ids = [ + f'"{d.test_data_event_id}"' + for d in test_data.data + if d.dataset == rule.dataset + ] + td_event_ids = ", ".join(test_data_event_ids) + query = f"config timeframe = 10y | datamodel dataset in({rule.dataset}) | filter {rule.dataset}.test_data_event_id in({td_event_ids})" + + try: + result = retrying_caller(xsiam_execute_query, xsiam_client, query) + except requests.exceptions.HTTPError: + logger.info( + success_msg, + extra={"markup": True}, + ) + else: + if not result: + logger.info( + success_msg, + extra={"markup": True}, + ) + else: + logger.error( + error_msg, + extra={"markup": True}, + ) + validate_event_id_does_not_exist_on_tenant_test_case.result += [ + Error(error_msg) + ] + validate_expected_values_test_cases.append( + validate_event_id_does_not_exist_on_tenant_test_case + ) + + return validate_expected_values_test_cases + + +def delete_dataset( + xsiam_client: XsiamApiClient, + dataset_name: str, +): + logger.info( + f"[cyan]Deleting existing {dataset_name} dataset[/cyan]", + extra={"markup": True}, + ) + xsiam_client.delete_dataset(dataset_name) + logger.info( + f"[green]Dataset {dataset_name} deleted successfully[/green]", + extra={"markup": True}, + ) + + +def delete_existing_dataset_flow( + xsiam_client: XsiamApiClient, test_data: TestData, retrying_caller: Retrying +) -> None: + """ + Delete existing dataset if it exists in the tenant. + Args: + xsiam_client (XsiamApiClient): Xsiam API client. + test_data (TestData): Test data object parsed from the test data file. + retrying_caller (Retrying): The retrying caller object. + """ + dataset_to_check = list(set([data.dataset for data in test_data.data])) + for dataset in dataset_to_check: + dataset_set_test_case = check_dataset_exists( + xsiam_client, retrying_caller, dataset, print_errors=False + ) + if dataset_set_test_case.is_passed: + delete_dataset(xsiam_client, dataset) + else: + logger.info("[cyan]Dataset does not exists on tenant[/cyan]") + + +def verify_data_sets_exists(xsiam_client, retrying_caller, test_data): + datasets_test_case_ls = [] + for dataset in test_data.data: + dataset_name = dataset.dataset + dataset_test_case = check_dataset_exists( + xsiam_client, retrying_caller, dataset_name + ) + datasets_test_case_ls.append(dataset_test_case) + return datasets_test_case_ls + + +def run_test(test_file, xsiam_client: XsiamApiClient, durations_path): + class ClientPlugin: + def __init__(self, client): + self.client = client + + def pytest_generate_tests(self, metafunc): + if "api_client" in metafunc.fixturenames: + metafunc.parametrize("api_client", [self.client], indirect=True) + + # Run pytest with the specified arguments + pytest_args = [ + "-v", # Verbose output + test_file, # Path to the test file + "--durations=" + str(5), # Record and show durations + "--durations-report=" + durations_path, + ] + + # Pass the client object using a custom plugin + try: + pytest.main(pytest_args, plugins=[ClientPlugin(xsiam_client)]) + except Exception as e: + logger.warning(str(e)) + + + +# def validate_modeling_rule( +# modeling_rule_directory: Path, +# xsiam_url: str, +# retrying_caller: Retrying, +# push: bool, +# interactive: bool, +# ctx: typer.Context, +# delete_existing_dataset: bool, +# is_nightly: bool, +# xsiam_client: XsiamApiClient, +# tenant_demisto_version: Version, +# ) -> Tuple[bool, Union[TestSuite, None]]: +# """Validate a modeling rule. + +# Args: +# modeling_rule_directory (Path): Path to the modeling rule directory. +# retrying_caller (tenacity.Retrying): The retrying caller object. +# xsiam_url (str): URL of the xsiam tenant. +# push (bool): Whether to push test event data to the tenant. +# interactive (bool): Whether command is being run in interactive mode. +# ctx (typer.Context): Typer context. +# delete_existing_dataset (bool): Whether to delete the existing dataset in the tenant. +# is_nightly (bool): Whether the command is being run in nightly mode. +# xsiam_client (XsiamApiClient): The XSIAM client used to do API calls to the tenant. +# tenant_demisto_version (Version): The demisto version of the XSIAM tenant. +# """ +# modeling_rule = ModelingRule(modeling_rule_directory.as_posix()) +# modeling_rule_file_name = Path(modeling_rule.path).name +# containing_pack = get_containing_pack(modeling_rule) +# executed_command = ( +# f"{ctx.command_path} {get_relative_path_to_content(modeling_rule_directory)}" +# ) + +# modeling_rule_test_suite = TestSuite( +# f"Modeling Rule Test Results {modeling_rule_file_name}" +# ) +# modeling_rule_test_suite.add_property( +# "file_name", modeling_rule_file_name +# ) # used in the convert to jira issue. +# modeling_rule_test_suite.filepath = get_relative_path_to_content( # type:ignore[arg-type] +# modeling_rule.path +# ) +# modeling_rule_test_suite.add_property( +# "modeling_rule_path", get_relative_path_to_content(modeling_rule.path) +# ) +# modeling_rule_test_suite.add_property( +# "modeling_rule_file_name", modeling_rule_file_name +# ) +# modeling_rule_test_suite.add_property( +# "test_data_path", +# get_relative_path_to_content(modeling_rule.testdata_path) +# if modeling_rule.testdata_path +# else NOT_AVAILABLE, +# ) +# modeling_rule_test_suite.add_property( +# "schema_path", +# get_relative_path_to_content( +# modeling_rule.schema_path # type:ignore[arg-type] +# ), +# ) +# modeling_rule_test_suite.add_property("push", push) # type:ignore[arg-type] +# modeling_rule_test_suite.add_property( +# "interactive", +# interactive, # type:ignore[arg-type] +# ) +# modeling_rule_test_suite.add_property("xsiam_url", xsiam_url) +# modeling_rule_test_suite.add_property( +# "from_version", +# modeling_rule.from_version, # type:ignore[arg-type] +# ) # +# modeling_rule_test_suite.add_property( +# "to_version", +# modeling_rule.to_version, # type:ignore[arg-type] +# ) # +# modeling_rule_test_suite.add_property( +# "pack_id", containing_pack.id +# ) # used in the convert to jira issue. +# if CI_PIPELINE_ID: +# modeling_rule_test_suite.add_property("ci_pipeline_id", CI_PIPELINE_ID) +# if modeling_rule.testdata_path: +# logger.info( +# f"[cyan]Test data file found at {get_relative_path_to_content(modeling_rule.testdata_path)}\n" +# f"Checking that event data was added to the test data file[/cyan]", +# extra={"markup": True}, +# ) +# try: +# test_data = TestData.parse_file(modeling_rule.testdata_path.as_posix()) +# except ValueError as ex: +# err = f"Failed to parse test data file {get_relative_path_to_content(modeling_rule.testdata_path)} as JSON" +# logger.error( +# f"[red]{err}[/red]", +# extra={"markup": True}, +# ) +# test_case = TestCase( +# "Failed to parse test data file as JSON", +# classname="Modeling Rule", +# ) +# test_case.system_err = str(ex) +# test_case.result += [Error(err)] +# modeling_rule_test_suite.add_testcase(test_case) +# return False, modeling_rule_test_suite + +# modeling_rule_is_compatible = validate_modeling_rule_version_against_tenant( +# to_version=modeling_rule.to_version, +# from_version=modeling_rule.from_version, +# tenant_demisto_version=tenant_demisto_version, +# ) +# if not modeling_rule_is_compatible: +# # Modeling rule version is not compatible with the demisto version of the tenant, skipping +# skipped = f"XSIAM Tenant's Demisto version doesn't match Modeling Rule {modeling_rule} version, skipping" +# logger.warning(f"[yellow]{skipped}[/yellow]", extra={"markup": True}) +# test_case = TestCase( +# "Modeling Rule not compatible with XSIAM tenant's demisto version", +# classname=f"Modeling Rule {modeling_rule_file_name}", +# ) +# test_case.result += [Skipped(skipped)] # type:ignore[arg-type] +# modeling_rule_test_suite.add_testcase(test_case) +# # Return True since we don't want to fail the command +# return True, modeling_rule_test_suite +# if ( +# Validations.TEST_DATA_CONFIG_IGNORE.value +# not in test_data.ignored_validations +# ): +# logger.info( +# "[green]test data config is not ignored starting the test data validation...[/green]", +# extra={"markup": True}, +# ) +# missing_event_data, _ = is_test_data_exists_on_server( +# modeling_rule.testdata_path +# ) +# if not verify_pack_exists_on_tenant( +# xsiam_client, retrying_caller, modeling_rule, interactive +# ): +# test_case = TestCase( +# "Pack not installed on tenant", classname="Modeling Rule" +# ) +# return add_result_to_test_case( +# "Pack not installed on tenant", +# test_case, +# modeling_rule_test_suite, +# ) +# if delete_existing_dataset: +# delete_existing_dataset_flow(xsiam_client, test_data, retrying_caller) +# schema_test_case = TestCase( +# "Validate Schema", +# classname=f"Modeling Rule {get_relative_path_to_content(modeling_rule.schema_path)}", # type:ignore[arg-type] +# ) +# if schema_path := modeling_rule.schema_path: +# try: +# schema = get_file(schema_path) +# except json.JSONDecodeError as ex: +# err = f"Failed to parse schema file {get_relative_path_to_content(modeling_rule.schema_path)} as JSON" +# logger.error( +# f"[red]{err}[/red]", +# extra={"markup": True}, +# ) +# schema_test_case.system_err = str(ex) +# return add_result_to_test_case( +# err, schema_test_case, modeling_rule_test_suite +# ) +# else: +# err = f"Schema file does not exist in path {get_relative_path_to_content(modeling_rule.schema_path)}" +# return log_error_to_test_case( +# err, schema_test_case, modeling_rule_test_suite +# ) +# if ( +# Validations.SCHEMA_TYPES_ALIGNED_WITH_TEST_DATA.value +# not in test_data.ignored_validations +# ): +# logger.info( +# f"[green]Validating that the schema {get_relative_path_to_content(schema_path)} " +# "is aligned with TestData file.[/green]", +# extra={"markup": True}, +# ) + +# success, results = validate_schema_aligned_with_test_data( +# test_data=test_data, +# schema=schema, # type:ignore[arg-type] +# ) +# schema_test_case.result += results +# if not success: +# err = ( +# f"The schema {get_relative_path_to_content(schema_path)} is not aligned with the test data file " +# f"{get_relative_path_to_content(modeling_rule.testdata_path)}" +# ) +# return log_error_to_test_case( +# err, schema_test_case, modeling_rule_test_suite +# ) +# else: +# skipped = ( +# f"Skipping the validation to check that the schema {get_relative_path_to_content(schema_path)} " +# "is aligned with TestData file." +# ) +# logger.info(f"[green]{skipped}[/green]", extra={"markup": True}) +# schema_test_case.result += [Skipped(skipped)] # type:ignore[arg-type] +# modeling_rule_test_suite.add_testcase(schema_test_case) + +# if push: +# event_id_exists_test_case = verify_event_id_does_not_exist_on_tenant( +# xsiam_client, modeling_rule, test_data, retrying_caller +# ) +# modeling_rule_test_suite.add_testcases(event_id_exists_test_case) +# if missing_event_data: +# return handle_missing_event_data_in_modeling_rule( +# missing_event_data, +# modeling_rule, +# modeling_rule_test_suite, +# executed_command, +# ) +# push_test_data_test_case = push_test_data_to_tenant( +# xsiam_client, retrying_caller, modeling_rule, test_data +# ) +# modeling_rule_test_suite.add_testcase(push_test_data_test_case) +# if not push_test_data_test_case.is_passed: +# return False, modeling_rule_test_suite +# datasets_test_case = verify_data_sets_exists( +# xsiam_client, retrying_caller, test_data +# ) +# modeling_rule_test_suite.add_testcases(datasets_test_case) +# else: +# logger.info( +# '[cyan]The command flag "--no-push" was passed - skipping pushing of test data[/cyan]', +# extra={"markup": True}, +# ) +# logger.info( +# "[cyan]Validating expected_values...[/cyan]", extra={"markup": True} +# ) +# validate_expected_values_test_cases = validate_expected_values( +# xsiam_client, retrying_caller, modeling_rule, test_data +# ) +# modeling_rule_test_suite.add_testcases(validate_expected_values_test_cases) +# if ( +# not modeling_rule_test_suite.errors +# and not modeling_rule_test_suite.failures +# ): +# logger.info( +# "[green]All mappings validated successfully[/green]", +# extra={"markup": True}, +# ) +# return True, modeling_rule_test_suite +# return False, modeling_rule_test_suite +# else: +# logger.info( +# "[green]test data config is ignored skipping the test data validation[/green]", +# extra={"markup": True}, +# ) +# return True, modeling_rule_test_suite +# else: +# logger.warning( +# f"[yellow]No test data file found for {get_relative_path_to_content(modeling_rule_directory)}[/yellow]", +# extra={"markup": True}, +# ) +# if interactive: +# if typer.confirm( +# f"Would you like to generate a test data file for {get_relative_path_to_content(modeling_rule_directory)}?" +# ): +# logger.info( +# "[cyan][underline]Generate Test Data File[/underline][/cyan]", +# extra={"markup": True}, +# ) +# events_count = typer.prompt( +# "For how many events would you like to generate templates?", +# type=int, +# default=1, +# show_default=True, +# ) + +# from demisto_sdk.commands.test_content.test_modeling_rule.init_test_data import ( +# app as init_td_app, +# ) + +# if not init_td_app.registered_commands: +# err = ( +# '[red]Failed to load the "init-test-data" typer application to interactively create a ' +# "testdata file.[/red]" +# ) +# logger.error(err, extra={"markup": True}) +# return False, None + +# # the init-test-data typer application should only have the one command +# init_td_cmd_info = init_td_app.registered_commands[0] + +# init_td_cmd = get_command_from_info( +# init_td_cmd_info, +# pretty_exceptions_short=app.pretty_exceptions_short, +# rich_markup_mode=app.rich_markup_mode, +# ) +# init_td_cmd_ctx = init_td_cmd.make_context( +# init_td_cmd.name, +# [modeling_rule_directory.as_posix(), f"--count={events_count}"], +# parent=ctx, +# ) +# init_td_cmd.invoke(init_td_cmd_ctx) + +# if modeling_rule.testdata_path: +# logger.info( +# f"[green]Test data file generated for " +# f"{get_relative_path_to_content(modeling_rule_directory)}" +# f"Please complete the test data file at {get_relative_path_to_content(modeling_rule.testdata_path)} " +# f"with test event(s) data and expected outputs and then run:\n[bold]{executed_command}[/bold][/green]", +# extra={"markup": True}, +# ) +# return True, None +# logger.error( +# f"[red]Failed to generate test data file for " +# f"{get_relative_path_to_content(modeling_rule_directory)}[/red]", +# extra={"markup": True}, +# ) +# else: +# logger.warning( +# f"[yellow]Skipping test data file generation for " +# f"{get_relative_path_to_content(modeling_rule_directory)}[/yellow]", +# extra={"markup": True}, +# ) +# logger.error( +# f"[red]Please create a test data file for " +# f"{get_relative_path_to_content(modeling_rule_directory)} and then rerun\n{executed_command}[/red]", +# extra={"markup": True}, +# ) +# else: +# if is_nightly: +# # Running in nightly mode, don't fail the test if no test data file is found. +# err = f"No test data file for {get_relative_path_to_content(modeling_rule_directory)} found. " +# logger.warning( +# f"[red]{err}[/red]", +# extra={"markup": True}, +# ) +# test_data_test_case = TestCase( +# "Test data file does not exist", +# classname=f"Modeling Rule {get_relative_path_to_content(modeling_rule.schema_path)}", # type:ignore[arg-type] +# ) +# test_data_test_case.result += [Skipped(err)] # type:ignore[arg-type] +# modeling_rule_test_suite.add_testcase(test_data_test_case) +# return True, modeling_rule_test_suite + +# # Not running in nightly mode, fail the test if no test data file is found. +# err = ( +# f"Please create a test data file for {get_relative_path_to_content(modeling_rule_directory)} " +# f"and then rerun\n{executed_command}" +# ) +# logger.error( +# f"[red]{err}[/red]", +# extra={"markup": True}, +# ) +# test_data_test_case = TestCase( +# "Test data file does not exist", +# classname=f"Modeling Rule {get_relative_path_to_content(modeling_rule.schema_path)}", # type:ignore[arg-type] +# ) +# test_data_test_case.result += [Error(err)] # type:ignore[arg-type] +# modeling_rule_test_suite.add_testcase(test_data_test_case) +# return False, modeling_rule_test_suite +# return False, None + + +def validate_modeling_rule_version_against_tenant( + to_version: Version, from_version: Version, tenant_demisto_version: Version +) -> bool: + """Checks if the version of the modeling rule is compatible with the XSIAM tenant's demisto version. + Compatibility is checked by: from_version <= tenant_xsiam_version <= to_version + + Args: + to_version (Version): The to version of the modeling rule + from_version (Version): The from version of the modeling rule + tenant_demisto_version (Version): The demisto version of the XSIAM tenant + + Returns: + bool: True if the version of the modeling rule is compatible, else False + """ + return from_version <= tenant_demisto_version <= to_version + + +def handle_missing_event_data_in_modeling_rule( + missing_event_data: List[UUID], + modeling_rule: ModelingRule, + modeling_rule_test_suite: TestSuite, + executed_command: str, +) -> Tuple[bool, TestSuite]: + """Handle missing event data in the modeling rule. + Args: + missing_event_data (List[UUID]): List of event ids that do not have example event data. + modeling_rule (ModelingRule): Modeling rule object parsed from the modeling rule file. + modeling_rule_test_suite (TestSuite): Test suite for the modeling rule. + executed_command (str): The executed command. + Returns: + Tuple[bool, TestSuite]: Tuple of a boolean indicating whether the test passed and the test suite. + """ + missing_event_data_test_case = TestCase( + "Missing Event Data", classname="Modeling Rule" + ) + err = f"Missing Event Data for the following test data event ids: {missing_event_data}" + missing_event_data_test_case.result += [Error(err)] # type:ignore[arg-type] + prefix = "Event log test data is missing for the following ids:" + system_errors = [prefix] + logger.warning( + f"[yellow]{prefix}[/yellow]", + extra={"markup": True}, + ) + for test_data_event_id in missing_event_data: + logger.warning( + f"[yellow] - {test_data_event_id}[/yellow]", + extra={"markup": True}, + ) + system_errors.append(str(test_data_event_id)) + suffix = ( + f"Please complete the test data file at {get_relative_path_to_content(modeling_rule.testdata_path)} " # type:ignore[arg-type] + f"with test event(s) data and expected outputs and then rerun" + ) + logger.warning( + f"[yellow]{suffix}[/yellow]\n[bold][yellow]{executed_command}[/yellow][/bold]", + extra={"markup": True}, + ) + system_errors.extend([suffix, executed_command]) + missing_event_data_test_case.system_err = "\n".join(system_errors) + modeling_rule_test_suite.add_testcase(missing_event_data_test_case) + + return False, modeling_rule_test_suite + + +def log_error_to_test_case( + err: str, schema_test_case: TestCase, modeling_rule_test_suite: TestSuite +) -> Tuple[bool, TestSuite]: + logger.error( + f"[red]{err}[/red]", + extra={"markup": True}, + ) + schema_test_case.system_err = err + return add_result_to_test_case(err, schema_test_case, modeling_rule_test_suite) + + +def add_result_to_test_case( + err: str, test_case: TestCase, modeling_rule_test_suite: TestSuite +) -> Tuple[bool, TestSuite]: + test_case.result += [Error(err)] # type:ignore[arg-type] + modeling_rule_test_suite.add_testcase(test_case) + return False, modeling_rule_test_suite + + +# ====================== test-modeling-rule ====================== # + + +def tenant_config_cb( + ctx: typer.Context, param: typer.CallbackParam, value: Optional[str] +): + if ctx.resilient_parsing: + return + # Only check the params if the machine_assignment is not set. + if param.value_is_missing(value) and not ctx.params.get("machine_assignment"): + err_str = ( + f"{param.name} must be set either via the environment variable " + f'"{param.envvar}" or passed explicitly when running the command' + ) + raise typer.BadParameter(err_str) + return value + + +def logs_token_cb(ctx: typer.Context, param: typer.CallbackParam, value: Optional[str]): + if ctx.resilient_parsing: + return + # Only check the params if the machine_assignment is not set. + if param.value_is_missing(value) and not ctx.params.get("machine_assignment"): + parameter_to_check = "xsiam_token" + other_token = ctx.params.get(parameter_to_check) + if not other_token: + err_str = ( + f"One of {param.name} or {parameter_to_check} must be set either via it's associated" + " environment variable or passed explicitly when running the command" + ) + raise typer.BadParameter(err_str) + return value + + +class TestResults: + def __init__( + self, + service_account: str = None, + artifacts_bucket: str = None, + ): + self.test_results_xml_file = JUnitXml() + self.errors = False + self.service_account = service_account + self.artifacts_bucket = artifacts_bucket + + def upload_modeling_rules_result_json_to_bucket( + self, + repository_name: str, + file_name, + original_file_path: Path, + logging_module: Union[Any, ParallelLoggingManager] = logging, + ): + """Uploads a JSON object to a specified path in the GCP bucket. + + Args: + original_file_path: The path to the JSON file to upload. + repository_name: The name of the repository within the bucket. + file_name: The desired filename for the uploaded JSON data. + logging_module: Logging module to use for upload_modeling_rules_result_json_to_bucket. + """ + logging_module.info("Start uploading modeling rules results file to bucket") + + storage_client = storage.Client.from_service_account_json(self.service_account) + storage_bucket = storage_client.bucket(self.artifacts_bucket) + + blob = storage_bucket.blob( + f"content-test-modeling-rules/{repository_name}/{file_name}" + ) + blob.upload_from_filename( + original_file_path.as_posix(), + content_type="application/xml", + ) + + logging_module.info("Finished uploading modeling rules results file to bucket") + + +class BuildContext: + def __init__( + self, + nightly: bool, + build_number: Optional[str], + branch_name: Optional[str], + retry_attempts: int, + sleep_interval: int, + logging_module: ParallelLoggingManager, + cloud_servers_path: str, + cloud_servers_api_keys: str, + service_account: Optional[str], + artifacts_bucket: Optional[str], + xsiam_url: Optional[str], + xsiam_token: Optional[str], + api_key: Optional[str], + auth_id: Optional[str], + collector_token: Optional[str], + inputs: Optional[List[Path]], + machine_assignment: str, + push: bool, + interactive: bool, + delete_existing_dataset: bool, + ctx: typer.Context, + ): + self.logging_module: ParallelLoggingManager = logging_module + self.retrying_caller = create_retrying_caller(retry_attempts, sleep_interval) + self.ctx = ctx + + # --------------------------- overall build configuration ------------------------------- + self.is_nightly = nightly + self.build_number = build_number + self.build_name = branch_name + + # -------------------------- Manual run on a single instance -------------------------- + self.xsiam_url = xsiam_url + self.xsiam_token = xsiam_token + self.api_key = api_key + self.auth_id = auth_id + self.collector_token = collector_token + self.inputs = inputs + + # --------------------------- Pushing data settings ------------------------------- + + self.push = push + self.interactive = interactive + self.delete_existing_dataset = delete_existing_dataset + + # --------------------------- Machine preparation ------------------------------- + + self.cloud_servers_path_json = get_json_file(cloud_servers_path) + self.cloud_servers_api_keys_json = get_json_file(cloud_servers_api_keys) + self.machine_assignment_json = get_json_file(machine_assignment) + + # --------------------------- Testing preparation ------------------------------- + + self.tests_data_keeper = TestResults( + service_account, + artifacts_bucket, + ) + + # --------------------------- Machine preparation logic ------------------------------- + + self.servers = self.create_servers() + + @staticmethod + def prefix_with_packs(path_str: Union[str, Path]) -> Path: + path = Path(path_str) + if path.parts[0] == "Packs": + return path + return Path("Packs") / path + + def create_servers(self): + """ + Create servers object based on build type. + """ + # If xsiam_url is provided we assume it's a run on a single server. + if self.xsiam_url: + return [ + CloudServerContext( + self, + base_url=self.xsiam_url, + api_key=self.api_key, # type: ignore[arg-type] + auth_id=self.auth_id, # type: ignore[arg-type] + token=self.xsiam_token, # type: ignore[arg-type] + collector_token=self.collector_token, + ui_url=get_ui_url(self.xsiam_url), + tests=[BuildContext.prefix_with_packs(test) for test in self.inputs] + if self.inputs + else [], + ) + ] + servers_list = [] + for machine, assignment in self.machine_assignment_json.items(): + tests = [ + BuildContext.prefix_with_packs(test) + for test in assignment.get("tests", {}).get('PlaybookFlowTest', []) + ] + if not tests: + logger.info(f"No playbook flow tests found for machine {machine}") + continue + servers_list.append( + CloudServerContext( + self, + base_url=self.cloud_servers_path_json.get(machine, {}).get( + "base_url", "" + ), + ui_url=self.cloud_servers_path_json.get(machine, {}).get( + "ui_url", "" + ), + tests=tests, + api_key=self.cloud_servers_api_keys_json.get(machine, {}).get( + "api-key" + ), + auth_id=self.cloud_servers_api_keys_json.get(machine, {}).get( + "x-xdr-auth-id" + ), + token=self.cloud_servers_api_keys_json.get(machine, {}).get( + "token" + ), + ) + ) + return servers_list + + +class CloudServerContext: + def __init__( + self, + build_context: BuildContext, + base_url: str, + api_key: str, + auth_id: str, + token: str, + ui_url: str, + tests: List[Path], + collector_token: Optional[str] = None, + ): + self.build_context = build_context + self.client = None + self.base_url = base_url + self.api_key = api_key + self.auth_id = auth_id + self.token = token + self.collector_token = collector_token + os.environ.pop( + "DEMISTO_USERNAME", None + ) # we use client without demisto username + self.configure_new_client() + self.ui_url = ui_url + self.tests = tests + + def configure_new_client(self): + if self.client: + self.client.api_client.pool.close() + self.client.api_client.pool.terminate() + del self.client + self.client = demisto_client.configure( + base_url=self.base_url, + api_key=self.api_key, + auth_id=self.auth_id, + verify_ssl=False, + ) + + def execute_tests(self): + try: + self.build_context.logging_module.info( + f"Starts tests with server url - {get_ui_url(self.ui_url)}", + real_time=True, + ) + start_time = get_utc_now() + self.build_context.logging_module.info( + f"Running the following tests: {self.tests}", + real_time=True, + ) + + xsiam_client_cfg = XsiamApiClientConfig( + base_url=self.base_url, # type: ignore[arg-type] + api_key=self.api_key, # type: ignore[arg-type] + auth_id=self.auth_id, # type: ignore[arg-type] + token=self.token, # type: ignore[arg-type] + collector_token=self.collector_token, # type: ignore[arg-type] + ) + xsiam_client = XsiamApiClient(xsiam_client_cfg) + tenant_demisto_version: Version = xsiam_client.get_demisto_version() + for i, playbook_flow_directory in enumerate(self.tests, start=1): + logger.info( + f"[cyan][{i}/{len(self.tests)}] Playbook Flow Test: {get_relative_path_to_content(playbook_flow_directory)}[/cyan]", + extra={"markup": True}, + ) + success, modeling_rule_test_suite = validate_modeling_rule( + playbook_flow_directory, + # can ignore the types since if they are not set to str values an error occurs + self.base_url, # type: ignore[arg-type] + self.build_context.retrying_caller, + self.build_context.push, + self.build_context.interactive, + self.build_context.ctx, + self.build_context.delete_existing_dataset, + self.build_context.is_nightly, + xsiam_client=xsiam_client, + tenant_demisto_version=tenant_demisto_version, + ) + if success: + logger.info( + f"[green]Test Modeling rule {get_relative_path_to_content(modeling_rule_directory)} passed[/green]", + extra={"markup": True}, + ) + else: + self.build_context.tests_data_keeper.errors = True + logger.error( + f"[red]Test Modeling Rule {get_relative_path_to_content(modeling_rule_directory)} failed[/red]", + extra={"markup": True}, + ) + if modeling_rule_test_suite: + modeling_rule_test_suite.add_property( + "start_time", + start_time, # type:ignore[arg-type] + ) + self.build_context.tests_data_keeper.test_results_xml_file.add_testsuite( + modeling_rule_test_suite + ) + + self.build_context.logging_module.info( + f"Finished tests with server url - " f"{self.ui_url}", + real_time=True, + ) + duration = duration_since_start_time(start_time) + self.build_context.logging_module.info( + f"Finished tests with server url - {self.ui_url}, Took: {duration} seconds", + real_time=True, + ) + except Exception: + self.build_context.logging_module.exception("~~ Thread failed ~~") + self.build_context.tests_data_keeper.errors = True + finally: + self.build_context.logging_module.execute_logs() + + +@app.command( + no_args_is_help=True, + context_settings={ + "allow_extra_args": True, + "ignore_unknown_options": True, + "help_option_names": ["-h", "--help"], + }, +) +def run_flow_test( + ctx: typer.Context, + inputs: List[Path] = typer.Argument( + None, + exists=True, + dir_okay=True, + resolve_path=True, + show_default=False, + help="The path to a directory of a modeling rule. May pass multiple paths to test multiple modeling rules.", + ), + xsiam_url: Optional[str] = typer.Option( + None, + envvar="DEMISTO_BASE_URL", + help="The base url to the xsiam tenant.", + rich_help_panel="XSIAM Tenant Configuration", + show_default=False, + callback=tenant_config_cb, + ), + api_key: Optional[str] = typer.Option( + None, + envvar="DEMISTO_API_KEY", + help="The api key for the xsiam tenant.", + rich_help_panel="XSIAM Tenant Configuration", + show_default=False, + callback=tenant_config_cb, + ), + auth_id: Optional[str] = typer.Option( + None, + envvar="XSIAM_AUTH_ID", + help="The auth id associated with the xsiam api key being used.", + rich_help_panel="XSIAM Tenant Configuration", + show_default=False, + callback=tenant_config_cb, + ), + xsiam_token: Optional[str] = typer.Option( + None, + envvar="XSIAM_TOKEN", + help="The token used to push event logs to XSIAM", + rich_help_panel="XSIAM Tenant Configuration", + show_default=False, + ), + collector_token: Optional[str] = typer.Option( + None, + envvar="XSIAM_COLLECTOR_TOKEN", + help="The token used to push event logs to a custom HTTP Collector", + rich_help_panel="XSIAM Tenant Configuration", + show_default=False, + callback=logs_token_cb, + ), + push: bool = typer.Option( + True, + "--push/--no-push", + "-p/-np", + help=( + "In the event that you've already pushed test data and only want to verify expected values, you can" + ' pass "--no-push" to skip pushing the test data.' + ), + rich_help_panel="Interactive Configuration", + ), + interactive: bool = typer.Option( + True, + "--interactive/--non-interactive", + "-i/-ni", + help=( + "Interactive mode, will prompt the user if they want to generate test " + "data templates if none exists for the passed modeling rules." + ), + rich_help_panel="Interactive Configuration", + hidden=True, + ), + output_junit_file: Optional[Path] = typer.Option( + None, "-jp", "--junit-path", help="Path to the output JUnit XML file." + ), + sleep_interval: int = typer.Option( + XSIAM_CLIENT_SLEEP_INTERVAL, + "-si", + "--sleep_interval", + min=0, + show_default=True, + help="The number of seconds to wait between requests to the server.", + ), + retry_attempts: int = typer.Option( + XSIAM_CLIENT_RETRY_ATTEMPTS, + "-ra", + "--retry_attempts", + min=0, + show_default=True, + help="The number of times to retry the request against the server.", + ), + delete_existing_dataset: bool = typer.Option( + False, + "--delete_existing_dataset", + "-dd", + help="Deletion of the existing dataset from the tenant. Default: False.", + ), + service_account: Optional[str] = typer.Option( + None, + "-sa", + "--service_account", + envvar="GCP_SERVICE_ACCOUNT", + help="GCP service account.", + show_default=False, + ), + cloud_servers_path: str = typer.Option( + "", + "-csp", + "--cloud_servers_path", + help="Path to secret cloud server metadata file.", + show_default=False, + ), + cloud_servers_api_keys: str = typer.Option( + "", + "-csak", + "--cloud_servers_api_keys", + help="Path to file with cloud Servers api keys.", + show_default=False, + ), + machine_assignment: str = typer.Option( + "", + "-ma", + "--machine_assignment", + help="the path to the machine assignment file.", + show_default=False, + ), + branch_name: str = typer.Option( + "master", + "-bn", + "--branch_name", + help="The current content branch name.", + show_default=True, + ), + build_number: str = typer.Option( + "", + "-bn", + "--build_number", + help="The build number.", + show_default=True, + ), + nightly: str = typer.Option( + "false", + "--nightly", + "-n", + help="Whether the command is being run in nightly mode.", + ), + artifacts_bucket: str = typer.Option( + None, + "-ab", + "--artifacts_bucket", + help="The artifacts bucket name to upload the results to", + show_default=False, + ), + console_log_threshold: str = typer.Option( + "INFO", + "-clt", + "--console-log-threshold", + help="Minimum logging threshold for the console logger.", + ), + file_log_threshold: str = typer.Option( + "DEBUG", + "-flt", + "--file-log-threshold", + help="Minimum logging threshold for the file logger.", + ), + log_file_path: Optional[str] = typer.Option( + None, + "-lp", + "--log-file-path", + help="Path to save log files onto.", + ), +): + """ + Test a modeling rule against an XSIAM tenant + """ + logging_setup( + console_log_threshold=console_log_threshold, # type: ignore[arg-type] + file_log_threshold=file_log_threshold, # type: ignore[arg-type] + log_file_path=log_file_path, + ) + handle_deprecated_args(ctx.args) + + logging_module = ParallelLoggingManager( + "playbook_flow_test.log", real_time_logs_only=not nightly + ) + + if machine_assignment: + if inputs: + logger.error( + "You cannot pass both machine_assignment and inputs arguments." + ) + raise typer.Exit(1) + if xsiam_url: + logger.error( + "You cannot pass both machine_assignment and xsiam_url arguments." + ) + raise typer.Exit(1) + + start_time = get_utc_now() + is_nightly = string_to_bool(nightly) + build_context = BuildContext( + nightly=is_nightly, + build_number=build_number, + branch_name=branch_name, + retry_attempts=retry_attempts, + sleep_interval=sleep_interval, + logging_module=logging_module, + cloud_servers_path=cloud_servers_path, + cloud_servers_api_keys=cloud_servers_api_keys, + service_account=service_account, + artifacts_bucket=artifacts_bucket, + machine_assignment=machine_assignment, + push=push, + interactive=interactive, + delete_existing_dataset=delete_existing_dataset, + ctx=ctx, + xsiam_url=xsiam_url, + xsiam_token=xsiam_token, + api_key=api_key, + auth_id=auth_id, + collector_token=collector_token, + inputs=inputs, + ) + + logging_module.info( + "Playbook Flow Tests to test:", + ) + + for build_context_server in build_context.servers: + for playbook_flow_dir in build_context_server.tests: + logging_module.info( + f"\tmachine:{build_context_server.base_url} - " + f"{get_relative_path_to_content(playbook_flow_dir)}" + ) + + threads_list = [] + for index, server in enumerate(build_context.servers, start=1): + thread_name = f"Thread-{index} (execute_tests)" + threads_list.append(Thread(target=server.execute_tests, name=thread_name)) + + logging_module.info("Finished creating configurations, starting to run tests.") + for thread in threads_list: + thread.start() + + for t in threads_list: + t.join() + + logging_module.info("Finished running tests.") + + if output_junit_file: + logger.info( + f"[cyan]Writing JUnit XML to {get_relative_path_to_content(output_junit_file)}[/cyan]", + extra={"markup": True}, + ) + build_context.tests_data_keeper.test_results_xml_file.write( + output_junit_file.as_posix(), pretty=True + ) + if nightly: + if service_account and artifacts_bucket: + build_context.tests_data_keeper.upload_modeling_rules_result_json_to_bucket( + XSIAM_SERVER_TYPE, + f"test_modeling_rules_report_{build_number}.xml", + output_junit_file, + logging_module, + ) + else: + logger.warning( + "[yellow]Service account or artifacts bucket not provided, skipping uploading JUnit XML to bucket[/yellow]", + extra={"markup": True}, + ) + else: + logger.info( + "[cyan]No JUnit XML file path was passed - skipping writing JUnit XML[/cyan]", + extra={"markup": True}, + ) + + duration = duration_since_start_time(start_time) + if build_context.tests_data_keeper.errors: + logger.info( + f"[red]Test Modeling Rules: Failed, took:{duration} seconds[/red]", + extra={"markup": True}, + ) + raise typer.Exit(1) + + logger.info( + f"[green]Test Modeling Rules: Passed, took:{duration} seconds[/green]", + extra={"markup": True}, + ) + + +if __name__ == "__main__": + app() From c0a375c38450e7a0f2ca306ddf7a72e2d4f9f20b Mon Sep 17 00:00:00 2001 From: Jasmine Date: Tue, 12 Nov 2024 10:24:00 +0200 Subject: [PATCH 04/58] remove not needed code --- demisto_sdk/__main__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/demisto_sdk/__main__.py b/demisto_sdk/__main__.py index bb53c5cac68..b5611a54fad 100644 --- a/demisto_sdk/__main__.py +++ b/demisto_sdk/__main__.py @@ -3866,9 +3866,9 @@ def pre_commit( playbook_flow_app.command("test", no_args_is_help=True)( run_playbook_flow_test.run_flow_test ) -playbook_flow_app.command("init", no_args_is_help=True)( - init_flow_test.create_new_flow_test -) +# playbook_flow_app.command("init", no_args_is_help=True)( +# init_flow_test.create_new_flow_test +# ) typer_click_object = typer.main.get_command(playbook_flow_app) main.add_command(typer_click_object, "playbook-flow-test") From 925ef3ddf1d75ddaf8a312b98a8bca868dc164f8 Mon Sep 17 00:00:00 2001 From: Jasmine Date: Mon, 18 Nov 2024 10:20:05 +0200 Subject: [PATCH 05/58] added sdk handling --- demisto_sdk/__main__.py | 10 +- .../run_playbook_flow_test.py | 881 ++---------------- 2 files changed, 78 insertions(+), 813 deletions(-) diff --git a/demisto_sdk/__main__.py b/demisto_sdk/__main__.py index b5611a54fad..c23c55aea26 100644 --- a/demisto_sdk/__main__.py +++ b/demisto_sdk/__main__.py @@ -68,10 +68,7 @@ ) from demisto_sdk.commands.setup_env.setup_environment import IDEType from demisto_sdk.commands.split.ymlsplitter import YmlSplitter -from demisto_sdk.commands.test_content.playbook_flow_test import ( - init_flow_test, - run_playbook_flow_test, -) +from demisto_sdk.commands.test_content.playbook_flow_test import run_playbook_flow_test from demisto_sdk.commands.test_content.test_modeling_rule import ( init_test_data, test_modeling_rule, @@ -3866,12 +3863,11 @@ def pre_commit( playbook_flow_app.command("test", no_args_is_help=True)( run_playbook_flow_test.run_flow_test ) -# playbook_flow_app.command("init", no_args_is_help=True)( -# init_flow_test.create_new_flow_test -# ) + typer_click_object = typer.main.get_command(playbook_flow_app) main.add_command(typer_click_object, "playbook-flow-test") + # ====================== graph command group ====================== # graph_cmd_group = typer.Typer( diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py index ee04a5fe4a0..a50a43d092a 100644 --- a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py +++ b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py @@ -220,686 +220,34 @@ def xsiam_get_installed_packs(xsiam_client: XsiamApiClient) -> List[Dict[str, An return xsiam_client.installed_packs -def verify_results( - modeling_rule: ModelingRule, - tested_dataset: str, - results: List[dict], - test_data: TestData, -) -> List[TestCase]: - """Verify that the results of the XQL query match the expected values. +def run_playbook_flow_test_pytest(test_file, durations_path = None, result_file_path = "test_result.txt"): - Args: - modeling_rule: The modeling rule object parsed from the modeling rule file. - tested_dataset (str): The dataset to verify result for. - results (List[dict]): The results of the XQL query. - test_data (init_test_data.TestData): The data parsed from the test data file. - - Returns: - list[TestCase]: List of test cases for the results of the XQL query. - """ - - if not results: - logger.error( - f"[red]{SYNTAX_ERROR_IN_MODELING_RULE}[/red]", extra={"markup": True} - ) - test_case = TestCase( - f"Modeling rule - {modeling_rule.normalize_file_name()}", - classname="Modeling Rule Results", - ) - test_case.result += [Failure(SYNTAX_ERROR_IN_MODELING_RULE)] - test_case.system_err = SYNTAX_ERROR_IN_MODELING_RULE - return [test_case] - - rule_relevant_data = [ - data for data in test_data.data if data.dataset == tested_dataset - ] - if len(results) != len(rule_relevant_data): - err = ( - f"Expected {len(test_data.data)} results, got {len(results)}. Verify that the event" - " data used in your test data file meets the criteria of the modeling rule, e.g. the filter" - " condition." - ) - test_case = TestCase( - f"Modeling rule - {modeling_rule.normalize_file_name()}", - classname="Modeling Rule Results", - ) - test_case.result += [Failure(err)] - logger.error(f"[red]{err}[/red]", extra={"markup": True}) - return [test_case] - - test_cases = [] - for i, result in enumerate(results, start=1): - td_event_id = result.pop(f"{tested_dataset}.test_data_event_id") - msg = ( - f"Modeling rule - {get_relative_path_to_content(modeling_rule.path)} {i}/{len(results)}" - f" test_data_event_id:{td_event_id}" - ) - logger.info( - f"[cyan]{msg}[/cyan]", - extra={"markup": True}, - ) - result_test_case = TestCase( - msg, - classname=f"test_data_event_id:{td_event_id}", - ) - verify_results_against_test_data( - result_test_case, result, test_data, td_event_id - ) - - test_cases.append(result_test_case) - - return test_cases - - -def verify_results_against_test_data( - result_test_case: TestCase, - result: Dict[str, Any], - test_data: TestData, - td_event_id: str, -): - """Verify that the results of the XQL query match the expected values.""" - - result_test_case_system_out = [] - result_test_case_system_err = [] - result_test_case_results = [] - tenant_timezone: str = "" - expected_values = None - # Find the expected values for the given test data event ID. - for e in test_data.data: - if str(e.test_data_event_id) == td_event_id: - expected_values = e.expected_values - tenant_timezone = e.tenant_timezone - break - if not tenant_timezone: - result_test_case_system_out.append(TIME_ZONE_WARNING) - logger.warning(f"[yellow]{TIME_ZONE_WARNING}[/yellow]") - if expected_values: - if ( - expected_time_value := expected_values.get(SingleModelingRule.TIME_FIELD) - ) and (time_value := result.get(SingleModelingRule.TIME_FIELD)): - result[SingleModelingRule.TIME_FIELD] = convert_epoch_time_to_string_time( - time_value, "." in expected_time_value, tenant_timezone - ) - table_result = create_table(expected_values, result) - logger.info(f"\n{table_result}") - for expected_key, expected_value in expected_values.items(): - if expected_value: - received_value = result.get(expected_key) - expected_value_type = get_type_pretty_name(expected_value) - ( - received_value_type_sanitized, - received_value_sanitized, - ) = sanitize_received_value_by_expected_type( - received_value, expected_value_type - ) - out = ( - f"Checking for key {expected_key} - " - f"expected value:{expected_value} expected type:{expected_value_type} " - f"received value:{received_value_sanitized} received type:{received_value_type_sanitized} " - f"before sanitization - received value:{received_value} received type: " - f"{get_type_pretty_name(received_value)}" - ) - logger.debug(f"[cyan]{out}[/cyan]", extra={"markup": True}) - result_test_case_system_out.append(out) - if ( - received_value_sanitized == expected_value - and received_value_type_sanitized == expected_value_type - ): - out = f"Value:{received_value_sanitized} and Type:{received_value_type_sanitized} Matched for key {expected_key}" - result_test_case_system_out.append(out) - logger.debug(out) - else: - if received_value_type_sanitized == expected_value_type: - err = ( - f"Expected value does not match for key {expected_key}: - expected: {expected_value} - " - f"received: {received_value_sanitized} Types match:{received_value_type_sanitized}" - ) - logger.error( - f'[red][bold]{expected_key}[/bold] --- "{received_value_sanitized}" != "{expected_value}" ' - f"Types match:{received_value_type_sanitized}[/red]", - extra={"markup": True}, - ) - else: - # Types don't match, so values are not matching either, - # so it means that both do not match. - err = ( - f"Expected value and type do not match for key {expected_key}: - expected: {expected_value} - " - f"received: {received_value_sanitized} expected type: {expected_value_type} " - f"received type: {received_value_type_sanitized}" - ) - logger.error( - f'[red][bold]{expected_key}[/bold][red] --- "{received_value_sanitized}" != "{expected_value}"\n' - f' [bold]{expected_key}[/bold][red] --- Received value type: "{received_value_type_sanitized}" ' - f'!= Expected value type: "{expected_value_type}"[/red]', - extra={"markup": True}, - ) - result_test_case_system_err.append(err) - result_test_case_results.append(Failure(err)) - else: - err = f"No mapping for key {expected_key} - skipping checking match" - result_test_case_system_out.append(err) - result_test_case_results.append(Skipped(err)) # type:ignore[arg-type] - logger.debug(f"[cyan]{err}[/cyan]", extra={"markup": True}) - else: - err = f"No matching expected_values found for test_data_event_id={td_event_id} in test_data {test_data}" - logger.error(f"[red]{err}[/red]", extra={"markup": True}) - result_test_case_results.append(Failure(err)) - result_test_case.system_err = "\n".join(result_test_case_system_err) - result_test_case.system_out = "\n".join(result_test_case_system_out) - if result_test_case_results: - result_test_case.result += result_test_case_results - return result_test_case - - -def validate_expected_values( - xsiam_client: XsiamApiClient, - retrying_caller: Retrying, - modeling_rule: ModelingRule, - test_data: TestData, -) -> List[TestCase]: - """Validate the expected_values in the given test data file.""" - validate_expected_values_test_cases = [] - for rule in modeling_rule.rules: - validate_expected_values_test_case = TestCase( - f"Validate expected_values {modeling_rule.path} dataset:{rule.dataset} " - f"vendor:{rule.vendor} product:{rule.product}", - classname="Validate expected values query", - ) - query = generate_xql_query( - rule, - [ - str(d.test_data_event_id) - for d in test_data.data - if d.dataset == rule.dataset - ], - ) - query_info = f"Query for dataset {rule.dataset}:\n{query}" - logger.debug(query_info) - validate_expected_values_test_case_system_out = [query_info] - try: - results = retrying_caller(xsiam_execute_query, xsiam_client, query) - except requests.exceptions.RequestException: - logger.error( - f"[red]{XQL_QUERY_ERROR_EXPLANATION}[/red]", - extra={"markup": True}, - ) - validate_expected_values_test_case.system_err = XQL_QUERY_ERROR_EXPLANATION - validate_expected_values_test_case.result += [ - Error("Failed to execute XQL query") - ] - else: - verify_results_test_cases = verify_results( - modeling_rule, rule.dataset, results, test_data - ) - validate_expected_values_test_cases.extend(verify_results_test_cases) - validate_expected_values_test_case.system_out = "\n".join( - validate_expected_values_test_case_system_out - ) - validate_expected_values_test_cases.append(validate_expected_values_test_case) - - return validate_expected_values_test_cases - - -def validate_schema_aligned_with_test_data( - test_data: TestData, - schema: Dict, -) -> Tuple[bool, List[Result]]: - """ - Validates that the schema is aligned with the test-data types. - - Args: - test_data: the test data object. - schema: the content of the schema file. - Returns: - Tuple[bool, List[Result]]: if the schema is aligned with the test-data types and a list of the results. - """ - - # map each dataset from the schema to the correct events that has the same dataset - schema_dataset_to_events = { - dataset: [ - event_log for event_log in test_data.data if event_log.dataset == dataset - ] - for dataset in schema.keys() - } - - errors_occurred = False - results: List[Result] = [] - - for dataset, event_logs in schema_dataset_to_events.items(): - all_schema_dataset_mappings = schema[dataset] - test_data_mappings: Dict = {} - error_logs = set() - for event_log in event_logs: - for ( - event_key, - event_val, - ) in event_log.event_data.items(): # type:ignore[union-attr] - if ( - event_val is None - ): # if event_val is None, warn and continue looping. - info = f"{event_key=} is null on {event_log.test_data_event_id} event for {dataset=}, ignoring {event_key=}" - logger.warning(f"[yellow]{info}[/yellow]", extra={"markup": True}) - results.append(Skipped(info)) - # add the event key to the mapping to validate there isn't another key with a different type - test_data_mappings[event_key] = None - continue - - if schema_key_mappings := all_schema_dataset_mappings.get(event_key): - # we do not consider epochs as datetime in xsiam - if ( - isinstance(event_val, str) - and not is_epoch_datetime(event_val) - and dateparser.parse( - event_val, settings={"STRICT_PARSING": True} - ) - ): - event_val_type = datetime - else: - event_val_type = type(event_val) - - test_data_key_mappings = EXPECTED_SCHEMA_MAPPINGS[event_val_type] - - if ( - existing_testdata_key_mapping := test_data_mappings.get( - event_key - ) - ) and existing_testdata_key_mapping != test_data_key_mappings: - err = ( - f"The testdata contains events with the same {event_key=} " - f"that have different types for dataset {dataset}" - ) - error_logs.add(err) - results.append(Error(err)) # type:ignore[arg-type] - errors_occurred = True - continue - else: - test_data_mappings[event_key] = test_data_key_mappings - - if test_data_key_mappings != schema_key_mappings: - err = ( - f"The field {event_key} has mismatch on type or is_array in " - f"event ID {event_log.test_data_event_id} between testdata and schema --- " - f'TestData Mapping "{test_data_key_mappings}" != Schema Mapping "{schema_key_mappings}"' - ) - results.append(Error(err)) # type:ignore[arg-type] - error_logs.add( - f"[red][bold]the field {event_key} has mismatch on type or is_array in " - f"event ID {event_log.test_data_event_id} between testdata and schema[/bold][red] --- " - f'TestData Mapping "{test_data_key_mappings}" != Schema Mapping "{schema_key_mappings}"[/red]' - ) - errors_occurred = True - - if missing_test_data_keys := set(all_schema_dataset_mappings.keys()) - set( - test_data_mappings.keys() - ): - skipped = ( - f"The following fields {missing_test_data_keys} are in schema for dataset {dataset}, but not " - "in test-data, make sure to remove them from the schema or add them to test-data if necessary" - ) - logger.warning(f"[yellow]{skipped}[/yellow]", extra={"markup": True}) - results.append(Skipped(skipped)) - - if error_logs: - for _log in error_logs: - logger.error(_log, extra={"markup": True}) - else: - logger.info( - f"[green]Schema type mappings = Testdata type mappings for dataset {dataset}[/green]", - extra={"markup": True}, - ) - return not errors_occurred, results - - -def check_dataset_exists( - xsiam_client: XsiamApiClient, - retrying_caller: Retrying, - dataset: str, - init_sleep_time: int = 30, - print_errors: bool = True, -) -> TestCase: - """Check if the dataset in the test data file exists in the tenant. - - Args: - xsiam_client (XsiamApiClient): Xsiam API client. - retrying_caller (tenacity.Retrying): The retrying caller object. - dataset (str): The data set name. - init_sleep_time (int, optional): The number of seconds to wait for dataset installation. Defaults to 30. - print_errors (bool): Whether to print errors. - Returns: - TestCase: Test case for checking if the dataset exists in the tenant. - """ - process_failed = False - dataset_set_test_case = TestCase( - "Check if dataset exists in tenant", classname="Check dataset exists" - ) - dataset_set_test_case_start_time = get_utc_now() - test_case_results = [] - logger.debug( - f"Sleeping for {init_sleep_time} seconds before query for the dataset, to make sure the dataset was installed correctly." - ) - sleep(init_sleep_time) - start_time = get_utc_now() - results_exist = False - dataset_exist = False - logger.info( - f'[cyan]Checking if dataset "{dataset}" exists on the tenant...[/cyan]', - extra={"markup": True}, - ) - query = f"config timeframe = 10y | dataset = {dataset}" - try: - results = retrying_caller(xsiam_execute_query, xsiam_client, query) - - dataset_exist = True - if results: - logger.info( - f"[green]Dataset {dataset} exists[/green]", - extra={"markup": True}, - ) - results_exist = True - except requests.exceptions.RequestException: - results = [] - - # There are no results from the dataset, but it exists. - if not results: - err = ( - f"Dataset {dataset} exists but no results were returned. This could mean that your testdata " - "does not meet the criteria for an associated Parsing Rule and is therefore being dropped from " - "the dataset. Check to see if a Parsing Rule exists for your dataset and that your testdata " - "meets the criteria for that rule." - ) - test_case_results.append(Error(err)) - if print_errors: - logger.error(f"[red]{err}[/red]", extra={"markup": True}) - if not dataset_exist: - err = f"[red]Dataset {dataset} does not exist[/red]" - test_case_results.append(Error(err)) - if print_errors: - logger.error(f"[red]{err}[/red]", extra={"markup": True}) - - duration = duration_since_start_time(start_time) - logger.info(f"Processing Dataset {dataset} finished after {duration:.2f} seconds") - # OR statement between existence var and results of each data set, if at least one of dataset_exist or results_exist are False process_failed will be true. - process_failed |= not (dataset_exist and results_exist) - - if test_case_results: - dataset_set_test_case.result += test_case_results - dataset_set_test_case.time = duration_since_start_time( - dataset_set_test_case_start_time - ) - return dataset_set_test_case - - -def push_test_data_to_tenant( - xsiam_client: XsiamApiClient, - retrying_caller: Retrying, - mr: ModelingRule, - test_data: TestData, -) -> TestCase: - """Push the test data to the tenant. - - Args: - retrying_caller (tenacity.Retrying): The retrying caller object. - xsiam_client (XsiamApiClient): Xsiam API client. - mr (ModelingRule): Modeling rule object parsed from the modeling rule file. - test_data (init_test_data.TestData): Test data object parsed from the test data file. - Returns: - TestCase: Test case for pushing the test data to the tenant. - """ - push_test_data_test_case = TestCase( - f"Push test data to tenant {mr.path}", - classname="Push test data to tenant", - ) - push_test_data_test_case_start_time = get_utc_now() - system_errors = [] - for rule in mr.rules: - events_test_data = [ - { - **event_log.event_data, - "test_data_event_id": str(event_log.test_data_event_id), - } - for event_log in test_data.data - if isinstance(event_log.event_data, dict) - and event_log.dataset == rule.dataset - ] - logger.info( - f"[cyan]Pushing test data for {rule.dataset} to tenant...[/cyan]", - extra={"markup": True}, - ) - try: - retrying_caller(xsiam_push_to_dataset, xsiam_client, events_test_data, rule) - except requests.exceptions.RequestException: - system_err = ( - f"Failed pushing test data to tenant for dataset {rule.dataset}" - ) - system_errors.append(system_err) - logger.error(f"[red]{system_err}[/red]", extra={"markup": True}) - - if system_errors: - logger.error( - f"[red]{FAILURE_TO_PUSH_EXPLANATION}[/red]", - extra={"markup": True}, - ) - push_test_data_test_case.system_err = "\n".join(system_errors) - push_test_data_test_case.result += [Failure(FAILURE_TO_PUSH_EXPLANATION)] - else: - system_out = f"Test data pushed successfully for Modeling rule:{get_relative_path_to_content(mr.path)}" - push_test_data_test_case.system_out = system_out - logger.info(f"[green]{system_out}[/green]", extra={"markup": True}) - push_test_data_test_case.time = duration_since_start_time( - push_test_data_test_case_start_time - ) - return push_test_data_test_case - - -def verify_pack_exists_on_tenant( - xsiam_client: XsiamApiClient, - retrying_caller: Retrying, - mr: ModelingRule, - interactive: bool, -) -> bool: - """Verify that the pack containing the modeling rule exists on the tenant. - - Args: - retrying_caller (tenacity.Retrying): The retrying caller object. - xsiam_client (XsiamApiClient): Xsiam API client. - mr (ModelingRule): Modeling rule object parsed from the modeling rule file. - interactive (bool): Whether command is being run in interactive mode. - """ - logger.info( - "[cyan]Verifying pack installed on tenant[/cyan]", extra={"markup": True} - ) - containing_pack = get_containing_pack(mr) - containing_pack_id = containing_pack.id - installed_packs = retrying_caller(xsiam_get_installed_packs, xsiam_client) - if found_pack := next( - (pack for pack in installed_packs if containing_pack_id == pack.get("id")), - None, - ): - logger.debug( - f"[cyan]Found pack on tenant:\n{found_pack}[/cyan]", extra={"markup": True} - ) - else: - logger.error( - f"[red]Pack {containing_pack_id} was not found on tenant[/red]", - extra={"markup": True}, - ) - - upload_result = 0 - if interactive: - if typer.confirm( - f"Would you like to upload {containing_pack_id} to the tenant?" - ): - logger.info( - f'[cyan][underline]Upload "{containing_pack_id}"[/underline][/cyan]', - extra={"markup": True}, - ) - upload_kwargs = { - "zip": True, - "xsiam": True, - "input": containing_pack.path, - "keep_zip": None, - "insecure": False, - "input_config_file": None, - "skip_validation": False, - "reattach": True, - } - upload_result = upload_cmd(**upload_kwargs) - if upload_result != 0: - logger.error( - f"[red]Failed to upload pack {containing_pack_id} to tenant[/red]", - extra={"markup": True}, - ) - # wait for pack to finish installing - sleep(1) - else: - upload_result = 1 - if not interactive or upload_result != 0: - logger.error( - "[red]Pack does not exist on the tenant. Please install or upload the pack and try again[/red]", - extra={"markup": True}, - ) - logger.info( - f"\ndemisto-sdk upload -z -x -i {containing_pack.path}\ndemisto-sdk modeling-rules test {mr.path.parent}" - ) - return False - return True - - -def is_test_data_exists_on_server( - test_data_path: Path, -) -> Tuple[List[UUID], List[UUID]]: - """Verify that the test data exists and is valid. - - Args: - test_data_path (Path): Path to the test data file. - - Returns: - Tuple[List[str], List[str]]: Tuple of lists where the first list is test event - first list: ids that do not have example event data. - second list is test event ids that do not have expected_values to check. - """ - missing_event_data, missing_expected_values_data = [], [] - test_data = TestData.parse_file(test_data_path) - for event_log in test_data.data: - if not event_log.event_data: - missing_event_data.append(event_log.test_data_event_id) - if all(val is None for val in event_log.expected_values.values()): - missing_expected_values_data.append(event_log.test_data_event_id) - return missing_event_data, missing_expected_values_data - - -def verify_event_id_does_not_exist_on_tenant( - xsiam_client: XsiamApiClient, - modeling_rule: ModelingRule, - test_data: TestData, - retrying_caller: Retrying, -) -> List[TestCase]: - """ - Verify that the event ID does not exist on the tenant. - Args: - xsiam_client (XsiamApiClient): Xsiam API client. - modeling_rule (ModelingRule): Modeling rule object parsed from the modeling rule file. - test_data (init_test_data.TestData): Test data object parsed from the test data file. - retrying_caller (Retrying): The retrying caller object. - """ - logger.info( - "[cyan]Verifying that the event IDs does not exist on the tenant[/cyan]", - extra={"markup": True}, - ) - success_msg = "[green]The event IDs does not exists on the tenant[/green]" - error_msg = "The event id already exists in the tenant" - validate_expected_values_test_cases = [] - - for rule in modeling_rule.rules: - validate_event_id_does_not_exist_on_tenant_test_case = TestCase( - f"Validate event_id_does_not_exist_on_tenant {get_relative_path_to_content(modeling_rule.path)} dataset:{rule.dataset} " - f"vendor:{rule.vendor} product:{rule.product}", - classname="Validate event id does not exist query", - ) - test_data_event_ids = [ - f'"{d.test_data_event_id}"' - for d in test_data.data - if d.dataset == rule.dataset + # Configure pytest arguments + pytest_args = [ + test_file, # Specify the test file + "-v", # Verbose output ] - td_event_ids = ", ".join(test_data_event_ids) - query = f"config timeframe = 10y | datamodel dataset in({rule.dataset}) | filter {rule.dataset}.test_data_event_id in({td_event_ids})" - try: - result = retrying_caller(xsiam_execute_query, xsiam_client, query) - except requests.exceptions.HTTPError: - logger.info( - success_msg, - extra={"markup": True}, - ) - else: - if not result: - logger.info( - success_msg, - extra={"markup": True}, - ) - else: - logger.error( - error_msg, - extra={"markup": True}, - ) - validate_event_id_does_not_exist_on_tenant_test_case.result += [ - Error(error_msg) - ] - validate_expected_values_test_cases.append( - validate_event_id_does_not_exist_on_tenant_test_case - ) + pytest.main(pytest_args) - return validate_expected_values_test_cases -def delete_dataset( - xsiam_client: XsiamApiClient, - dataset_name: str, -): - logger.info( - f"[cyan]Deleting existing {dataset_name} dataset[/cyan]", - extra={"markup": True}, - ) - xsiam_client.delete_dataset(dataset_name) - logger.info( - f"[green]Dataset {dataset_name} deleted successfully[/green]", - extra={"markup": True}, - ) +def run_playbook_flow_test_pytest2(test_file, xsiam_client: XsiamApiClient, durations_path = None, result_file_path = "test_result.txt"): + class ResultsCollector: + def __init__(self): + self.results = [] -def delete_existing_dataset_flow( - xsiam_client: XsiamApiClient, test_data: TestData, retrying_caller: Retrying -) -> None: - """ - Delete existing dataset if it exists in the tenant. - Args: - xsiam_client (XsiamApiClient): Xsiam API client. - test_data (TestData): Test data object parsed from the test data file. - retrying_caller (Retrying): The retrying caller object. - """ - dataset_to_check = list(set([data.dataset for data in test_data.data])) - for dataset in dataset_to_check: - dataset_set_test_case = check_dataset_exists( - xsiam_client, retrying_caller, dataset, print_errors=False - ) - if dataset_set_test_case.is_passed: - delete_dataset(xsiam_client, dataset) - else: - logger.info("[cyan]Dataset does not exists on tenant[/cyan]") - - -def verify_data_sets_exists(xsiam_client, retrying_caller, test_data): - datasets_test_case_ls = [] - for dataset in test_data.data: - dataset_name = dataset.dataset - dataset_test_case = check_dataset_exists( - xsiam_client, retrying_caller, dataset_name - ) - datasets_test_case_ls.append(dataset_test_case) - return datasets_test_case_ls + def pytest_sessionfinish(self, session, exitstatus): + self.results = summarize_results(session) + def summarize_results(session): + summary = [] + for item in session.items: + result = "PASSED" if item.rep_call.passed else "FAILED" + summary.append((item.nodeid, result)) + return summary -def run_test(test_file, xsiam_client: XsiamApiClient, durations_path): class ClientPlugin: def __init__(self, client): self.client = client @@ -907,23 +255,37 @@ def __init__(self, client): def pytest_generate_tests(self, metafunc): if "api_client" in metafunc.fixturenames: metafunc.parametrize("api_client", [self.client], indirect=True) + if "api_client" in metafunc.fixturenames: + metafunc.parametrize("api_client2", [self.client], indirect=False) - # Run pytest with the specified arguments + + # Creating an instance of your results collector + results_collector = ResultsCollector() + playbook_flow_test_suite = TestSuite(f"Playbook Flow Test Results {result_file_path}") + + # Configure pytest arguments pytest_args = [ - "-v", # Verbose output - test_file, # Path to the test file - "--durations=" + str(5), # Record and show durations - "--durations-report=" + durations_path, + "-v", + test_file, + "--durations=" + ("5" if durations_path is None else durations_path), ] - # Pass the client object using a custom plugin + # Running pytest try: - pytest.main(pytest_args, plugins=[ClientPlugin(xsiam_client)]) + pytest.main(pytest_args, plugins=[ClientPlugin(xsiam_client), results_collector]) except Exception as e: logger.warning(str(e)) + return None + # Here, results_collector.results will have the summary of results + # Process or return them as needed, e.g., write to a file or just return + with open(result_file_path, 'w') as result_file: + for test, outcome in results_collector.results: + result_file.write(f"{test}: {outcome}\n") + return True, playbook_flow_test_suite + return results_collector.results - +# ===================================================================================================== # def validate_modeling_rule( # modeling_rule_directory: Path, # xsiam_url: str, @@ -1295,53 +657,6 @@ def validate_modeling_rule_version_against_tenant( return from_version <= tenant_demisto_version <= to_version -def handle_missing_event_data_in_modeling_rule( - missing_event_data: List[UUID], - modeling_rule: ModelingRule, - modeling_rule_test_suite: TestSuite, - executed_command: str, -) -> Tuple[bool, TestSuite]: - """Handle missing event data in the modeling rule. - Args: - missing_event_data (List[UUID]): List of event ids that do not have example event data. - modeling_rule (ModelingRule): Modeling rule object parsed from the modeling rule file. - modeling_rule_test_suite (TestSuite): Test suite for the modeling rule. - executed_command (str): The executed command. - Returns: - Tuple[bool, TestSuite]: Tuple of a boolean indicating whether the test passed and the test suite. - """ - missing_event_data_test_case = TestCase( - "Missing Event Data", classname="Modeling Rule" - ) - err = f"Missing Event Data for the following test data event ids: {missing_event_data}" - missing_event_data_test_case.result += [Error(err)] # type:ignore[arg-type] - prefix = "Event log test data is missing for the following ids:" - system_errors = [prefix] - logger.warning( - f"[yellow]{prefix}[/yellow]", - extra={"markup": True}, - ) - for test_data_event_id in missing_event_data: - logger.warning( - f"[yellow] - {test_data_event_id}[/yellow]", - extra={"markup": True}, - ) - system_errors.append(str(test_data_event_id)) - suffix = ( - f"Please complete the test data file at {get_relative_path_to_content(modeling_rule.testdata_path)} " # type:ignore[arg-type] - f"with test event(s) data and expected outputs and then rerun" - ) - logger.warning( - f"[yellow]{suffix}[/yellow]\n[bold][yellow]{executed_command}[/yellow][/bold]", - extra={"markup": True}, - ) - system_errors.extend([suffix, executed_command]) - missing_event_data_test_case.system_err = "\n".join(system_errors) - modeling_rule_test_suite.add_testcase(missing_event_data_test_case) - - return False, modeling_rule_test_suite - - def log_error_to_test_case( err: str, schema_test_case: TestCase, modeling_rule_test_suite: TestSuite ) -> Tuple[bool, TestSuite]: @@ -1450,12 +765,6 @@ def __init__( cloud_servers_api_keys: str, service_account: Optional[str], artifacts_bucket: Optional[str], - xsiam_url: Optional[str], - xsiam_token: Optional[str], - api_key: Optional[str], - auth_id: Optional[str], - collector_token: Optional[str], - inputs: Optional[List[Path]], machine_assignment: str, push: bool, interactive: bool, @@ -1471,14 +780,6 @@ def __init__( self.build_number = build_number self.build_name = branch_name - # -------------------------- Manual run on a single instance -------------------------- - self.xsiam_url = xsiam_url - self.xsiam_token = xsiam_token - self.api_key = api_key - self.auth_id = auth_id - self.collector_token = collector_token - self.inputs = inputs - # --------------------------- Pushing data settings ------------------------------- self.push = push @@ -1513,22 +814,6 @@ def create_servers(self): """ Create servers object based on build type. """ - # If xsiam_url is provided we assume it's a run on a single server. - if self.xsiam_url: - return [ - CloudServerContext( - self, - base_url=self.xsiam_url, - api_key=self.api_key, # type: ignore[arg-type] - auth_id=self.auth_id, # type: ignore[arg-type] - token=self.xsiam_token, # type: ignore[arg-type] - collector_token=self.collector_token, - ui_url=get_ui_url(self.xsiam_url), - tests=[BuildContext.prefix_with_packs(test) for test in self.inputs] - if self.inputs - else [], - ) - ] servers_list = [] for machine, assignment in self.machine_assignment_json.items(): tests = [ @@ -1599,6 +884,12 @@ def configure_new_client(self): auth_id=self.auth_id, verify_ssl=False, ) + def set_machine_cred_to_env(self): + os.environ['DEMISTO_BASE_URL'] = self.base_url + os.environ['DEMISTO_API_KEY'] = self.api_key + os.environ['XSIAM_AUTH_ID'] = str(self.auth_id) + os.environ['XSIAM_TOKEN'] = self.token + os.environ['DEMISTO_VERIFY_SSL'] = str(False) def execute_tests(self): try: @@ -1626,38 +917,37 @@ def execute_tests(self): f"[cyan][{i}/{len(self.tests)}] Playbook Flow Test: {get_relative_path_to_content(playbook_flow_directory)}[/cyan]", extra={"markup": True}, ) - success, modeling_rule_test_suite = validate_modeling_rule( + success, playbook_flow_test_suite = run_playbook_flow_test_pytest( playbook_flow_directory, - # can ignore the types since if they are not set to str values an error occurs - self.base_url, # type: ignore[arg-type] - self.build_context.retrying_caller, - self.build_context.push, - self.build_context.interactive, - self.build_context.ctx, - self.build_context.delete_existing_dataset, - self.build_context.is_nightly, - xsiam_client=xsiam_client, - tenant_demisto_version=tenant_demisto_version, + # # can ignore the types since if they are not set to str values an error occurs + # self.base_url, # type: ignore[arg-type] + # self.build_context.retrying_caller, + # self.build_context.push, + # self.build_context.interactive, + # self.build_context.ctx, + # self.build_context.is_nightly, + # xsiam_client=xsiam_client, + # tenant_demisto_version=tenant_demisto_version, ) if success: logger.info( - f"[green]Test Modeling rule {get_relative_path_to_content(modeling_rule_directory)} passed[/green]", + f"[green]Playbook Flow Test {get_relative_path_to_content(playbook_flow_directory)} passed[/green]", extra={"markup": True}, ) else: self.build_context.tests_data_keeper.errors = True logger.error( - f"[red]Test Modeling Rule {get_relative_path_to_content(modeling_rule_directory)} failed[/red]", + f"[red]Playbook Flow Test {get_relative_path_to_content(playbook_flow_directory)} failed[/red]", extra={"markup": True}, ) - if modeling_rule_test_suite: - modeling_rule_test_suite.add_property( + if playbook_flow_test_suite: + playbook_flow_test_suite.add_property( "start_time", start_time, # type:ignore[arg-type] ) - self.build_context.tests_data_keeper.test_results_xml_file.add_testsuite( - modeling_rule_test_suite - ) + # self.build_context.tests_data_keeper.test_results_xml_file.add_testsuite( + # modeling_rule_test_suite + # ) self.build_context.logging_module.info( f"Finished tests with server url - " f"{self.ui_url}", @@ -1685,14 +975,6 @@ def execute_tests(self): ) def run_flow_test( ctx: typer.Context, - inputs: List[Path] = typer.Argument( - None, - exists=True, - dir_okay=True, - resolve_path=True, - show_default=False, - help="The path to a directory of a modeling rule. May pass multiple paths to test multiple modeling rules.", - ), xsiam_url: Optional[str] = typer.Option( None, envvar="DEMISTO_BASE_URL", @@ -1854,31 +1136,19 @@ def run_flow_test( ), ): """ - Test a modeling rule against an XSIAM tenant + Test a playbook flow against an XSIAM tenant """ - logging_setup( - console_log_threshold=console_log_threshold, # type: ignore[arg-type] - file_log_threshold=file_log_threshold, # type: ignore[arg-type] - log_file_path=log_file_path, - ) + # logging_setup( + # console_threshold=console_log_threshold, # type: ignore[arg-type] + # file_threshold=file_log_threshold, # type: ignore[arg-type] + # path=log_file_path, + # ) handle_deprecated_args(ctx.args) logging_module = ParallelLoggingManager( "playbook_flow_test.log", real_time_logs_only=not nightly ) - if machine_assignment: - if inputs: - logger.error( - "You cannot pass both machine_assignment and inputs arguments." - ) - raise typer.Exit(1) - if xsiam_url: - logger.error( - "You cannot pass both machine_assignment and xsiam_url arguments." - ) - raise typer.Exit(1) - start_time = get_utc_now() is_nightly = string_to_bool(nightly) build_context = BuildContext( @@ -1896,13 +1166,7 @@ def run_flow_test( push=push, interactive=interactive, delete_existing_dataset=delete_existing_dataset, - ctx=ctx, - xsiam_url=xsiam_url, - xsiam_token=xsiam_token, - api_key=api_key, - auth_id=auth_id, - collector_token=collector_token, - inputs=inputs, + ctx=ctx ) logging_module.info( @@ -1910,6 +1174,11 @@ def run_flow_test( ) for build_context_server in build_context.servers: + logging_module.info( + f"\tmachine:{build_context_server.base_url} - Saving env var" + ) + build_context_server.set_machine_cred_to_env() + for playbook_flow_dir in build_context_server.tests: logging_module.info( f"\tmachine:{build_context_server.base_url} - " From 41b5444b508d8a42d180df844d150435ff92dbe1 Mon Sep 17 00:00:00 2001 From: Jasmine Date: Tue, 19 Nov 2024 17:55:37 +0200 Subject: [PATCH 06/58] added running pytest with args --- .../commands/common/clients/__init__.py | 26 + .../run_playbook_flow_test.py | 621 +----------------- 2 files changed, 53 insertions(+), 594 deletions(-) diff --git a/demisto_sdk/commands/common/clients/__init__.py b/demisto_sdk/commands/common/clients/__init__.py index 08266ff329b..dae69e67b76 100644 --- a/demisto_sdk/commands/common/clients/__init__.py +++ b/demisto_sdk/commands/common/clients/__init__.py @@ -232,3 +232,29 @@ def get_client_from_server_type( f"make sure the {DEMISTO_BASE_URL}, {DEMISTO_KEY}, {AUTH_ID} are defined properly" ) raise + + +# =================== PLaybook Flow Tests +def parse_str_to_dict(input_str): + """Internal function to convert a string representing a dictionary into an actual dictionary. + + Args: + input_str (str): A string in the format 'key1=value1,key2=value2'. + + Returns: + dict: A dictionary with the parsed key-value pairs. + """ + return dict(pair.split("=") for pair in input_str.split(",") if "=" in pair) + +def get_client_conf_from_pytest_request(request): + # Manually parse command-line argument + for arg in request.config.invocation_params.args: + if isinstance(arg, str) and arg.startswith("--client_conf="): + client_conf = arg.replace("--client_conf=", '') + return parse_str_to_dict(client_conf) + # If a client data was not provided, we proceed to use default. + return None + + + + diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py index a50a43d092a..8c5a3825d0d 100644 --- a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py +++ b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py @@ -3,7 +3,6 @@ from datetime import datetime from pathlib import Path from threading import Thread -from time import sleep from typing import Any, Dict, List, Optional, Tuple, Union from uuid import UUID @@ -16,7 +15,6 @@ from google.cloud import storage # type: ignore[attr-defined] from junitparser import Error, JUnitXml, TestCase, TestSuite from junitparser.junitparser import Failure, Result, Skipped -from packaging.version import Version from tabulate import tabulate from tenacity import ( Retrying, @@ -25,19 +23,15 @@ stop_after_attempt, wait_fixed, ) -from typer.main import get_command_from_info from demisto_sdk.commands.common.content_constant_paths import CONTENT_PATH from demisto_sdk.commands.common.handlers import DEFAULT_JSON_HANDLER as json from demisto_sdk.commands.common.logger import ( - handle_deprecated_args, logger, logging_setup, ) from demisto_sdk.commands.common.tools import ( - get_file, get_json_file, - is_epoch_datetime, parse_int_or_default, string_to_bool, ) @@ -50,7 +44,6 @@ XsiamApiClientConfig, ) from demisto_sdk.commands.upload.upload import upload_content_entity as upload_cmd -from demisto_sdk.utils.utils import get_containing_pack CI_PIPELINE_ID = os.environ.get("CI_PIPELINE_ID") XSIAM_CLIENT_SLEEP_INTERVAL = 60 @@ -175,30 +168,6 @@ def get_type_pretty_name(obj: Any) -> str: }.get(type(obj), str(type(obj))) -def sanitize_received_value_by_expected_type( - received_value: Any, expected_type: str -) -> Tuple[str, Any]: - """ - XSIAM returns numeric values from the API always as float, so we need to check if the expected type is int and if that's the - case and the value returned is a numeric without a floating point value, we can assume it's an int. - Args: - expected_type: The expected type of the object. - received_value: The object to get the type for. - - Returns: - The expected type of the object, and the object itself after being sanitized. - """ - received_value_type = get_type_pretty_name(received_value) - # The values returned from XSIAM for int/float are always float, so we need to check if the expected type is int. - if ( - expected_type == "int" - and received_value_type == "float" - and int(received_value) == received_value - ): - return "int", int(received_value) - return received_value_type, received_value - - def create_retrying_caller(retry_attempts: int, sleep_interval: int) -> Retrying: """Create a Retrying object with the given retry_attempts and sleep_interval.""" sleep_interval = parse_int_or_default(sleep_interval, XSIAM_CLIENT_SLEEP_INTERVAL) @@ -213,502 +182,54 @@ def create_retrying_caller(retry_attempts: int, sleep_interval: int) -> Retrying return Retrying(**retry_params) -def xsiam_get_installed_packs(xsiam_client: XsiamApiClient) -> List[Dict[str, Any]]: - """Get the list of installed packs from the XSIAM tenant. - Wrapper for XsiamApiClient.get_installed_packs() with retry logic. - """ - return xsiam_client.installed_packs - - -def run_playbook_flow_test_pytest(test_file, durations_path = None, result_file_path = "test_result.txt"): - - # Configure pytest arguments - pytest_args = [ - test_file, # Specify the test file - "-v", # Verbose output - ] - - pytest.main(pytest_args) - - - -def run_playbook_flow_test_pytest2(test_file, xsiam_client: XsiamApiClient, durations_path = None, result_file_path = "test_result.txt"): - class ResultsCollector: - - def __init__(self): - self.results = [] - - def pytest_sessionfinish(self, session, exitstatus): - self.results = summarize_results(session) - - def summarize_results(session): - summary = [] - for item in session.items: - result = "PASSED" if item.rep_call.passed else "FAILED" - summary.append((item.nodeid, result)) - return summary - - class ClientPlugin: - def __init__(self, client): - self.client = client - - def pytest_generate_tests(self, metafunc): - if "api_client" in metafunc.fixturenames: - metafunc.parametrize("api_client", [self.client], indirect=True) - if "api_client" in metafunc.fixturenames: - metafunc.parametrize("api_client2", [self.client], indirect=False) - +def run_playbook_flow_test_pytest(test_file, xsiam_client: XsiamApiClient, durations_path = None, result_file_path = "test_result.txt"): # Creating an instance of your results collector - results_collector = ResultsCollector() playbook_flow_test_suite = TestSuite(f"Playbook Flow Test Results {result_file_path}") # Configure pytest arguments + conf = f"base_url={str(xsiam_client.base_url)},api_key={xsiam_client.api_key},auth_id={xsiam_client.auth_id}" pytest_args = [ "-v", test_file, + f"--client_conf={conf}", "--durations=" + ("5" if durations_path is None else durations_path), + "--junitxml={result_file_path}", ] # Running pytest try: - pytest.main(pytest_args, plugins=[ClientPlugin(xsiam_client), results_collector]) + status_code = pytest.main(pytest_args) except Exception as e: logger.warning(str(e)) return None # Here, results_collector.results will have the summary of results - # Process or return them as needed, e.g., write to a file or just return - with open(result_file_path, 'w') as result_file: - for test, outcome in results_collector.results: - result_file.write(f"{test}: {outcome}\n") - return True, playbook_flow_test_suite - return results_collector.results - -# ===================================================================================================== -# def validate_modeling_rule( -# modeling_rule_directory: Path, -# xsiam_url: str, -# retrying_caller: Retrying, -# push: bool, -# interactive: bool, -# ctx: typer.Context, -# delete_existing_dataset: bool, -# is_nightly: bool, -# xsiam_client: XsiamApiClient, -# tenant_demisto_version: Version, -# ) -> Tuple[bool, Union[TestSuite, None]]: -# """Validate a modeling rule. - -# Args: -# modeling_rule_directory (Path): Path to the modeling rule directory. -# retrying_caller (tenacity.Retrying): The retrying caller object. -# xsiam_url (str): URL of the xsiam tenant. -# push (bool): Whether to push test event data to the tenant. -# interactive (bool): Whether command is being run in interactive mode. -# ctx (typer.Context): Typer context. -# delete_existing_dataset (bool): Whether to delete the existing dataset in the tenant. -# is_nightly (bool): Whether the command is being run in nightly mode. -# xsiam_client (XsiamApiClient): The XSIAM client used to do API calls to the tenant. -# tenant_demisto_version (Version): The demisto version of the XSIAM tenant. -# """ -# modeling_rule = ModelingRule(modeling_rule_directory.as_posix()) -# modeling_rule_file_name = Path(modeling_rule.path).name -# containing_pack = get_containing_pack(modeling_rule) -# executed_command = ( -# f"{ctx.command_path} {get_relative_path_to_content(modeling_rule_directory)}" -# ) - -# modeling_rule_test_suite = TestSuite( -# f"Modeling Rule Test Results {modeling_rule_file_name}" -# ) -# modeling_rule_test_suite.add_property( -# "file_name", modeling_rule_file_name -# ) # used in the convert to jira issue. -# modeling_rule_test_suite.filepath = get_relative_path_to_content( # type:ignore[arg-type] -# modeling_rule.path -# ) -# modeling_rule_test_suite.add_property( -# "modeling_rule_path", get_relative_path_to_content(modeling_rule.path) -# ) -# modeling_rule_test_suite.add_property( -# "modeling_rule_file_name", modeling_rule_file_name -# ) -# modeling_rule_test_suite.add_property( -# "test_data_path", -# get_relative_path_to_content(modeling_rule.testdata_path) -# if modeling_rule.testdata_path -# else NOT_AVAILABLE, -# ) -# modeling_rule_test_suite.add_property( -# "schema_path", -# get_relative_path_to_content( -# modeling_rule.schema_path # type:ignore[arg-type] -# ), -# ) -# modeling_rule_test_suite.add_property("push", push) # type:ignore[arg-type] -# modeling_rule_test_suite.add_property( -# "interactive", -# interactive, # type:ignore[arg-type] -# ) -# modeling_rule_test_suite.add_property("xsiam_url", xsiam_url) -# modeling_rule_test_suite.add_property( -# "from_version", -# modeling_rule.from_version, # type:ignore[arg-type] -# ) # -# modeling_rule_test_suite.add_property( -# "to_version", -# modeling_rule.to_version, # type:ignore[arg-type] -# ) # -# modeling_rule_test_suite.add_property( -# "pack_id", containing_pack.id -# ) # used in the convert to jira issue. -# if CI_PIPELINE_ID: -# modeling_rule_test_suite.add_property("ci_pipeline_id", CI_PIPELINE_ID) -# if modeling_rule.testdata_path: -# logger.info( -# f"[cyan]Test data file found at {get_relative_path_to_content(modeling_rule.testdata_path)}\n" -# f"Checking that event data was added to the test data file[/cyan]", -# extra={"markup": True}, -# ) -# try: -# test_data = TestData.parse_file(modeling_rule.testdata_path.as_posix()) -# except ValueError as ex: -# err = f"Failed to parse test data file {get_relative_path_to_content(modeling_rule.testdata_path)} as JSON" -# logger.error( -# f"[red]{err}[/red]", -# extra={"markup": True}, -# ) -# test_case = TestCase( -# "Failed to parse test data file as JSON", -# classname="Modeling Rule", -# ) -# test_case.system_err = str(ex) -# test_case.result += [Error(err)] -# modeling_rule_test_suite.add_testcase(test_case) -# return False, modeling_rule_test_suite - -# modeling_rule_is_compatible = validate_modeling_rule_version_against_tenant( -# to_version=modeling_rule.to_version, -# from_version=modeling_rule.from_version, -# tenant_demisto_version=tenant_demisto_version, -# ) -# if not modeling_rule_is_compatible: -# # Modeling rule version is not compatible with the demisto version of the tenant, skipping -# skipped = f"XSIAM Tenant's Demisto version doesn't match Modeling Rule {modeling_rule} version, skipping" -# logger.warning(f"[yellow]{skipped}[/yellow]", extra={"markup": True}) -# test_case = TestCase( -# "Modeling Rule not compatible with XSIAM tenant's demisto version", -# classname=f"Modeling Rule {modeling_rule_file_name}", -# ) -# test_case.result += [Skipped(skipped)] # type:ignore[arg-type] -# modeling_rule_test_suite.add_testcase(test_case) -# # Return True since we don't want to fail the command -# return True, modeling_rule_test_suite -# if ( -# Validations.TEST_DATA_CONFIG_IGNORE.value -# not in test_data.ignored_validations -# ): -# logger.info( -# "[green]test data config is not ignored starting the test data validation...[/green]", -# extra={"markup": True}, -# ) -# missing_event_data, _ = is_test_data_exists_on_server( -# modeling_rule.testdata_path -# ) -# if not verify_pack_exists_on_tenant( -# xsiam_client, retrying_caller, modeling_rule, interactive -# ): -# test_case = TestCase( -# "Pack not installed on tenant", classname="Modeling Rule" -# ) -# return add_result_to_test_case( -# "Pack not installed on tenant", -# test_case, -# modeling_rule_test_suite, -# ) -# if delete_existing_dataset: -# delete_existing_dataset_flow(xsiam_client, test_data, retrying_caller) -# schema_test_case = TestCase( -# "Validate Schema", -# classname=f"Modeling Rule {get_relative_path_to_content(modeling_rule.schema_path)}", # type:ignore[arg-type] -# ) -# if schema_path := modeling_rule.schema_path: -# try: -# schema = get_file(schema_path) -# except json.JSONDecodeError as ex: -# err = f"Failed to parse schema file {get_relative_path_to_content(modeling_rule.schema_path)} as JSON" -# logger.error( -# f"[red]{err}[/red]", -# extra={"markup": True}, -# ) -# schema_test_case.system_err = str(ex) -# return add_result_to_test_case( -# err, schema_test_case, modeling_rule_test_suite -# ) -# else: -# err = f"Schema file does not exist in path {get_relative_path_to_content(modeling_rule.schema_path)}" -# return log_error_to_test_case( -# err, schema_test_case, modeling_rule_test_suite -# ) -# if ( -# Validations.SCHEMA_TYPES_ALIGNED_WITH_TEST_DATA.value -# not in test_data.ignored_validations -# ): -# logger.info( -# f"[green]Validating that the schema {get_relative_path_to_content(schema_path)} " -# "is aligned with TestData file.[/green]", -# extra={"markup": True}, -# ) - -# success, results = validate_schema_aligned_with_test_data( -# test_data=test_data, -# schema=schema, # type:ignore[arg-type] -# ) -# schema_test_case.result += results -# if not success: -# err = ( -# f"The schema {get_relative_path_to_content(schema_path)} is not aligned with the test data file " -# f"{get_relative_path_to_content(modeling_rule.testdata_path)}" -# ) -# return log_error_to_test_case( -# err, schema_test_case, modeling_rule_test_suite -# ) -# else: -# skipped = ( -# f"Skipping the validation to check that the schema {get_relative_path_to_content(schema_path)} " -# "is aligned with TestData file." -# ) -# logger.info(f"[green]{skipped}[/green]", extra={"markup": True}) -# schema_test_case.result += [Skipped(skipped)] # type:ignore[arg-type] -# modeling_rule_test_suite.add_testcase(schema_test_case) - -# if push: -# event_id_exists_test_case = verify_event_id_does_not_exist_on_tenant( -# xsiam_client, modeling_rule, test_data, retrying_caller -# ) -# modeling_rule_test_suite.add_testcases(event_id_exists_test_case) -# if missing_event_data: -# return handle_missing_event_data_in_modeling_rule( -# missing_event_data, -# modeling_rule, -# modeling_rule_test_suite, -# executed_command, -# ) -# push_test_data_test_case = push_test_data_to_tenant( -# xsiam_client, retrying_caller, modeling_rule, test_data -# ) -# modeling_rule_test_suite.add_testcase(push_test_data_test_case) -# if not push_test_data_test_case.is_passed: -# return False, modeling_rule_test_suite -# datasets_test_case = verify_data_sets_exists( -# xsiam_client, retrying_caller, test_data -# ) -# modeling_rule_test_suite.add_testcases(datasets_test_case) -# else: -# logger.info( -# '[cyan]The command flag "--no-push" was passed - skipping pushing of test data[/cyan]', -# extra={"markup": True}, -# ) -# logger.info( -# "[cyan]Validating expected_values...[/cyan]", extra={"markup": True} -# ) -# validate_expected_values_test_cases = validate_expected_values( -# xsiam_client, retrying_caller, modeling_rule, test_data -# ) -# modeling_rule_test_suite.add_testcases(validate_expected_values_test_cases) -# if ( -# not modeling_rule_test_suite.errors -# and not modeling_rule_test_suite.failures -# ): -# logger.info( -# "[green]All mappings validated successfully[/green]", -# extra={"markup": True}, -# ) -# return True, modeling_rule_test_suite -# return False, modeling_rule_test_suite -# else: -# logger.info( -# "[green]test data config is ignored skipping the test data validation[/green]", -# extra={"markup": True}, -# ) -# return True, modeling_rule_test_suite -# else: -# logger.warning( -# f"[yellow]No test data file found for {get_relative_path_to_content(modeling_rule_directory)}[/yellow]", -# extra={"markup": True}, -# ) -# if interactive: -# if typer.confirm( -# f"Would you like to generate a test data file for {get_relative_path_to_content(modeling_rule_directory)}?" -# ): -# logger.info( -# "[cyan][underline]Generate Test Data File[/underline][/cyan]", -# extra={"markup": True}, -# ) -# events_count = typer.prompt( -# "For how many events would you like to generate templates?", -# type=int, -# default=1, -# show_default=True, -# ) - -# from demisto_sdk.commands.test_content.test_modeling_rule.init_test_data import ( -# app as init_td_app, -# ) - -# if not init_td_app.registered_commands: -# err = ( -# '[red]Failed to load the "init-test-data" typer application to interactively create a ' -# "testdata file.[/red]" -# ) -# logger.error(err, extra={"markup": True}) -# return False, None - -# # the init-test-data typer application should only have the one command -# init_td_cmd_info = init_td_app.registered_commands[0] - -# init_td_cmd = get_command_from_info( -# init_td_cmd_info, -# pretty_exceptions_short=app.pretty_exceptions_short, -# rich_markup_mode=app.rich_markup_mode, -# ) -# init_td_cmd_ctx = init_td_cmd.make_context( -# init_td_cmd.name, -# [modeling_rule_directory.as_posix(), f"--count={events_count}"], -# parent=ctx, -# ) -# init_td_cmd.invoke(init_td_cmd_ctx) - -# if modeling_rule.testdata_path: -# logger.info( -# f"[green]Test data file generated for " -# f"{get_relative_path_to_content(modeling_rule_directory)}" -# f"Please complete the test data file at {get_relative_path_to_content(modeling_rule.testdata_path)} " -# f"with test event(s) data and expected outputs and then run:\n[bold]{executed_command}[/bold][/green]", -# extra={"markup": True}, -# ) -# return True, None -# logger.error( -# f"[red]Failed to generate test data file for " -# f"{get_relative_path_to_content(modeling_rule_directory)}[/red]", -# extra={"markup": True}, -# ) -# else: -# logger.warning( -# f"[yellow]Skipping test data file generation for " -# f"{get_relative_path_to_content(modeling_rule_directory)}[/yellow]", -# extra={"markup": True}, -# ) -# logger.error( -# f"[red]Please create a test data file for " -# f"{get_relative_path_to_content(modeling_rule_directory)} and then rerun\n{executed_command}[/red]", -# extra={"markup": True}, -# ) -# else: -# if is_nightly: -# # Running in nightly mode, don't fail the test if no test data file is found. -# err = f"No test data file for {get_relative_path_to_content(modeling_rule_directory)} found. " -# logger.warning( -# f"[red]{err}[/red]", -# extra={"markup": True}, -# ) -# test_data_test_case = TestCase( -# "Test data file does not exist", -# classname=f"Modeling Rule {get_relative_path_to_content(modeling_rule.schema_path)}", # type:ignore[arg-type] -# ) -# test_data_test_case.result += [Skipped(err)] # type:ignore[arg-type] -# modeling_rule_test_suite.add_testcase(test_data_test_case) -# return True, modeling_rule_test_suite - -# # Not running in nightly mode, fail the test if no test data file is found. -# err = ( -# f"Please create a test data file for {get_relative_path_to_content(modeling_rule_directory)} " -# f"and then rerun\n{executed_command}" -# ) -# logger.error( -# f"[red]{err}[/red]", -# extra={"markup": True}, -# ) -# test_data_test_case = TestCase( -# "Test data file does not exist", -# classname=f"Modeling Rule {get_relative_path_to_content(modeling_rule.schema_path)}", # type:ignore[arg-type] -# ) -# test_data_test_case.result += [Error(err)] # type:ignore[arg-type] -# modeling_rule_test_suite.add_testcase(test_data_test_case) -# return False, modeling_rule_test_suite -# return False, None - - -def validate_modeling_rule_version_against_tenant( - to_version: Version, from_version: Version, tenant_demisto_version: Version -) -> bool: - """Checks if the version of the modeling rule is compatible with the XSIAM tenant's demisto version. - Compatibility is checked by: from_version <= tenant_xsiam_version <= to_version - Args: - to_version (Version): The to version of the modeling rule - from_version (Version): The from version of the modeling rule - tenant_demisto_version (Version): The demisto version of the XSIAM tenant - - Returns: - bool: True if the version of the modeling rule is compatible, else False - """ - return from_version <= tenant_demisto_version <= to_version + # with open(result_file_path, 'w') as result_file: + # for test, outcome in results_collector.results: + # result_file.write(f"{test}: {outcome}\n") + # return True, playbook_flow_test_suite + # return results_collector.results def log_error_to_test_case( - err: str, schema_test_case: TestCase, modeling_rule_test_suite: TestSuite + err: str, schema_test_case: TestCase, playbook_flow_test_suite: TestSuite ) -> Tuple[bool, TestSuite]: logger.error( f"[red]{err}[/red]", extra={"markup": True}, ) schema_test_case.system_err = err - return add_result_to_test_case(err, schema_test_case, modeling_rule_test_suite) + return add_result_to_test_case(err, schema_test_case, playbook_flow_test_suite) def add_result_to_test_case( - err: str, test_case: TestCase, modeling_rule_test_suite: TestSuite + err: str, test_case: TestCase, playbook_flow_test_suite: TestSuite ) -> Tuple[bool, TestSuite]: test_case.result += [Error(err)] # type:ignore[arg-type] - modeling_rule_test_suite.add_testcase(test_case) - return False, modeling_rule_test_suite - - -# ====================== test-modeling-rule ====================== # - - -def tenant_config_cb( - ctx: typer.Context, param: typer.CallbackParam, value: Optional[str] -): - if ctx.resilient_parsing: - return - # Only check the params if the machine_assignment is not set. - if param.value_is_missing(value) and not ctx.params.get("machine_assignment"): - err_str = ( - f"{param.name} must be set either via the environment variable " - f'"{param.envvar}" or passed explicitly when running the command' - ) - raise typer.BadParameter(err_str) - return value - - -def logs_token_cb(ctx: typer.Context, param: typer.CallbackParam, value: Optional[str]): - if ctx.resilient_parsing: - return - # Only check the params if the machine_assignment is not set. - if param.value_is_missing(value) and not ctx.params.get("machine_assignment"): - parameter_to_check = "xsiam_token" - other_token = ctx.params.get(parameter_to_check) - if not other_token: - err_str = ( - f"One of {param.name} or {parameter_to_check} must be set either via it's associated" - " environment variable or passed explicitly when running the command" - ) - raise typer.BadParameter(err_str) - return value - + playbook_flow_test_suite.add_testcase(test_case) + return False, playbook_flow_test_suite class TestResults: def __init__( @@ -721,7 +242,7 @@ def __init__( self.service_account = service_account self.artifacts_bucket = artifacts_bucket - def upload_modeling_rules_result_json_to_bucket( + def upload_playbook_flow_test_result_json_to_bucket( self, repository_name: str, file_name, @@ -734,22 +255,22 @@ def upload_modeling_rules_result_json_to_bucket( original_file_path: The path to the JSON file to upload. repository_name: The name of the repository within the bucket. file_name: The desired filename for the uploaded JSON data. - logging_module: Logging module to use for upload_modeling_rules_result_json_to_bucket. + logging_module: Logging module to use for upload_playbook_flow_test_result_json_to_bucket. """ - logging_module.info("Start uploading modeling rules results file to bucket") + logging_module.info("Start uploading Playbook Flow Tests results file to bucket") storage_client = storage.Client.from_service_account_json(self.service_account) storage_bucket = storage_client.bucket(self.artifacts_bucket) blob = storage_bucket.blob( - f"content-test-modeling-rules/{repository_name}/{file_name}" + f"content-playbook_flow_test/{repository_name}/{file_name}" ) blob.upload_from_filename( original_file_path.as_posix(), content_type="application/xml", ) - logging_module.info("Finished uploading modeling rules results file to bucket") + logging_module.info("Finished uploading Playbook Flow Tests results file to bucket") class BuildContext: @@ -766,26 +287,14 @@ def __init__( service_account: Optional[str], artifacts_bucket: Optional[str], machine_assignment: str, - push: bool, - interactive: bool, - delete_existing_dataset: bool, - ctx: typer.Context, ): self.logging_module: ParallelLoggingManager = logging_module self.retrying_caller = create_retrying_caller(retry_attempts, sleep_interval) - self.ctx = ctx # --------------------------- overall build configuration ------------------------------- self.is_nightly = nightly self.build_number = build_number self.build_name = branch_name - - # --------------------------- Pushing data settings ------------------------------- - - self.push = push - self.interactive = interactive - self.delete_existing_dataset = delete_existing_dataset - # --------------------------- Machine preparation ------------------------------- self.cloud_servers_path_json = get_json_file(cloud_servers_path) @@ -911,7 +420,6 @@ def execute_tests(self): collector_token=self.collector_token, # type: ignore[arg-type] ) xsiam_client = XsiamApiClient(xsiam_client_cfg) - tenant_demisto_version: Version = xsiam_client.get_demisto_version() for i, playbook_flow_directory in enumerate(self.tests, start=1): logger.info( f"[cyan][{i}/{len(self.tests)}] Playbook Flow Test: {get_relative_path_to_content(playbook_flow_directory)}[/cyan]", @@ -919,15 +427,7 @@ def execute_tests(self): ) success, playbook_flow_test_suite = run_playbook_flow_test_pytest( playbook_flow_directory, - # # can ignore the types since if they are not set to str values an error occurs - # self.base_url, # type: ignore[arg-type] - # self.build_context.retrying_caller, - # self.build_context.push, - # self.build_context.interactive, - # self.build_context.ctx, - # self.build_context.is_nightly, - # xsiam_client=xsiam_client, - # tenant_demisto_version=tenant_demisto_version, + xsiam_client=xsiam_client, ) if success: logger.info( @@ -945,9 +445,9 @@ def execute_tests(self): "start_time", start_time, # type:ignore[arg-type] ) - # self.build_context.tests_data_keeper.test_results_xml_file.add_testsuite( - # modeling_rule_test_suite - # ) + self.build_context.tests_data_keeper.test_results_xml_file.add_testsuite( + playbook_flow_test_suite + ) self.build_context.logging_module.info( f"Finished tests with server url - " f"{self.ui_url}", @@ -975,45 +475,6 @@ def execute_tests(self): ) def run_flow_test( ctx: typer.Context, - xsiam_url: Optional[str] = typer.Option( - None, - envvar="DEMISTO_BASE_URL", - help="The base url to the xsiam tenant.", - rich_help_panel="XSIAM Tenant Configuration", - show_default=False, - callback=tenant_config_cb, - ), - api_key: Optional[str] = typer.Option( - None, - envvar="DEMISTO_API_KEY", - help="The api key for the xsiam tenant.", - rich_help_panel="XSIAM Tenant Configuration", - show_default=False, - callback=tenant_config_cb, - ), - auth_id: Optional[str] = typer.Option( - None, - envvar="XSIAM_AUTH_ID", - help="The auth id associated with the xsiam api key being used.", - rich_help_panel="XSIAM Tenant Configuration", - show_default=False, - callback=tenant_config_cb, - ), - xsiam_token: Optional[str] = typer.Option( - None, - envvar="XSIAM_TOKEN", - help="The token used to push event logs to XSIAM", - rich_help_panel="XSIAM Tenant Configuration", - show_default=False, - ), - collector_token: Optional[str] = typer.Option( - None, - envvar="XSIAM_COLLECTOR_TOKEN", - help="The token used to push event logs to a custom HTTP Collector", - rich_help_panel="XSIAM Tenant Configuration", - show_default=False, - callback=logs_token_cb, - ), push: bool = typer.Option( True, "--push/--no-push", @@ -1054,12 +515,6 @@ def run_flow_test( show_default=True, help="The number of times to retry the request against the server.", ), - delete_existing_dataset: bool = typer.Option( - False, - "--delete_existing_dataset", - "-dd", - help="Deletion of the existing dataset from the tenant. Default: False.", - ), service_account: Optional[str] = typer.Option( None, "-sa", @@ -1143,7 +598,6 @@ def run_flow_test( # file_threshold=file_log_threshold, # type: ignore[arg-type] # path=log_file_path, # ) - handle_deprecated_args(ctx.args) logging_module = ParallelLoggingManager( "playbook_flow_test.log", real_time_logs_only=not nightly @@ -1163,10 +617,6 @@ def run_flow_test( service_account=service_account, artifacts_bucket=artifacts_bucket, machine_assignment=machine_assignment, - push=push, - interactive=interactive, - delete_existing_dataset=delete_existing_dataset, - ctx=ctx ) logging_module.info( @@ -1174,11 +624,6 @@ def run_flow_test( ) for build_context_server in build_context.servers: - logging_module.info( - f"\tmachine:{build_context_server.base_url} - Saving env var" - ) - build_context_server.set_machine_cred_to_env() - for playbook_flow_dir in build_context_server.tests: logging_module.info( f"\tmachine:{build_context_server.base_url} - " @@ -1207,19 +652,7 @@ def run_flow_test( build_context.tests_data_keeper.test_results_xml_file.write( output_junit_file.as_posix(), pretty=True ) - if nightly: - if service_account and artifacts_bucket: - build_context.tests_data_keeper.upload_modeling_rules_result_json_to_bucket( - XSIAM_SERVER_TYPE, - f"test_modeling_rules_report_{build_number}.xml", - output_junit_file, - logging_module, - ) - else: - logger.warning( - "[yellow]Service account or artifacts bucket not provided, skipping uploading JUnit XML to bucket[/yellow]", - extra={"markup": True}, - ) + else: logger.info( "[cyan]No JUnit XML file path was passed - skipping writing JUnit XML[/cyan]", @@ -1229,13 +662,13 @@ def run_flow_test( duration = duration_since_start_time(start_time) if build_context.tests_data_keeper.errors: logger.info( - f"[red]Test Modeling Rules: Failed, took:{duration} seconds[/red]", + f"[red]Playbook Flow Tests: Failed, took:{duration} seconds[/red]", extra={"markup": True}, ) raise typer.Exit(1) logger.info( - f"[green]Test Modeling Rules: Passed, took:{duration} seconds[/green]", + f"[green]Playbook Flow Tests: Passed, took:{duration} seconds[/green]", extra={"markup": True}, ) From 554ce445dad5124e334078ebaa63c56401cb7f24 Mon Sep 17 00:00:00 2001 From: Jasmine Date: Tue, 19 Nov 2024 18:15:54 +0200 Subject: [PATCH 07/58] WIP --- .../common/clients/xsiam/xsiam_api_client.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py index 2e4d879fbdb..7967849d592 100644 --- a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py +++ b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py @@ -32,8 +32,10 @@ def is_server_type(self) -> bool: self.get_ioc_rules() return True except ApiException as error: - logger.debug( - f"{self} is not {self.server_type} server, error: {error}") + logger.debug( # noqa: PLE1205 + "{}", + f"{self} is not {self.server_type} server, error: {error}", + ) return False @property @@ -222,16 +224,6 @@ def get_ioc_rules(self): return response - # def connect_xdr(alerts): - # headers = { - # "Authorization": self.public_api_key.key, - # "x-xdr-auth-id": self.public_api_key.id, - # "Content-Type": "application/json", - # } - # alert_payload = {"request_data": {"alerts": alerts}} - # res = requests.post( - # url=f'https://api-{xsoar_host}/public_api/v1/alerts/insert_parsed_alerts/', headers=headers, json=alert_payload) - """ ############################# Alerts related methods From 06b02da5c34b09a1d3c20e27fdbfd7a71906ab1e Mon Sep 17 00:00:00 2001 From: Jasmine Date: Tue, 19 Nov 2024 18:29:47 +0200 Subject: [PATCH 08/58] added template file --- .../playbook_flow_test/template_file.py | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 demisto_sdk/commands/test_content/playbook_flow_test/template_file.py diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/template_file.py b/demisto_sdk/commands/test_content/playbook_flow_test/template_file.py new file mode 100644 index 00000000000..c3f774b4e66 --- /dev/null +++ b/demisto_sdk/commands/test_content/playbook_flow_test/template_file.py @@ -0,0 +1,77 @@ +""" +{ + "additional_needed_packs": { + "PackOne": "instance_name1", + "PackTwo": "" + } +} +""" +import json +import pytest + +from demisto_sdk.commands.common.clients import ( + XsiamClient, + get_client_from_server_type, +) + +# Any additional imports your tests require + +def util_load_json(path): + with open(path, encoding="utf-8") as f: + return json.loads(f.read()) + +@pytest.fixture +def client_conf(request): + # Manually parse command-line arguments + return get_client_conf_from_pytest_request(request) + +@pytest.fixture +def api_client(client_conf): + if client_conf: # Running from external pipeline + client_obj = get_client_from_server_type(**client_conf) + + else: # Running manually using pytest. + client_obj = get_client_from_server_type() + yield client_obj + +class TestExample: + @classmethod + def setup_class(self): + """Run once for the class before *all* tests""" + print("Testing out running in setup!") + self.data = "test" + + @pytest.fixture + def setup_method(self, client_conf = None): + if client_conf: + self.client = get_client_from_server_type(client_conf) + else: + self.client = get_client_from_server_type() + + def some_helper_function(self, method): + pass + + def teardown_method(self, method): + print("tearing down") + + @classmethod + def teardown_class(self): + """Run once for the class after all tests""" + pass + + # PLAYBOOK X CHECKING VALID alert + def test_feature_one_manual_true(self, api_client: XsiamClient): + """Test feature one""" + a = api_client.list_indicators() + assert a is not None + + def test_feature_two(self, api_client: XsiamClient): + """Test feature two""" + # Test another aspect of your application + api_client.run_cli_command( + investigation_id="INCIDENT-1", command='!Set key=test value=A') + assert False # replace with actual assertions for your application + + +if __name__ == "__main__": + pytest.main() From b0ee17ac42f11d3456e953b87e33c246048ae9c9 Mon Sep 17 00:00:00 2001 From: Jasmine Date: Tue, 19 Nov 2024 18:31:28 +0200 Subject: [PATCH 09/58] wip --- demisto_sdk/commands/common/clients/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/demisto_sdk/commands/common/clients/__init__.py b/demisto_sdk/commands/common/clients/__init__.py index dae69e67b76..44e2dbf1e88 100644 --- a/demisto_sdk/commands/common/clients/__init__.py +++ b/demisto_sdk/commands/common/clients/__init__.py @@ -234,7 +234,8 @@ def get_client_from_server_type( raise -# =================== PLaybook Flow Tests +# =================== Playbook Flow Tests ================= + def parse_str_to_dict(input_str): """Internal function to convert a string representing a dictionary into an actual dictionary. From 1319502a394c4358f5cc0abd64decd01e1423f64 Mon Sep 17 00:00:00 2001 From: Jasmine Date: Tue, 19 Nov 2024 18:32:32 +0200 Subject: [PATCH 10/58] wip --- .../commands/test_content/playbook_flow_test/template_file.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/template_file.py b/demisto_sdk/commands/test_content/playbook_flow_test/template_file.py index c3f774b4e66..ebabe815ddb 100644 --- a/demisto_sdk/commands/test_content/playbook_flow_test/template_file.py +++ b/demisto_sdk/commands/test_content/playbook_flow_test/template_file.py @@ -7,10 +7,12 @@ } """ import json + import pytest from demisto_sdk.commands.common.clients import ( XsiamClient, + get_client_conf_from_pytest_request, get_client_from_server_type, ) From c33ac6e9ac0273128a5505d536953cc6b76fe613 Mon Sep 17 00:00:00 2001 From: Jasmine Date: Thu, 21 Nov 2024 09:38:27 +0200 Subject: [PATCH 11/58] add changelog --- .changelog/6669.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .changelog/6669.yml diff --git a/.changelog/6669.yml b/.changelog/6669.yml new file mode 100644 index 00000000000..d1d4fb18e15 --- /dev/null +++ b/.changelog/6669.yml @@ -0,0 +1,4 @@ +changes: +- description: Adding fixtures to xsiam client. + type: internal +pr_number: 6669 From e6e9db174075466119f0979609cdc66cc9e08120 Mon Sep 17 00:00:00 2001 From: Jasmine Date: Thu, 21 Nov 2024 09:43:56 +0200 Subject: [PATCH 12/58] mypy --- .../common/clients/xsiam/xsiam_api_client.py | 74 +++++++++++-------- 1 file changed, 45 insertions(+), 29 deletions(-) diff --git a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py index 7967849d592..c676042f2c5 100644 --- a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py +++ b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py @@ -53,21 +53,24 @@ def marketplace(self) -> MarketplaceVersions: """ def _process_response(self, response, status_code, expected_status=200): - """Process the HTTP response coming from the XSOAR client.""" # noqa: E999 + """Process the HTTP response coming from the XSOAR client.""" if status_code == expected_status: if response: try: return json.loads(response) except json.JSONDecodeError: - api_response = response.replace("'", '"').replace( - "False", "false").replace("True", "true").replace("None", "null") + api_response = ( + response.replace("'", '"') + .replace("False", "false") + .replace("True", "true") + .replace("None", "null") + ) return json.loads(api_response) return {} else: error_message = f"Expected status {expected_status}, but got {status_code}. Response: {response}" raise Exception(error_message) - """ ############################# xsoar related methods @@ -82,8 +85,7 @@ def delete_incidents( response_type: str = "object", ): # if in the future it will be possible to delete incidents in XSIAM, implement this method - raise NotImplementedError( - "it is not possible to delete incidents in XSIAM") + raise NotImplementedError("it is not possible to delete incidents in XSIAM") """ ############################# @@ -99,8 +101,7 @@ def push_to_dataset( data_format: str = "json", ): if self.server_config.token: - endpoint = urljoin( - self.server_config.base_api_url, "logs/v1/xsiam") + endpoint = urljoin(self.server_config.base_api_url, "logs/v1/xsiam") additional_headers = { "authorization": self.server_config.token, "format": data_format, @@ -110,8 +111,7 @@ def push_to_dataset( } token_type = "xsiam_token" elif self.server_config.collector_token: - endpoint = urljoin( - self.server_config.base_api_url, "logs/v1/event") + endpoint = urljoin(self.server_config.base_api_url, "logs/v1/event") additional_headers = { "authorization": self.server_config.collector_token, "content-type": "application/json" @@ -191,8 +191,7 @@ def get_xql_query_result(self, execution_id: str, timeout: int = 300): self.server_config.base_api_url, "public_api/v1/xql/get_query_results/" ) logger.info(f"Getting xql query results: endpoint={endpoint}") - response = self._xdr_client.post( - endpoint, data=payload, timeout=timeout) + response = self._xdr_client.post(endpoint, data=payload, timeout=timeout) logger.debug("Request completed to get xql query results") data = response.json() logger.debug(pformat(data)) @@ -213,7 +212,8 @@ def get_xql_query_result(self, execution_id: str, timeout: int = 300): def get_ioc_rules(self): # /ioc-rules is only an endpoint in XSIAM. response, status_code, response_headers = self._xsoar_client.generic_request( - "/ioc-rules", "GET", response_type="object") + "/ioc-rules", "GET", response_type="object" + ) if ( "text/html" in response_headers.get("Content-Type") or status_code != requests.codes.ok @@ -232,43 +232,55 @@ def get_ioc_rules(self): def create_alert_from_json(self, json_content: dict) -> int: alert_payload = {"request_data": {"alert": json_content}} - res = requests.post(url=f'{self.base_url}/public_api/v1/alerts/create_alert', - headers=self._xdr_client.headers, json=alert_payload) + res = requests.post( + url=f"{self.base_url}/public_api/v1/alerts/create_alert", + headers=self._xdr_client.headers, + json=alert_payload, + ) alert_data = self._process_response(res.content, res.status_code, 200) - return alert_data['reply'] + return alert_data["reply"] def get_internal_alert_id(self, alert_external_id: str) -> int: data = self.search_alerts(alert_external_id) - return data['alerts'][0]['alert_id'] + return data["alerts"][0]["alert_id"] - def update_alert(self, alert_id: str | list[str], updated_data: dict): + def update_alert(self, alert_id: str | list[str], updated_data: dict) -> dict: """ Args: alert_id (str | list[str]): alert ids to edit. updated_data (dict): The data to update the alerts with. https://cortex-panw.stoplight.io/docs/cortex-xsiam-1/rpt3p1ne2bwfe-update-alerts """ - alert_payload = {"request_data": { - "update_data": updated_data, "alert_id_list": alert_id}} - res = requests.post(url=f'{self.base_url}/public_api/v1/alerts/update_alerts', - headers=self._xdr_client.headers, json=alert_payload) + alert_payload = { + "request_data": {"update_data": updated_data, "alert_id_list": alert_id} + } + res = requests.post( + url=f"{self.base_url}/public_api/v1/alerts/update_alerts", + headers=self._xdr_client.headers, + json=alert_payload, + ) alert_data = self._process_response(res.content, res.status_code, 200) return alert_data - def search_alerts(self, external_alert_id: str | list[str]): + def search_alerts(self, external_alert_id: str | list[str]) -> dict: body = { "request_data": { "filters": [ { "field": "external_id_list", "operator": "in", - "value": external_alert_id if isinstance(external_alert_id, list) else [external_alert_id] + "value": external_alert_id + if isinstance(external_alert_id, list) + else [external_alert_id], } ] } } - res = requests.post(url=f'{self.base_url}/public_api/v1/alerts/get_alerts/', - headers=self._xdr_client.headers, json=body) - return self._process_response(res.content, res.status_code, 200)['reply'] + res = requests.post( + url=f"{self.base_url}/public_api/v1/alerts/get_alerts/", + headers=self._xdr_client.headers, + json=body, + ) + return self._process_response(res.content, res.status_code, 200)["reply"] """ ############################# @@ -279,10 +291,14 @@ def search_alerts(self, external_alert_id: str | list[str]): def get_playbook_data(self, playbook_id: int) -> dict: playbook_endpoint = f"/playbook/{playbook_id}" - response, status_code, _ = self._xsoar_client.generic_request(playbook_endpoint, method='GET', accept='application/json') + response, status_code, _ = self._xsoar_client.generic_request( + playbook_endpoint, method="GET", accept="application/json" + ) return self._process_response(response, status_code, 200) def update_playbook_input(self, playbook_id: str, new_inputs: dict): saving_inputs_path = f"/playbook/inputs/{playbook_id}" - response, status_code, _ = self._xsoar_client.generic_request(saving_inputs_path, method='POST', body={"inputs":new_inputs}) + response, status_code, _ = self._xsoar_client.generic_request( + saving_inputs_path, method="POST", body={"inputs": new_inputs} + ) return self._process_response(response, status_code, 200) From b83b9b769c13f549b77451dea5ef4e96ec989e91 Mon Sep 17 00:00:00 2001 From: Jasmine Beilin <71636766+JasBeilin@users.noreply.github.com> Date: Thu, 21 Nov 2024 09:57:40 +0200 Subject: [PATCH 13/58] Update and rename 6669.yml to 4650.yml --- .changelog/{6669.yml => 4650.yml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename .changelog/{6669.yml => 4650.yml} (82%) diff --git a/.changelog/6669.yml b/.changelog/4650.yml similarity index 82% rename from .changelog/6669.yml rename to .changelog/4650.yml index d1d4fb18e15..158f764f15f 100644 --- a/.changelog/6669.yml +++ b/.changelog/4650.yml @@ -1,4 +1,4 @@ changes: - description: Adding fixtures to xsiam client. type: internal -pr_number: 6669 +pr_number: 4650 From 4726b598ec3d78aede55c528b84c133949068fdd Mon Sep 17 00:00:00 2001 From: Jasmine Date: Thu, 21 Nov 2024 10:43:14 +0200 Subject: [PATCH 14/58] wip --- demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py index c676042f2c5..dc38f8edd9e 100644 --- a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py +++ b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py @@ -244,7 +244,7 @@ def get_internal_alert_id(self, alert_external_id: str) -> int: data = self.search_alerts(alert_external_id) return data["alerts"][0]["alert_id"] - def update_alert(self, alert_id: str | list[str], updated_data: dict) -> dict: + def update_alert(self, alert_id: Union[str, list[str]], updated_data: dict) -> dict: """ Args: alert_id (str | list[str]): alert ids to edit. From 1208413001b77e20bc3f35a6120a4574eda5ee99 Mon Sep 17 00:00:00 2001 From: epintzov Date: Tue, 26 Nov 2024 15:11:58 +0200 Subject: [PATCH 15/58] test xdr client --- .../common/clients/xsiam/xsiam_api_client.py | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py index dc38f8edd9e..803dd537176 100644 --- a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py +++ b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py @@ -232,11 +232,13 @@ def get_ioc_rules(self): def create_alert_from_json(self, json_content: dict) -> int: alert_payload = {"request_data": {"alert": json_content}} - res = requests.post( - url=f"{self.base_url}/public_api/v1/alerts/create_alert", - headers=self._xdr_client.headers, - json=alert_payload, - ) + endpoint = "/public_api/v1/alerts/create_alert" + res = self._xdr_client.post(endpoint=endpoint, json=alert_payload) + # res = requests.post( + # url=f"{self.base_url}/public_api/v1/alerts/create_alert", + # headers=self._xdr_client.headers, + # json=alert_payload, + # ) alert_data = self._process_response(res.content, res.status_code, 200) return alert_data["reply"] @@ -253,11 +255,13 @@ def update_alert(self, alert_id: Union[str, list[str]], updated_data: dict) -> d alert_payload = { "request_data": {"update_data": updated_data, "alert_id_list": alert_id} } - res = requests.post( - url=f"{self.base_url}/public_api/v1/alerts/update_alerts", - headers=self._xdr_client.headers, - json=alert_payload, - ) + endpoint = "/public_api/v1/alerts/update_alerts" + res = self._xdr_client.post(endpoint=endpoint, json=json) + # res = requests.post( + # url=f"{self.base_url}/public_api/v1/alerts/update_alerts", + # headers=self._xdr_client.headers, + # json=alert_payload, + # ) alert_data = self._process_response(res.content, res.status_code, 200) return alert_data @@ -275,11 +279,13 @@ def search_alerts(self, external_alert_id: str | list[str]) -> dict: ] } } - res = requests.post( - url=f"{self.base_url}/public_api/v1/alerts/get_alerts/", - headers=self._xdr_client.headers, - json=body, - ) + endpoint = "/public_api/v1/alerts/get_alerts/" + res = self._xdr_client.post(endpoint=endpoint, json=body) + # res = requests.post( + # url=f"{self.base_url}/public_api/v1/alerts/get_alerts/", + # headers=self._xdr_client.headers, + # json=body, + # ) return self._process_response(res.content, res.status_code, 200)["reply"] """ From e6e9eb6fd913964daac15c42b201e10334663f2e Mon Sep 17 00:00:00 2001 From: epintzov Date: Tue, 26 Nov 2024 15:19:19 +0200 Subject: [PATCH 16/58] test xdr client --- .../commands/common/clients/xsiam/xsiam_api_client.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py index 803dd537176..55ba7727fcf 100644 --- a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py +++ b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py @@ -233,7 +233,7 @@ def get_ioc_rules(self): def create_alert_from_json(self, json_content: dict) -> int: alert_payload = {"request_data": {"alert": json_content}} endpoint = "/public_api/v1/alerts/create_alert" - res = self._xdr_client.post(endpoint=endpoint, json=alert_payload) + res = self._xdr_client.post(endpoint, json=alert_payload) # res = requests.post( # url=f"{self.base_url}/public_api/v1/alerts/create_alert", # headers=self._xdr_client.headers, @@ -256,7 +256,7 @@ def update_alert(self, alert_id: Union[str, list[str]], updated_data: dict) -> d "request_data": {"update_data": updated_data, "alert_id_list": alert_id} } endpoint = "/public_api/v1/alerts/update_alerts" - res = self._xdr_client.post(endpoint=endpoint, json=json) + res = self._xdr_client.post(endpoint, json=json) # res = requests.post( # url=f"{self.base_url}/public_api/v1/alerts/update_alerts", # headers=self._xdr_client.headers, @@ -280,7 +280,7 @@ def search_alerts(self, external_alert_id: str | list[str]) -> dict: } } endpoint = "/public_api/v1/alerts/get_alerts/" - res = self._xdr_client.post(endpoint=endpoint, json=body) + res = self._xdr_client.post(endpoint, json=body) # res = requests.post( # url=f"{self.base_url}/public_api/v1/alerts/get_alerts/", # headers=self._xdr_client.headers, From 8893847bfd319b6df77cf3404d4f358d84f146f3 Mon Sep 17 00:00:00 2001 From: epintzov Date: Tue, 26 Nov 2024 15:24:22 +0200 Subject: [PATCH 17/58] test xdr client --- .../common/clients/xsiam/xsiam_api_client.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py index 55ba7727fcf..7b4a13a483b 100644 --- a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py +++ b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py @@ -232,7 +232,9 @@ def get_ioc_rules(self): def create_alert_from_json(self, json_content: dict) -> int: alert_payload = {"request_data": {"alert": json_content}} - endpoint = "/public_api/v1/alerts/create_alert" + endpoint = urljoin( + self.server_config.base_api_url, "/public_api/v1/alerts/create_alert" + ) res = self._xdr_client.post(endpoint, json=alert_payload) # res = requests.post( # url=f"{self.base_url}/public_api/v1/alerts/create_alert", @@ -255,8 +257,10 @@ def update_alert(self, alert_id: Union[str, list[str]], updated_data: dict) -> d alert_payload = { "request_data": {"update_data": updated_data, "alert_id_list": alert_id} } - endpoint = "/public_api/v1/alerts/update_alerts" - res = self._xdr_client.post(endpoint, json=json) + endpoint = urljoin( + self.server_config.base_api_url, "/public_api/v1/alerts/update_alerts" + ) + res = self._xdr_client.post(endpoint, json=alert_payload) # res = requests.post( # url=f"{self.base_url}/public_api/v1/alerts/update_alerts", # headers=self._xdr_client.headers, @@ -279,7 +283,9 @@ def search_alerts(self, external_alert_id: str | list[str]) -> dict: ] } } - endpoint = "/public_api/v1/alerts/get_alerts/" + endpoint = urljoin( + self.server_config.base_api_url, "/public_api/v1/alerts/get_alerts/" + ) res = self._xdr_client.post(endpoint, json=body) # res = requests.post( # url=f"{self.base_url}/public_api/v1/alerts/get_alerts/", From 45907d116120c45a323498ddd3b21294ac99e3e2 Mon Sep 17 00:00:00 2001 From: epintzov Date: Tue, 26 Nov 2024 17:04:57 +0200 Subject: [PATCH 18/58] bug fix --- .../common/clients/xsiam/xsiam_api_client.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py index 7b4a13a483b..9f4a9ff5cfc 100644 --- a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py +++ b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py @@ -236,11 +236,6 @@ def create_alert_from_json(self, json_content: dict) -> int: self.server_config.base_api_url, "/public_api/v1/alerts/create_alert" ) res = self._xdr_client.post(endpoint, json=alert_payload) - # res = requests.post( - # url=f"{self.base_url}/public_api/v1/alerts/create_alert", - # headers=self._xdr_client.headers, - # json=alert_payload, - # ) alert_data = self._process_response(res.content, res.status_code, 200) return alert_data["reply"] @@ -261,11 +256,6 @@ def update_alert(self, alert_id: Union[str, list[str]], updated_data: dict) -> d self.server_config.base_api_url, "/public_api/v1/alerts/update_alerts" ) res = self._xdr_client.post(endpoint, json=alert_payload) - # res = requests.post( - # url=f"{self.base_url}/public_api/v1/alerts/update_alerts", - # headers=self._xdr_client.headers, - # json=alert_payload, - # ) alert_data = self._process_response(res.content, res.status_code, 200) return alert_data @@ -287,11 +277,6 @@ def search_alerts(self, external_alert_id: str | list[str]) -> dict: self.server_config.base_api_url, "/public_api/v1/alerts/get_alerts/" ) res = self._xdr_client.post(endpoint, json=body) - # res = requests.post( - # url=f"{self.base_url}/public_api/v1/alerts/get_alerts/", - # headers=self._xdr_client.headers, - # json=body, - # ) return self._process_response(res.content, res.status_code, 200)["reply"] """ From 7fbff0becfe6ca04003732ed1a2e3402e6d80286 Mon Sep 17 00:00:00 2001 From: epintzov Date: Wed, 27 Nov 2024 15:51:14 +0200 Subject: [PATCH 19/58] test --- conftest.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/conftest.py b/conftest.py index af46bfece8f..83ba04088f4 100644 --- a/conftest.py +++ b/conftest.py @@ -20,6 +20,7 @@ from TestSuite.repo import Repo from TestSuite.yml import YAML + # Helper Functions @@ -39,7 +40,7 @@ def get_pack(request: FixtureRequest, tmp_path_factory: TempPathFactory) -> Pack def get_integration( - request: FixtureRequest, tmp_path_factory: TempPathFactory + request: FixtureRequest, tmp_path_factory: TempPathFactory ) -> Integration: """Mocking tmp_path""" integration = get_pack(request, tmp_path_factory).create_integration() @@ -48,7 +49,7 @@ def get_integration( def get_playbook( - request: FixtureRequest, tmp_path_factory: TempPathFactory + request: FixtureRequest, tmp_path_factory: TempPathFactory ) -> Playbook: """Mocking tmp_path""" playbook = get_pack(request, tmp_path_factory).create_playbook() @@ -78,7 +79,7 @@ def script(request: FixtureRequest, tmp_path_factory: TempPathFactory): @pytest.fixture def integration( - request: FixtureRequest, tmp_path_factory: TempPathFactory + request: FixtureRequest, tmp_path_factory: TempPathFactory ) -> Integration: """Mocking tmp_path""" return get_integration(request, tmp_path_factory) @@ -162,7 +163,7 @@ def mock_update_id_set_cpu_count() -> Generator: all physical cpu's (36) it uses too many processes in the process pools. """ with mock.patch( - "demisto_sdk.commands.common.update_id_set.cpu_count", return_value=2 + "demisto_sdk.commands.common.update_id_set.cpu_count", return_value=2 ) as _fixture: yield _fixture @@ -175,3 +176,12 @@ def disable_log_colors(): @pytest.fixture(autouse=True) def clear_cache(): tools.get_file.cache_clear() + + +def pytest_addoption(parser): + parser.addoption( + "--client_conf", + action="store", + default=None, + help="Custom client configuration" + ) From 0e0e8e47a0e930ea4c216229208a963820492981 Mon Sep 17 00:00:00 2001 From: epintzov Date: Thu, 28 Nov 2024 18:45:56 +0200 Subject: [PATCH 20/58] adding command logic --- conftest.py | 18 +- demisto_sdk/__main__.py | 10 +- .../commands/common/clients/__init__.py | 11 +- .../run_playbook_flow_test.py | 863 ++++++++++-------- .../playbook_flow_test/template_file.py | 8 +- 5 files changed, 519 insertions(+), 391 deletions(-) diff --git a/conftest.py b/conftest.py index 83ba04088f4..af46bfece8f 100644 --- a/conftest.py +++ b/conftest.py @@ -20,7 +20,6 @@ from TestSuite.repo import Repo from TestSuite.yml import YAML - # Helper Functions @@ -40,7 +39,7 @@ def get_pack(request: FixtureRequest, tmp_path_factory: TempPathFactory) -> Pack def get_integration( - request: FixtureRequest, tmp_path_factory: TempPathFactory + request: FixtureRequest, tmp_path_factory: TempPathFactory ) -> Integration: """Mocking tmp_path""" integration = get_pack(request, tmp_path_factory).create_integration() @@ -49,7 +48,7 @@ def get_integration( def get_playbook( - request: FixtureRequest, tmp_path_factory: TempPathFactory + request: FixtureRequest, tmp_path_factory: TempPathFactory ) -> Playbook: """Mocking tmp_path""" playbook = get_pack(request, tmp_path_factory).create_playbook() @@ -79,7 +78,7 @@ def script(request: FixtureRequest, tmp_path_factory: TempPathFactory): @pytest.fixture def integration( - request: FixtureRequest, tmp_path_factory: TempPathFactory + request: FixtureRequest, tmp_path_factory: TempPathFactory ) -> Integration: """Mocking tmp_path""" return get_integration(request, tmp_path_factory) @@ -163,7 +162,7 @@ def mock_update_id_set_cpu_count() -> Generator: all physical cpu's (36) it uses too many processes in the process pools. """ with mock.patch( - "demisto_sdk.commands.common.update_id_set.cpu_count", return_value=2 + "demisto_sdk.commands.common.update_id_set.cpu_count", return_value=2 ) as _fixture: yield _fixture @@ -176,12 +175,3 @@ def disable_log_colors(): @pytest.fixture(autouse=True) def clear_cache(): tools.get_file.cache_clear() - - -def pytest_addoption(parser): - parser.addoption( - "--client_conf", - action="store", - default=None, - help="Custom client configuration" - ) diff --git a/demisto_sdk/__main__.py b/demisto_sdk/__main__.py index c23c55aea26..2dd1fb8ccba 100644 --- a/demisto_sdk/__main__.py +++ b/demisto_sdk/__main__.py @@ -3855,17 +3855,19 @@ def pre_commit( # ====================== playbook-flow test command group ====================== # playbook_flow_app = typer.Typer( - name="playbook-flow-test", + name="playbook-flow", hidden=True, no_args_is_help=True, context_settings={"help_option_names": ["-h", "--help"]}, ) + playbook_flow_app.command("test", no_args_is_help=True)( - run_playbook_flow_test.run_flow_test + run_playbook_flow_test.test_playbook_flow_test ) +playbook_flow_app.command("generate_template_flow", no_args_is_help=True)(run_playbook_flow_test.test_playbook_flow_test) + -typer_click_object = typer.main.get_command(playbook_flow_app) -main.add_command(typer_click_object, "playbook-flow-test") +main.add_command(typer.main.get_command(playbook_flow_app), "playbook-flow") # ====================== graph command group ====================== # diff --git a/demisto_sdk/commands/common/clients/__init__.py b/demisto_sdk/commands/common/clients/__init__.py index 44e2dbf1e88..c8054450bf3 100644 --- a/demisto_sdk/commands/common/clients/__init__.py +++ b/demisto_sdk/commands/common/clients/__init__.py @@ -247,15 +247,14 @@ def parse_str_to_dict(input_str): """ return dict(pair.split("=") for pair in input_str.split(",") if "=" in pair) -def get_client_conf_from_pytest_request(request): +def get_client_conf_from_pytest_request(): # Manually parse command-line argument - for arg in request.config.invocation_params.args: - if isinstance(arg, str) and arg.startswith("--client_conf="): - client_conf = arg.replace("--client_conf=", '') - return parse_str_to_dict(client_conf) - # If a client data was not provided, we proceed to use default. + client_conf = os.getenv("CLIENT_CONF") + if client_conf: + return parse_str_to_dict(client_conf) return None + diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py index 8c5a3825d0d..b2daeaec68c 100644 --- a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py +++ b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py @@ -1,8 +1,11 @@ -import logging +import io +import logging # noqa: TID251 # specific case, passed as argument to 3rd party import os +from contextlib import redirect_stdout from datetime import datetime from pathlib import Path from threading import Thread +from time import sleep from typing import Any, Dict, List, Optional, Tuple, Union from uuid import UUID @@ -15,6 +18,7 @@ from google.cloud import storage # type: ignore[attr-defined] from junitparser import Error, JUnitXml, TestCase, TestSuite from junitparser.junitparser import Failure, Result, Skipped +from packaging.version import Version from tabulate import tabulate from tenacity import ( Retrying, @@ -23,27 +27,52 @@ stop_after_attempt, wait_fixed, ) +from typer.main import get_command_from_info +from demisto_sdk.commands.common.constants import ( + TEST_MODELING_RULES, + XSIAM_SERVER_TYPE, +) +from demisto_sdk.commands.common.content.objects.pack_objects.modeling_rule.modeling_rule import ( + ModelingRule, + SingleModelingRule, +) from demisto_sdk.commands.common.content_constant_paths import CONTENT_PATH from demisto_sdk.commands.common.handlers import DEFAULT_JSON_HANDLER as json from demisto_sdk.commands.common.logger import ( + handle_deprecated_args, logger, logging_setup, ) from demisto_sdk.commands.common.tools import ( + get_file, get_json_file, + is_epoch_datetime, parse_int_or_default, string_to_bool, ) from demisto_sdk.commands.test_content.ParallelLoggingManager import ( ParallelLoggingManager, ) +from demisto_sdk.commands.test_content.test_modeling_rule.constants import ( + EXPECTED_SCHEMA_MAPPINGS, + FAILURE_TO_PUSH_EXPLANATION, + NOT_AVAILABLE, + SYNTAX_ERROR_IN_MODELING_RULE, + TIME_ZONE_WARNING, + XQL_QUERY_ERROR_EXPLANATION, +) from demisto_sdk.commands.test_content.tools import get_ui_url +from demisto_sdk.commands.test_content.xsiam_tools.test_data import ( + TestData, + Validations, +) from demisto_sdk.commands.test_content.xsiam_tools.xsiam_client import ( XsiamApiClient, XsiamApiClientConfig, ) from demisto_sdk.commands.upload.upload import upload_content_entity as upload_cmd +from demisto_sdk.utils.utils import get_containing_pack CI_PIPELINE_ID = os.environ.get("CI_PIPELINE_ID") XSIAM_CLIENT_SLEEP_INTERVAL = 60 @@ -52,202 +81,49 @@ app = typer.Typer() -def get_utc_now() -> datetime: - """Get the current time in UTC, with timezone aware.""" - return datetime.now(tz=pytz.UTC) - - -def duration_since_start_time(start_time: datetime) -> float: - """Get the duration since the given start time, in seconds. - - Args: - start_time (datetime): Start time. - - Returns: - float: Duration since the given start time, in seconds. - """ - return (get_utc_now() - start_time).total_seconds() - - -def create_table(expected: Dict[str, Any], received: Dict[str, Any]) -> str: - """Create a table to display the expected and received values. - - Args: - expected: mapping of keys to expected values - received: mapping of keys to received values - - Returns: - String representation of a table, to display the expected and received values. - """ - data = [(key, str(val), str(received.get(key))) for key, val in expected.items()] - return tabulate( - data, - tablefmt="grid", - headers=["Model Field", "Expected Value", "Received Value"], - colalign=("left", "left", "left"), - ) - - -def day_suffix(day: int) -> str: - """ - Returns a suffix string base on the day of the month. - for 1, 21, 31 => st - for 2, 22 => nd - for 3, 23 => rd - for to all the others => th - - see here for more details: https://en.wikipedia.org/wiki/English_numerals#Ordinal_numbers - - Args: - day: The day of the month represented by a number. - - Returns: - suffix string (st, nd, rd, th). - """ - return "th" if 11 <= day <= 13 else {1: "st", 2: "nd", 3: "rd"}.get(day % 10, "th") - - -def get_relative_path_to_content(path: Path) -> str: - """Get the relative path to the content directory. - - Args: - path: The path to the content item. - - Returns: - Path: The relative path to the content directory. +# ============================================== Classes ============================================ # +class TestResultCapture: """ - if path.is_absolute() and path.as_posix().startswith(CONTENT_PATH.as_posix()): - return path.as_posix().replace(f"{CONTENT_PATH.as_posix()}{os.path.sep}", "") - return path.as_posix() - - -def convert_epoch_time_to_string_time( - epoch_time: int, with_ms: bool = False, tenant_timezone: str = "UTC" -) -> str: - """ - Converts epoch time with milliseconds to string time with timezone delta. - - Args: - epoch_time: The received epoch time (with milliseconds). - with_ms: Whether to convert the epoch time with ms or not default is False. - tenant_timezone: The timezone of the XSIAM tenant. - - Returns: - The string time with timezone delta. - """ - datetime_object = datetime.fromtimestamp( - epoch_time / 1000, pytz.timezone(tenant_timezone) - ) - time_format = ( - f"%b %-d{day_suffix(datetime_object.day)} %Y %H:%M:%S{'.%f' if with_ms else ''}" - ) - return datetime_object.strftime(time_format) - - -def get_type_pretty_name(obj: Any) -> str: - """Get the pretty name of the type of the given object. - - Args: - obj (Any): The object to get the type name for. - - Returns: - str: The pretty name of the type of the given object. + This class is used to store the pytest results in test suite """ - return { - type(None): "null", - list: "list", - dict: "dict", - tuple: "tuple", - set: "set", - UUID: "UUID", - str: "string", - int: "int", - float: "float", - bool: "boolean", - datetime: "datetime", - }.get(type(obj), str(type(obj))) - - -def create_retrying_caller(retry_attempts: int, sleep_interval: int) -> Retrying: - """Create a Retrying object with the given retry_attempts and sleep_interval.""" - sleep_interval = parse_int_or_default(sleep_interval, XSIAM_CLIENT_SLEEP_INTERVAL) - retry_attempts = parse_int_or_default(retry_attempts, XSIAM_CLIENT_RETRY_ATTEMPTS) - retry_params: Dict[str, Any] = { - "reraise": True, - "before_sleep": before_sleep_log(logger, logging.DEBUG), - "retry": retry_if_exception_type(requests.exceptions.RequestException), - "stop": stop_after_attempt(retry_attempts), - "wait": wait_fixed(sleep_interval), - } - return Retrying(**retry_params) + def __init__(self, junit_testsuite): + self.junit_testsuite = junit_testsuite + + def pytest_runtest_logreport(self, report): + if report.when == "call": # Only capture results of test calls + test_case = TestCase(report.nodeid) + test_case.classname = report.location[0] # Test's module or class + test_case.time = report.duration # Add the test duration + if report.outcome == "passed": + self.junit_testsuite.add_testcase(test_case) + elif report.outcome == "failed": + failure = Failure(report.longreprtext if report.longrepr else "Test failed") + test_case.result = failure + self.junit_testsuite.add_testcase(test_case) + elif report.outcome == "skipped": + skipped = Skipped("Test skipped") + test_case.result = skipped + self.junit_testsuite.add_testcase(test_case) -def run_playbook_flow_test_pytest(test_file, xsiam_client: XsiamApiClient, durations_path = None, result_file_path = "test_result.txt"): - - # Creating an instance of your results collector - playbook_flow_test_suite = TestSuite(f"Playbook Flow Test Results {result_file_path}") - - # Configure pytest arguments - conf = f"base_url={str(xsiam_client.base_url)},api_key={xsiam_client.api_key},auth_id={xsiam_client.auth_id}" - pytest_args = [ - "-v", - test_file, - f"--client_conf={conf}", - "--durations=" + ("5" if durations_path is None else durations_path), - "--junitxml={result_file_path}", - ] - - # Running pytest - try: - status_code = pytest.main(pytest_args) - except Exception as e: - logger.warning(str(e)) - return None - - # Here, results_collector.results will have the summary of results - - # with open(result_file_path, 'w') as result_file: - # for test, outcome in results_collector.results: - # result_file.write(f"{test}: {outcome}\n") - # return True, playbook_flow_test_suite - # return results_collector.results - - -def log_error_to_test_case( - err: str, schema_test_case: TestCase, playbook_flow_test_suite: TestSuite -) -> Tuple[bool, TestSuite]: - logger.error( - f"[red]{err}[/red]", - extra={"markup": True}, - ) - schema_test_case.system_err = err - return add_result_to_test_case(err, schema_test_case, playbook_flow_test_suite) - - -def add_result_to_test_case( - err: str, test_case: TestCase, playbook_flow_test_suite: TestSuite -) -> Tuple[bool, TestSuite]: - test_case.result += [Error(err)] # type:ignore[arg-type] - playbook_flow_test_suite.add_testcase(test_case) - return False, playbook_flow_test_suite class TestResults: def __init__( - self, - service_account: str = None, - artifacts_bucket: str = None, + self, + service_account: str = None, + artifacts_bucket: str = None, ): self.test_results_xml_file = JUnitXml() self.errors = False self.service_account = service_account self.artifacts_bucket = artifacts_bucket - def upload_playbook_flow_test_result_json_to_bucket( - self, - repository_name: str, - file_name, - original_file_path: Path, - logging_module: Union[Any, ParallelLoggingManager] = logging, + def upload_modeling_rules_result_json_to_bucket( + self, + repository_name: str, + file_name, + original_file_path: Path, + logging_module: Union[Any, ParallelLoggingManager] = logging, ): """Uploads a JSON object to a specified path in the GCP bucket. @@ -255,46 +131,63 @@ def upload_playbook_flow_test_result_json_to_bucket( original_file_path: The path to the JSON file to upload. repository_name: The name of the repository within the bucket. file_name: The desired filename for the uploaded JSON data. - logging_module: Logging module to use for upload_playbook_flow_test_result_json_to_bucket. + logging_module: Logging module to use for upload_modeling_rules_result_json_to_bucket. """ - logging_module.info("Start uploading Playbook Flow Tests results file to bucket") + logging_module.info("Start uploading modeling rules results file to bucket") storage_client = storage.Client.from_service_account_json(self.service_account) storage_bucket = storage_client.bucket(self.artifacts_bucket) blob = storage_bucket.blob( - f"content-playbook_flow_test/{repository_name}/{file_name}" + f"content-test-modeling-rules/{repository_name}/{file_name}" ) blob.upload_from_filename( original_file_path.as_posix(), content_type="application/xml", ) - logging_module.info("Finished uploading Playbook Flow Tests results file to bucket") + logging_module.info("Finished uploading modeling rules results file to bucket") class BuildContext: def __init__( - self, - nightly: bool, - build_number: Optional[str], - branch_name: Optional[str], - retry_attempts: int, - sleep_interval: int, - logging_module: ParallelLoggingManager, - cloud_servers_path: str, - cloud_servers_api_keys: str, - service_account: Optional[str], - artifacts_bucket: Optional[str], - machine_assignment: str, + self, + nightly: bool, + build_number: Optional[str], + branch_name: Optional[str], + retry_attempts: int, + sleep_interval: int, + logging_module: ParallelLoggingManager, + cloud_servers_path: str, + cloud_servers_api_keys: str, + service_account: Optional[str], + artifacts_bucket: Optional[str], + xsiam_url: Optional[str], + xsiam_token: Optional[str], + api_key: Optional[str], + auth_id: Optional[str], + collector_token: Optional[str], + inputs: Optional[List[Path]], + machine_assignment: str, + ctx: typer.Context, ): self.logging_module: ParallelLoggingManager = logging_module self.retrying_caller = create_retrying_caller(retry_attempts, sleep_interval) + self.ctx = ctx # --------------------------- overall build configuration ------------------------------- self.is_nightly = nightly self.build_number = build_number self.build_name = branch_name + + # -------------------------- Manual run on a single instance -------------------------- + self.xsiam_url = xsiam_url + self.xsiam_token = xsiam_token + self.api_key = api_key + self.auth_id = auth_id + self.collector_token = collector_token + self.inputs = inputs + # --------------------------- Machine preparation ------------------------------- self.cloud_servers_path_json = get_json_file(cloud_servers_path) @@ -323,14 +216,30 @@ def create_servers(self): """ Create servers object based on build type. """ + # If xsiam_url is provided we assume it's a run on a single server. + if self.xsiam_url: + return [ + CloudServerContext( + self, + base_url=self.xsiam_url, + api_key=self.api_key, # type: ignore[arg-type] + auth_id=self.auth_id, # type: ignore[arg-type] + token=self.xsiam_token, # type: ignore[arg-type] + collector_token=self.collector_token, + ui_url=get_ui_url(self.xsiam_url), + tests=[BuildContext.prefix_with_packs(test) for test in self.inputs] + if self.inputs + else [], + ) + ] servers_list = [] for machine, assignment in self.machine_assignment_json.items(): tests = [ BuildContext.prefix_with_packs(test) - for test in assignment.get("tests", {}).get('PlaybookFlowTest', []) + for test in assignment.get("tests", {}).get(TEST_MODELING_RULES, []) ] if not tests: - logger.info(f"No playbook flow tests found for machine {machine}") + logger.info(f"No modeling rules found for machine {machine}") continue servers_list.append( CloudServerContext( @@ -358,15 +267,15 @@ def create_servers(self): class CloudServerContext: def __init__( - self, - build_context: BuildContext, - base_url: str, - api_key: str, - auth_id: str, - token: str, - ui_url: str, - tests: List[Path], - collector_token: Optional[str] = None, + self, + build_context: BuildContext, + base_url: str, + api_key: str, + auth_id: str, + token: str, + ui_url: str, + tests: List[Path], + collector_token: Optional[str] = None, ): self.build_context = build_context self.client = None @@ -393,12 +302,6 @@ def configure_new_client(self): auth_id=self.auth_id, verify_ssl=False, ) - def set_machine_cred_to_env(self): - os.environ['DEMISTO_BASE_URL'] = self.base_url - os.environ['DEMISTO_API_KEY'] = self.api_key - os.environ['XSIAM_AUTH_ID'] = str(self.auth_id) - os.environ['XSIAM_TOKEN'] = self.token - os.environ['DEMISTO_VERIFY_SSL'] = str(False) def execute_tests(self): try: @@ -420,33 +323,33 @@ def execute_tests(self): collector_token=self.collector_token, # type: ignore[arg-type] ) xsiam_client = XsiamApiClient(xsiam_client_cfg) - for i, playbook_flow_directory in enumerate(self.tests, start=1): + + for i, playbook_flow_test_directory in enumerate(self.tests, start=1): logger.info( - f"[cyan][{i}/{len(self.tests)}] Playbook Flow Test: {get_relative_path_to_content(playbook_flow_directory)}[/cyan]", - extra={"markup": True}, + f"[{i}/{len(self.tests)}] Test Modeling Rule: {get_relative_path_to_content(playbook_flow_test_directory)}", ) - success, playbook_flow_test_suite = run_playbook_flow_test_pytest( - playbook_flow_directory, - xsiam_client=xsiam_client, + + success, playbook_flow_test_test_suite = run_playbook_flow_test_pytest( + playbook_flow_test_directory, + xsiam_client=xsiam_client ) + if success: logger.info( - f"[green]Playbook Flow Test {get_relative_path_to_content(playbook_flow_directory)} passed[/green]", - extra={"markup": True}, + f"Playbook flow test {get_relative_path_to_content(playbook_flow_test_directory)} passed", ) else: self.build_context.tests_data_keeper.errors = True logger.error( - f"[red]Playbook Flow Test {get_relative_path_to_content(playbook_flow_directory)} failed[/red]", - extra={"markup": True}, + f"Playbook flow test {get_relative_path_to_content(playbook_flow_test_directory)} failed", ) - if playbook_flow_test_suite: - playbook_flow_test_suite.add_property( + if playbook_flow_test_test_suite: + playbook_flow_test_test_suite.add_property( "start_time", start_time, # type:ignore[arg-type] ) self.build_context.tests_data_keeper.test_results_xml_file.add_testsuite( - playbook_flow_test_suite + playbook_flow_test_test_suite ) self.build_context.logging_module.info( @@ -465,6 +368,182 @@ def execute_tests(self): self.build_context.logging_module.execute_logs() +# ============================================== Helper methods ============================================ # + +def get_utc_now() -> datetime: + """Get the current time in UTC, with timezone aware.""" + return datetime.now(tz=pytz.UTC) + + +def duration_since_start_time(start_time: datetime) -> float: + """Get the duration since the given start time, in seconds. + + Args: + start_time (datetime): Start time. + + Returns: + float: Duration since the given start time, in seconds. + """ + return (get_utc_now() - start_time).total_seconds() + + +def day_suffix(day: int) -> str: + """ + Returns a suffix string base on the day of the month. + for 1, 21, 31 => st + for 2, 22 => nd + for 3, 23 => rd + for to all the others => th + + see here for more details: https://en.wikipedia.org/wiki/English_numerals#Ordinal_numbers + + Args: + day: The day of the month represented by a number. + + Returns: + suffix string (st, nd, rd, th). + """ + return "th" if 11 <= day <= 13 else {1: "st", 2: "nd", 3: "rd"}.get(day % 10, "th") + + +def get_relative_path_to_content(path: Path) -> str: + """Get the relative path to the content directory. + + Args: + path: The path to the content item. + + Returns: + Path: The relative path to the content directory. + """ + if path.is_absolute() and path.as_posix().startswith(CONTENT_PATH.as_posix()): + return path.as_posix().replace(f"{CONTENT_PATH.as_posix()}{os.path.sep}", "") + return path.as_posix() + + +def get_type_pretty_name(obj: Any) -> str: + """Get the pretty name of the type of the given object. + + Args: + obj (Any): The object to get the type name for. + + Returns: + str: The pretty name of the type of the given object. + """ + return { + type(None): "null", + list: "list", + dict: "dict", + tuple: "tuple", + set: "set", + UUID: "UUID", + str: "string", + int: "int", + float: "float", + bool: "boolean", + datetime: "datetime", + }.get(type(obj), str(type(obj))) + + +def create_retrying_caller(retry_attempts: int, sleep_interval: int) -> Retrying: + """Create a Retrying object with the given retry_attempts and sleep_interval.""" + sleep_interval = parse_int_or_default(sleep_interval, XSIAM_CLIENT_SLEEP_INTERVAL) + retry_attempts = parse_int_or_default(retry_attempts, XSIAM_CLIENT_RETRY_ATTEMPTS) + retry_params: Dict[str, Any] = { + "reraise": True, + "before_sleep": before_sleep_log(logging.getLogger(), logging.DEBUG), + "retry": retry_if_exception_type(requests.exceptions.RequestException), + "stop": stop_after_attempt(retry_attempts), + "wait": wait_fixed(sleep_interval), + } + return Retrying(**retry_params) + + +def xsiam_get_installed_packs(xsiam_client: XsiamApiClient) -> List[Dict[str, Any]]: + """Get the list of installed packs from the XSIAM tenant. + Wrapper for XsiamApiClient.get_installed_packs() with retry logic. + """ + return xsiam_client.installed_packs + + +def tenant_config_cb( + ctx: typer.Context, param: typer.CallbackParam, value: Optional[str] +): + if ctx.resilient_parsing: + return + # Only check the params if the machine_assignment is not set. + if param.value_is_missing(value) and not ctx.params.get("machine_assignment"): + err_str = ( + f"{param.name} must be set either via the environment variable " + f'"{param.envvar}" or passed explicitly when running the command' + ) + raise typer.BadParameter(err_str) + return value + + +def logs_token_cb(ctx: typer.Context, param: typer.CallbackParam, value: Optional[str]): + if ctx.resilient_parsing: + return + # Only check the params if the machine_assignment is not set. + if param.value_is_missing(value) and not ctx.params.get("machine_assignment"): + parameter_to_check = "xsiam_token" + other_token = ctx.params.get(parameter_to_check) + if not other_token: + err_str = ( + f"One of {param.name} or {parameter_to_check} must be set either via it's associated" + " environment variable or passed explicitly when running the command" + ) + raise typer.BadParameter(err_str) + return value + + +# ============================================== Command logic ============================================ # + +def run_playbook_flow_test_pytest( + playbook_flow_test_directory: Path, + xsiam_client: XsiamApiClient, + durations: int = 5) -> Tuple[bool, Union[TestSuite, None]]: + """Runs a playbook flow test + + Args: + playbook_flow_test_directory (Path): Path to the playbook flow test directory. + durations (int): Number of slow tests to show durations for. + xsiam_client (XsiamApiClient): The XSIAM client used to do API calls to the tenant. + """ + # Creating an instance of your results collector + playbook_flow_test_suite = TestSuite(f"Playbook Flow Test") + playbook_flow_test_suite.add_property( + "file_name", str(playbook_flow_test_directory) + ) + + # Configure pytest arguments + os.environ["CLIENT_CONF"] = (f"base_url={str(xsiam_client.base_url)}," + f"api_key={xsiam_client.api_key}," + f"auth_id={xsiam_client.auth_id}") + + pytest_args = [ + "-v", + str(playbook_flow_test_directory), + f"--durations={str(durations)}", + f"--junitxml=report.xml", + "--log-cli-level=CRITICAL" + ] + + logger.info(f"Runnig pytest for file {playbook_flow_test_directory}") + + # Running pytest + result_capture = TestResultCapture(playbook_flow_test_suite) + status_code = pytest.main(pytest_args, plugins=[result_capture]) + + if status_code == pytest.ExitCode.OK: + logger.info(f"Pytest run tests in {playbook_flow_test_directory} successfully") + return True, playbook_flow_test_suite + else: + logger.error( + f"Pytest failed with statsu {status_code}", + ) + return False, playbook_flow_test_suite + + @app.command( no_args_is_help=True, context_settings={ @@ -473,136 +552,176 @@ def execute_tests(self): "help_option_names": ["-h", "--help"], }, ) -def run_flow_test( - ctx: typer.Context, - push: bool = typer.Option( - True, - "--push/--no-push", - "-p/-np", - help=( - "In the event that you've already pushed test data and only want to verify expected values, you can" - ' pass "--no-push" to skip pushing the test data.' +def test_playbook_flow_test( + ctx: typer.Context, + inputs: List[Path] = typer.Argument( + None, + exists=True, + dir_okay=True, + resolve_path=True, + show_default=False, + help="The path to a directory of a modeling rule. May pass multiple paths to test multiple modeling rules.", + ), + xsiam_url: Optional[str] = typer.Option( + None, + envvar="DEMISTO_BASE_URL", + help="The base url to the xsiam tenant.", + rich_help_panel="XSIAM Tenant Configuration", + show_default=False, + callback=tenant_config_cb, + ), + api_key: Optional[str] = typer.Option( + None, + envvar="DEMISTO_API_KEY", + help="The api key for the xsiam tenant.", + rich_help_panel="XSIAM Tenant Configuration", + show_default=False, + callback=tenant_config_cb, + ), + auth_id: Optional[str] = typer.Option( + None, + envvar="XSIAM_AUTH_ID", + help="The auth id associated with the xsiam api key being used.", + rich_help_panel="XSIAM Tenant Configuration", + show_default=False, + callback=tenant_config_cb, + ), + xsiam_token: Optional[str] = typer.Option( + None, + envvar="XSIAM_TOKEN", + help="The token used to push event logs to XSIAM", + rich_help_panel="XSIAM Tenant Configuration", + show_default=False, + ), + collector_token: Optional[str] = typer.Option( + None, + envvar="XSIAM_COLLECTOR_TOKEN", + help="The token used to push event logs to a custom HTTP Collector", + rich_help_panel="XSIAM Tenant Configuration", + show_default=False, + callback=logs_token_cb, + ), + output_junit_file: Optional[Path] = typer.Option( + None, "-jp", "--junit-path", help="Path to the output JUnit XML file." + ), + sleep_interval: int = typer.Option( + XSIAM_CLIENT_SLEEP_INTERVAL, + "-si", + "--sleep_interval", + min=0, + show_default=True, + help="The number of seconds to wait between requests to the server.", + ), + retry_attempts: int = typer.Option( + XSIAM_CLIENT_RETRY_ATTEMPTS, + "-ra", + "--retry_attempts", + min=0, + show_default=True, + help="The number of times to retry the request against the server.", + ), + service_account: Optional[str] = typer.Option( + None, + "-sa", + "--service_account", + envvar="GCP_SERVICE_ACCOUNT", + help="GCP service account.", + show_default=False, + ), + cloud_servers_path: str = typer.Option( + "", + "-csp", + "--cloud_servers_path", + help="Path to secret cloud server metadata file.", + show_default=False, ), - rich_help_panel="Interactive Configuration", - ), - interactive: bool = typer.Option( - True, - "--interactive/--non-interactive", - "-i/-ni", - help=( - "Interactive mode, will prompt the user if they want to generate test " - "data templates if none exists for the passed modeling rules." + cloud_servers_api_keys: str = typer.Option( + "", + "-csak", + "--cloud_servers_api_keys", + help="Path to file with cloud Servers api keys.", + show_default=False, + ), + machine_assignment: str = typer.Option( + "", + "-ma", + "--machine_assignment", + help="the path to the machine assignment file.", + show_default=False, + ), + branch_name: str = typer.Option( + "master", + "-bn", + "--branch_name", + help="The current content branch name.", + show_default=True, + ), + build_number: str = typer.Option( + "", + "-bn", + "--build_number", + help="The build number.", + show_default=True, + ), + nightly: str = typer.Option( + "false", + "--nightly", + "-n", + help="Whether the command is being run in nightly mode.", + ), + artifacts_bucket: str = typer.Option( + None, + "-ab", + "--artifacts_bucket", + help="The artifacts bucket name to upload the results to", + show_default=False, + ), + console_log_threshold: str = typer.Option( + "INFO", + "-clt", + "--console-log-threshold", + help="Minimum logging threshold for the console logger.", + ), + file_log_threshold: str = typer.Option( + "DEBUG", + "-flt", + "--file-log-threshold", + help="Minimum logging threshold for the file logger.", + ), + log_file_path: Optional[str] = typer.Option( + None, + "-lp", + "--log-file-path", + help="Path to save log files onto.", ), - rich_help_panel="Interactive Configuration", - hidden=True, - ), - output_junit_file: Optional[Path] = typer.Option( - None, "-jp", "--junit-path", help="Path to the output JUnit XML file." - ), - sleep_interval: int = typer.Option( - XSIAM_CLIENT_SLEEP_INTERVAL, - "-si", - "--sleep_interval", - min=0, - show_default=True, - help="The number of seconds to wait between requests to the server.", - ), - retry_attempts: int = typer.Option( - XSIAM_CLIENT_RETRY_ATTEMPTS, - "-ra", - "--retry_attempts", - min=0, - show_default=True, - help="The number of times to retry the request against the server.", - ), - service_account: Optional[str] = typer.Option( - None, - "-sa", - "--service_account", - envvar="GCP_SERVICE_ACCOUNT", - help="GCP service account.", - show_default=False, - ), - cloud_servers_path: str = typer.Option( - "", - "-csp", - "--cloud_servers_path", - help="Path to secret cloud server metadata file.", - show_default=False, - ), - cloud_servers_api_keys: str = typer.Option( - "", - "-csak", - "--cloud_servers_api_keys", - help="Path to file with cloud Servers api keys.", - show_default=False, - ), - machine_assignment: str = typer.Option( - "", - "-ma", - "--machine_assignment", - help="the path to the machine assignment file.", - show_default=False, - ), - branch_name: str = typer.Option( - "master", - "-bn", - "--branch_name", - help="The current content branch name.", - show_default=True, - ), - build_number: str = typer.Option( - "", - "-bn", - "--build_number", - help="The build number.", - show_default=True, - ), - nightly: str = typer.Option( - "false", - "--nightly", - "-n", - help="Whether the command is being run in nightly mode.", - ), - artifacts_bucket: str = typer.Option( - None, - "-ab", - "--artifacts_bucket", - help="The artifacts bucket name to upload the results to", - show_default=False, - ), - console_log_threshold: str = typer.Option( - "INFO", - "-clt", - "--console-log-threshold", - help="Minimum logging threshold for the console logger.", - ), - file_log_threshold: str = typer.Option( - "DEBUG", - "-flt", - "--file-log-threshold", - help="Minimum logging threshold for the file logger.", - ), - log_file_path: Optional[str] = typer.Option( - None, - "-lp", - "--log-file-path", - help="Path to save log files onto.", - ), ): """ - Test a playbook flow against an XSIAM tenant + Test a modeling rule against an XSIAM tenant """ - # logging_setup( - # console_threshold=console_log_threshold, # type: ignore[arg-type] - # file_threshold=file_log_threshold, # type: ignore[arg-type] - # path=log_file_path, - # ) + logging_setup( + console_threshold=console_log_threshold, # type: ignore[arg-type] + file_threshold=file_log_threshold, # type: ignore[arg-type] + path=log_file_path, + calling_function=__name__, + ) + handle_deprecated_args(ctx.args) logging_module = ParallelLoggingManager( - "playbook_flow_test.log", real_time_logs_only=not nightly + "test_modeling_rules.log", real_time_logs_only=not nightly ) + if machine_assignment: + if inputs: + logger.error( + "You cannot pass both machine_assignment and inputs arguments." + ) + raise typer.Exit(1) + if xsiam_url: + logger.error( + "You cannot pass both machine_assignment and xsiam_url arguments." + ) + raise typer.Exit(1) + start_time = get_utc_now() is_nightly = string_to_bool(nightly) build_context = BuildContext( @@ -617,17 +736,24 @@ def run_flow_test( service_account=service_account, artifacts_bucket=artifacts_bucket, machine_assignment=machine_assignment, + ctx=ctx, + xsiam_url=xsiam_url, + xsiam_token=xsiam_token, + api_key=api_key, + auth_id=auth_id, + collector_token=collector_token, + inputs=inputs, ) logging_module.info( - "Playbook Flow Tests to test:", + "Test Modeling Rules to test:", ) for build_context_server in build_context.servers: - for playbook_flow_dir in build_context_server.tests: + for playbook_flow_test_directory in build_context_server.tests: logging_module.info( f"\tmachine:{build_context_server.base_url} - " - f"{get_relative_path_to_content(playbook_flow_dir)}" + f"{get_relative_path_to_content(playbook_flow_test_directory)}" ) threads_list = [] @@ -646,30 +772,37 @@ def run_flow_test( if output_junit_file: logger.info( - f"[cyan]Writing JUnit XML to {get_relative_path_to_content(output_junit_file)}[/cyan]", - extra={"markup": True}, + f"Writing JUnit XML to {get_relative_path_to_content(output_junit_file)}", ) build_context.tests_data_keeper.test_results_xml_file.write( output_junit_file.as_posix(), pretty=True ) - + if nightly: + if service_account and artifacts_bucket: + build_context.tests_data_keeper.upload_modeling_rules_result_json_to_bucket( + XSIAM_SERVER_TYPE, + f"playbook_flow_test_{build_number}.xml", + output_junit_file, + logging_module, + ) + else: + logger.warning( + "Service account or artifacts bucket not provided, skipping uploading JUnit XML to bucket", + ) else: logger.info( - "[cyan]No JUnit XML file path was passed - skipping writing JUnit XML[/cyan]", - extra={"markup": True}, + "No JUnit XML file path was passed - skipping writing JUnit XML", ) duration = duration_since_start_time(start_time) if build_context.tests_data_keeper.errors: - logger.info( - f"[red]Playbook Flow Tests: Failed, took:{duration} seconds[/red]", - extra={"markup": True}, + logger.error( + f"Playbook flow test: Failed, took:{duration} seconds", ) raise typer.Exit(1) - logger.info( - f"[green]Playbook Flow Tests: Passed, took:{duration} seconds[/green]", - extra={"markup": True}, + logger.success( + f"Playbook flow test: Passed, took:{duration} seconds", ) diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/template_file.py b/demisto_sdk/commands/test_content/playbook_flow_test/template_file.py index ebabe815ddb..3fb88caf9d9 100644 --- a/demisto_sdk/commands/test_content/playbook_flow_test/template_file.py +++ b/demisto_sdk/commands/test_content/playbook_flow_test/template_file.py @@ -16,16 +16,19 @@ get_client_from_server_type, ) + # Any additional imports your tests require def util_load_json(path): with open(path, encoding="utf-8") as f: return json.loads(f.read()) + @pytest.fixture def client_conf(request): # Manually parse command-line arguments - return get_client_conf_from_pytest_request(request) + return get_client_conf_from_pytest_request() + @pytest.fixture def api_client(client_conf): @@ -36,6 +39,7 @@ def api_client(client_conf): client_obj = get_client_from_server_type() yield client_obj + class TestExample: @classmethod def setup_class(self): @@ -44,7 +48,7 @@ def setup_class(self): self.data = "test" @pytest.fixture - def setup_method(self, client_conf = None): + def setup_method(self, client_conf=None): if client_conf: self.client = get_client_from_server_type(client_conf) else: From b14d5628f4adb3cb192aa4bd5065d4376244c7d5 Mon Sep 17 00:00:00 2001 From: epintzov Date: Mon, 2 Dec 2024 15:22:48 +0200 Subject: [PATCH 21/58] added new version of the commands playbook flow according to new schema --- demisto_sdk/__main__.py | 4 ++++ .../playbook_flow_test_setup.py | 22 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 demisto_sdk/commands/test_content/playbook_flow_test/playbook_flow_test_setup.py diff --git a/demisto_sdk/__main__.py b/demisto_sdk/__main__.py index 2955893b69b..188f09dde36 100644 --- a/demisto_sdk/__main__.py +++ b/demisto_sdk/__main__.py @@ -64,6 +64,9 @@ from demisto_sdk.commands.test_content.test_modeling_rule.modeling_rules_setup import ( modeling_rules_app, ) +from demisto_sdk.commands.test_content.playbook_flow_test.playbook_flow_test_setup import ( + playbook_flow_app +) from demisto_sdk.commands.update_release_notes.update_release_notes_setup import ( update_release_notes, ) @@ -200,6 +203,7 @@ app.command(name="generate-modeling-rules", help="Generated modeling-rules.")( generate_modeling_rules ) +app.add_typer(playbook_flow_app, name="playbook-flow") app.command( name="lint", help="Deprecated, use demisto-sdk pre-commit instead.", hidden=True )(lint) diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/playbook_flow_test_setup.py b/demisto_sdk/commands/test_content/playbook_flow_test/playbook_flow_test_setup.py new file mode 100644 index 00000000000..4caa080bc02 --- /dev/null +++ b/demisto_sdk/commands/test_content/playbook_flow_test/playbook_flow_test_setup.py @@ -0,0 +1,22 @@ +import typer + +from demisto_sdk.commands.test_content.playbook_flow_test import ( + run_playbook_flow_test, +) + +playbook_flow_app = typer.Typer( + name="playbook-flow", + hidden=True, + no_args_is_help=True, + context_settings={"help_option_names": ["-h", "--help"]}, +) +playbook_flow_app.command("test", no_args_is_help=True)( + run_playbook_flow_test.test_playbook_flow_test +) + +playbook_flow_app.command("generate_template_flow", no_args_is_help=True)( + run_playbook_flow_test.test_playbook_flow_test) + +if __name__ == "__main__": + playbook_flow_app() + From d1d286c0777fec60de076713a9dd1a5a715e35d3 Mon Sep 17 00:00:00 2001 From: epintzov Date: Wed, 4 Dec 2024 14:01:37 +0200 Subject: [PATCH 22/58] order and removing modeling --- .../run_playbook_flow_test.py | 217 +++--------------- .../test_modeling_rule/test_modeling_rule.py | 133 ++--------- .../tests/test_modeling_rule_test.py | 41 ---- .../commands/test_content/tests/test_tools.py | 43 ++++ demisto_sdk/commands/test_content/tools.py | 152 +++++++++++- 5 files changed, 239 insertions(+), 347 deletions(-) diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py index b2daeaec68c..2b01d15e758 100644 --- a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py +++ b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py @@ -1,82 +1,54 @@ -import io import logging # noqa: TID251 # specific case, passed as argument to 3rd party import os -from contextlib import redirect_stdout -from datetime import datetime + from pathlib import Path from threading import Thread -from time import sleep -from typing import Any, Dict, List, Optional, Tuple, Union -from uuid import UUID +from typing import Any, List, Optional, Tuple, Union -import dateparser import demisto_client import pytest -import pytz -import requests + import typer from google.cloud import storage # type: ignore[attr-defined] from junitparser import Error, JUnitXml, TestCase, TestSuite from junitparser.junitparser import Failure, Result, Skipped -from packaging.version import Version -from tabulate import tabulate -from tenacity import ( - Retrying, - before_sleep_log, - retry_if_exception_type, - stop_after_attempt, - wait_fixed, -) -from typer.main import get_command_from_info + from demisto_sdk.commands.common.constants import ( - TEST_MODELING_RULES, + PLAYBOOKS_FLOW_TEST, XSIAM_SERVER_TYPE, ) -from demisto_sdk.commands.common.content.objects.pack_objects.modeling_rule.modeling_rule import ( - ModelingRule, - SingleModelingRule, -) -from demisto_sdk.commands.common.content_constant_paths import CONTENT_PATH -from demisto_sdk.commands.common.handlers import DEFAULT_JSON_HANDLER as json + from demisto_sdk.commands.common.logger import ( handle_deprecated_args, logger, logging_setup, ) from demisto_sdk.commands.common.tools import ( - get_file, get_json_file, - is_epoch_datetime, - parse_int_or_default, string_to_bool, ) from demisto_sdk.commands.test_content.ParallelLoggingManager import ( ParallelLoggingManager, ) -from demisto_sdk.commands.test_content.test_modeling_rule.constants import ( - EXPECTED_SCHEMA_MAPPINGS, - FAILURE_TO_PUSH_EXPLANATION, - NOT_AVAILABLE, - SYNTAX_ERROR_IN_MODELING_RULE, - TIME_ZONE_WARNING, - XQL_QUERY_ERROR_EXPLANATION, -) -from demisto_sdk.commands.test_content.tools import get_ui_url -from demisto_sdk.commands.test_content.xsiam_tools.test_data import ( - TestData, - Validations, +from demisto_sdk.commands.test_content.tools import ( + get_ui_url, + XSIAM_CLIENT_SLEEP_INTERVAL, + XSIAM_CLIENT_RETRY_ATTEMPTS, + logs_token_cb, + tenant_config_cb, + create_retrying_caller, + get_relative_path_to_content, + duration_since_start_time, + get_utc_now ) + from demisto_sdk.commands.test_content.xsiam_tools.xsiam_client import ( XsiamApiClient, XsiamApiClientConfig, ) -from demisto_sdk.commands.upload.upload import upload_content_entity as upload_cmd -from demisto_sdk.utils.utils import get_containing_pack CI_PIPELINE_ID = os.environ.get("CI_PIPELINE_ID") -XSIAM_CLIENT_SLEEP_INTERVAL = 60 -XSIAM_CLIENT_RETRY_ATTEMPTS = 5 app = typer.Typer() @@ -118,7 +90,7 @@ def __init__( self.service_account = service_account self.artifacts_bucket = artifacts_bucket - def upload_modeling_rules_result_json_to_bucket( + def upload_result_json_to_bucket( self, repository_name: str, file_name, @@ -131,22 +103,22 @@ def upload_modeling_rules_result_json_to_bucket( original_file_path: The path to the JSON file to upload. repository_name: The name of the repository within the bucket. file_name: The desired filename for the uploaded JSON data. - logging_module: Logging module to use for upload_modeling_rules_result_json_to_bucket. + logging_module: Logging module to use for upload_result_json_to_bucket. """ - logging_module.info("Start uploading modeling rules results file to bucket") + logging_module.info("Start uploading playbook flow test results file to bucket") storage_client = storage.Client.from_service_account_json(self.service_account) storage_bucket = storage_client.bucket(self.artifacts_bucket) blob = storage_bucket.blob( - f"content-test-modeling-rules/{repository_name}/{file_name}" + f"content-playbook-flow-test/{repository_name}/{file_name}" ) blob.upload_from_filename( original_file_path.as_posix(), content_type="application/xml", ) - logging_module.info("Finished uploading modeling rules results file to bucket") + logging_module.info("Finished uploading playbook flow test results file to bucket") class BuildContext: @@ -236,10 +208,10 @@ def create_servers(self): for machine, assignment in self.machine_assignment_json.items(): tests = [ BuildContext.prefix_with_packs(test) - for test in assignment.get("tests", {}).get(TEST_MODELING_RULES, []) + for test in assignment.get("tests", {}).get(PLAYBOOKS_FLOW_TEST, []) ] if not tests: - logger.info(f"No modeling rules found for machine {machine}") + logger.info(f"No playbook flow tests found for machine {machine}") continue servers_list.append( CloudServerContext( @@ -326,7 +298,7 @@ def execute_tests(self): for i, playbook_flow_test_directory in enumerate(self.tests, start=1): logger.info( - f"[{i}/{len(self.tests)}] Test Modeling Rule: {get_relative_path_to_content(playbook_flow_test_directory)}", + f"[{i}/{len(self.tests)}] playbook flow tests: {get_relative_path_to_content(playbook_flow_test_directory)}", ) success, playbook_flow_test_test_suite = run_playbook_flow_test_pytest( @@ -367,135 +339,6 @@ def execute_tests(self): finally: self.build_context.logging_module.execute_logs() - -# ============================================== Helper methods ============================================ # - -def get_utc_now() -> datetime: - """Get the current time in UTC, with timezone aware.""" - return datetime.now(tz=pytz.UTC) - - -def duration_since_start_time(start_time: datetime) -> float: - """Get the duration since the given start time, in seconds. - - Args: - start_time (datetime): Start time. - - Returns: - float: Duration since the given start time, in seconds. - """ - return (get_utc_now() - start_time).total_seconds() - - -def day_suffix(day: int) -> str: - """ - Returns a suffix string base on the day of the month. - for 1, 21, 31 => st - for 2, 22 => nd - for 3, 23 => rd - for to all the others => th - - see here for more details: https://en.wikipedia.org/wiki/English_numerals#Ordinal_numbers - - Args: - day: The day of the month represented by a number. - - Returns: - suffix string (st, nd, rd, th). - """ - return "th" if 11 <= day <= 13 else {1: "st", 2: "nd", 3: "rd"}.get(day % 10, "th") - - -def get_relative_path_to_content(path: Path) -> str: - """Get the relative path to the content directory. - - Args: - path: The path to the content item. - - Returns: - Path: The relative path to the content directory. - """ - if path.is_absolute() and path.as_posix().startswith(CONTENT_PATH.as_posix()): - return path.as_posix().replace(f"{CONTENT_PATH.as_posix()}{os.path.sep}", "") - return path.as_posix() - - -def get_type_pretty_name(obj: Any) -> str: - """Get the pretty name of the type of the given object. - - Args: - obj (Any): The object to get the type name for. - - Returns: - str: The pretty name of the type of the given object. - """ - return { - type(None): "null", - list: "list", - dict: "dict", - tuple: "tuple", - set: "set", - UUID: "UUID", - str: "string", - int: "int", - float: "float", - bool: "boolean", - datetime: "datetime", - }.get(type(obj), str(type(obj))) - - -def create_retrying_caller(retry_attempts: int, sleep_interval: int) -> Retrying: - """Create a Retrying object with the given retry_attempts and sleep_interval.""" - sleep_interval = parse_int_or_default(sleep_interval, XSIAM_CLIENT_SLEEP_INTERVAL) - retry_attempts = parse_int_or_default(retry_attempts, XSIAM_CLIENT_RETRY_ATTEMPTS) - retry_params: Dict[str, Any] = { - "reraise": True, - "before_sleep": before_sleep_log(logging.getLogger(), logging.DEBUG), - "retry": retry_if_exception_type(requests.exceptions.RequestException), - "stop": stop_after_attempt(retry_attempts), - "wait": wait_fixed(sleep_interval), - } - return Retrying(**retry_params) - - -def xsiam_get_installed_packs(xsiam_client: XsiamApiClient) -> List[Dict[str, Any]]: - """Get the list of installed packs from the XSIAM tenant. - Wrapper for XsiamApiClient.get_installed_packs() with retry logic. - """ - return xsiam_client.installed_packs - - -def tenant_config_cb( - ctx: typer.Context, param: typer.CallbackParam, value: Optional[str] -): - if ctx.resilient_parsing: - return - # Only check the params if the machine_assignment is not set. - if param.value_is_missing(value) and not ctx.params.get("machine_assignment"): - err_str = ( - f"{param.name} must be set either via the environment variable " - f'"{param.envvar}" or passed explicitly when running the command' - ) - raise typer.BadParameter(err_str) - return value - - -def logs_token_cb(ctx: typer.Context, param: typer.CallbackParam, value: Optional[str]): - if ctx.resilient_parsing: - return - # Only check the params if the machine_assignment is not set. - if param.value_is_missing(value) and not ctx.params.get("machine_assignment"): - parameter_to_check = "xsiam_token" - other_token = ctx.params.get(parameter_to_check) - if not other_token: - err_str = ( - f"One of {param.name} or {parameter_to_check} must be set either via it's associated" - " environment variable or passed explicitly when running the command" - ) - raise typer.BadParameter(err_str) - return value - - # ============================================== Command logic ============================================ # def run_playbook_flow_test_pytest( @@ -560,7 +403,7 @@ def test_playbook_flow_test( dir_okay=True, resolve_path=True, show_default=False, - help="The path to a directory of a modeling rule. May pass multiple paths to test multiple modeling rules.", + help="The path to a directory of a playbook flow tests. May pass multiple paths to test multiple playbook flow tests.", ), xsiam_url: Optional[str] = typer.Option( None, @@ -696,7 +539,7 @@ def test_playbook_flow_test( ), ): """ - Test a modeling rule against an XSIAM tenant + Test a playbook flow test against an XSIAM tenant """ logging_setup( console_threshold=console_log_threshold, # type: ignore[arg-type] @@ -707,7 +550,7 @@ def test_playbook_flow_test( handle_deprecated_args(ctx.args) logging_module = ParallelLoggingManager( - "test_modeling_rules.log", real_time_logs_only=not nightly + "playbook_flow_test.log", real_time_logs_only=not nightly ) if machine_assignment: @@ -746,7 +589,7 @@ def test_playbook_flow_test( ) logging_module.info( - "Test Modeling Rules to test:", + "playbook flow tests to test:", ) for build_context_server in build_context.servers: @@ -779,7 +622,7 @@ def test_playbook_flow_test( ) if nightly: if service_account and artifacts_bucket: - build_context.tests_data_keeper.upload_modeling_rules_result_json_to_bucket( + build_context.tests_data_keeper.upload_result_json_to_bucket( XSIAM_SERVER_TYPE, f"playbook_flow_test_{build_number}.xml", output_junit_file, diff --git a/demisto_sdk/commands/test_content/test_modeling_rule/test_modeling_rule.py b/demisto_sdk/commands/test_content/test_modeling_rule/test_modeling_rule.py index 1e4dc215ada..ef104080e14 100644 --- a/demisto_sdk/commands/test_content/test_modeling_rule/test_modeling_rule.py +++ b/demisto_sdk/commands/test_content/test_modeling_rule/test_modeling_rule.py @@ -59,7 +59,20 @@ TIME_ZONE_WARNING, XQL_QUERY_ERROR_EXPLANATION, ) -from demisto_sdk.commands.test_content.tools import get_ui_url +from demisto_sdk.commands.test_content.tools import ( + get_ui_url, + XSIAM_CLIENT_SLEEP_INTERVAL, + XSIAM_CLIENT_RETRY_ATTEMPTS, + logs_token_cb, + tenant_config_cb, + xsiam_get_installed_packs, + create_retrying_caller, + get_type_pretty_name, + day_suffix, + get_relative_path_to_content, + duration_since_start_time, + get_utc_now +) from demisto_sdk.commands.test_content.xsiam_tools.test_data import ( TestData, Validations, @@ -72,27 +85,14 @@ from demisto_sdk.utils.utils import get_containing_pack CI_PIPELINE_ID = os.environ.get("CI_PIPELINE_ID") -XSIAM_CLIENT_SLEEP_INTERVAL = 60 -XSIAM_CLIENT_RETRY_ATTEMPTS = 5 + app = typer.Typer() -def get_utc_now() -> datetime: - """Get the current time in UTC, with timezone aware.""" - return datetime.now(tz=pytz.UTC) -def duration_since_start_time(start_time: datetime) -> float: - """Get the duration since the given start time, in seconds. - Args: - start_time (datetime): Start time. - - Returns: - float: Duration since the given start time, in seconds. - """ - return (get_utc_now() - start_time).total_seconds() def create_table(expected: Dict[str, Any], received: Dict[str, Any]) -> str: @@ -114,37 +114,7 @@ def create_table(expected: Dict[str, Any], received: Dict[str, Any]) -> str: ) -def day_suffix(day: int) -> str: - """ - Returns a suffix string base on the day of the month. - for 1, 21, 31 => st - for 2, 22 => nd - for 3, 23 => rd - for to all the others => th - - see here for more details: https://en.wikipedia.org/wiki/English_numerals#Ordinal_numbers - - Args: - day: The day of the month represented by a number. - - Returns: - suffix string (st, nd, rd, th). - """ - return "th" if 11 <= day <= 13 else {1: "st", 2: "nd", 3: "rd"}.get(day % 10, "th") - - -def get_relative_path_to_content(path: Path) -> str: - """Get the relative path to the content directory. - - Args: - path: The path to the content item. - Returns: - Path: The relative path to the content directory. - """ - if path.is_absolute() and path.as_posix().startswith(CONTENT_PATH.as_posix()): - return path.as_posix().replace(f"{CONTENT_PATH.as_posix()}{os.path.sep}", "") - return path.as_posix() def convert_epoch_time_to_string_time( @@ -170,29 +140,6 @@ def convert_epoch_time_to_string_time( return datetime_object.strftime(time_format) -def get_type_pretty_name(obj: Any) -> str: - """Get the pretty name of the type of the given object. - - Args: - obj (Any): The object to get the type name for. - - Returns: - str: The pretty name of the type of the given object. - """ - return { - type(None): "null", - list: "list", - dict: "dict", - tuple: "tuple", - set: "set", - UUID: "UUID", - str: "string", - int: "int", - float: "float", - bool: "boolean", - datetime: "datetime", - }.get(type(obj), str(type(obj))) - def sanitize_received_value_by_expected_type( received_value: Any, expected_type: str @@ -218,18 +165,6 @@ def sanitize_received_value_by_expected_type( return received_value_type, received_value -def create_retrying_caller(retry_attempts: int, sleep_interval: int) -> Retrying: - """Create a Retrying object with the given retry_attempts and sleep_interval.""" - sleep_interval = parse_int_or_default(sleep_interval, XSIAM_CLIENT_SLEEP_INTERVAL) - retry_attempts = parse_int_or_default(retry_attempts, XSIAM_CLIENT_RETRY_ATTEMPTS) - retry_params: Dict[str, Any] = { - "reraise": True, - "before_sleep": before_sleep_log(logging.getLogger(), logging.DEBUG), - "retry": retry_if_exception_type(requests.exceptions.RequestException), - "stop": stop_after_attempt(retry_attempts), - "wait": wait_fixed(sleep_interval), - } - return Retrying(**retry_params) def xsiam_execute_query(xsiam_client: XsiamApiClient, query: str) -> List[dict]: @@ -249,12 +184,6 @@ def xsiam_push_to_dataset( return xsiam_client.push_to_dataset(events_test_data, rule.vendor, rule.product) -def xsiam_get_installed_packs(xsiam_client: XsiamApiClient) -> List[Dict[str, Any]]: - """Get the list of installed packs from the XSIAM tenant. - Wrapper for XsiamApiClient.get_installed_packs() with retry logic. - """ - return xsiam_client.installed_packs - def verify_results( modeling_rule: ModelingRule, @@ -1356,38 +1285,6 @@ def add_result_to_test_case( # ====================== test-modeling-rule ====================== # - -def tenant_config_cb( - ctx: typer.Context, param: typer.CallbackParam, value: Optional[str] -): - if ctx.resilient_parsing: - return - # Only check the params if the machine_assignment is not set. - if param.value_is_missing(value) and not ctx.params.get("machine_assignment"): - err_str = ( - f"{param.name} must be set either via the environment variable " - f'"{param.envvar}" or passed explicitly when running the command' - ) - raise typer.BadParameter(err_str) - return value - - -def logs_token_cb(ctx: typer.Context, param: typer.CallbackParam, value: Optional[str]): - if ctx.resilient_parsing: - return - # Only check the params if the machine_assignment is not set. - if param.value_is_missing(value) and not ctx.params.get("machine_assignment"): - parameter_to_check = "xsiam_token" - other_token = ctx.params.get(parameter_to_check) - if not other_token: - err_str = ( - f"One of {param.name} or {parameter_to_check} must be set either via it's associated" - " environment variable or passed explicitly when running the command" - ) - raise typer.BadParameter(err_str) - return value - - class TestResults: def __init__( self, diff --git a/demisto_sdk/commands/test_content/test_modeling_rule/tests/test_modeling_rule_test.py b/demisto_sdk/commands/test_content/test_modeling_rule/tests/test_modeling_rule_test.py index 780aba20fac..726d1d46aab 100644 --- a/demisto_sdk/commands/test_content/test_modeling_rule/tests/test_modeling_rule_test.py +++ b/demisto_sdk/commands/test_content/test_modeling_rule/tests/test_modeling_rule_test.py @@ -165,47 +165,6 @@ def test_convert_epoch_time_to_string_time(epoc_time, with_ms, human_readable_ti ) -@pytest.mark.parametrize( - "day, suffix", - [ - (1, "st"), - (2, "nd"), - (3, "rd"), - (4, "th"), - (10, "th"), - (11, "th"), - (12, "th"), - (21, "st"), - (31, "st"), - ], -) -def test_day_suffix(day, suffix): - """ - Given: - - A day of a month. - case-1: 1 => st. - case-2: 2 => nd. - case-3: 3 => rd. - case-4: 4 => th. - case-5: 10 => th. - case-6: 11 => th. - case-7: 12 => th. - case-8: 21 => st. - case-9: 31 => st. - - When: - - The day_suffix function is running. - - Then: - - Verify we get the expected results. - """ - from demisto_sdk.commands.test_content.test_modeling_rule.test_modeling_rule import ( - day_suffix, - ) - - assert day_suffix(day) == suffix - - @pytest.mark.parametrize( "mr_text, expected_result", [ diff --git a/demisto_sdk/commands/test_content/tests/test_tools.py b/demisto_sdk/commands/test_content/tests/test_tools.py index 6108c7546a6..b54fe3a7352 100644 --- a/demisto_sdk/commands/test_content/tests/test_tools.py +++ b/demisto_sdk/commands/test_content/tests/test_tools.py @@ -1,5 +1,7 @@ from subprocess import CalledProcessError +import pytest + from demisto_sdk.commands.test_content.constants import SSH_USER from demisto_sdk.commands.test_content.tools import is_redhat_instance @@ -20,3 +22,44 @@ def test_is_redhat_instance_positive(mocker): def test_is_redhat_instance_negative(mocker): mocker.patch("subprocess.check_output", side_effect=raise_exception) assert not is_redhat_instance("instance_ip") + + +@pytest.mark.parametrize( + "day, suffix", + [ + (1, "st"), + (2, "nd"), + (3, "rd"), + (4, "th"), + (10, "th"), + (11, "th"), + (12, "th"), + (21, "st"), + (31, "st"), + ], +) +def test_day_suffix(day, suffix): + """ + Given: + - A day of a month. + case-1: 1 => st. + case-2: 2 => nd. + case-3: 3 => rd. + case-4: 4 => th. + case-5: 10 => th. + case-6: 11 => th. + case-7: 12 => th. + case-8: 21 => st. + case-9: 31 => st. + + When: + - The day_suffix function is running. + + Then: + - Verify we get the expected results. + """ + from demisto_sdk.commands.test_content.tools import ( + day_suffix, + ) + + assert day_suffix(day) == suffix diff --git a/demisto_sdk/commands/test_content/tools.py b/demisto_sdk/commands/test_content/tools.py index ad9266bfc1c..1ae3066f850 100644 --- a/demisto_sdk/commands/test_content/tools.py +++ b/demisto_sdk/commands/test_content/tools.py @@ -1,14 +1,34 @@ import ast +import logging # noqa: TID251 # specific case, passed as argument to 3rd party +import os from copy import deepcopy +from datetime import datetime +from pathlib import Path from pprint import pformat from subprocess import STDOUT, CalledProcessError, check_output -from typing import Dict, Optional, Set +from typing import Dict, Optional, Set, Any, List +from uuid import UUID +from tenacity import ( + Retrying, + before_sleep_log, + retry_if_exception_type, + stop_after_attempt, + wait_fixed, +) +import pytz +import requests +import typer import demisto_client +from demisto_sdk.commands.common.content_constant_paths import CONTENT_PATH from demisto_sdk.commands.common.logger import logger +from demisto_sdk.commands.common.tools import parse_int_or_default from demisto_sdk.commands.test_content.constants import SSH_USER +from demisto_sdk.commands.test_content.xsiam_tools.xsiam_client import XsiamApiClient +XSIAM_CLIENT_SLEEP_INTERVAL = 60 +XSIAM_CLIENT_RETRY_ATTEMPTS = 5 def update_server_configuration( client: demisto_client, @@ -101,3 +121,133 @@ def get_ui_url(client_host): """ return client_host.replace("https://api-", "https://") + + +# ================= Methods and Classes used in modeling rules and playbook flow commands ================= # + + +def get_utc_now() -> datetime: + """Get the current time in UTC, with timezone aware.""" + return datetime.now(tz=pytz.UTC) + + +def duration_since_start_time(start_time: datetime) -> float: + """Get the duration since the given start time, in seconds. + + Args: + start_time (datetime): Start time. + + Returns: + float: Duration since the given start time, in seconds. + """ + return (get_utc_now() - start_time).total_seconds() + + +def day_suffix(day: int) -> str: + """ + Returns a suffix string base on the day of the month. + for 1, 21, 31 => st + for 2, 22 => nd + for 3, 23 => rd + for to all the others => th + + see here for more details: https://en.wikipedia.org/wiki/English_numerals#Ordinal_numbers + + Args: + day: The day of the month represented by a number. + + Returns: + suffix string (st, nd, rd, th). + """ + return "th" if 11 <= day <= 13 else {1: "st", 2: "nd", 3: "rd"}.get(day % 10, "th") + + +def get_relative_path_to_content(path: Path) -> str: + """Get the relative path to the content directory. + + Args: + path: The path to the content item. + + Returns: + Path: The relative path to the content directory. + """ + if path.is_absolute() and path.as_posix().startswith(CONTENT_PATH.as_posix()): + return path.as_posix().replace(f"{CONTENT_PATH.as_posix()}{os.path.sep}", "") + return path.as_posix() + + +def get_type_pretty_name(obj: Any) -> str: + """Get the pretty name of the type of the given object. + + Args: + obj (Any): The object to get the type name for. + + Returns: + str: The pretty name of the type of the given object. + """ + return { + type(None): "null", + list: "list", + dict: "dict", + tuple: "tuple", + set: "set", + UUID: "UUID", + str: "string", + int: "int", + float: "float", + bool: "boolean", + datetime: "datetime", + }.get(type(obj), str(type(obj))) + + +def create_retrying_caller(retry_attempts: int, sleep_interval: int) -> Retrying: + """Create a Retrying object with the given retry_attempts and sleep_interval.""" + sleep_interval = parse_int_or_default(sleep_interval, XSIAM_CLIENT_SLEEP_INTERVAL) + retry_attempts = parse_int_or_default(retry_attempts, XSIAM_CLIENT_RETRY_ATTEMPTS) + retry_params: Dict[str, Any] = { + "reraise": True, + "before_sleep": before_sleep_log(logging.getLogger(), logging.DEBUG), + "retry": retry_if_exception_type(requests.exceptions.RequestException), + "stop": stop_after_attempt(retry_attempts), + "wait": wait_fixed(sleep_interval), + } + return Retrying(**retry_params) + + +def xsiam_get_installed_packs(xsiam_client: XsiamApiClient) -> List[Dict[str, Any]]: + """Get the list of installed packs from the XSIAM tenant. + Wrapper for XsiamApiClient.get_installed_packs() with retry logic. + """ + return xsiam_client.installed_packs + + +def tenant_config_cb( + ctx: typer.Context, param: typer.CallbackParam, value: Optional[str] +): + if ctx.resilient_parsing: + return + # Only check the params if the machine_assignment is not set. + if param.value_is_missing(value) and not ctx.params.get("machine_assignment"): + err_str = ( + f"{param.name} must be set either via the environment variable " + f'"{param.envvar}" or passed explicitly when running the command' + ) + raise typer.BadParameter(err_str) + return value + + +def logs_token_cb(ctx: typer.Context, param: typer.CallbackParam, value: Optional[str]): + if ctx.resilient_parsing: + return + # Only check the params if the machine_assignment is not set. + if param.value_is_missing(value) and not ctx.params.get("machine_assignment"): + parameter_to_check = "xsiam_token" + other_token = ctx.params.get(parameter_to_check) + if not other_token: + err_str = ( + f"One of {param.name} or {parameter_to_check} must be set either via it's associated" + " environment variable or passed explicitly when running the command" + ) + raise typer.BadParameter(err_str) + return value + From 3bbbb7d593c33ce7ecef0b52dbb3f26c7fcab0b7 Mon Sep 17 00:00:00 2001 From: epintzov Date: Wed, 4 Dec 2024 18:12:20 +0200 Subject: [PATCH 23/58] fix --- .../commands/common/clients/__init__.py | 18 +++++++++++++----- .../run_playbook_flow_test.py | 12 ++++++------ .../playbook_flow_test/template_file.py | 2 +- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/demisto_sdk/commands/common/clients/__init__.py b/demisto_sdk/commands/common/clients/__init__.py index c8054450bf3..0d44573fe59 100644 --- a/demisto_sdk/commands/common/clients/__init__.py +++ b/demisto_sdk/commands/common/clients/__init__.py @@ -247,14 +247,22 @@ def parse_str_to_dict(input_str): """ return dict(pair.split("=") for pair in input_str.split(",") if "=" in pair) -def get_client_conf_from_pytest_request(): +# def get_client_conf_from_pytest_request(): +# # Manually parse command-line argument +# client_conf = os.getenv("CLIENT_CONF") +# if client_conf: +# return parse_str_to_dict(client_conf) +# return None + +def get_client_conf_from_pytest_request(request): # Manually parse command-line argument - client_conf = os.getenv("CLIENT_CONF") - if client_conf: - return parse_str_to_dict(client_conf) + for arg in request.config.invocation_params.args: + if isinstance(arg, str) and arg.startswith("--client_conf="): + client_conf = arg.replace("--client_conf=", '') + return parse_str_to_dict(client_conf) + # If a client data was not provided, we proceed to use default. return None - diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py index 2b01d15e758..5fdfa39f981 100644 --- a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py +++ b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py @@ -207,7 +207,7 @@ def create_servers(self): servers_list = [] for machine, assignment in self.machine_assignment_json.items(): tests = [ - BuildContext.prefix_with_packs(test) + test for test in assignment.get("tests", {}).get(PLAYBOOKS_FLOW_TEST, []) ] if not tests: @@ -358,16 +358,16 @@ def run_playbook_flow_test_pytest( "file_name", str(playbook_flow_test_directory) ) - # Configure pytest arguments - os.environ["CLIENT_CONF"] = (f"base_url={str(xsiam_client.base_url)}," - f"api_key={xsiam_client.api_key}," - f"auth_id={xsiam_client.auth_id}") + # # Configure pytest arguments + # os.environ["CLIENT_CONF"] = (f"base_url={str(xsiam_client.base_url)}," + # f"api_key={xsiam_client.api_key}," + # f"auth_id={xsiam_client.auth_id}") pytest_args = [ "-v", + f"--client_conf=base_url={str(xsiam_client.base_url)},api_key={xsiam_client.api_key},auth_id={xsiam_client.auth_id}", str(playbook_flow_test_directory), f"--durations={str(durations)}", - f"--junitxml=report.xml", "--log-cli-level=CRITICAL" ] diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/template_file.py b/demisto_sdk/commands/test_content/playbook_flow_test/template_file.py index 3fb88caf9d9..24cb3f79ed7 100644 --- a/demisto_sdk/commands/test_content/playbook_flow_test/template_file.py +++ b/demisto_sdk/commands/test_content/playbook_flow_test/template_file.py @@ -27,7 +27,7 @@ def util_load_json(path): @pytest.fixture def client_conf(request): # Manually parse command-line arguments - return get_client_conf_from_pytest_request() + return get_client_conf_from_pytest_request(request) @pytest.fixture From 7eebf1a2a713dc234846a2dd987360ecd127d0bd Mon Sep 17 00:00:00 2001 From: epintzov Date: Thu, 5 Dec 2024 11:01:58 +0200 Subject: [PATCH 24/58] fix --- .../test_content/playbook_flow_test/run_playbook_flow_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py index 5fdfa39f981..b311cfaed49 100644 --- a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py +++ b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py @@ -596,7 +596,7 @@ def test_playbook_flow_test( for playbook_flow_test_directory in build_context_server.tests: logging_module.info( f"\tmachine:{build_context_server.base_url} - " - f"{get_relative_path_to_content(playbook_flow_test_directory)}" + f"{get_relative_path_to_content(Path(playbook_flow_test_directory))}" ) threads_list = [] From 019abf9c8aedc3bb817b73e892073a522a51d68a Mon Sep 17 00:00:00 2001 From: epintzov Date: Thu, 5 Dec 2024 15:05:18 +0200 Subject: [PATCH 25/58] fix --- .../test_content/playbook_flow_test/run_playbook_flow_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py index b311cfaed49..9e743fdf53d 100644 --- a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py +++ b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py @@ -207,7 +207,7 @@ def create_servers(self): servers_list = [] for machine, assignment in self.machine_assignment_json.items(): tests = [ - test + Path(test) for test in assignment.get("tests", {}).get(PLAYBOOKS_FLOW_TEST, []) ] if not tests: @@ -596,7 +596,7 @@ def test_playbook_flow_test( for playbook_flow_test_directory in build_context_server.tests: logging_module.info( f"\tmachine:{build_context_server.base_url} - " - f"{get_relative_path_to_content(Path(playbook_flow_test_directory))}" + f"{get_relative_path_to_content(playbook_flow_test_directory)}" ) threads_list = [] From b15dc5203f7838d2bd8be3a040c78366b898076b Mon Sep 17 00:00:00 2001 From: epintzov Date: Thu, 5 Dec 2024 16:48:22 +0200 Subject: [PATCH 26/58] added conftest --- conftest.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/conftest.py b/conftest.py index af46bfece8f..83ba04088f4 100644 --- a/conftest.py +++ b/conftest.py @@ -20,6 +20,7 @@ from TestSuite.repo import Repo from TestSuite.yml import YAML + # Helper Functions @@ -39,7 +40,7 @@ def get_pack(request: FixtureRequest, tmp_path_factory: TempPathFactory) -> Pack def get_integration( - request: FixtureRequest, tmp_path_factory: TempPathFactory + request: FixtureRequest, tmp_path_factory: TempPathFactory ) -> Integration: """Mocking tmp_path""" integration = get_pack(request, tmp_path_factory).create_integration() @@ -48,7 +49,7 @@ def get_integration( def get_playbook( - request: FixtureRequest, tmp_path_factory: TempPathFactory + request: FixtureRequest, tmp_path_factory: TempPathFactory ) -> Playbook: """Mocking tmp_path""" playbook = get_pack(request, tmp_path_factory).create_playbook() @@ -78,7 +79,7 @@ def script(request: FixtureRequest, tmp_path_factory: TempPathFactory): @pytest.fixture def integration( - request: FixtureRequest, tmp_path_factory: TempPathFactory + request: FixtureRequest, tmp_path_factory: TempPathFactory ) -> Integration: """Mocking tmp_path""" return get_integration(request, tmp_path_factory) @@ -162,7 +163,7 @@ def mock_update_id_set_cpu_count() -> Generator: all physical cpu's (36) it uses too many processes in the process pools. """ with mock.patch( - "demisto_sdk.commands.common.update_id_set.cpu_count", return_value=2 + "demisto_sdk.commands.common.update_id_set.cpu_count", return_value=2 ) as _fixture: yield _fixture @@ -175,3 +176,12 @@ def disable_log_colors(): @pytest.fixture(autouse=True) def clear_cache(): tools.get_file.cache_clear() + + +def pytest_addoption(parser): + parser.addoption( + "--client_conf", + action="store", + default=None, + help="Custom client configuration" + ) From df6c50a55b5cd42f9437e271993b929a76aa2988 Mon Sep 17 00:00:00 2001 From: epintzov Date: Sun, 8 Dec 2024 10:54:03 +0200 Subject: [PATCH 27/58] added content path --- .../playbook_flow_test/run_playbook_flow_test.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py index 9e743fdf53d..f5e6705ac77 100644 --- a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py +++ b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py @@ -178,11 +178,11 @@ def __init__( self.servers = self.create_servers() @staticmethod - def prefix_with_packs(path_str: Union[str, Path]) -> Path: + def edit_prefix(path_str: Union[str, Path]) -> Path: path = Path(path_str) - if path.parts[0] == "Packs": + if path.parts[0] == "content/Packs": return path - return Path("Packs") / path + return Path("content/Packs") / path def create_servers(self): """ @@ -199,7 +199,7 @@ def create_servers(self): token=self.xsiam_token, # type: ignore[arg-type] collector_token=self.collector_token, ui_url=get_ui_url(self.xsiam_url), - tests=[BuildContext.prefix_with_packs(test) for test in self.inputs] + tests=[BuildContext.edit_prefix(test) for test in self.inputs] if self.inputs else [], ) From ada99614a8a927e00a4fd2571284532cdec8ee1d Mon Sep 17 00:00:00 2001 From: epintzov Date: Sun, 8 Dec 2024 13:50:53 +0200 Subject: [PATCH 28/58] fix --- .../test_content/playbook_flow_test/run_playbook_flow_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py index f5e6705ac77..fcdf77c52ee 100644 --- a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py +++ b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py @@ -207,7 +207,7 @@ def create_servers(self): servers_list = [] for machine, assignment in self.machine_assignment_json.items(): tests = [ - Path(test) + BuildContext.edit_prefix(test) for test in assignment.get("tests", {}).get(PLAYBOOKS_FLOW_TEST, []) ] if not tests: From 6dec80fe6f08e9edad98f8008be92cf15838e816 Mon Sep 17 00:00:00 2001 From: epintzov Date: Sun, 8 Dec 2024 16:15:51 +0200 Subject: [PATCH 29/58] fix --- .../run_playbook_flow_test.py | 13 +++- .../tests/run_playbook_flow_test_test.py | 70 +++++++++++++++++++ 2 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 demisto_sdk/commands/test_content/playbook_flow_test/tests/run_playbook_flow_test_test.py diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py index fcdf77c52ee..35204a15224 100644 --- a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py +++ b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py @@ -1,9 +1,11 @@ import logging # noqa: TID251 # specific case, passed as argument to 3rd party import os +import shutil from pathlib import Path from threading import Thread from typing import Any, List, Optional, Tuple, Union +from demisto_sdk.commands.common.content_constant_paths import CONTENT_PATH import demisto_client import pytest @@ -180,9 +182,9 @@ def __init__( @staticmethod def edit_prefix(path_str: Union[str, Path]) -> Path: path = Path(path_str) - if path.parts[0] == "content/Packs": + if path.parts[0] == "Packs": return path - return Path("content/Packs") / path + return Path("Packs") / path def create_servers(self): """ @@ -340,6 +342,11 @@ def execute_tests(self): self.build_context.logging_module.execute_logs() # ============================================== Command logic ============================================ # +def copy_conftest(test_dir): + source_conftest = Path(f"{CONTENT_PATH}/Tests/scripts/dev_envs/pytest/conftest.py") + dest_conftest = test_dir / "conftest.py" + + shutil.copy(source_conftest, dest_conftest) def run_playbook_flow_test_pytest( playbook_flow_test_directory: Path, @@ -358,6 +365,8 @@ def run_playbook_flow_test_pytest( "file_name", str(playbook_flow_test_directory) ) + test_dir = playbook_flow_test_directory.parent + copy_conftest(test_dir) # # Configure pytest arguments # os.environ["CLIENT_CONF"] = (f"base_url={str(xsiam_client.base_url)}," # f"api_key={xsiam_client.api_key}," diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/tests/run_playbook_flow_test_test.py b/demisto_sdk/commands/test_content/playbook_flow_test/tests/run_playbook_flow_test_test.py new file mode 100644 index 00000000000..dd31dc6d56c --- /dev/null +++ b/demisto_sdk/commands/test_content/playbook_flow_test/tests/run_playbook_flow_test_test.py @@ -0,0 +1,70 @@ +import unittest +from unittest.mock import patch, MagicMock +from pathlib import Path + + +# Mock dependencies +class TestSuite: + def __init__(self, name): + self.name = name + self.properties = {} + + def add_property(self, key, value): + self.properties[key] = value + + +class XsiamApiClient: + def __init__(self, base_url, api_key, auth_id): + self.base_url = base_url + self.api_key = api_key + self.auth_id = auth_id + + +class TestResultCapture: + def __init__(self, test_suite): + self.test_suite = test_suite + + +# Unit test class +class TestRunPlaybookFlowTestPytest(unittest.TestCase): + + @patch("pytest.main") + @patch("__main__.TestResultCapture") + def test_run_playbook_flow_test_pytest_success(self, mock_result_capture, mock_pytest_main): + from demisto_sdk.commands.test_content.playbook_flow_test.run_playbook_flow_test import \ + run_playbook_flow_test_pytest + + # Arrange + playbook_flow_test_directory = Path("/path/to/test") + xsiam_client = XsiamApiClient("http://example.com", "api_key", "auth_id") + mock_pytest_main.return_value = 0 + mock_result_capture.return_value = MagicMock() + + # Act + success, test_suite = run_playbook_flow_test_pytest( + playbook_flow_test_directory, xsiam_client, durations=5 + ) + + # Assert + self.assertTrue(success) + self.assertIsInstance(test_suite, TestSuite) + self.assertEqual(test_suite.properties["file_name"], str(playbook_flow_test_directory)) + + @patch("pytest.main") + @patch("__main__.TestResultCapture") + def test_run_playbook_flow_test_pytest_failure(self, mock_result_capture, mock_pytest_main): + # Arrange + playbook_flow_test_directory = Path("/path/to/test") + xsiam_client = XsiamApiClient("http://example.com", "api_key", "auth_id") + mock_pytest_main.return_value = 1 + mock_result_capture.return_value = MagicMock() + + # Act + success, test_suite = run_playbook_flow_test_pytest( + playbook_flow_test_directory, xsiam_client, durations=5 + ) + + # Assert + self.assertFalse(success) + self.assertIsInstance(test_suite, TestSuite) + self.assertEqual(test_suite.properties["file_name"], str(playbook_flow_test_directory)) From f3cf78ff6aa4e025753f856d06a67ee0bf51a7e0 Mon Sep 17 00:00:00 2001 From: epintzov Date: Sun, 8 Dec 2024 20:00:43 +0200 Subject: [PATCH 30/58] remoced v --- .../playbook_flow_test/run_playbook_flow_test.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py index 35204a15224..9f4e52967d2 100644 --- a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py +++ b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py @@ -367,13 +367,9 @@ def run_playbook_flow_test_pytest( test_dir = playbook_flow_test_directory.parent copy_conftest(test_dir) - # # Configure pytest arguments - # os.environ["CLIENT_CONF"] = (f"base_url={str(xsiam_client.base_url)}," - # f"api_key={xsiam_client.api_key}," - # f"auth_id={xsiam_client.auth_id}") + pytest_args = [ - "-v", f"--client_conf=base_url={str(xsiam_client.base_url)},api_key={xsiam_client.api_key},auth_id={xsiam_client.auth_id}", str(playbook_flow_test_directory), f"--durations={str(durations)}", From 79f27b59e1fb9ab22a025652cb2aaa882fa5f941 Mon Sep 17 00:00:00 2001 From: epintzov Date: Tue, 10 Dec 2024 10:28:17 +0200 Subject: [PATCH 31/58] test --- demisto_sdk/commands/common/clients/__init__.py | 3 +++ .../test_content/playbook_flow_test/run_playbook_flow_test.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/demisto_sdk/commands/common/clients/__init__.py b/demisto_sdk/commands/common/clients/__init__.py index 0d44573fe59..23b26a9669b 100644 --- a/demisto_sdk/commands/common/clients/__init__.py +++ b/demisto_sdk/commands/common/clients/__init__.py @@ -245,6 +245,8 @@ def parse_str_to_dict(input_str): Returns: dict: A dictionary with the parsed key-value pairs. """ + x = dict(pair.split("=") for pair in input_str.split(",") if "=" in pair) + logger.info(x.get('base_url', "no base url")) return dict(pair.split("=") for pair in input_str.split(",") if "=" in pair) # def get_client_conf_from_pytest_request(): @@ -258,6 +260,7 @@ def get_client_conf_from_pytest_request(request): # Manually parse command-line argument for arg in request.config.invocation_params.args: if isinstance(arg, str) and arg.startswith("--client_conf="): + logger.info("there is --client_conf recognized") client_conf = arg.replace("--client_conf=", '') return parse_str_to_dict(client_conf) # If a client data was not provided, we proceed to use default. diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py index 9f4e52967d2..290309e1db8 100644 --- a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py +++ b/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py @@ -368,7 +368,7 @@ def run_playbook_flow_test_pytest( test_dir = playbook_flow_test_directory.parent copy_conftest(test_dir) - + logger.info(f'before sending pytest {str(xsiam_client.base_url)}') pytest_args = [ f"--client_conf=base_url={str(xsiam_client.base_url)},api_key={xsiam_client.api_key},auth_id={xsiam_client.auth_id}", str(playbook_flow_test_directory), From be71a83ab95a7271bf7dfbd1a3399beccde16151 Mon Sep 17 00:00:00 2001 From: epintzov Date: Thu, 12 Dec 2024 10:37:42 +0200 Subject: [PATCH 32/58] changed to use case --- demisto_sdk/__main__.py | 9 +- demisto_sdk/commands/common/constants.py | 2 +- .../playbook_flow_test_setup.py | 22 ----- .../template_file.py | 0 .../test_use_case.py} | 88 ++++++++++--------- .../tests/run_playbook_flow_test_test.py | 6 +- 6 files changed, 55 insertions(+), 72 deletions(-) delete mode 100644 demisto_sdk/commands/test_content/playbook_flow_test/playbook_flow_test_setup.py rename demisto_sdk/commands/test_content/{playbook_flow_test => test_use_case}/template_file.py (100%) rename demisto_sdk/commands/test_content/{playbook_flow_test/run_playbook_flow_test.py => test_use_case/test_use_case.py} (88%) rename demisto_sdk/commands/test_content/{playbook_flow_test => test_use_case}/tests/run_playbook_flow_test_test.py (91%) diff --git a/demisto_sdk/__main__.py b/demisto_sdk/__main__.py index bd25aa2b2d0..1b504571de2 100644 --- a/demisto_sdk/__main__.py +++ b/demisto_sdk/__main__.py @@ -67,8 +67,8 @@ from demisto_sdk.commands.test_content.test_modeling_rule.modeling_rules_setup import ( modeling_rules_app, ) -from demisto_sdk.commands.test_content.playbook_flow_test.playbook_flow_test_setup import ( - playbook_flow_app +from demisto_sdk.commands.test_content.test_use_case.test_use_case import ( + run_test_use_case ) from demisto_sdk.commands.update_release_notes.update_release_notes_setup import ( update_release_notes, @@ -206,7 +206,10 @@ app.command(name="generate-modeling-rules", help="Generated modeling-rules.")( generate_modeling_rules ) -app.add_typer(playbook_flow_app, name="playbook-flow") +app.command(name="test-use-case", + hidden=True, + no_args_is_help=True, + help="Test Use Cases.")(run_test_use_case) app.command( name="lint", help="Deprecated, use demisto-sdk pre-commit instead.", hidden=True )(lint) diff --git a/demisto_sdk/commands/common/constants.py b/demisto_sdk/commands/common/constants.py index a323961f852..0013fced5fe 100644 --- a/demisto_sdk/commands/common/constants.py +++ b/demisto_sdk/commands/common/constants.py @@ -2218,4 +2218,4 @@ class PlaybookTaskType(StrEnum): # Test types: TEST_PLAYBOOKS = "TestPlaybooks" TEST_MODELING_RULES = "TestModelingRules" -PLAYBOOKS_FLOW_TEST = "PlaybookFlowTest" +Test_Use_Cases = "TestUseCases" diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/playbook_flow_test_setup.py b/demisto_sdk/commands/test_content/playbook_flow_test/playbook_flow_test_setup.py deleted file mode 100644 index 4caa080bc02..00000000000 --- a/demisto_sdk/commands/test_content/playbook_flow_test/playbook_flow_test_setup.py +++ /dev/null @@ -1,22 +0,0 @@ -import typer - -from demisto_sdk.commands.test_content.playbook_flow_test import ( - run_playbook_flow_test, -) - -playbook_flow_app = typer.Typer( - name="playbook-flow", - hidden=True, - no_args_is_help=True, - context_settings={"help_option_names": ["-h", "--help"]}, -) -playbook_flow_app.command("test", no_args_is_help=True)( - run_playbook_flow_test.test_playbook_flow_test -) - -playbook_flow_app.command("generate_template_flow", no_args_is_help=True)( - run_playbook_flow_test.test_playbook_flow_test) - -if __name__ == "__main__": - playbook_flow_app() - diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/template_file.py b/demisto_sdk/commands/test_content/test_use_case/template_file.py similarity index 100% rename from demisto_sdk/commands/test_content/playbook_flow_test/template_file.py rename to demisto_sdk/commands/test_content/test_use_case/template_file.py diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py similarity index 88% rename from demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py rename to demisto_sdk/commands/test_content/test_use_case/test_use_case.py index 290309e1db8..0e788c51a1f 100644 --- a/demisto_sdk/commands/test_content/playbook_flow_test/run_playbook_flow_test.py +++ b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py @@ -15,9 +15,8 @@ from junitparser import Error, JUnitXml, TestCase, TestSuite from junitparser.junitparser import Failure, Result, Skipped - from demisto_sdk.commands.common.constants import ( - PLAYBOOKS_FLOW_TEST, + Test_Use_Cases, XSIAM_SERVER_TYPE, ) @@ -107,20 +106,20 @@ def upload_result_json_to_bucket( file_name: The desired filename for the uploaded JSON data. logging_module: Logging module to use for upload_result_json_to_bucket. """ - logging_module.info("Start uploading playbook flow test results file to bucket") + logging_module.info("Start uploading test use case results file to bucket") storage_client = storage.Client.from_service_account_json(self.service_account) storage_bucket = storage_client.bucket(self.artifacts_bucket) blob = storage_bucket.blob( - f"content-playbook-flow-test/{repository_name}/{file_name}" + f"content-test-use-case/{repository_name}/{file_name}" ) blob.upload_from_filename( original_file_path.as_posix(), content_type="application/xml", ) - logging_module.info("Finished uploading playbook flow test results file to bucket") + logging_module.info("Finished uploading test use case results file to bucket") class BuildContext: @@ -210,10 +209,10 @@ def create_servers(self): for machine, assignment in self.machine_assignment_json.items(): tests = [ BuildContext.edit_prefix(test) - for test in assignment.get("tests", {}).get(PLAYBOOKS_FLOW_TEST, []) + for test in assignment.get("tests", {}).get(Test_Use_Cases, []) ] if not tests: - logger.info(f"No playbook flow tests found for machine {machine}") + logger.info(f"No test use cases found for machine {machine}") continue servers_list.append( CloudServerContext( @@ -298,32 +297,32 @@ def execute_tests(self): ) xsiam_client = XsiamApiClient(xsiam_client_cfg) - for i, playbook_flow_test_directory in enumerate(self.tests, start=1): + for i, test_use_case_directory in enumerate(self.tests, start=1): logger.info( - f"[{i}/{len(self.tests)}] playbook flow tests: {get_relative_path_to_content(playbook_flow_test_directory)}", + f"[{i}/{len(self.tests)}] test use cases: {get_relative_path_to_content(test_use_case_directory)}", ) - success, playbook_flow_test_test_suite = run_playbook_flow_test_pytest( - playbook_flow_test_directory, + success, test_use_case_test_suite = run_test_use_case_pytest( + test_use_case_directory, xsiam_client=xsiam_client ) if success: logger.info( - f"Playbook flow test {get_relative_path_to_content(playbook_flow_test_directory)} passed", + f"Test use case {get_relative_path_to_content(test_use_case_directory)} passed", ) else: self.build_context.tests_data_keeper.errors = True logger.error( - f"Playbook flow test {get_relative_path_to_content(playbook_flow_test_directory)} failed", + f"Test use case {get_relative_path_to_content(test_use_case_directory)} failed", ) - if playbook_flow_test_test_suite: - playbook_flow_test_test_suite.add_property( + if test_use_case_test_suite: + test_use_case_test_suite.add_property( "start_time", start_time, # type:ignore[arg-type] ) self.build_context.tests_data_keeper.test_results_xml_file.add_testsuite( - playbook_flow_test_test_suite + test_use_case_test_suite ) self.build_context.logging_module.info( @@ -341,6 +340,7 @@ def execute_tests(self): finally: self.build_context.logging_module.execute_logs() + # ============================================== Command logic ============================================ # def copy_conftest(test_dir): source_conftest = Path(f"{CONTENT_PATH}/Tests/scripts/dev_envs/pytest/conftest.py") @@ -348,48 +348,50 @@ def copy_conftest(test_dir): shutil.copy(source_conftest, dest_conftest) -def run_playbook_flow_test_pytest( - playbook_flow_test_directory: Path, + +def run_test_use_case_pytest( + test_use_case_directory: Path, xsiam_client: XsiamApiClient, durations: int = 5) -> Tuple[bool, Union[TestSuite, None]]: - """Runs a playbook flow test + """Runs a test use case Args: - playbook_flow_test_directory (Path): Path to the playbook flow test directory. + test_use_case_directory (Path): Path to the test use case directory. durations (int): Number of slow tests to show durations for. xsiam_client (XsiamApiClient): The XSIAM client used to do API calls to the tenant. """ # Creating an instance of your results collector - playbook_flow_test_suite = TestSuite(f"Playbook Flow Test") - playbook_flow_test_suite.add_property( - "file_name", str(playbook_flow_test_directory) + test_use_case_suite = TestSuite(f"Test Use Case") + test_use_case_suite.add_property( + "file_name", str(test_use_case_directory) ) - test_dir = playbook_flow_test_directory.parent - copy_conftest(test_dir) + test_dir = test_use_case_directory.parent + # copy_conftest(test_dir) logger.info(f'before sending pytest {str(xsiam_client.base_url)}') pytest_args = [ f"--client_conf=base_url={str(xsiam_client.base_url)},api_key={xsiam_client.api_key},auth_id={xsiam_client.auth_id}", - str(playbook_flow_test_directory), + str(test_use_case_directory), f"--durations={str(durations)}", - "--log-cli-level=CRITICAL" + "--log-cli-level=CRITICAL", + "--no-summary" ] - logger.info(f"Runnig pytest for file {playbook_flow_test_directory}") + logger.info(f"Runnig pytest for file {test_use_case_directory}") # Running pytest - result_capture = TestResultCapture(playbook_flow_test_suite) + result_capture = TestResultCapture(test_use_case_suite) status_code = pytest.main(pytest_args, plugins=[result_capture]) if status_code == pytest.ExitCode.OK: - logger.info(f"Pytest run tests in {playbook_flow_test_directory} successfully") - return True, playbook_flow_test_suite + logger.info(f"Pytest run tests in {test_use_case_directory} successfully") + return True, test_use_case_suite else: logger.error( f"Pytest failed with statsu {status_code}", ) - return False, playbook_flow_test_suite + return False, test_use_case_suite @app.command( @@ -400,7 +402,7 @@ def run_playbook_flow_test_pytest( "help_option_names": ["-h", "--help"], }, ) -def test_playbook_flow_test( +def run_test_use_case( ctx: typer.Context, inputs: List[Path] = typer.Argument( None, @@ -408,7 +410,7 @@ def test_playbook_flow_test( dir_okay=True, resolve_path=True, show_default=False, - help="The path to a directory of a playbook flow tests. May pass multiple paths to test multiple playbook flow tests.", + help="The path to a directory of a test use cases. May pass multiple paths to test multiple test use cases.", ), xsiam_url: Optional[str] = typer.Option( None, @@ -541,10 +543,10 @@ def test_playbook_flow_test( "-lp", "--log-file-path", help="Path to save log files onto.", - ), + ) ): """ - Test a playbook flow test against an XSIAM tenant + Test a test use case against an XSIAM tenant """ logging_setup( console_threshold=console_log_threshold, # type: ignore[arg-type] @@ -555,7 +557,7 @@ def test_playbook_flow_test( handle_deprecated_args(ctx.args) logging_module = ParallelLoggingManager( - "playbook_flow_test.log", real_time_logs_only=not nightly + "test_use_case.log", real_time_logs_only=not nightly ) if machine_assignment: @@ -594,14 +596,14 @@ def test_playbook_flow_test( ) logging_module.info( - "playbook flow tests to test:", + "test use cases to test:", ) for build_context_server in build_context.servers: - for playbook_flow_test_directory in build_context_server.tests: + for test_use_case_directory in build_context_server.tests: logging_module.info( f"\tmachine:{build_context_server.base_url} - " - f"{get_relative_path_to_content(playbook_flow_test_directory)}" + f"{get_relative_path_to_content(test_use_case_directory)}" ) threads_list = [] @@ -629,7 +631,7 @@ def test_playbook_flow_test( if service_account and artifacts_bucket: build_context.tests_data_keeper.upload_result_json_to_bucket( XSIAM_SERVER_TYPE, - f"playbook_flow_test_{build_number}.xml", + f"test_use_case_{build_number}.xml", output_junit_file, logging_module, ) @@ -645,12 +647,12 @@ def test_playbook_flow_test( duration = duration_since_start_time(start_time) if build_context.tests_data_keeper.errors: logger.error( - f"Playbook flow test: Failed, took:{duration} seconds", + f"Test use case: Failed, took:{duration} seconds", ) raise typer.Exit(1) logger.success( - f"Playbook flow test: Passed, took:{duration} seconds", + f"Test use case: Passed, took:{duration} seconds", ) diff --git a/demisto_sdk/commands/test_content/playbook_flow_test/tests/run_playbook_flow_test_test.py b/demisto_sdk/commands/test_content/test_use_case/tests/run_playbook_flow_test_test.py similarity index 91% rename from demisto_sdk/commands/test_content/playbook_flow_test/tests/run_playbook_flow_test_test.py rename to demisto_sdk/commands/test_content/test_use_case/tests/run_playbook_flow_test_test.py index dd31dc6d56c..e9de574a8c3 100644 --- a/demisto_sdk/commands/test_content/playbook_flow_test/tests/run_playbook_flow_test_test.py +++ b/demisto_sdk/commands/test_content/test_use_case/tests/run_playbook_flow_test_test.py @@ -31,8 +31,8 @@ class TestRunPlaybookFlowTestPytest(unittest.TestCase): @patch("pytest.main") @patch("__main__.TestResultCapture") def test_run_playbook_flow_test_pytest_success(self, mock_result_capture, mock_pytest_main): - from demisto_sdk.commands.test_content.playbook_flow_test.run_playbook_flow_test import \ - run_playbook_flow_test_pytest + from demisto_sdk.commands.test_content.test_use_case.test_use_case import \ + run_test_use_case_pytest # Arrange playbook_flow_test_directory = Path("/path/to/test") @@ -41,7 +41,7 @@ def test_run_playbook_flow_test_pytest_success(self, mock_result_capture, mock_p mock_result_capture.return_value = MagicMock() # Act - success, test_suite = run_playbook_flow_test_pytest( + success, test_suite = run_test_use_case_pytest( playbook_flow_test_directory, xsiam_client, durations=5 ) From cc443f86387b4aacf91c475a3ee45d270e7c2e94 Mon Sep 17 00:00:00 2001 From: epintzov Date: Thu, 12 Dec 2024 13:03:43 +0200 Subject: [PATCH 33/58] conftest --- .../commands/test_content/test_use_case/test_use_case.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py index 0e788c51a1f..8ed64820b9b 100644 --- a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py +++ b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py @@ -367,7 +367,7 @@ def run_test_use_case_pytest( ) test_dir = test_use_case_directory.parent - # copy_conftest(test_dir) + copy_conftest(test_dir) logger.info(f'before sending pytest {str(xsiam_client.base_url)}') pytest_args = [ From ba6d255b46f4f5cbaf9a75f785c433096f9dd298 Mon Sep 17 00:00:00 2001 From: epintzov Date: Thu, 12 Dec 2024 18:30:40 +0200 Subject: [PATCH 34/58] added fix --- .../test_use_case/test_use_case.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py index 8ed64820b9b..ac6eab4895d 100644 --- a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py +++ b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py @@ -54,6 +54,20 @@ app = typer.Typer() +def get_containing_pack(use_case_path: Path) -> str: + """Get pack object that contains the content entity. + + Args: + content_entity: Content entity object. + + Returns: + Pack: Pack object that contains the content entity. + """ + while use_case_path.parent.name.casefold() != "packs": + use_case_path = use_case_path.parent + return str(use_case_path) + + # ============================================== Classes ============================================ # class TestResultCapture: """ @@ -362,9 +376,16 @@ def run_test_use_case_pytest( """ # Creating an instance of your results collector test_use_case_suite = TestSuite(f"Test Use Case") + containing_pack = get_containing_pack(test_use_case_directory) + test_use_case_suite.add_property( "file_name", str(test_use_case_directory) ) + test_use_case_suite.add_property( + "pack_id", containing_pack + ) + if CI_PIPELINE_ID: + test_use_case_suite.add_property("ci_pipeline_id", CI_PIPELINE_ID) test_dir = test_use_case_directory.parent copy_conftest(test_dir) From 0d308cc809e51e80ac26587d829101d84548becf Mon Sep 17 00:00:00 2001 From: epintzov Date: Wed, 18 Dec 2024 10:48:15 +0200 Subject: [PATCH 35/58] xsoar 8 support --- .../test_use_case/test_use_case.py | 82 ++++++------------- 1 file changed, 23 insertions(+), 59 deletions(-) diff --git a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py index ac6eab4895d..3e32ebf1ed2 100644 --- a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py +++ b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py @@ -5,6 +5,9 @@ from pathlib import Path from threading import Thread from typing import Any, List, Optional, Tuple, Union + +from demisto_sdk.commands.common.clients import get_client_from_server_type +from demisto_sdk.commands.common.clients.xsoar.xsoar_api_client import XsoarClient from demisto_sdk.commands.common.content_constant_paths import CONTENT_PATH import demisto_client @@ -36,7 +39,6 @@ get_ui_url, XSIAM_CLIENT_SLEEP_INTERVAL, XSIAM_CLIENT_RETRY_ATTEMPTS, - logs_token_cb, tenant_config_cb, create_retrying_caller, get_relative_path_to_content, @@ -44,11 +46,6 @@ get_utc_now ) -from demisto_sdk.commands.test_content.xsiam_tools.xsiam_client import ( - XsiamApiClient, - XsiamApiClientConfig, -) - CI_PIPELINE_ID = os.environ.get("CI_PIPELINE_ID") app = typer.Typer() @@ -149,11 +146,9 @@ def __init__( cloud_servers_api_keys: str, service_account: Optional[str], artifacts_bucket: Optional[str], - xsiam_url: Optional[str], - xsiam_token: Optional[str], + cloud_url: Optional[str], api_key: Optional[str], auth_id: Optional[str], - collector_token: Optional[str], inputs: Optional[List[Path]], machine_assignment: str, ctx: typer.Context, @@ -168,11 +163,9 @@ def __init__( self.build_name = branch_name # -------------------------- Manual run on a single instance -------------------------- - self.xsiam_url = xsiam_url - self.xsiam_token = xsiam_token + self.cloud_url = cloud_url self.api_key = api_key self.auth_id = auth_id - self.collector_token = collector_token self.inputs = inputs # --------------------------- Machine preparation ------------------------------- @@ -203,17 +196,15 @@ def create_servers(self): """ Create servers object based on build type. """ - # If xsiam_url is provided we assume it's a run on a single server. - if self.xsiam_url: + # If cloud_url is provided we assume it's a run on a single server. + if self.cloud_url: return [ CloudServerContext( self, - base_url=self.xsiam_url, + base_url=self.cloud_url, api_key=self.api_key, # type: ignore[arg-type] auth_id=self.auth_id, # type: ignore[arg-type] - token=self.xsiam_token, # type: ignore[arg-type] - collector_token=self.collector_token, - ui_url=get_ui_url(self.xsiam_url), + ui_url=get_ui_url(self.cloud_url), tests=[BuildContext.edit_prefix(test) for test in self.inputs] if self.inputs else [], @@ -244,9 +235,6 @@ def create_servers(self): auth_id=self.cloud_servers_api_keys_json.get(machine, {}).get( "x-xdr-auth-id" ), - token=self.cloud_servers_api_keys_json.get(machine, {}).get( - "token" - ), ) ) return servers_list @@ -259,18 +247,14 @@ def __init__( base_url: str, api_key: str, auth_id: str, - token: str, ui_url: str, tests: List[Path], - collector_token: Optional[str] = None, ): self.build_context = build_context self.client = None self.base_url = base_url self.api_key = api_key self.auth_id = auth_id - self.token = token - self.collector_token = collector_token os.environ.pop( "DEMISTO_USERNAME", None ) # we use client without demisto username @@ -302,14 +286,11 @@ def execute_tests(self): real_time=True, ) - xsiam_client_cfg = XsiamApiClientConfig( - base_url=self.base_url, # type: ignore[arg-type] - api_key=self.api_key, # type: ignore[arg-type] - auth_id=self.auth_id, # type: ignore[arg-type] - token=self.token, # type: ignore[arg-type] - collector_token=self.collector_token, # type: ignore[arg-type] + cloud_client = get_client_from_server_type( + base_url=self.base_url, + api_key=self.api_key, + auth_id=self.auth_id ) - xsiam_client = XsiamApiClient(xsiam_client_cfg) for i, test_use_case_directory in enumerate(self.tests, start=1): logger.info( @@ -318,7 +299,7 @@ def execute_tests(self): success, test_use_case_test_suite = run_test_use_case_pytest( test_use_case_directory, - xsiam_client=xsiam_client + cloud_client=cloud_client ) if success: @@ -365,14 +346,14 @@ def copy_conftest(test_dir): def run_test_use_case_pytest( test_use_case_directory: Path, - xsiam_client: XsiamApiClient, + cloud_client: XsoarClient, durations: int = 5) -> Tuple[bool, Union[TestSuite, None]]: """Runs a test use case Args: test_use_case_directory (Path): Path to the test use case directory. durations (int): Number of slow tests to show durations for. - xsiam_client (XsiamApiClient): The XSIAM client used to do API calls to the tenant. + cloud_client (XsoarClient): The XSIAM client used to do API calls to the tenant. """ # Creating an instance of your results collector test_use_case_suite = TestSuite(f"Test Use Case") @@ -390,9 +371,9 @@ def run_test_use_case_pytest( test_dir = test_use_case_directory.parent copy_conftest(test_dir) - logger.info(f'before sending pytest {str(xsiam_client.base_url)}') + logger.info(f'before sending pytest {str(cloud_client.base_url)}') pytest_args = [ - f"--client_conf=base_url={str(xsiam_client.base_url)},api_key={xsiam_client.api_key},auth_id={xsiam_client.auth_id}", + f"--client_conf=base_url={str(cloud_client.server_config.base_url)},api_key={cloud_client.server_config.api_key},auth_id={cloud_client.server_config.auth_id}", str(test_use_case_directory), f"--durations={str(durations)}", "--log-cli-level=CRITICAL", @@ -436,15 +417,15 @@ def run_test_use_case( xsiam_url: Optional[str] = typer.Option( None, envvar="DEMISTO_BASE_URL", - help="The base url to the xsiam tenant.", - rich_help_panel="XSIAM Tenant Configuration", + help="The base url to the cloud tenant.", + rich_help_panel="Cloud Tenant Configuration", show_default=False, callback=tenant_config_cb, ), api_key: Optional[str] = typer.Option( None, envvar="DEMISTO_API_KEY", - help="The api key for the xsiam tenant.", + help="The api key for the cloud tenant.", rich_help_panel="XSIAM Tenant Configuration", show_default=False, callback=tenant_config_cb, @@ -452,26 +433,11 @@ def run_test_use_case( auth_id: Optional[str] = typer.Option( None, envvar="XSIAM_AUTH_ID", - help="The auth id associated with the xsiam api key being used.", + help="The auth id associated with the cloud api key being used.", rich_help_panel="XSIAM Tenant Configuration", show_default=False, callback=tenant_config_cb, ), - xsiam_token: Optional[str] = typer.Option( - None, - envvar="XSIAM_TOKEN", - help="The token used to push event logs to XSIAM", - rich_help_panel="XSIAM Tenant Configuration", - show_default=False, - ), - collector_token: Optional[str] = typer.Option( - None, - envvar="XSIAM_COLLECTOR_TOKEN", - help="The token used to push event logs to a custom HTTP Collector", - rich_help_panel="XSIAM Tenant Configuration", - show_default=False, - callback=logs_token_cb, - ), output_junit_file: Optional[Path] = typer.Option( None, "-jp", "--junit-path", help="Path to the output JUnit XML file." ), @@ -608,11 +574,9 @@ def run_test_use_case( artifacts_bucket=artifacts_bucket, machine_assignment=machine_assignment, ctx=ctx, - xsiam_url=xsiam_url, - xsiam_token=xsiam_token, + cloud_url=xsiam_url, api_key=api_key, auth_id=auth_id, - collector_token=collector_token, inputs=inputs, ) From 0e4e19380ca14597b5feae62fb6853e4a23064f8 Mon Sep 17 00:00:00 2001 From: epintzov Date: Wed, 18 Dec 2024 18:12:01 +0200 Subject: [PATCH 36/58] fix --- .../commands/test_content/test_use_case/test_use_case.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py index 3e32ebf1ed2..28c46d7c51b 100644 --- a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py +++ b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py @@ -373,7 +373,9 @@ def run_test_use_case_pytest( logger.info(f'before sending pytest {str(cloud_client.base_url)}') pytest_args = [ - f"--client_conf=base_url={str(cloud_client.server_config.base_url)},api_key={cloud_client.server_config.api_key},auth_id={cloud_client.server_config.auth_id}", + f"--client_conf=base_url={str(cloud_client.server_config.base_api_url)}," + f"api_key={cloud_client.server_config.api_key.get_secret_value()}," + f"auth_id={cloud_client.server_config.auth_id}", str(test_use_case_directory), f"--durations={str(durations)}", "--log-cli-level=CRITICAL", From 7328074dc4b83a59e2150b0817ed0b5172884027 Mon Sep 17 00:00:00 2001 From: epintzov Date: Mon, 23 Dec 2024 10:24:36 +0200 Subject: [PATCH 37/58] moved methods and renamed test file --- .../test_content/test_use_case/template_file.py | 15 ++------------- .../test_content/test_use_case/test_use_case.py | 14 ++++++++------ 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/demisto_sdk/commands/test_content/test_use_case/template_file.py b/demisto_sdk/commands/test_content/test_use_case/template_file.py index 24cb3f79ed7..ce35954bcd1 100644 --- a/demisto_sdk/commands/test_content/test_use_case/template_file.py +++ b/demisto_sdk/commands/test_content/test_use_case/template_file.py @@ -24,13 +24,13 @@ def util_load_json(path): return json.loads(f.read()) -@pytest.fixture +@pytest.fixture(scope="class") def client_conf(request): # Manually parse command-line arguments return get_client_conf_from_pytest_request(request) -@pytest.fixture +@pytest.fixture(scope="class") def api_client(client_conf): if client_conf: # Running from external pipeline client_obj = get_client_from_server_type(**client_conf) @@ -44,22 +44,11 @@ class TestExample: @classmethod def setup_class(self): """Run once for the class before *all* tests""" - print("Testing out running in setup!") self.data = "test" - @pytest.fixture - def setup_method(self, client_conf=None): - if client_conf: - self.client = get_client_from_server_type(client_conf) - else: - self.client = get_client_from_server_type() - def some_helper_function(self, method): pass - def teardown_method(self, method): - print("tearing down") - @classmethod def teardown_class(self): """Run once for the class after all tests""" diff --git a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py index 28c46d7c51b..457da454137 100644 --- a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py +++ b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py @@ -55,7 +55,7 @@ def get_containing_pack(use_case_path: Path) -> str: """Get pack object that contains the content entity. Args: - content_entity: Content entity object. + use_case_path: path to the use case Returns: Pack: Pack object that contains the content entity. @@ -65,6 +65,13 @@ def get_containing_pack(use_case_path: Path) -> str: return str(use_case_path) +def copy_conftest(test_dir): + source_conftest = Path(f"{CONTENT_PATH}/Tests/scripts/dev_envs/pytest/conftest.py") + dest_conftest = test_dir / "conftest.py" + + shutil.copy(source_conftest, dest_conftest) + + # ============================================== Classes ============================================ # class TestResultCapture: """ @@ -337,11 +344,6 @@ def execute_tests(self): # ============================================== Command logic ============================================ # -def copy_conftest(test_dir): - source_conftest = Path(f"{CONTENT_PATH}/Tests/scripts/dev_envs/pytest/conftest.py") - dest_conftest = test_dir / "conftest.py" - - shutil.copy(source_conftest, dest_conftest) def run_test_use_case_pytest( From e248a060f010de90305ca737eaf0e5a6d3e33adf Mon Sep 17 00:00:00 2001 From: epintzov Date: Tue, 24 Dec 2024 10:12:59 +0200 Subject: [PATCH 38/58] changed use test case --- .../common/clients/xsiam/xsiam_api_client.py | 21 ++- .../test_use_case/test_use_case.py | 10 +- .../tests/run_playbook_flow_test_test.py | 70 ------- .../test_use_case/tests/test_use_case_test.py | 173 ++++++++++++++++++ 4 files changed, 190 insertions(+), 84 deletions(-) delete mode 100644 demisto_sdk/commands/test_content/test_use_case/tests/run_playbook_flow_test_test.py create mode 100644 demisto_sdk/commands/test_content/test_use_case/tests/test_use_case_test.py diff --git a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py index 9f4a9ff5cfc..082d779429e 100644 --- a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py +++ b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py @@ -259,18 +259,19 @@ def update_alert(self, alert_id: Union[str, list[str]], updated_data: dict) -> d alert_data = self._process_response(res.content, res.status_code, 200) return alert_data - def search_alerts(self, external_alert_id: str | list[str]) -> dict: + def search_alerts(self, filters: list, search_from: int, search_to: int, sort: dict) -> dict: + """ + filters should be a list of dicts contains field, operator, value. + For example: + [{field: alert_id_list, operator: in, value: [1,2,3,4]}] + Allowed values for fields - alert_id_list, alert_source, severity, creation_time + """ body = { "request_data": { - "filters": [ - { - "field": "external_id_list", - "operator": "in", - "value": external_alert_id - if isinstance(external_alert_id, list) - else [external_alert_id], - } - ] + "filters": filters, + "search_from": search_from, + "search_to": search_to, + "sort": sort } } endpoint = urljoin( diff --git a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py index 457da454137..7470db70f5b 100644 --- a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py +++ b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py @@ -15,8 +15,8 @@ import typer from google.cloud import storage # type: ignore[attr-defined] -from junitparser import Error, JUnitXml, TestCase, TestSuite -from junitparser.junitparser import Failure, Result, Skipped +from junitparser import JUnitXml, TestCase, TestSuite +from junitparser.junitparser import Failure, Skipped from demisto_sdk.commands.common.constants import ( Test_Use_Cases, @@ -381,7 +381,7 @@ def run_test_use_case_pytest( str(test_use_case_directory), f"--durations={str(durations)}", "--log-cli-level=CRITICAL", - "--no-summary" + # "--no-summary" ] logger.info(f"Runnig pytest for file {test_use_case_directory}") @@ -393,11 +393,13 @@ def run_test_use_case_pytest( if status_code == pytest.ExitCode.OK: logger.info(f"Pytest run tests in {test_use_case_directory} successfully") return True, test_use_case_suite - else: + elif status_code == pytest.ExitCode.TESTS_FAILED: logger.error( f"Pytest failed with statsu {status_code}", ) return False, test_use_case_suite + else: + raise Exception(f"Pytest failed with {status_code=}") @app.command( diff --git a/demisto_sdk/commands/test_content/test_use_case/tests/run_playbook_flow_test_test.py b/demisto_sdk/commands/test_content/test_use_case/tests/run_playbook_flow_test_test.py deleted file mode 100644 index e9de574a8c3..00000000000 --- a/demisto_sdk/commands/test_content/test_use_case/tests/run_playbook_flow_test_test.py +++ /dev/null @@ -1,70 +0,0 @@ -import unittest -from unittest.mock import patch, MagicMock -from pathlib import Path - - -# Mock dependencies -class TestSuite: - def __init__(self, name): - self.name = name - self.properties = {} - - def add_property(self, key, value): - self.properties[key] = value - - -class XsiamApiClient: - def __init__(self, base_url, api_key, auth_id): - self.base_url = base_url - self.api_key = api_key - self.auth_id = auth_id - - -class TestResultCapture: - def __init__(self, test_suite): - self.test_suite = test_suite - - -# Unit test class -class TestRunPlaybookFlowTestPytest(unittest.TestCase): - - @patch("pytest.main") - @patch("__main__.TestResultCapture") - def test_run_playbook_flow_test_pytest_success(self, mock_result_capture, mock_pytest_main): - from demisto_sdk.commands.test_content.test_use_case.test_use_case import \ - run_test_use_case_pytest - - # Arrange - playbook_flow_test_directory = Path("/path/to/test") - xsiam_client = XsiamApiClient("http://example.com", "api_key", "auth_id") - mock_pytest_main.return_value = 0 - mock_result_capture.return_value = MagicMock() - - # Act - success, test_suite = run_test_use_case_pytest( - playbook_flow_test_directory, xsiam_client, durations=5 - ) - - # Assert - self.assertTrue(success) - self.assertIsInstance(test_suite, TestSuite) - self.assertEqual(test_suite.properties["file_name"], str(playbook_flow_test_directory)) - - @patch("pytest.main") - @patch("__main__.TestResultCapture") - def test_run_playbook_flow_test_pytest_failure(self, mock_result_capture, mock_pytest_main): - # Arrange - playbook_flow_test_directory = Path("/path/to/test") - xsiam_client = XsiamApiClient("http://example.com", "api_key", "auth_id") - mock_pytest_main.return_value = 1 - mock_result_capture.return_value = MagicMock() - - # Act - success, test_suite = run_playbook_flow_test_pytest( - playbook_flow_test_directory, xsiam_client, durations=5 - ) - - # Assert - self.assertFalse(success) - self.assertIsInstance(test_suite, TestSuite) - self.assertEqual(test_suite.properties["file_name"], str(playbook_flow_test_directory)) diff --git a/demisto_sdk/commands/test_content/test_use_case/tests/test_use_case_test.py b/demisto_sdk/commands/test_content/test_use_case/tests/test_use_case_test.py new file mode 100644 index 00000000000..662b452bf86 --- /dev/null +++ b/demisto_sdk/commands/test_content/test_use_case/tests/test_use_case_test.py @@ -0,0 +1,173 @@ +from datetime import datetime +from pathlib import Path +import pytest + +from junitparser import TestSuite, TestCase, Failure, Skipped + +from demisto_sdk.commands.common.content_constant_paths import CONTENT_PATH +from demisto_sdk.commands.test_content.test_use_case.test_use_case import get_containing_pack, copy_conftest, \ + run_test_use_case_pytest +import demisto_sdk.commands.test_content.test_use_case.test_use_case as test_use_case + +from unittest.mock import Mock +from pytest import ExitCode + + +# Mock the dependencies +@pytest.fixture +def mocker_cloud_client(mocker): + # Mock the XsoarClient + cloud_client = mocker.Mock() + cloud_client.server_config.base_api_url = 'https://example.com' + cloud_client.server_config.api_key.get_secret_value.return_value = 'API_KEY' + cloud_client.server_config.auth_id = 'AUTH_ID' + return cloud_client + + +@pytest.fixture +def mocker_test_use_case_directory(mocker): + # Mock the test_use_case_directory + return mocker.Mock() + + +def test_run_test_use_case_pytest(mocker, mocker_cloud_client, mocker_test_use_case_directory): + """ + Given: parameters for running the tests. + When: running the test_use_case command. + Then: validate the correct params are used when running the pytest method. + """ + test_result_mocker = mocker.Mock() + mocker.patch.object(test_use_case, 'get_containing_pack', return_value='/path/to/pack') + mocker.patch.object(test_use_case, 'copy_conftest') + mocker.patch.object(test_use_case, 'logger') + mocker.patch.object(test_use_case, 'TestResultCapture', return_value=test_result_mocker) + mocker.patch('pytest.main', return_value=ExitCode.OK) + + # Call the function to be tested + result, test_use_case_suite = run_test_use_case_pytest( + mocker_test_use_case_directory, + mocker_cloud_client, + durations=5 + ) + + # Verify the expected behavior and assertions + assert result is True + assert isinstance(test_use_case_suite, TestSuite) + + # Additional assertions for the mocked dependencies + pytest.main.assert_called_once_with( + [ + f"--client_conf=base_url=https://example.com," + f"api_key=API_KEY," + f"auth_id=AUTH_ID", + str(mocker_test_use_case_directory), + "--durations=5", + "--log-cli-level=CRITICAL", + "--no-summary" + ], + plugins=[test_result_mocker] + ) + mocker_cloud_client.server_config.api_key.get_secret_value.assert_called_once() + + +def test_get_containing_pack(): + """ + Given: path to use case file + When: running the test_use_case command. + Then: validate the correct path to the pack dir is returned. + """ + # Test case 1: Use case path is directly inside the "packs" directory + use_case_path = Path("/path/to/packs/pack1/use_case.py") + expected_result = "/path/to/packs/pack1" + assert get_containing_pack(use_case_path) == expected_result + + # Test case 2: Use case path is multiple levels deep inside the "packs" directory + use_case_path = Path("/path/to/packs/pack1/subdir1/subdir2/use_case.py") + expected_result = "/path/to/packs/pack1" + assert get_containing_pack(use_case_path) == expected_result + + +def test_pytest_runtest_logreport_passed(mocker): + """ + When: pytest_runtest_logreport is called with a passing test, + Given: a TestResultCapture instance and a passing report, + Then: Validate the correct testcase is appended the test suite. + + + """ + junit_testsuite = TestSuite("Test Suite") + test_result_capture = test_use_case.TestResultCapture(junit_testsuite) + + report = mocker.Mock() + report.when = "call" + report.nodeid = "test_module.test_function" + report.location = ("test_module",) + report.duration = 0.5 + report.outcome = "passed" + + test_result_capture.pytest_runtest_logreport(report) + + assert len(junit_testsuite) == 1 + + for testcase in junit_testsuite: + assert testcase.name == "test_module.test_function" + assert testcase.classname == "test_module" + assert testcase.time == 0.5 + assert len(testcase.result) == 0 + + +def test_pytest_runtest_logreport_failed(mocker): + """ + When: pytest_runtest_logreport is called with a failing test, + Given: a TestResultCapture instance and a failing report, + Then: Validate the correct testcase is appended the test suite. + """ + junit_testsuite = TestSuite("Test Suite") + test_result_capture = test_use_case.TestResultCapture(junit_testsuite) + + report = mocker.Mock() + report.when = "call" + report.nodeid = "test_module.test_function" + report.location = ("test_module",) + report.duration = 0.5 + report.outcome = "failed" + report.longreprtext = "AssertionError: Expected 1, but got 2" + + test_result_capture.pytest_runtest_logreport(report) + + assert len(junit_testsuite) == 1 + + for testcase in junit_testsuite: + assert testcase.name == "test_module.test_function" + assert testcase.classname == "test_module" + assert testcase.time == 0.5 + assert testcase.result[0].message == "AssertionError: Expected 1, but got 2" + + +def test_pytest_runtest_logreport_skipped(mocker): + """ + When: pytest_runtest_logreport is called with a skipped test, + Given: a TestResultCapture instance and a skipped report, + Then: Validate the correct testcase is appended the test suite. + """ + junit_testsuite = TestSuite("Test Suite") + test_result_capture = test_use_case.TestResultCapture(junit_testsuite) + + report = mocker.Mock() + report.when = "call" + report.nodeid = "test_module.test_function" + report.location = ("test_module",) + report.duration = 0.5 + report.outcome = "skipped" + + test_result_capture.pytest_runtest_logreport(report) + + assert len(junit_testsuite) == 1 + + for testcase in junit_testsuite: + assert testcase.name == "test_module.test_function" + assert testcase.classname == "test_module" + assert testcase.time == 0.5 + assert testcase.result[0].message == "Test skipped" + + From cc9544f2bcbd70339c567c2258d3ec5e690721f5 Mon Sep 17 00:00:00 2001 From: epintzov Date: Sun, 29 Dec 2024 09:41:37 +0200 Subject: [PATCH 39/58] added search alert by name --- .../common/clients/xsiam/xsiam_api_client.py | 56 +++++++++++++------ 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py index 082d779429e..3f8037da1fd 100644 --- a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py +++ b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py @@ -78,11 +78,11 @@ def _process_response(self, response, status_code, expected_status=200): """ def delete_incidents( - self, - incident_ids: Union[str, List[str]], - filters: Dict[str, Any] = None, - _all: bool = False, - response_type: str = "object", + self, + incident_ids: Union[str, List[str]], + filters: Dict[str, Any] = None, + _all: bool = False, + response_type: str = "object", ): # if in the future it will be possible to delete incidents in XSIAM, implement this method raise NotImplementedError("it is not possible to delete incidents in XSIAM") @@ -94,11 +94,11 @@ def delete_incidents( """ def push_to_dataset( - self, - data: List[Dict[str, Any]], - vendor: str, - product: str, - data_format: str = "json", + self, + data: List[Dict[str, Any]], + vendor: str, + product: str, + data_format: str = "json", ): if self.server_config.token: endpoint = urljoin(self.server_config.base_api_url, "logs/v1/xsiam") @@ -197,8 +197,8 @@ def get_xql_query_result(self, execution_id: str, timeout: int = 300): logger.debug(pformat(data)) if ( - response.status_code in range(200, 300) - and data.get("reply", {}).get("status", "") == "SUCCESS" + response.status_code in range(200, 300) + and data.get("reply", {}).get("status", "") == "SUCCESS" ): return data.get("reply", {}).get("results", {}).get("data", []) response.raise_for_status() @@ -215,8 +215,8 @@ def get_ioc_rules(self): "/ioc-rules", "GET", response_type="object" ) if ( - "text/html" in response_headers.get("Content-Type") - or status_code != requests.codes.ok + "text/html" in response_headers.get("Content-Type") + or status_code != requests.codes.ok ): raise ApiException( status=404, reason=f'{self} does not have "/ioc-rules" endpoint' @@ -240,7 +240,9 @@ def create_alert_from_json(self, json_content: dict) -> int: return alert_data["reply"] def get_internal_alert_id(self, alert_external_id: str) -> int: - data = self.search_alerts(alert_external_id) + data = self.search_alerts(filters=[{"field": "external_id_list", + "operator": "in", + "value": [alert_external_id]}]) return data["alerts"][0]["alert_id"] def update_alert(self, alert_id: Union[str, list[str]], updated_data: dict) -> dict: @@ -259,7 +261,8 @@ def update_alert(self, alert_id: Union[str, list[str]], updated_data: dict) -> d alert_data = self._process_response(res.content, res.status_code, 200) return alert_data - def search_alerts(self, filters: list, search_from: int, search_to: int, sort: dict) -> dict: + def search_alerts(self, filters: list = None, search_from: int = None, search_to: int = None, + sort: dict = None) -> dict: """ filters should be a list of dicts contains field, operator, value. For example: @@ -280,6 +283,27 @@ def search_alerts(self, filters: list, search_from: int, search_to: int, sort: d res = self._xdr_client.post(endpoint, json=body) return self._process_response(res.content, res.status_code, 200)["reply"] + def search_alerts_by_alert_name(self, alert_names=None, filters: list = None): + + if alert_names is None: + alert_names = [] + alert_ids = [] + + res = self.search_alerts(filters=filters) + alerts = res.get('alerts') + count = res.get('result_count') + + while len(alerts) > 0 and len(alert_names) > len(alert_ids): + for alert in alerts: + if alert.get('name') in alert_names: + alert_ids.append(alert.get('alert_id')) + + res = self.search_alerts(filters=filters, search_from=count) + alerts = res.get('alerts') + count = res.get('result_count') + + return alert_ids + """ ############################# Playbooks related methods From cdef09012e23635b20525401d5a54f21b0e437ac Mon Sep 17 00:00:00 2001 From: epintzov Date: Sun, 29 Dec 2024 11:56:49 +0200 Subject: [PATCH 40/58] pre commit --- conftest.py | 11 +- demisto_sdk/__main__.py | 9 +- .../commands/common/clients/__init__.py | 11 +- .../common/clients/xsiam/xsiam_api_client.py | 72 ++-- .../test_modeling_rule/test_modeling_rule.py | 35 +- .../test_use_case/template_file.py | 6 +- .../test_use_case/test_use_case.py | 380 +++++++++--------- .../test_use_case/tests/test_use_case_test.py | 68 ++-- demisto_sdk/commands/test_content/tools.py | 16 +- 9 files changed, 296 insertions(+), 312 deletions(-) diff --git a/conftest.py b/conftest.py index 83ba04088f4..2857d99d1a2 100644 --- a/conftest.py +++ b/conftest.py @@ -20,7 +20,6 @@ from TestSuite.repo import Repo from TestSuite.yml import YAML - # Helper Functions @@ -40,7 +39,7 @@ def get_pack(request: FixtureRequest, tmp_path_factory: TempPathFactory) -> Pack def get_integration( - request: FixtureRequest, tmp_path_factory: TempPathFactory + request: FixtureRequest, tmp_path_factory: TempPathFactory ) -> Integration: """Mocking tmp_path""" integration = get_pack(request, tmp_path_factory).create_integration() @@ -49,7 +48,7 @@ def get_integration( def get_playbook( - request: FixtureRequest, tmp_path_factory: TempPathFactory + request: FixtureRequest, tmp_path_factory: TempPathFactory ) -> Playbook: """Mocking tmp_path""" playbook = get_pack(request, tmp_path_factory).create_playbook() @@ -79,7 +78,7 @@ def script(request: FixtureRequest, tmp_path_factory: TempPathFactory): @pytest.fixture def integration( - request: FixtureRequest, tmp_path_factory: TempPathFactory + request: FixtureRequest, tmp_path_factory: TempPathFactory ) -> Integration: """Mocking tmp_path""" return get_integration(request, tmp_path_factory) @@ -163,7 +162,7 @@ def mock_update_id_set_cpu_count() -> Generator: all physical cpu's (36) it uses too many processes in the process pools. """ with mock.patch( - "demisto_sdk.commands.common.update_id_set.cpu_count", return_value=2 + "demisto_sdk.commands.common.update_id_set.cpu_count", return_value=2 ) as _fixture: yield _fixture @@ -183,5 +182,5 @@ def pytest_addoption(parser): "--client_conf", action="store", default=None, - help="Custom client configuration" + help="Custom client configuration", ) diff --git a/demisto_sdk/__main__.py b/demisto_sdk/__main__.py index 1b504571de2..c63ca7d55cc 100644 --- a/demisto_sdk/__main__.py +++ b/demisto_sdk/__main__.py @@ -68,7 +68,7 @@ modeling_rules_app, ) from demisto_sdk.commands.test_content.test_use_case.test_use_case import ( - run_test_use_case + run_test_use_case, ) from demisto_sdk.commands.update_release_notes.update_release_notes_setup import ( update_release_notes, @@ -206,10 +206,9 @@ app.command(name="generate-modeling-rules", help="Generated modeling-rules.")( generate_modeling_rules ) -app.command(name="test-use-case", - hidden=True, - no_args_is_help=True, - help="Test Use Cases.")(run_test_use_case) +app.command( + name="test-use-case", hidden=True, no_args_is_help=True, help="Test Use Cases." +)(run_test_use_case) app.command( name="lint", help="Deprecated, use demisto-sdk pre-commit instead.", hidden=True )(lint) diff --git a/demisto_sdk/commands/common/clients/__init__.py b/demisto_sdk/commands/common/clients/__init__.py index 23b26a9669b..be5491256ef 100644 --- a/demisto_sdk/commands/common/clients/__init__.py +++ b/demisto_sdk/commands/common/clients/__init__.py @@ -236,6 +236,7 @@ def get_client_from_server_type( # =================== Playbook Flow Tests ================= + def parse_str_to_dict(input_str): """Internal function to convert a string representing a dictionary into an actual dictionary. @@ -246,9 +247,10 @@ def parse_str_to_dict(input_str): dict: A dictionary with the parsed key-value pairs. """ x = dict(pair.split("=") for pair in input_str.split(",") if "=" in pair) - logger.info(x.get('base_url', "no base url")) + logger.info(x.get("base_url", "no base url")) return dict(pair.split("=") for pair in input_str.split(",") if "=" in pair) + # def get_client_conf_from_pytest_request(): # # Manually parse command-line argument # client_conf = os.getenv("CLIENT_CONF") @@ -256,16 +258,13 @@ def parse_str_to_dict(input_str): # return parse_str_to_dict(client_conf) # return None + def get_client_conf_from_pytest_request(request): # Manually parse command-line argument for arg in request.config.invocation_params.args: if isinstance(arg, str) and arg.startswith("--client_conf="): logger.info("there is --client_conf recognized") - client_conf = arg.replace("--client_conf=", '') + client_conf = arg.replace("--client_conf=", "") return parse_str_to_dict(client_conf) # If a client data was not provided, we proceed to use default. return None - - - - diff --git a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py index 3f8037da1fd..ddab59560de 100644 --- a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py +++ b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py @@ -78,11 +78,11 @@ def _process_response(self, response, status_code, expected_status=200): """ def delete_incidents( - self, - incident_ids: Union[str, List[str]], - filters: Dict[str, Any] = None, - _all: bool = False, - response_type: str = "object", + self, + incident_ids: Union[str, List[str]], + filters: Dict[str, Any] = None, + _all: bool = False, + response_type: str = "object", ): # if in the future it will be possible to delete incidents in XSIAM, implement this method raise NotImplementedError("it is not possible to delete incidents in XSIAM") @@ -94,11 +94,11 @@ def delete_incidents( """ def push_to_dataset( - self, - data: List[Dict[str, Any]], - vendor: str, - product: str, - data_format: str = "json", + self, + data: List[Dict[str, Any]], + vendor: str, + product: str, + data_format: str = "json", ): if self.server_config.token: endpoint = urljoin(self.server_config.base_api_url, "logs/v1/xsiam") @@ -197,8 +197,8 @@ def get_xql_query_result(self, execution_id: str, timeout: int = 300): logger.debug(pformat(data)) if ( - response.status_code in range(200, 300) - and data.get("reply", {}).get("status", "") == "SUCCESS" + response.status_code in range(200, 300) + and data.get("reply", {}).get("status", "") == "SUCCESS" ): return data.get("reply", {}).get("results", {}).get("data", []) response.raise_for_status() @@ -215,8 +215,8 @@ def get_ioc_rules(self): "/ioc-rules", "GET", response_type="object" ) if ( - "text/html" in response_headers.get("Content-Type") - or status_code != requests.codes.ok + "text/html" in response_headers.get("Content-Type") + or status_code != requests.codes.ok ): raise ApiException( status=404, reason=f'{self} does not have "/ioc-rules" endpoint' @@ -240,9 +240,15 @@ def create_alert_from_json(self, json_content: dict) -> int: return alert_data["reply"] def get_internal_alert_id(self, alert_external_id: str) -> int: - data = self.search_alerts(filters=[{"field": "external_id_list", - "operator": "in", - "value": [alert_external_id]}]) + data = self.search_alerts( + filters=[ + { + "field": "external_id_list", + "operator": "in", + "value": [alert_external_id], + } + ] + ) return data["alerts"][0]["alert_id"] def update_alert(self, alert_id: Union[str, list[str]], updated_data: dict) -> dict: @@ -261,20 +267,25 @@ def update_alert(self, alert_id: Union[str, list[str]], updated_data: dict) -> d alert_data = self._process_response(res.content, res.status_code, 200) return alert_data - def search_alerts(self, filters: list = None, search_from: int = None, search_to: int = None, - sort: dict = None) -> dict: + def search_alerts( + self, + filters: list = None, + search_from: int = None, + search_to: int = None, + sort: dict = None, + ) -> dict: """ - filters should be a list of dicts contains field, operator, value. - For example: - [{field: alert_id_list, operator: in, value: [1,2,3,4]}] - Allowed values for fields - alert_id_list, alert_source, severity, creation_time + filters should be a list of dicts contains field, operator, value. + For example: + [{field: alert_id_list, operator: in, value: [1,2,3,4]}] + Allowed values for fields - alert_id_list, alert_source, severity, creation_time """ body = { "request_data": { "filters": filters, "search_from": search_from, "search_to": search_to, - "sort": sort + "sort": sort, } } endpoint = urljoin( @@ -284,23 +295,22 @@ def search_alerts(self, filters: list = None, search_from: int = None, search_to return self._process_response(res.content, res.status_code, 200)["reply"] def search_alerts_by_alert_name(self, alert_names=None, filters: list = None): - if alert_names is None: alert_names = [] alert_ids = [] res = self.search_alerts(filters=filters) - alerts = res.get('alerts') - count = res.get('result_count') + alerts = res.get("alerts") + count = res.get("result_count") while len(alerts) > 0 and len(alert_names) > len(alert_ids): for alert in alerts: - if alert.get('name') in alert_names: - alert_ids.append(alert.get('alert_id')) + if alert.get("name") in alert_names: + alert_ids.append(alert.get("alert_id")) res = self.search_alerts(filters=filters, search_from=count) - alerts = res.get('alerts') - count = res.get('result_count') + alerts = res.get("alerts") + count = res.get("result_count") return alert_ids diff --git a/demisto_sdk/commands/test_content/test_modeling_rule/test_modeling_rule.py b/demisto_sdk/commands/test_content/test_modeling_rule/test_modeling_rule.py index ef104080e14..acfe7baa2f4 100644 --- a/demisto_sdk/commands/test_content/test_modeling_rule/test_modeling_rule.py +++ b/demisto_sdk/commands/test_content/test_modeling_rule/test_modeling_rule.py @@ -19,10 +19,6 @@ from tabulate import tabulate from tenacity import ( Retrying, - before_sleep_log, - retry_if_exception_type, - stop_after_attempt, - wait_fixed, ) from typer.main import get_command_from_info @@ -34,7 +30,6 @@ ModelingRule, SingleModelingRule, ) -from demisto_sdk.commands.common.content_constant_paths import CONTENT_PATH from demisto_sdk.commands.common.handlers import DEFAULT_JSON_HANDLER as json from demisto_sdk.commands.common.logger import ( handle_deprecated_args, @@ -45,7 +40,6 @@ get_file, get_json_file, is_epoch_datetime, - parse_int_or_default, string_to_bool, ) from demisto_sdk.commands.test_content.ParallelLoggingManager import ( @@ -60,18 +54,18 @@ XQL_QUERY_ERROR_EXPLANATION, ) from demisto_sdk.commands.test_content.tools import ( - get_ui_url, - XSIAM_CLIENT_SLEEP_INTERVAL, XSIAM_CLIENT_RETRY_ATTEMPTS, - logs_token_cb, - tenant_config_cb, - xsiam_get_installed_packs, + XSIAM_CLIENT_SLEEP_INTERVAL, create_retrying_caller, - get_type_pretty_name, day_suffix, - get_relative_path_to_content, duration_since_start_time, - get_utc_now + get_relative_path_to_content, + get_type_pretty_name, + get_ui_url, + get_utc_now, + logs_token_cb, + tenant_config_cb, + xsiam_get_installed_packs, ) from demisto_sdk.commands.test_content.xsiam_tools.test_data import ( TestData, @@ -90,11 +84,6 @@ app = typer.Typer() - - - - - def create_table(expected: Dict[str, Any], received: Dict[str, Any]) -> str: """Create a table to display the expected and received values. @@ -114,9 +103,6 @@ def create_table(expected: Dict[str, Any], received: Dict[str, Any]) -> str: ) - - - def convert_epoch_time_to_string_time( epoch_time: int, with_ms: bool = False, tenant_timezone: str = "UTC" ) -> str: @@ -140,7 +126,6 @@ def convert_epoch_time_to_string_time( return datetime_object.strftime(time_format) - def sanitize_received_value_by_expected_type( received_value: Any, expected_type: str ) -> Tuple[str, Any]: @@ -165,8 +150,6 @@ def sanitize_received_value_by_expected_type( return received_value_type, received_value - - def xsiam_execute_query(xsiam_client: XsiamApiClient, query: str) -> List[dict]: """Execute an XQL query and return the results. Wrapper for XsiamApiClient.execute_query() with retry logic. @@ -184,7 +167,6 @@ def xsiam_push_to_dataset( return xsiam_client.push_to_dataset(events_test_data, rule.vendor, rule.product) - def verify_results( modeling_rule: ModelingRule, tested_dataset: str, @@ -1285,6 +1267,7 @@ def add_result_to_test_case( # ====================== test-modeling-rule ====================== # + class TestResults: def __init__( self, diff --git a/demisto_sdk/commands/test_content/test_use_case/template_file.py b/demisto_sdk/commands/test_content/test_use_case/template_file.py index ce35954bcd1..ebbc6b8d3df 100644 --- a/demisto_sdk/commands/test_content/test_use_case/template_file.py +++ b/demisto_sdk/commands/test_content/test_use_case/template_file.py @@ -6,6 +6,7 @@ } } """ + import json import pytest @@ -16,9 +17,9 @@ get_client_from_server_type, ) - # Any additional imports your tests require + def util_load_json(path): with open(path, encoding="utf-8") as f: return json.loads(f.read()) @@ -64,7 +65,8 @@ def test_feature_two(self, api_client: XsiamClient): """Test feature two""" # Test another aspect of your application api_client.run_cli_command( - investigation_id="INCIDENT-1", command='!Set key=test value=A') + investigation_id="INCIDENT-1", command="!Set key=test value=A" + ) assert False # replace with actual assertions for your application diff --git a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py index 7470db70f5b..9d06ea708e0 100644 --- a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py +++ b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py @@ -1,28 +1,24 @@ import logging # noqa: TID251 # specific case, passed as argument to 3rd party import os import shutil - from pathlib import Path from threading import Thread from typing import Any, List, Optional, Tuple, Union -from demisto_sdk.commands.common.clients import get_client_from_server_type -from demisto_sdk.commands.common.clients.xsoar.xsoar_api_client import XsoarClient -from demisto_sdk.commands.common.content_constant_paths import CONTENT_PATH - import demisto_client import pytest - import typer from google.cloud import storage # type: ignore[attr-defined] from junitparser import JUnitXml, TestCase, TestSuite from junitparser.junitparser import Failure, Skipped +from demisto_sdk.commands.common.clients import get_client_from_server_type +from demisto_sdk.commands.common.clients.xsoar.xsoar_api_client import XsoarClient from demisto_sdk.commands.common.constants import ( - Test_Use_Cases, XSIAM_SERVER_TYPE, + Test_Use_Cases, ) - +from demisto_sdk.commands.common.content_constant_paths import CONTENT_PATH from demisto_sdk.commands.common.logger import ( handle_deprecated_args, logger, @@ -36,14 +32,14 @@ ParallelLoggingManager, ) from demisto_sdk.commands.test_content.tools import ( - get_ui_url, - XSIAM_CLIENT_SLEEP_INTERVAL, XSIAM_CLIENT_RETRY_ATTEMPTS, - tenant_config_cb, + XSIAM_CLIENT_SLEEP_INTERVAL, create_retrying_caller, - get_relative_path_to_content, duration_since_start_time, - get_utc_now + get_relative_path_to_content, + get_ui_url, + get_utc_now, + tenant_config_cb, ) CI_PIPELINE_ID = os.environ.get("CI_PIPELINE_ID") @@ -75,7 +71,7 @@ def copy_conftest(test_dir): # ============================================== Classes ============================================ # class TestResultCapture: """ - This class is used to store the pytest results in test suite + This class is used to store the pytest results in test suite """ def __init__(self, junit_testsuite): @@ -89,7 +85,9 @@ def pytest_runtest_logreport(self, report): if report.outcome == "passed": self.junit_testsuite.add_testcase(test_case) elif report.outcome == "failed": - failure = Failure(report.longreprtext if report.longrepr else "Test failed") + failure = Failure( + report.longreprtext if report.longrepr else "Test failed" + ) test_case.result = failure self.junit_testsuite.add_testcase(test_case) elif report.outcome == "skipped": @@ -100,9 +98,9 @@ def pytest_runtest_logreport(self, report): class TestResults: def __init__( - self, - service_account: str = None, - artifacts_bucket: str = None, + self, + service_account: str = None, + artifacts_bucket: str = None, ): self.test_results_xml_file = JUnitXml() self.errors = False @@ -110,11 +108,11 @@ def __init__( self.artifacts_bucket = artifacts_bucket def upload_result_json_to_bucket( - self, - repository_name: str, - file_name, - original_file_path: Path, - logging_module: Union[Any, ParallelLoggingManager] = logging, + self, + repository_name: str, + file_name, + original_file_path: Path, + logging_module: Union[Any, ParallelLoggingManager] = logging, ): """Uploads a JSON object to a specified path in the GCP bucket. @@ -142,23 +140,23 @@ def upload_result_json_to_bucket( class BuildContext: def __init__( - self, - nightly: bool, - build_number: Optional[str], - branch_name: Optional[str], - retry_attempts: int, - sleep_interval: int, - logging_module: ParallelLoggingManager, - cloud_servers_path: str, - cloud_servers_api_keys: str, - service_account: Optional[str], - artifacts_bucket: Optional[str], - cloud_url: Optional[str], - api_key: Optional[str], - auth_id: Optional[str], - inputs: Optional[List[Path]], - machine_assignment: str, - ctx: typer.Context, + self, + nightly: bool, + build_number: Optional[str], + branch_name: Optional[str], + retry_attempts: int, + sleep_interval: int, + logging_module: ParallelLoggingManager, + cloud_servers_path: str, + cloud_servers_api_keys: str, + service_account: Optional[str], + artifacts_bucket: Optional[str], + cloud_url: Optional[str], + api_key: Optional[str], + auth_id: Optional[str], + inputs: Optional[List[Path]], + machine_assignment: str, + ctx: typer.Context, ): self.logging_module: ParallelLoggingManager = logging_module self.retrying_caller = create_retrying_caller(retry_attempts, sleep_interval) @@ -249,13 +247,13 @@ def create_servers(self): class CloudServerContext: def __init__( - self, - build_context: BuildContext, - base_url: str, - api_key: str, - auth_id: str, - ui_url: str, - tests: List[Path], + self, + build_context: BuildContext, + base_url: str, + api_key: str, + auth_id: str, + ui_url: str, + tests: List[Path], ): self.build_context = build_context self.client = None @@ -294,9 +292,7 @@ def execute_tests(self): ) cloud_client = get_client_from_server_type( - base_url=self.base_url, - api_key=self.api_key, - auth_id=self.auth_id + base_url=self.base_url, api_key=self.api_key, auth_id=self.auth_id ) for i, test_use_case_directory in enumerate(self.tests, start=1): @@ -305,8 +301,7 @@ def execute_tests(self): ) success, test_use_case_test_suite = run_test_use_case_pytest( - test_use_case_directory, - cloud_client=cloud_client + test_use_case_directory, cloud_client=cloud_client ) if success: @@ -347,33 +342,28 @@ def execute_tests(self): def run_test_use_case_pytest( - test_use_case_directory: Path, - cloud_client: XsoarClient, - durations: int = 5) -> Tuple[bool, Union[TestSuite, None]]: + test_use_case_directory: Path, cloud_client: XsoarClient, durations: int = 5 +) -> Tuple[bool, Union[TestSuite, None]]: """Runs a test use case - Args: - test_use_case_directory (Path): Path to the test use case directory. - durations (int): Number of slow tests to show durations for. - cloud_client (XsoarClient): The XSIAM client used to do API calls to the tenant. + Args: + test_use_case_directory (Path): Path to the test use case directory. + durations (int): Number of slow tests to show durations for. + cloud_client (XsoarClient): The XSIAM client used to do API calls to the tenant. """ # Creating an instance of your results collector - test_use_case_suite = TestSuite(f"Test Use Case") + test_use_case_suite = TestSuite("Test Use Case") containing_pack = get_containing_pack(test_use_case_directory) - test_use_case_suite.add_property( - "file_name", str(test_use_case_directory) - ) - test_use_case_suite.add_property( - "pack_id", containing_pack - ) + test_use_case_suite.add_property("file_name", str(test_use_case_directory)) + test_use_case_suite.add_property("pack_id", containing_pack) if CI_PIPELINE_ID: test_use_case_suite.add_property("ci_pipeline_id", CI_PIPELINE_ID) test_dir = test_use_case_directory.parent copy_conftest(test_dir) - logger.info(f'before sending pytest {str(cloud_client.base_url)}') + logger.info(f"before sending pytest {str(cloud_client.base_url)}") pytest_args = [ f"--client_conf=base_url={str(cloud_client.server_config.base_api_url)}," f"api_key={cloud_client.server_config.api_key.get_secret_value()}," @@ -391,7 +381,9 @@ def run_test_use_case_pytest( status_code = pytest.main(pytest_args, plugins=[result_capture]) if status_code == pytest.ExitCode.OK: - logger.info(f"Pytest run tests in {test_use_case_directory} successfully") + logger.info( + f"Pytest run tests in {test_use_case_directory} successfully" + ) return True, test_use_case_suite elif status_code == pytest.ExitCode.TESTS_FAILED: logger.error( @@ -411,132 +403,132 @@ def run_test_use_case_pytest( }, ) def run_test_use_case( - ctx: typer.Context, - inputs: List[Path] = typer.Argument( - None, - exists=True, - dir_okay=True, - resolve_path=True, - show_default=False, - help="The path to a directory of a test use cases. May pass multiple paths to test multiple test use cases.", - ), - xsiam_url: Optional[str] = typer.Option( - None, - envvar="DEMISTO_BASE_URL", - help="The base url to the cloud tenant.", - rich_help_panel="Cloud Tenant Configuration", - show_default=False, - callback=tenant_config_cb, - ), - api_key: Optional[str] = typer.Option( - None, - envvar="DEMISTO_API_KEY", - help="The api key for the cloud tenant.", - rich_help_panel="XSIAM Tenant Configuration", - show_default=False, - callback=tenant_config_cb, - ), - auth_id: Optional[str] = typer.Option( - None, - envvar="XSIAM_AUTH_ID", - help="The auth id associated with the cloud api key being used.", - rich_help_panel="XSIAM Tenant Configuration", - show_default=False, - callback=tenant_config_cb, - ), - output_junit_file: Optional[Path] = typer.Option( - None, "-jp", "--junit-path", help="Path to the output JUnit XML file." - ), - sleep_interval: int = typer.Option( - XSIAM_CLIENT_SLEEP_INTERVAL, - "-si", - "--sleep_interval", - min=0, - show_default=True, - help="The number of seconds to wait between requests to the server.", - ), - retry_attempts: int = typer.Option( - XSIAM_CLIENT_RETRY_ATTEMPTS, - "-ra", - "--retry_attempts", - min=0, - show_default=True, - help="The number of times to retry the request against the server.", - ), - service_account: Optional[str] = typer.Option( - None, - "-sa", - "--service_account", - envvar="GCP_SERVICE_ACCOUNT", - help="GCP service account.", - show_default=False, - ), - cloud_servers_path: str = typer.Option( - "", - "-csp", - "--cloud_servers_path", - help="Path to secret cloud server metadata file.", - show_default=False, - ), - cloud_servers_api_keys: str = typer.Option( - "", - "-csak", - "--cloud_servers_api_keys", - help="Path to file with cloud Servers api keys.", - show_default=False, - ), - machine_assignment: str = typer.Option( - "", - "-ma", - "--machine_assignment", - help="the path to the machine assignment file.", - show_default=False, - ), - branch_name: str = typer.Option( - "master", - "-bn", - "--branch_name", - help="The current content branch name.", - show_default=True, - ), - build_number: str = typer.Option( - "", - "-bn", - "--build_number", - help="The build number.", - show_default=True, - ), - nightly: str = typer.Option( - "false", - "--nightly", - "-n", - help="Whether the command is being run in nightly mode.", - ), - artifacts_bucket: str = typer.Option( - None, - "-ab", - "--artifacts_bucket", - help="The artifacts bucket name to upload the results to", - show_default=False, - ), - console_log_threshold: str = typer.Option( - "INFO", - "-clt", - "--console-log-threshold", - help="Minimum logging threshold for the console logger.", - ), - file_log_threshold: str = typer.Option( - "DEBUG", - "-flt", - "--file-log-threshold", - help="Minimum logging threshold for the file logger.", - ), - log_file_path: Optional[str] = typer.Option( - None, - "-lp", - "--log-file-path", - help="Path to save log files onto.", - ) + ctx: typer.Context, + inputs: List[Path] = typer.Argument( + None, + exists=True, + dir_okay=True, + resolve_path=True, + show_default=False, + help="The path to a directory of a test use cases. May pass multiple paths to test multiple test use cases.", + ), + xsiam_url: Optional[str] = typer.Option( + None, + envvar="DEMISTO_BASE_URL", + help="The base url to the cloud tenant.", + rich_help_panel="Cloud Tenant Configuration", + show_default=False, + callback=tenant_config_cb, + ), + api_key: Optional[str] = typer.Option( + None, + envvar="DEMISTO_API_KEY", + help="The api key for the cloud tenant.", + rich_help_panel="XSIAM Tenant Configuration", + show_default=False, + callback=tenant_config_cb, + ), + auth_id: Optional[str] = typer.Option( + None, + envvar="XSIAM_AUTH_ID", + help="The auth id associated with the cloud api key being used.", + rich_help_panel="XSIAM Tenant Configuration", + show_default=False, + callback=tenant_config_cb, + ), + output_junit_file: Optional[Path] = typer.Option( + None, "-jp", "--junit-path", help="Path to the output JUnit XML file." + ), + sleep_interval: int = typer.Option( + XSIAM_CLIENT_SLEEP_INTERVAL, + "-si", + "--sleep_interval", + min=0, + show_default=True, + help="The number of seconds to wait between requests to the server.", + ), + retry_attempts: int = typer.Option( + XSIAM_CLIENT_RETRY_ATTEMPTS, + "-ra", + "--retry_attempts", + min=0, + show_default=True, + help="The number of times to retry the request against the server.", + ), + service_account: Optional[str] = typer.Option( + None, + "-sa", + "--service_account", + envvar="GCP_SERVICE_ACCOUNT", + help="GCP service account.", + show_default=False, + ), + cloud_servers_path: str = typer.Option( + "", + "-csp", + "--cloud_servers_path", + help="Path to secret cloud server metadata file.", + show_default=False, + ), + cloud_servers_api_keys: str = typer.Option( + "", + "-csak", + "--cloud_servers_api_keys", + help="Path to file with cloud Servers api keys.", + show_default=False, + ), + machine_assignment: str = typer.Option( + "", + "-ma", + "--machine_assignment", + help="the path to the machine assignment file.", + show_default=False, + ), + branch_name: str = typer.Option( + "master", + "-bn", + "--branch_name", + help="The current content branch name.", + show_default=True, + ), + build_number: str = typer.Option( + "", + "-bn", + "--build_number", + help="The build number.", + show_default=True, + ), + nightly: str = typer.Option( + "false", + "--nightly", + "-n", + help="Whether the command is being run in nightly mode.", + ), + artifacts_bucket: str = typer.Option( + None, + "-ab", + "--artifacts_bucket", + help="The artifacts bucket name to upload the results to", + show_default=False, + ), + console_log_threshold: str = typer.Option( + "INFO", + "-clt", + "--console-log-threshold", + help="Minimum logging threshold for the console logger.", + ), + file_log_threshold: str = typer.Option( + "DEBUG", + "-flt", + "--file-log-threshold", + help="Minimum logging threshold for the file logger.", + ), + log_file_path: Optional[str] = typer.Option( + None, + "-lp", + "--log-file-path", + help="Path to save log files onto.", + ), ): """ Test a test use case against an XSIAM tenant diff --git a/demisto_sdk/commands/test_content/test_use_case/tests/test_use_case_test.py b/demisto_sdk/commands/test_content/test_use_case/tests/test_use_case_test.py index 662b452bf86..75998c8db12 100644 --- a/demisto_sdk/commands/test_content/test_use_case/tests/test_use_case_test.py +++ b/demisto_sdk/commands/test_content/test_use_case/tests/test_use_case_test.py @@ -1,16 +1,14 @@ -from datetime import datetime from pathlib import Path -import pytest -from junitparser import TestSuite, TestCase, Failure, Skipped +import pytest +from junitparser import TestSuite +from pytest import ExitCode -from demisto_sdk.commands.common.content_constant_paths import CONTENT_PATH -from demisto_sdk.commands.test_content.test_use_case.test_use_case import get_containing_pack, copy_conftest, \ - run_test_use_case_pytest import demisto_sdk.commands.test_content.test_use_case.test_use_case as test_use_case - -from unittest.mock import Mock -from pytest import ExitCode +from demisto_sdk.commands.test_content.test_use_case.test_use_case import ( + get_containing_pack, + run_test_use_case_pytest, +) # Mock the dependencies @@ -18,9 +16,9 @@ def mocker_cloud_client(mocker): # Mock the XsoarClient cloud_client = mocker.Mock() - cloud_client.server_config.base_api_url = 'https://example.com' - cloud_client.server_config.api_key.get_secret_value.return_value = 'API_KEY' - cloud_client.server_config.auth_id = 'AUTH_ID' + cloud_client.server_config.base_api_url = "https://example.com" + cloud_client.server_config.api_key.get_secret_value.return_value = "API_KEY" + cloud_client.server_config.auth_id = "AUTH_ID" return cloud_client @@ -30,24 +28,28 @@ def mocker_test_use_case_directory(mocker): return mocker.Mock() -def test_run_test_use_case_pytest(mocker, mocker_cloud_client, mocker_test_use_case_directory): +def test_run_test_use_case_pytest( + mocker, mocker_cloud_client, mocker_test_use_case_directory +): """ - Given: parameters for running the tests. - When: running the test_use_case command. - Then: validate the correct params are used when running the pytest method. + Given: parameters for running the tests. + When: running the test_use_case command. + Then: validate the correct params are used when running the pytest method. """ test_result_mocker = mocker.Mock() - mocker.patch.object(test_use_case, 'get_containing_pack', return_value='/path/to/pack') - mocker.patch.object(test_use_case, 'copy_conftest') - mocker.patch.object(test_use_case, 'logger') - mocker.patch.object(test_use_case, 'TestResultCapture', return_value=test_result_mocker) - mocker.patch('pytest.main', return_value=ExitCode.OK) + mocker.patch.object( + test_use_case, "get_containing_pack", return_value="/path/to/pack" + ) + mocker.patch.object(test_use_case, "copy_conftest") + mocker.patch.object(test_use_case, "logger") + mocker.patch.object( + test_use_case, "TestResultCapture", return_value=test_result_mocker + ) + mocker.patch("pytest.main", return_value=ExitCode.OK) # Call the function to be tested result, test_use_case_suite = run_test_use_case_pytest( - mocker_test_use_case_directory, - mocker_cloud_client, - durations=5 + mocker_test_use_case_directory, mocker_cloud_client, durations=5 ) # Verify the expected behavior and assertions @@ -57,24 +59,24 @@ def test_run_test_use_case_pytest(mocker, mocker_cloud_client, mocker_test_use_c # Additional assertions for the mocked dependencies pytest.main.assert_called_once_with( [ - f"--client_conf=base_url=https://example.com," - f"api_key=API_KEY," - f"auth_id=AUTH_ID", + "--client_conf=base_url=https://example.com," + "api_key=API_KEY," + "auth_id=AUTH_ID", str(mocker_test_use_case_directory), "--durations=5", "--log-cli-level=CRITICAL", - "--no-summary" + "--no-summary", ], - plugins=[test_result_mocker] + plugins=[test_result_mocker], ) mocker_cloud_client.server_config.api_key.get_secret_value.assert_called_once() def test_get_containing_pack(): """ - Given: path to use case file - When: running the test_use_case command. - Then: validate the correct path to the pack dir is returned. + Given: path to use case file + When: running the test_use_case command. + Then: validate the correct path to the pack dir is returned. """ # Test case 1: Use case path is directly inside the "packs" directory use_case_path = Path("/path/to/packs/pack1/use_case.py") @@ -169,5 +171,3 @@ def test_pytest_runtest_logreport_skipped(mocker): assert testcase.classname == "test_module" assert testcase.time == 0.5 assert testcase.result[0].message == "Test skipped" - - diff --git a/demisto_sdk/commands/test_content/tools.py b/demisto_sdk/commands/test_content/tools.py index 1ae3066f850..9d536bd52ec 100644 --- a/demisto_sdk/commands/test_content/tools.py +++ b/demisto_sdk/commands/test_content/tools.py @@ -6,8 +6,13 @@ from pathlib import Path from pprint import pformat from subprocess import STDOUT, CalledProcessError, check_output -from typing import Dict, Optional, Set, Any, List +from typing import Any, Dict, List, Optional, Set from uuid import UUID + +import demisto_client +import pytz +import requests +import typer from tenacity import ( Retrying, before_sleep_log, @@ -15,11 +20,6 @@ stop_after_attempt, wait_fixed, ) -import pytz -import requests -import typer - -import demisto_client from demisto_sdk.commands.common.content_constant_paths import CONTENT_PATH from demisto_sdk.commands.common.logger import logger @@ -30,6 +30,7 @@ XSIAM_CLIENT_SLEEP_INTERVAL = 60 XSIAM_CLIENT_RETRY_ATTEMPTS = 5 + def update_server_configuration( client: demisto_client, server_configuration: Optional[Dict], @@ -222,7 +223,7 @@ def xsiam_get_installed_packs(xsiam_client: XsiamApiClient) -> List[Dict[str, An def tenant_config_cb( - ctx: typer.Context, param: typer.CallbackParam, value: Optional[str] + ctx: typer.Context, param: typer.CallbackParam, value: Optional[str] ): if ctx.resilient_parsing: return @@ -250,4 +251,3 @@ def logs_token_cb(ctx: typer.Context, param: typer.CallbackParam, value: Optiona ) raise typer.BadParameter(err_str) return value - From 0ce3da0506b5c0f137e3d17da40fc629f7e970d5 Mon Sep 17 00:00:00 2001 From: epintzov Date: Sun, 29 Dec 2024 11:58:37 +0200 Subject: [PATCH 41/58] fix unit test --- demisto_sdk/commands/test_content/test_use_case/test_use_case.py | 1 - .../test_content/test_use_case/tests/test_use_case_test.py | 1 - 2 files changed, 2 deletions(-) diff --git a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py index 9d06ea708e0..68169edd791 100644 --- a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py +++ b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py @@ -371,7 +371,6 @@ def run_test_use_case_pytest( str(test_use_case_directory), f"--durations={str(durations)}", "--log-cli-level=CRITICAL", - # "--no-summary" ] logger.info(f"Runnig pytest for file {test_use_case_directory}") diff --git a/demisto_sdk/commands/test_content/test_use_case/tests/test_use_case_test.py b/demisto_sdk/commands/test_content/test_use_case/tests/test_use_case_test.py index 75998c8db12..2348fa81622 100644 --- a/demisto_sdk/commands/test_content/test_use_case/tests/test_use_case_test.py +++ b/demisto_sdk/commands/test_content/test_use_case/tests/test_use_case_test.py @@ -65,7 +65,6 @@ def test_run_test_use_case_pytest( str(mocker_test_use_case_directory), "--durations=5", "--log-cli-level=CRITICAL", - "--no-summary", ], plugins=[test_result_mocker], ) From 7a7551535efa6a3285d4e4862021358947ab3ac3 Mon Sep 17 00:00:00 2001 From: epintzov Date: Sun, 29 Dec 2024 16:14:39 +0200 Subject: [PATCH 42/58] added search by uuid --- .../common/clients/xsiam/xsiam_api_client.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py index ddab59560de..04af6719372 100644 --- a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py +++ b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py @@ -294,19 +294,19 @@ def search_alerts( res = self._xdr_client.post(endpoint, json=body) return self._process_response(res.content, res.status_code, 200)["reply"] - def search_alerts_by_alert_name(self, alert_names=None, filters: list = None): - if alert_names is None: - alert_names = [] + def search_alerts_by_uuid(self, alert_uuids=None, filters: list = None): + if alert_uuids is None: + alert_uuids = [] alert_ids = [] - res = self.search_alerts(filters=filters) alerts = res.get("alerts") count = res.get("result_count") - while len(alerts) > 0 and len(alert_names) > len(alert_ids): + while len(alerts) > 0 and len(alert_uuids) > len(alert_ids): for alert in alerts: - if alert.get("name") in alert_names: - alert_ids.append(alert.get("alert_id")) + for uuid in alert_uuids: + if alert.get("description").endswith(uuid): + alert_ids.append(alert.get("alert_id")) res = self.search_alerts(filters=filters, search_from=count) alerts = res.get("alerts") From 952ebaff8a43d2d47c87e80ef60700bd5141994f Mon Sep 17 00:00:00 2001 From: epintzov Date: Sun, 29 Dec 2024 17:55:06 +0200 Subject: [PATCH 43/58] pre commit --- .../common/clients/xsiam/xsiam_api_client.py | 12 ++++++------ .../test_content/test_use_case/template_file.py | 9 +-------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py index 04af6719372..b22bbf457cb 100644 --- a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py +++ b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py @@ -294,13 +294,13 @@ def search_alerts( res = self._xdr_client.post(endpoint, json=body) return self._process_response(res.content, res.status_code, 200)["reply"] - def search_alerts_by_uuid(self, alert_uuids=None, filters: list = None): + def search_alerts_by_uuid(self, alert_uuids: list = None, filters: list = None): if alert_uuids is None: alert_uuids = [] - alert_ids = [] + alert_ids: list = [] res = self.search_alerts(filters=filters) - alerts = res.get("alerts") - count = res.get("result_count") + alerts: list = res.get("alerts") # type: ignore + count: int = res.get("result_count") # type: ignore while len(alerts) > 0 and len(alert_uuids) > len(alert_ids): for alert in alerts: @@ -309,8 +309,8 @@ def search_alerts_by_uuid(self, alert_uuids=None, filters: list = None): alert_ids.append(alert.get("alert_id")) res = self.search_alerts(filters=filters, search_from=count) - alerts = res.get("alerts") - count = res.get("result_count") + alerts = res.get("alerts") # type: ignore + count = res.get("result_count") # type: ignore return alert_ids diff --git a/demisto_sdk/commands/test_content/test_use_case/template_file.py b/demisto_sdk/commands/test_content/test_use_case/template_file.py index ebbc6b8d3df..f28549824cd 100644 --- a/demisto_sdk/commands/test_content/test_use_case/template_file.py +++ b/demisto_sdk/commands/test_content/test_use_case/template_file.py @@ -7,8 +7,6 @@ } """ -import json - import pytest from demisto_sdk.commands.common.clients import ( @@ -20,11 +18,6 @@ # Any additional imports your tests require -def util_load_json(path): - with open(path, encoding="utf-8") as f: - return json.loads(f.read()) - - @pytest.fixture(scope="class") def client_conf(request): # Manually parse command-line arguments @@ -45,7 +38,7 @@ class TestExample: @classmethod def setup_class(self): """Run once for the class before *all* tests""" - self.data = "test" + pass def some_helper_function(self, method): pass From 54540834be2339b5a8f6d4e230e8ab4e6ee72d2b Mon Sep 17 00:00:00 2001 From: epintzov Date: Mon, 30 Dec 2024 11:27:52 +0200 Subject: [PATCH 44/58] changelog --- .changelog/4650.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.changelog/4650.yml b/.changelog/4650.yml index 158f764f15f..5af4b801685 100644 --- a/.changelog/4650.yml +++ b/.changelog/4650.yml @@ -1,4 +1,4 @@ changes: -- description: Adding fixtures to xsiam client. +- description: Adding new command **test-use-case** to test use case flows on cloud machines. type: internal -pr_number: 4650 +pr_number: 4658 From b6cffea8434afb9a3396915e4a32e4240de0b3eb Mon Sep 17 00:00:00 2001 From: epintzov Date: Mon, 30 Dec 2024 11:30:45 +0200 Subject: [PATCH 45/58] changelog --- .changelog/4650.yml | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 .changelog/4650.yml diff --git a/.changelog/4650.yml b/.changelog/4650.yml deleted file mode 100644 index 5af4b801685..00000000000 --- a/.changelog/4650.yml +++ /dev/null @@ -1,4 +0,0 @@ -changes: -- description: Adding new command **test-use-case** to test use case flows on cloud machines. - type: internal -pr_number: 4658 From 8804d2720b24c3c39eec1bd09f9603b459703ce1 Mon Sep 17 00:00:00 2001 From: epintzov Date: Mon, 30 Dec 2024 11:47:17 +0200 Subject: [PATCH 46/58] changelog --- .changelog/4658.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .changelog/4658.yml diff --git a/.changelog/4658.yml b/.changelog/4658.yml new file mode 100644 index 00000000000..5af4b801685 --- /dev/null +++ b/.changelog/4658.yml @@ -0,0 +1,4 @@ +changes: +- description: Adding new command **test-use-case** to test use case flows on cloud machines. + type: internal +pr_number: 4658 From 7ded6692127961a014ab05f4dd7579ff8f3ceaf3 Mon Sep 17 00:00:00 2001 From: epintzov Date: Tue, 31 Dec 2024 11:16:21 +0200 Subject: [PATCH 47/58] lcas_id --- .../commands/common/clients/__init__.py | 46 ++++++++-------- .../commands/common/clients/configs.py | 2 + .../xsoar_saas/xsoar_saas_api_client.py | 1 + demisto_sdk/commands/common/constants.py | 1 + .../test_use_case/template_file.py | 1 + .../test_use_case/test_use_case.py | 53 ++++++------------- 6 files changed, 42 insertions(+), 62 deletions(-) diff --git a/demisto_sdk/commands/common/clients/__init__.py b/demisto_sdk/commands/common/clients/__init__.py index be5491256ef..4d263547148 100644 --- a/demisto_sdk/commands/common/clients/__init__.py +++ b/demisto_sdk/commands/common/clients/__init__.py @@ -28,6 +28,7 @@ DEMISTO_USERNAME, DEMISTO_VERIFY_SSL, MarketplaceVersions, + LCAS_ID ) from demisto_sdk.commands.common.logger import logger from demisto_sdk.commands.common.tools import string_to_bool @@ -35,7 +36,7 @@ @lru_cache def get_client_from_config( - client_config: XsoarClientConfig, raise_if_server_not_healthy: bool = True + client_config: XsoarClientConfig, raise_if_server_not_healthy: bool = True ) -> XsoarClient: """ Returns the correct Client (xsoar on prem, xsoar saas or xsiam) based on the clients config object @@ -65,14 +66,14 @@ def get_client_from_config( def get_client_from_marketplace( - marketplace: MarketplaceVersions, - base_url: Optional[str] = None, - api_key: Optional[str] = None, - auth_id: Optional[str] = None, - username: Optional[str] = None, - password: Optional[str] = None, - verify_ssl: Optional[bool] = None, - raise_if_server_not_healthy: bool = True, + marketplace: MarketplaceVersions, + base_url: Optional[str] = None, + api_key: Optional[str] = None, + auth_id: Optional[str] = None, + username: Optional[str] = None, + password: Optional[str] = None, + verify_ssl: Optional[bool] = None, + raise_if_server_not_healthy: bool = True, ) -> XsoarClient: """ Returns the client based on the marketplace. @@ -127,13 +128,14 @@ def get_client_from_marketplace( @lru_cache def get_client_from_server_type( - base_url: Optional[str] = None, - api_key: Optional[str] = None, - auth_id: Optional[str] = None, - username: Optional[str] = None, - password: Optional[str] = None, - verify_ssl: Optional[bool] = None, - raise_if_server_not_healthy: bool = True, + base_url: Optional[str] = None, + api_key: Optional[str] = None, + auth_id: Optional[str] = None, + username: Optional[str] = None, + password: Optional[str] = None, + lcas_id: Optional[str] = None, + verify_ssl: Optional[bool] = None, + raise_if_server_not_healthy: bool = True, ) -> XsoarClient: """ Returns the client based on the server type by doing api requests to determine which server it is @@ -144,6 +146,7 @@ def get_client_from_server_type( auth_id: the auth ID, if not provided will take from XSIAM_AUTH_ID env var username: the username to authenticate, relevant only for xsoar on prem password: the password to authenticate, relevant only for xsoar on prem + lcas_id: the lcas id of the current cloud machine. verify_ssl: whether in each request SSL should be verified, True if yes, False if not, if verify_ssl = None, will take the SSL verification from DEMISTO_VERIFY_SSL env var raise_if_server_not_healthy: whether to raise an exception if the server is not healthy @@ -156,6 +159,7 @@ def get_client_from_server_type( _auth_id = auth_id or os.getenv(AUTH_ID) _username = username or os.getenv(DEMISTO_USERNAME, "") _password = password or os.getenv(DEMISTO_PASSWORD, "") + _lcas_id = lcas_id or os.getenv(LCAS_ID, "") _verify_ssl = ( verify_ssl if verify_ssl is not None @@ -188,6 +192,7 @@ def get_client_from_server_type( api_key=_api_key, auth_id=_auth_id, verify_ssl=_verify_ssl, + lcas_id=_lcas_id ), should_validate_server_type=should_validate_server_type, raise_if_server_not_healthy=raise_if_server_not_healthy, @@ -202,6 +207,7 @@ def get_client_from_server_type( api_key=_api_key, auth_id=_auth_id, verify_ssl=_verify_ssl, + lcas_id=_lcas_id ), should_validate_server_type=should_validate_server_type, raise_if_server_not_healthy=raise_if_server_not_healthy, @@ -251,14 +257,6 @@ def parse_str_to_dict(input_str): return dict(pair.split("=") for pair in input_str.split(",") if "=" in pair) -# def get_client_conf_from_pytest_request(): -# # Manually parse command-line argument -# client_conf = os.getenv("CLIENT_CONF") -# if client_conf: -# return parse_str_to_dict(client_conf) -# return None - - def get_client_conf_from_pytest_request(request): # Manually parse command-line argument for arg in request.config.invocation_params.args: diff --git a/demisto_sdk/commands/common/clients/configs.py b/demisto_sdk/commands/common/clients/configs.py index 4efd8ffb118..6d550ad4450 100644 --- a/demisto_sdk/commands/common/clients/configs.py +++ b/demisto_sdk/commands/common/clients/configs.py @@ -12,6 +12,7 @@ DEMISTO_VERIFY_SSL, XSIAM_COLLECTOR_TOKEN, XSIAM_TOKEN, + LCAS_ID, ) from demisto_sdk.commands.common.tools import string_to_bool @@ -72,6 +73,7 @@ def __eq__(self, other): class XsoarSaasClientConfig(XsoarClientConfig): auth_id: str = Field(default=os.getenv(AUTH_ID), description="XSOAR/XSIAM Auth ID") + lcas_id: str = Field(default=os.getenv(LCAS_ID), description="XSOAR/XSIAM LCAS ID") @root_validator() def validate_auth_params(cls, values: Dict[str, Any]): diff --git a/demisto_sdk/commands/common/clients/xsoar_saas/xsoar_saas_api_client.py b/demisto_sdk/commands/common/clients/xsoar_saas/xsoar_saas_api_client.py index e0860891544..3bfdd8110f2 100644 --- a/demisto_sdk/commands/common/clients/xsoar_saas/xsoar_saas_api_client.py +++ b/demisto_sdk/commands/common/clients/xsoar_saas/xsoar_saas_api_client.py @@ -42,6 +42,7 @@ def __init__( "Content-Type": "application/json", } ) + self.lcas_id = config.lcas_id super().__init__( config, client=client, diff --git a/demisto_sdk/commands/common/constants.py b/demisto_sdk/commands/common/constants.py index 0013fced5fe..4db61fd7eca 100644 --- a/demisto_sdk/commands/common/constants.py +++ b/demisto_sdk/commands/common/constants.py @@ -52,6 +52,7 @@ XSIAM_TOKEN = "XSIAM_TOKEN" XSIAM_COLLECTOR_TOKEN = "XSIAM_COLLECTOR_TOKEN" DEMISTO_VERIFY_SSL = "DEMISTO_VERIFY_SSL" +LCAS_ID = "LCAS_ID" # Logging DEMISTO_SDK_LOG_FILE_PATH = "DEMISTO_SDK_LOG_FILE_PATH" diff --git a/demisto_sdk/commands/test_content/test_use_case/template_file.py b/demisto_sdk/commands/test_content/test_use_case/template_file.py index f28549824cd..e4d250a1ceb 100644 --- a/demisto_sdk/commands/test_content/test_use_case/template_file.py +++ b/demisto_sdk/commands/test_content/test_use_case/template_file.py @@ -52,6 +52,7 @@ def teardown_class(self): def test_feature_one_manual_true(self, api_client: XsiamClient): """Test feature one""" a = api_client.list_indicators() + assert a is not None def test_feature_two(self, api_client: XsiamClient): diff --git a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py index 68169edd791..48cc2dbd152 100644 --- a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py +++ b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py @@ -32,9 +32,6 @@ ParallelLoggingManager, ) from demisto_sdk.commands.test_content.tools import ( - XSIAM_CLIENT_RETRY_ATTEMPTS, - XSIAM_CLIENT_SLEEP_INTERVAL, - create_retrying_caller, duration_since_start_time, get_relative_path_to_content, get_ui_url, @@ -143,9 +140,6 @@ def __init__( self, nightly: bool, build_number: Optional[str], - branch_name: Optional[str], - retry_attempts: int, - sleep_interval: int, logging_module: ParallelLoggingManager, cloud_servers_path: str, cloud_servers_api_keys: str, @@ -156,16 +150,16 @@ def __init__( auth_id: Optional[str], inputs: Optional[List[Path]], machine_assignment: str, + lcas_id: str, ctx: typer.Context, ): self.logging_module: ParallelLoggingManager = logging_module - self.retrying_caller = create_retrying_caller(retry_attempts, sleep_interval) self.ctx = ctx # --------------------------- overall build configuration ------------------------------- self.is_nightly = nightly self.build_number = build_number - self.build_name = branch_name + self.lcas_id = lcas_id # -------------------------- Manual run on a single instance -------------------------- self.cloud_url = cloud_url @@ -301,7 +295,7 @@ def execute_tests(self): ) success, test_use_case_test_suite = run_test_use_case_pytest( - test_use_case_directory, cloud_client=cloud_client + test_use_case_directory, cloud_client=cloud_client, lcas_id=self.build_context.lcas_id ) if success: @@ -342,7 +336,7 @@ def execute_tests(self): def run_test_use_case_pytest( - test_use_case_directory: Path, cloud_client: XsoarClient, durations: int = 5 + test_use_case_directory: Path, cloud_client: XsoarClient, durations: int = 5, lcas_id: str = None ) -> Tuple[bool, Union[TestSuite, None]]: """Runs a test use case @@ -367,13 +361,14 @@ def run_test_use_case_pytest( pytest_args = [ f"--client_conf=base_url={str(cloud_client.server_config.base_api_url)}," f"api_key={cloud_client.server_config.api_key.get_secret_value()}," - f"auth_id={cloud_client.server_config.auth_id}", + f"auth_id={cloud_client.server_config.auth_id}," + f"lcas_id={lcas_id}", str(test_use_case_directory), f"--durations={str(durations)}", "--log-cli-level=CRITICAL", ] - logger.info(f"Runnig pytest for file {test_use_case_directory}") + logger.info(f"Running pytest for file {test_use_case_directory}") # Running pytest result_capture = TestResultCapture(test_use_case_suite) @@ -438,22 +433,6 @@ def run_test_use_case( output_junit_file: Optional[Path] = typer.Option( None, "-jp", "--junit-path", help="Path to the output JUnit XML file." ), - sleep_interval: int = typer.Option( - XSIAM_CLIENT_SLEEP_INTERVAL, - "-si", - "--sleep_interval", - min=0, - show_default=True, - help="The number of seconds to wait between requests to the server.", - ), - retry_attempts: int = typer.Option( - XSIAM_CLIENT_RETRY_ATTEMPTS, - "-ra", - "--retry_attempts", - min=0, - show_default=True, - help="The number of times to retry the request against the server.", - ), service_account: Optional[str] = typer.Option( None, "-sa", @@ -483,13 +462,6 @@ def run_test_use_case( help="the path to the machine assignment file.", show_default=False, ), - branch_name: str = typer.Option( - "master", - "-bn", - "--branch_name", - help="The current content branch name.", - show_default=True, - ), build_number: str = typer.Option( "", "-bn", @@ -510,6 +482,13 @@ def run_test_use_case( help="The artifacts bucket name to upload the results to", show_default=False, ), + lacs_id: str = typer.Option( + None, + "-li", + "--lcas_id", + help="The machine LCAS ID", + show_default=False, + ), console_log_threshold: str = typer.Option( "INFO", "-clt", @@ -561,9 +540,6 @@ def run_test_use_case( build_context = BuildContext( nightly=is_nightly, build_number=build_number, - branch_name=branch_name, - retry_attempts=retry_attempts, - sleep_interval=sleep_interval, logging_module=logging_module, cloud_servers_path=cloud_servers_path, cloud_servers_api_keys=cloud_servers_api_keys, @@ -575,6 +551,7 @@ def run_test_use_case( api_key=api_key, auth_id=auth_id, inputs=inputs, + lcas_id=lacs_id ) logging_module.info( From be0a042bf4f7ae09b16ae7d2c11cea4eaaad30a7 Mon Sep 17 00:00:00 2001 From: epintzov Date: Tue, 31 Dec 2024 11:24:33 +0200 Subject: [PATCH 48/58] pre-commit --- .../commands/common/clients/__init__.py | 40 +++++++++---------- .../commands/common/clients/configs.py | 2 +- .../test_use_case/test_use_case.py | 11 +++-- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/demisto_sdk/commands/common/clients/__init__.py b/demisto_sdk/commands/common/clients/__init__.py index 4d263547148..163f2047fae 100644 --- a/demisto_sdk/commands/common/clients/__init__.py +++ b/demisto_sdk/commands/common/clients/__init__.py @@ -27,8 +27,8 @@ DEMISTO_PASSWORD, DEMISTO_USERNAME, DEMISTO_VERIFY_SSL, + LCAS_ID, MarketplaceVersions, - LCAS_ID ) from demisto_sdk.commands.common.logger import logger from demisto_sdk.commands.common.tools import string_to_bool @@ -36,7 +36,7 @@ @lru_cache def get_client_from_config( - client_config: XsoarClientConfig, raise_if_server_not_healthy: bool = True + client_config: XsoarClientConfig, raise_if_server_not_healthy: bool = True ) -> XsoarClient: """ Returns the correct Client (xsoar on prem, xsoar saas or xsiam) based on the clients config object @@ -66,14 +66,14 @@ def get_client_from_config( def get_client_from_marketplace( - marketplace: MarketplaceVersions, - base_url: Optional[str] = None, - api_key: Optional[str] = None, - auth_id: Optional[str] = None, - username: Optional[str] = None, - password: Optional[str] = None, - verify_ssl: Optional[bool] = None, - raise_if_server_not_healthy: bool = True, + marketplace: MarketplaceVersions, + base_url: Optional[str] = None, + api_key: Optional[str] = None, + auth_id: Optional[str] = None, + username: Optional[str] = None, + password: Optional[str] = None, + verify_ssl: Optional[bool] = None, + raise_if_server_not_healthy: bool = True, ) -> XsoarClient: """ Returns the client based on the marketplace. @@ -128,14 +128,14 @@ def get_client_from_marketplace( @lru_cache def get_client_from_server_type( - base_url: Optional[str] = None, - api_key: Optional[str] = None, - auth_id: Optional[str] = None, - username: Optional[str] = None, - password: Optional[str] = None, - lcas_id: Optional[str] = None, - verify_ssl: Optional[bool] = None, - raise_if_server_not_healthy: bool = True, + base_url: Optional[str] = None, + api_key: Optional[str] = None, + auth_id: Optional[str] = None, + username: Optional[str] = None, + password: Optional[str] = None, + lcas_id: Optional[str] = None, + verify_ssl: Optional[bool] = None, + raise_if_server_not_healthy: bool = True, ) -> XsoarClient: """ Returns the client based on the server type by doing api requests to determine which server it is @@ -192,7 +192,7 @@ def get_client_from_server_type( api_key=_api_key, auth_id=_auth_id, verify_ssl=_verify_ssl, - lcas_id=_lcas_id + lcas_id=_lcas_id, ), should_validate_server_type=should_validate_server_type, raise_if_server_not_healthy=raise_if_server_not_healthy, @@ -207,7 +207,7 @@ def get_client_from_server_type( api_key=_api_key, auth_id=_auth_id, verify_ssl=_verify_ssl, - lcas_id=_lcas_id + lcas_id=_lcas_id, ), should_validate_server_type=should_validate_server_type, raise_if_server_not_healthy=raise_if_server_not_healthy, diff --git a/demisto_sdk/commands/common/clients/configs.py b/demisto_sdk/commands/common/clients/configs.py index 6d550ad4450..fb910e659a9 100644 --- a/demisto_sdk/commands/common/clients/configs.py +++ b/demisto_sdk/commands/common/clients/configs.py @@ -10,9 +10,9 @@ DEMISTO_PASSWORD, DEMISTO_USERNAME, DEMISTO_VERIFY_SSL, + LCAS_ID, XSIAM_COLLECTOR_TOKEN, XSIAM_TOKEN, - LCAS_ID, ) from demisto_sdk.commands.common.tools import string_to_bool diff --git a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py index 48cc2dbd152..1dcdd1666ad 100644 --- a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py +++ b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py @@ -295,7 +295,9 @@ def execute_tests(self): ) success, test_use_case_test_suite = run_test_use_case_pytest( - test_use_case_directory, cloud_client=cloud_client, lcas_id=self.build_context.lcas_id + test_use_case_directory, + cloud_client=cloud_client, + lcas_id=self.build_context.lcas_id, ) if success: @@ -336,7 +338,10 @@ def execute_tests(self): def run_test_use_case_pytest( - test_use_case_directory: Path, cloud_client: XsoarClient, durations: int = 5, lcas_id: str = None + test_use_case_directory: Path, + cloud_client: XsoarClient, + durations: int = 5, + lcas_id: str = None, ) -> Tuple[bool, Union[TestSuite, None]]: """Runs a test use case @@ -551,7 +556,7 @@ def run_test_use_case( api_key=api_key, auth_id=auth_id, inputs=inputs, - lcas_id=lacs_id + lcas_id=lacs_id, ) logging_module.info( From 6b47ee8a81294cf3e4904efc059efab396e2b490 Mon Sep 17 00:00:00 2001 From: epintzov Date: Wed, 1 Jan 2025 10:32:57 +0200 Subject: [PATCH 49/58] added sanitize --- .../test_use_case/test_use_case.py | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py index 1dcdd1666ad..223ff31c608 100644 --- a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py +++ b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py @@ -1,5 +1,6 @@ import logging # noqa: TID251 # specific case, passed as argument to 3rd party import os +import re import shutil from pathlib import Path from threading import Thread @@ -82,9 +83,8 @@ def pytest_runtest_logreport(self, report): if report.outcome == "passed": self.junit_testsuite.add_testcase(test_case) elif report.outcome == "failed": - failure = Failure( - report.longreprtext if report.longrepr else "Test failed" - ) + error_text = self._sanitize_sensitive_data(report.longreprtext if report.longrepr else "Test failed") + failure = Failure(error_text) test_case.result = failure self.junit_testsuite.add_testcase(test_case) elif report.outcome == "skipped": @@ -92,6 +92,23 @@ def pytest_runtest_logreport(self, report): test_case.result = skipped self.junit_testsuite.add_testcase(test_case) + def _sanitize_sensitive_data(self, text): + """ + Remove or redact sensitive data from the given text. + + Args: + text (str): The text to sanitize. + + Returns: + str: The sanitized text with sensitive data removed or redacted. + """ + + pattern = r"('Authorization':\s*')([^']+)(')" + # Replace the sensitive part with '[REDACTED]' + sanitized_text = re.sub(pattern, r"\1[REDACTED]\3", text) + + return sanitized_text + class TestResults: def __init__( From aa14934ba94a0432b64959fa7df56aebfe0ff8a9 Mon Sep 17 00:00:00 2001 From: epintzov Date: Wed, 1 Jan 2025 10:33:59 +0200 Subject: [PATCH 50/58] added filename --- .../commands/test_content/test_use_case/test_use_case.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py index 223ff31c608..66bbb1c426d 100644 --- a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py +++ b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py @@ -371,7 +371,7 @@ def run_test_use_case_pytest( test_use_case_suite = TestSuite("Test Use Case") containing_pack = get_containing_pack(test_use_case_directory) - test_use_case_suite.add_property("file_name", str(test_use_case_directory)) + test_use_case_suite.add_property("file_name", str(test_use_case_directory.name)) test_use_case_suite.add_property("pack_id", containing_pack) if CI_PIPELINE_ID: test_use_case_suite.add_property("ci_pipeline_id", CI_PIPELINE_ID) From 3e852c826f2f607c638e2e6c9aff085e48899e82 Mon Sep 17 00:00:00 2001 From: epintzov Date: Thu, 2 Jan 2025 12:16:14 +0200 Subject: [PATCH 51/58] poetry --- poetry.lock | 1568 ++++++++++++++++++++++++------------------------ pyproject.toml | 2 + 2 files changed, 799 insertions(+), 771 deletions(-) diff --git a/poetry.lock b/poetry.lock index 67ec38c06c5..09371e42a6d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2,98 +2,98 @@ [[package]] name = "aiohappyeyeballs" -version = "2.4.3" +version = "2.4.4" description = "Happy Eyeballs for asyncio" optional = true python-versions = ">=3.8" files = [ - {file = "aiohappyeyeballs-2.4.3-py3-none-any.whl", hash = "sha256:8a7a83727b2756f394ab2895ea0765a0a8c475e3c71e98d43d76f22b4b435572"}, - {file = "aiohappyeyeballs-2.4.3.tar.gz", hash = "sha256:75cf88a15106a5002a8eb1dab212525c00d1f4c0fa96e551c9fbe6f09a621586"}, + {file = "aiohappyeyeballs-2.4.4-py3-none-any.whl", hash = "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8"}, + {file = "aiohappyeyeballs-2.4.4.tar.gz", hash = "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745"}, ] [[package]] name = "aiohttp" -version = "3.11.7" +version = "3.11.11" description = "Async http client/server framework (asyncio)" optional = true python-versions = ">=3.9" files = [ - {file = "aiohttp-3.11.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8bedb1f6cb919af3b6353921c71281b1491f948ca64408871465d889b4ee1b66"}, - {file = "aiohttp-3.11.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f5022504adab881e2d801a88b748ea63f2a9d130e0b2c430824682a96f6534be"}, - {file = "aiohttp-3.11.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e22d1721c978a6494adc824e0916f9d187fa57baeda34b55140315fa2f740184"}, - {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e993676c71288618eb07e20622572b1250d8713e7e00ab3aabae28cb70f3640d"}, - {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e13a05db87d3b241c186d0936808d0e4e12decc267c617d54e9c643807e968b6"}, - {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ba8d043fed7ffa117024d7ba66fdea011c0e7602327c6d73cacaea38abe4491"}, - {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dda3ed0a7869d2fa16aa41f9961ade73aa2c2e3b2fcb0a352524e7b744881889"}, - {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43bfd25113c1e98aec6c70e26d5f4331efbf4aa9037ba9ad88f090853bf64d7f"}, - {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3dd3e7e7c9ef3e7214f014f1ae260892286647b3cf7c7f1b644a568fd410f8ca"}, - {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:78c657ece7a73b976905ab9ec8be9ef2df12ed8984c24598a1791c58ce3b4ce4"}, - {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:db70a47987e34494b451a334605bee57a126fe8d290511349e86810b4be53b01"}, - {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:9e67531370a3b07e49b280c1f8c2df67985c790ad2834d1b288a2f13cd341c5f"}, - {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9202f184cc0582b1db15056f2225ab4c1e3dac4d9ade50dd0613ac3c46352ac2"}, - {file = "aiohttp-3.11.7-cp310-cp310-win32.whl", hash = "sha256:2257bdd5cf54a4039a4337162cd8048f05a724380a2283df34620f55d4e29341"}, - {file = "aiohttp-3.11.7-cp310-cp310-win_amd64.whl", hash = "sha256:b7215bf2b53bc6cb35808149980c2ae80a4ae4e273890ac85459c014d5aa60ac"}, - {file = "aiohttp-3.11.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cea52d11e02123f125f9055dfe0ccf1c3857225fb879e4a944fae12989e2aef2"}, - {file = "aiohttp-3.11.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3ce18f703b7298e7f7633efd6a90138d99a3f9a656cb52c1201e76cb5d79cf08"}, - {file = "aiohttp-3.11.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:670847ee6aeb3a569cd7cdfbe0c3bec1d44828bbfbe78c5d305f7f804870ef9e"}, - {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dda726f89bfa5c465ba45b76515135a3ece0088dfa2da49b8bb278f3bdeea12"}, - {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25b74a811dba37c7ea6a14d99eb9402d89c8d739d50748a75f3cf994cf19c43"}, - {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5522ee72f95661e79db691310290c4618b86dff2d9b90baedf343fd7a08bf79"}, - {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fbf41a6bbc319a7816ae0f0177c265b62f2a59ad301a0e49b395746eb2a9884"}, - {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:59ee1925b5a5efdf6c4e7be51deee93984d0ac14a6897bd521b498b9916f1544"}, - {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:24054fce8c6d6f33a3e35d1c603ef1b91bbcba73e3f04a22b4f2f27dac59b347"}, - {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:351849aca2c6f814575c1a485c01c17a4240413f960df1bf9f5deb0003c61a53"}, - {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:12724f3a211fa243570e601f65a8831372caf1a149d2f1859f68479f07efec3d"}, - {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:7ea4490360b605804bea8173d2d086b6c379d6bb22ac434de605a9cbce006e7d"}, - {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e0bf378db07df0a713a1e32381a1b277e62ad106d0dbe17b5479e76ec706d720"}, - {file = "aiohttp-3.11.7-cp311-cp311-win32.whl", hash = "sha256:cd8d62cab363dfe713067027a5adb4907515861f1e4ce63e7be810b83668b847"}, - {file = "aiohttp-3.11.7-cp311-cp311-win_amd64.whl", hash = "sha256:bf0e6cce113596377cadda4e3ac5fb89f095bd492226e46d91b4baef1dd16f60"}, - {file = "aiohttp-3.11.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4bb7493c3e3a36d3012b8564bd0e2783259ddd7ef3a81a74f0dbfa000fce48b7"}, - {file = "aiohttp-3.11.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e143b0ef9cb1a2b4f74f56d4fbe50caa7c2bb93390aff52f9398d21d89bc73ea"}, - {file = "aiohttp-3.11.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f7c58a240260822dc07f6ae32a0293dd5bccd618bb2d0f36d51c5dbd526f89c0"}, - {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d20cfe63a1c135d26bde8c1d0ea46fd1200884afbc523466d2f1cf517d1fe33"}, - {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12e4d45847a174f77b2b9919719203769f220058f642b08504cf8b1cf185dacf"}, - {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf4efa2d01f697a7dbd0509891a286a4af0d86902fc594e20e3b1712c28c0106"}, - {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee6a4cdcbf54b8083dc9723cdf5f41f722c00db40ccf9ec2616e27869151129"}, - {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c6095aaf852c34f42e1bd0cf0dc32d1e4b48a90bfb5054abdbb9d64b36acadcb"}, - {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1cf03d27885f8c5ebf3993a220cc84fc66375e1e6e812731f51aab2b2748f4a6"}, - {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:1a17f6a230f81eb53282503823f59d61dff14fb2a93847bf0399dc8e87817307"}, - {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:481f10a1a45c5f4c4a578bbd74cff22eb64460a6549819242a87a80788461fba"}, - {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:db37248535d1ae40735d15bdf26ad43be19e3d93ab3f3dad8507eb0f85bb8124"}, - {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9d18a8b44ec8502a7fde91446cd9c9b95ce7c49f1eacc1fb2358b8907d4369fd"}, - {file = "aiohttp-3.11.7-cp312-cp312-win32.whl", hash = "sha256:3d1c9c15d3999107cbb9b2d76ca6172e6710a12fda22434ee8bd3f432b7b17e8"}, - {file = "aiohttp-3.11.7-cp312-cp312-win_amd64.whl", hash = "sha256:018f1b04883a12e77e7fc161934c0f298865d3a484aea536a6a2ca8d909f0ba0"}, - {file = "aiohttp-3.11.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:241a6ca732d2766836d62c58c49ca7a93d08251daef0c1e3c850df1d1ca0cbc4"}, - {file = "aiohttp-3.11.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:aa3705a8d14de39898da0fbad920b2a37b7547c3afd2a18b9b81f0223b7d0f68"}, - {file = "aiohttp-3.11.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9acfc7f652b31853eed3b92095b0acf06fd5597eeea42e939bd23a17137679d5"}, - {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcefcf2915a2dbdbce37e2fc1622129a1918abfe3d06721ce9f6cdac9b6d2eaa"}, - {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c1f6490dd1862af5aae6cfcf2a274bffa9a5b32a8f5acb519a7ecf5a99a88866"}, - {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac5462582d6561c1c1708853a9faf612ff4e5ea5e679e99be36143d6eabd8e"}, - {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c1a6309005acc4b2bcc577ba3b9169fea52638709ffacbd071f3503264620da"}, - {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5b973cce96793725ef63eb449adfb74f99c043c718acb76e0d2a447ae369962"}, - {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ce91a24aac80de6be8512fb1c4838a9881aa713f44f4e91dd7bb3b34061b497d"}, - {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:875f7100ce0e74af51d4139495eec4025affa1a605280f23990b6434b81df1bd"}, - {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c171fc35d3174bbf4787381716564042a4cbc008824d8195eede3d9b938e29a8"}, - {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ee9afa1b0d2293c46954f47f33e150798ad68b78925e3710044e0d67a9487791"}, - {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8360c7cc620abb320e1b8d603c39095101391a82b1d0be05fb2225471c9c5c52"}, - {file = "aiohttp-3.11.7-cp313-cp313-win32.whl", hash = "sha256:7a9318da4b4ada9a67c1dd84d1c0834123081e746bee311a16bb449f363d965e"}, - {file = "aiohttp-3.11.7-cp313-cp313-win_amd64.whl", hash = "sha256:fc6da202068e0a268e298d7cd09b6e9f3997736cd9b060e2750963754552a0a9"}, - {file = "aiohttp-3.11.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:17829f37c0d31d89aa6b8b010475a10233774771f9b6dc2cc352ea4f8ce95d9a"}, - {file = "aiohttp-3.11.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d6177077a31b1aecfc3c9070bd2f11419dbb4a70f30f4c65b124714f525c2e48"}, - {file = "aiohttp-3.11.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:badda65ac99555791eed75e234afb94686ed2317670c68bff8a4498acdaee935"}, - {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0de6466b9d742b4ee56fe1b2440706e225eb48c77c63152b1584864a236e7a50"}, - {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04b0cc74d5a882c9dacaeeccc1444f0233212b6f5be8bc90833feef1e1ce14b9"}, - {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c7af3e50e5903d21d7b935aceed901cc2475463bc16ddd5587653548661fdb"}, - {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c63f898f683d1379b9be5afc3dd139e20b30b0b1e0bf69a3fc3681f364cf1629"}, - {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fdadc3f6a32d6eca45f9a900a254757fd7855dfb2d8f8dcf0e88f0fae3ff8eb1"}, - {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d329300fb23e14ed1f8c6d688dfd867d1dcc3b1d7cd49b7f8c5b44e797ce0932"}, - {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:5578cf40440eafcb054cf859964bc120ab52ebe0e0562d2b898126d868749629"}, - {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:7b2f8107a3c329789f3c00b2daad0e35f548d0a55cda6291579136622099a46e"}, - {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:43dd89a6194f6ab02a3fe36b09e42e2df19c211fc2050ce37374d96f39604997"}, - {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d2fa6fc7cc865d26ff42480ac9b52b8c9b7da30a10a6442a9cdf429de840e949"}, - {file = "aiohttp-3.11.7-cp39-cp39-win32.whl", hash = "sha256:a7d9a606355655617fee25dd7e54d3af50804d002f1fd3118dd6312d26692d70"}, - {file = "aiohttp-3.11.7-cp39-cp39-win_amd64.whl", hash = "sha256:53c921b58fdc6485d6b2603e0132bb01cd59b8f0620ffc0907f525e0ba071687"}, - {file = "aiohttp-3.11.7.tar.gz", hash = "sha256:01a8aca4af3da85cea5c90141d23f4b0eee3cbecfd33b029a45a80f28c66c668"}, + {file = "aiohttp-3.11.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a60804bff28662cbcf340a4d61598891f12eea3a66af48ecfdc975ceec21e3c8"}, + {file = "aiohttp-3.11.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4b4fa1cb5f270fb3eab079536b764ad740bb749ce69a94d4ec30ceee1b5940d5"}, + {file = "aiohttp-3.11.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:731468f555656767cda219ab42e033355fe48c85fbe3ba83a349631541715ba2"}, + {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb23d8bb86282b342481cad4370ea0853a39e4a32a0042bb52ca6bdde132df43"}, + {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f047569d655f81cb70ea5be942ee5d4421b6219c3f05d131f64088c73bb0917f"}, + {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd7659baae9ccf94ae5fe8bfaa2c7bc2e94d24611528395ce88d009107e00c6d"}, + {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af01e42ad87ae24932138f154105e88da13ce7d202a6de93fafdafb2883a00ef"}, + {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5854be2f3e5a729800bac57a8d76af464e160f19676ab6aea74bde18ad19d438"}, + {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6526e5fb4e14f4bbf30411216780c9967c20c5a55f2f51d3abd6de68320cc2f3"}, + {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:85992ee30a31835fc482468637b3e5bd085fa8fe9392ba0bdcbdc1ef5e9e3c55"}, + {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:88a12ad8ccf325a8a5ed80e6d7c3bdc247d66175afedbe104ee2aaca72960d8e"}, + {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0a6d3fbf2232e3a08c41eca81ae4f1dff3d8f1a30bae415ebe0af2d2458b8a33"}, + {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:84a585799c58b795573c7fa9b84c455adf3e1d72f19a2bf498b54a95ae0d194c"}, + {file = "aiohttp-3.11.11-cp310-cp310-win32.whl", hash = "sha256:bfde76a8f430cf5c5584553adf9926534352251d379dcb266ad2b93c54a29745"}, + {file = "aiohttp-3.11.11-cp310-cp310-win_amd64.whl", hash = "sha256:0fd82b8e9c383af11d2b26f27a478640b6b83d669440c0a71481f7c865a51da9"}, + {file = "aiohttp-3.11.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ba74ec819177af1ef7f59063c6d35a214a8fde6f987f7661f4f0eecc468a8f76"}, + {file = "aiohttp-3.11.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4af57160800b7a815f3fe0eba9b46bf28aafc195555f1824555fa2cfab6c1538"}, + {file = "aiohttp-3.11.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ffa336210cf9cd8ed117011085817d00abe4c08f99968deef0013ea283547204"}, + {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81b8fe282183e4a3c7a1b72f5ade1094ed1c6345a8f153506d114af5bf8accd9"}, + {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3af41686ccec6a0f2bdc66686dc0f403c41ac2089f80e2214a0f82d001052c03"}, + {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70d1f9dde0e5dd9e292a6d4d00058737052b01f3532f69c0c65818dac26dc287"}, + {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:249cc6912405917344192b9f9ea5cd5b139d49e0d2f5c7f70bdfaf6b4dbf3a2e"}, + {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0eb98d90b6690827dcc84c246811feeb4e1eea683c0eac6caed7549be9c84665"}, + {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec82bf1fda6cecce7f7b915f9196601a1bd1a3079796b76d16ae4cce6d0ef89b"}, + {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9fd46ce0845cfe28f108888b3ab17abff84ff695e01e73657eec3f96d72eef34"}, + {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:bd176afcf8f5d2aed50c3647d4925d0db0579d96f75a31e77cbaf67d8a87742d"}, + {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ec2aa89305006fba9ffb98970db6c8221541be7bee4c1d027421d6f6df7d1ce2"}, + {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:92cde43018a2e17d48bb09c79e4d4cb0e236de5063ce897a5e40ac7cb4878773"}, + {file = "aiohttp-3.11.11-cp311-cp311-win32.whl", hash = "sha256:aba807f9569455cba566882c8938f1a549f205ee43c27b126e5450dc9f83cc62"}, + {file = "aiohttp-3.11.11-cp311-cp311-win_amd64.whl", hash = "sha256:ae545f31489548c87b0cced5755cfe5a5308d00407000e72c4fa30b19c3220ac"}, + {file = "aiohttp-3.11.11-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e595c591a48bbc295ebf47cb91aebf9bd32f3ff76749ecf282ea7f9f6bb73886"}, + {file = "aiohttp-3.11.11-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3ea1b59dc06396b0b424740a10a0a63974c725b1c64736ff788a3689d36c02d2"}, + {file = "aiohttp-3.11.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8811f3f098a78ffa16e0ea36dffd577eb031aea797cbdba81be039a4169e242c"}, + {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7227b87a355ce1f4bf83bfae4399b1f5bb42e0259cb9405824bd03d2f4336a"}, + {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d40f9da8cabbf295d3a9dae1295c69975b86d941bc20f0a087f0477fa0a66231"}, + {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffb3dc385f6bb1568aa974fe65da84723210e5d9707e360e9ecb51f59406cd2e"}, + {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8f5f7515f3552d899c61202d99dcb17d6e3b0de777900405611cd747cecd1b8"}, + {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3499c7ffbfd9c6a3d8d6a2b01c26639da7e43d47c7b4f788016226b1e711caa8"}, + {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8e2bf8029dbf0810c7bfbc3e594b51c4cc9101fbffb583a3923aea184724203c"}, + {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b6212a60e5c482ef90f2d788835387070a88d52cf6241d3916733c9176d39eab"}, + {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d119fafe7b634dbfa25a8c597718e69a930e4847f0b88e172744be24515140da"}, + {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:6fba278063559acc730abf49845d0e9a9e1ba74f85f0ee6efd5803f08b285853"}, + {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:92fc484e34b733704ad77210c7957679c5c3877bd1e6b6d74b185e9320cc716e"}, + {file = "aiohttp-3.11.11-cp312-cp312-win32.whl", hash = "sha256:9f5b3c1ed63c8fa937a920b6c1bec78b74ee09593b3f5b979ab2ae5ef60d7600"}, + {file = "aiohttp-3.11.11-cp312-cp312-win_amd64.whl", hash = "sha256:1e69966ea6ef0c14ee53ef7a3d68b564cc408121ea56c0caa2dc918c1b2f553d"}, + {file = "aiohttp-3.11.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:541d823548ab69d13d23730a06f97460f4238ad2e5ed966aaf850d7c369782d9"}, + {file = "aiohttp-3.11.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:929f3ed33743a49ab127c58c3e0a827de0664bfcda566108989a14068f820194"}, + {file = "aiohttp-3.11.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0882c2820fd0132240edbb4a51eb8ceb6eef8181db9ad5291ab3332e0d71df5f"}, + {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b63de12e44935d5aca7ed7ed98a255a11e5cb47f83a9fded7a5e41c40277d104"}, + {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa54f8ef31d23c506910c21163f22b124facb573bff73930735cf9fe38bf7dff"}, + {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a344d5dc18074e3872777b62f5f7d584ae4344cd6006c17ba12103759d407af3"}, + {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b7fb429ab1aafa1f48578eb315ca45bd46e9c37de11fe45c7f5f4138091e2f1"}, + {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c341c7d868750e31961d6d8e60ff040fb9d3d3a46d77fd85e1ab8e76c3e9a5c4"}, + {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ed9ee95614a71e87f1a70bc81603f6c6760128b140bc4030abe6abaa988f1c3d"}, + {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:de8d38f1c2810fa2a4f1d995a2e9c70bb8737b18da04ac2afbf3971f65781d87"}, + {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a9b7371665d4f00deb8f32208c7c5e652059b0fda41cf6dbcac6114a041f1cc2"}, + {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:620598717fce1b3bd14dd09947ea53e1ad510317c85dda2c9c65b622edc96b12"}, + {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bf8d9bfee991d8acc72d060d53860f356e07a50f0e0d09a8dfedea1c554dd0d5"}, + {file = "aiohttp-3.11.11-cp313-cp313-win32.whl", hash = "sha256:9d73ee3725b7a737ad86c2eac5c57a4a97793d9f442599bea5ec67ac9f4bdc3d"}, + {file = "aiohttp-3.11.11-cp313-cp313-win_amd64.whl", hash = "sha256:c7a06301c2fb096bdb0bd25fe2011531c1453b9f2c163c8031600ec73af1cc99"}, + {file = "aiohttp-3.11.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3e23419d832d969f659c208557de4a123e30a10d26e1e14b73431d3c13444c2e"}, + {file = "aiohttp-3.11.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:21fef42317cf02e05d3b09c028712e1d73a9606f02467fd803f7c1f39cc59add"}, + {file = "aiohttp-3.11.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1f21bb8d0235fc10c09ce1d11ffbd40fc50d3f08a89e4cf3a0c503dc2562247a"}, + {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1642eceeaa5ab6c9b6dfeaaa626ae314d808188ab23ae196a34c9d97efb68350"}, + {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2170816e34e10f2fd120f603e951630f8a112e1be3b60963a1f159f5699059a6"}, + {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8be8508d110d93061197fd2d6a74f7401f73b6d12f8822bbcd6d74f2b55d71b1"}, + {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4eed954b161e6b9b65f6be446ed448ed3921763cc432053ceb606f89d793927e"}, + {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6c9af134da4bc9b3bd3e6a70072509f295d10ee60c697826225b60b9959acdd"}, + {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:44167fc6a763d534a6908bdb2592269b4bf30a03239bcb1654781adf5e49caf1"}, + {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:479b8c6ebd12aedfe64563b85920525d05d394b85f166b7873c8bde6da612f9c"}, + {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:10b4ff0ad793d98605958089fabfa350e8e62bd5d40aa65cdc69d6785859f94e"}, + {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:b540bd67cfb54e6f0865ceccd9979687210d7ed1a1cc8c01f8e67e2f1e883d28"}, + {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dac54e8ce2ed83b1f6b1a54005c87dfed139cf3f777fdc8afc76e7841101226"}, + {file = "aiohttp-3.11.11-cp39-cp39-win32.whl", hash = "sha256:568c1236b2fde93b7720f95a890741854c1200fba4a3471ff48b2934d2d93fd3"}, + {file = "aiohttp-3.11.11-cp39-cp39-win_amd64.whl", hash = "sha256:943a8b052e54dfd6439fd7989f67fc6a7f2138d0a2cf0a7de5f18aa4fe7eb3b1"}, + {file = "aiohttp-3.11.11.tar.gz", hash = "sha256:bb49c7f1e6ebf3821a42d81d494f538107610c3a705987f53068546b0e90303e"}, ] [package.dependencies] @@ -111,13 +111,13 @@ speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"] [[package]] name = "aiosignal" -version = "1.3.1" +version = "1.3.2" description = "aiosignal: a list of registered asynchronous callbacks" optional = true -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, - {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, + {file = "aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5"}, + {file = "aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54"}, ] [package.dependencies] @@ -136,13 +136,13 @@ files = [ [[package]] name = "argcomplete" -version = "3.5.1" +version = "3.5.3" description = "Bash tab completion for argparse" optional = true python-versions = ">=3.8" files = [ - {file = "argcomplete-3.5.1-py3-none-any.whl", hash = "sha256:1a1d148bdaa3e3b93454900163403df41448a248af01b6e849edc5ac08e6c363"}, - {file = "argcomplete-3.5.1.tar.gz", hash = "sha256:eb1ee355aa2557bd3d0145de7b06b2a45b0ce461e1e7813f5d066039ab4177b4"}, + {file = "argcomplete-3.5.3-py3-none-any.whl", hash = "sha256:2ab2c4a215c59fd6caaff41a869480a23e8f6a5f910b266c1808037f4e375b61"}, + {file = "argcomplete-3.5.3.tar.gz", hash = "sha256:c12bf50eded8aebb298c7b7da7a5ff3ee24dffd9f5281867dfe1424b58c55392"}, ] [package.extras] @@ -175,13 +175,13 @@ files = [ [[package]] name = "astroid" -version = "3.3.5" +version = "3.3.8" description = "An abstract syntax tree for Python with inference support." optional = false python-versions = ">=3.9.0" files = [ - {file = "astroid-3.3.5-py3-none-any.whl", hash = "sha256:a9d1c946ada25098d790e079ba2a1b112157278f3fb7e718ae6a9252f5835dc8"}, - {file = "astroid-3.3.5.tar.gz", hash = "sha256:5cfc40ae9f68311075d27ef68a4841bdc5cc7f6cf86671b49f00607d30188e2d"}, + {file = "astroid-3.3.8-py3-none-any.whl", hash = "sha256:187ccc0c248bfbba564826c26f070494f7bc964fd286b6d9fff4420e55de828c"}, + {file = "astroid-3.3.8.tar.gz", hash = "sha256:a88c7994f914a4ea8572fac479459f4955eeccc877be3f2d959a33273b0cf40b"}, ] [package.dependencies] @@ -189,21 +189,18 @@ typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} [[package]] name = "asttokens" -version = "2.4.1" +version = "3.0.0" description = "Annotate AST trees with source code positions" optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, - {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, + {file = "asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2"}, + {file = "asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7"}, ] -[package.dependencies] -six = ">=1.12.0" - [package.extras] -astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] -test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] +astroid = ["astroid (>=2,<4)"] +test = ["astroid (>=2,<4)", "pytest", "pytest-cov", "pytest-xdist"] [[package]] name = "async-timeout" @@ -218,19 +215,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -252,13 +249,13 @@ tomli = {version = "*", markers = "python_version < \"3.11\""} [[package]] name = "bandit" -version = "1.7.10" +version = "1.8.0" description = "Security oriented static analyser for python code." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "bandit-1.7.10-py3-none-any.whl", hash = "sha256:665721d7bebbb4485a339c55161ac0eedde27d51e638000d91c8c2d68343ad02"}, - {file = "bandit-1.7.10.tar.gz", hash = "sha256:59ed5caf5d92b6ada4bf65bc6437feea4a9da1093384445fed4d472acc6cff7b"}, + {file = "bandit-1.8.0-py3-none-any.whl", hash = "sha256:b1a61d829c0968aed625381e426aa378904b996529d048f8d908fa28f6b13e38"}, + {file = "bandit-1.8.0.tar.gz", hash = "sha256:b5bfe55a095abd9fe20099178a7c6c060f844bfd4fe4c76d28e35e4c52b9d31e"}, ] [package.dependencies] @@ -469,13 +466,13 @@ files = [ [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -581,127 +578,114 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -925,37 +909,37 @@ langdetect = ["langdetect"] [[package]] name = "debugpy" -version = "1.8.9" +version = "1.8.11" description = "An implementation of the Debug Adapter Protocol for Python" optional = false python-versions = ">=3.8" files = [ - {file = "debugpy-1.8.9-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:cfe1e6c6ad7178265f74981edf1154ffce97b69005212fbc90ca22ddfe3d017e"}, - {file = "debugpy-1.8.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ada7fb65102a4d2c9ab62e8908e9e9f12aed9d76ef44880367bc9308ebe49a0f"}, - {file = "debugpy-1.8.9-cp310-cp310-win32.whl", hash = "sha256:c36856343cbaa448171cba62a721531e10e7ffb0abff838004701454149bc037"}, - {file = "debugpy-1.8.9-cp310-cp310-win_amd64.whl", hash = "sha256:17c5e0297678442511cf00a745c9709e928ea4ca263d764e90d233208889a19e"}, - {file = "debugpy-1.8.9-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:b74a49753e21e33e7cf030883a92fa607bddc4ede1aa4145172debc637780040"}, - {file = "debugpy-1.8.9-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62d22dacdb0e296966d7d74a7141aaab4bec123fa43d1a35ddcb39bf9fd29d70"}, - {file = "debugpy-1.8.9-cp311-cp311-win32.whl", hash = "sha256:8138efff315cd09b8dcd14226a21afda4ca582284bf4215126d87342bba1cc66"}, - {file = "debugpy-1.8.9-cp311-cp311-win_amd64.whl", hash = "sha256:ff54ef77ad9f5c425398efb150239f6fe8e20c53ae2f68367eba7ece1e96226d"}, - {file = "debugpy-1.8.9-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:957363d9a7a6612a37458d9a15e72d03a635047f946e5fceee74b50d52a9c8e2"}, - {file = "debugpy-1.8.9-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e565fc54b680292b418bb809f1386f17081d1346dca9a871bf69a8ac4071afe"}, - {file = "debugpy-1.8.9-cp312-cp312-win32.whl", hash = "sha256:3e59842d6c4569c65ceb3751075ff8d7e6a6ada209ceca6308c9bde932bcef11"}, - {file = "debugpy-1.8.9-cp312-cp312-win_amd64.whl", hash = "sha256:66eeae42f3137eb428ea3a86d4a55f28da9bd5a4a3d369ba95ecc3a92c1bba53"}, - {file = "debugpy-1.8.9-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:957ecffff80d47cafa9b6545de9e016ae8c9547c98a538ee96ab5947115fb3dd"}, - {file = "debugpy-1.8.9-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1efbb3ff61487e2c16b3e033bc8595aea578222c08aaf3c4bf0f93fadbd662ee"}, - {file = "debugpy-1.8.9-cp313-cp313-win32.whl", hash = "sha256:7c4d65d03bee875bcb211c76c1d8f10f600c305dbd734beaed4077e902606fee"}, - {file = "debugpy-1.8.9-cp313-cp313-win_amd64.whl", hash = "sha256:e46b420dc1bea64e5bbedd678148be512442bc589b0111bd799367cde051e71a"}, - {file = "debugpy-1.8.9-cp38-cp38-macosx_14_0_x86_64.whl", hash = "sha256:472a3994999fe6c0756945ffa359e9e7e2d690fb55d251639d07208dbc37caea"}, - {file = "debugpy-1.8.9-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:365e556a4772d7d0d151d7eb0e77ec4db03bcd95f26b67b15742b88cacff88e9"}, - {file = "debugpy-1.8.9-cp38-cp38-win32.whl", hash = "sha256:54a7e6d3014c408eb37b0b06021366ee985f1539e12fe49ca2ee0d392d9ceca5"}, - {file = "debugpy-1.8.9-cp38-cp38-win_amd64.whl", hash = "sha256:8e99c0b1cc7bf86d83fb95d5ccdc4ad0586d4432d489d1f54e4055bcc795f693"}, - {file = "debugpy-1.8.9-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:7e8b079323a56f719977fde9d8115590cb5e7a1cba2fcee0986ef8817116e7c1"}, - {file = "debugpy-1.8.9-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6953b335b804a41f16a192fa2e7851bdcfd92173cbb2f9f777bb934f49baab65"}, - {file = "debugpy-1.8.9-cp39-cp39-win32.whl", hash = "sha256:7e646e62d4602bb8956db88b1e72fe63172148c1e25c041e03b103a25f36673c"}, - {file = "debugpy-1.8.9-cp39-cp39-win_amd64.whl", hash = "sha256:3d9755e77a2d680ce3d2c5394a444cf42be4a592caaf246dbfbdd100ffcf7ae5"}, - {file = "debugpy-1.8.9-py2.py3-none-any.whl", hash = "sha256:cc37a6c9987ad743d9c3a14fa1b1a14b7e4e6041f9dd0c8abf8895fe7a97b899"}, - {file = "debugpy-1.8.9.zip", hash = "sha256:1339e14c7d980407248f09824d1b25ff5c5616651689f1e0f0e51bdead3ea13e"}, + {file = "debugpy-1.8.11-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:2b26fefc4e31ff85593d68b9022e35e8925714a10ab4858fb1b577a8a48cb8cd"}, + {file = "debugpy-1.8.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61bc8b3b265e6949855300e84dc93d02d7a3a637f2aec6d382afd4ceb9120c9f"}, + {file = "debugpy-1.8.11-cp310-cp310-win32.whl", hash = "sha256:c928bbf47f65288574b78518449edaa46c82572d340e2750889bbf8cd92f3737"}, + {file = "debugpy-1.8.11-cp310-cp310-win_amd64.whl", hash = "sha256:8da1db4ca4f22583e834dcabdc7832e56fe16275253ee53ba66627b86e304da1"}, + {file = "debugpy-1.8.11-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:85de8474ad53ad546ff1c7c7c89230db215b9b8a02754d41cb5a76f70d0be296"}, + {file = "debugpy-1.8.11-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ffc382e4afa4aee367bf413f55ed17bd91b191dcaf979890af239dda435f2a1"}, + {file = "debugpy-1.8.11-cp311-cp311-win32.whl", hash = "sha256:40499a9979c55f72f4eb2fc38695419546b62594f8af194b879d2a18439c97a9"}, + {file = "debugpy-1.8.11-cp311-cp311-win_amd64.whl", hash = "sha256:987bce16e86efa86f747d5151c54e91b3c1e36acc03ce1ddb50f9d09d16ded0e"}, + {file = "debugpy-1.8.11-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:84e511a7545d11683d32cdb8f809ef63fc17ea2a00455cc62d0a4dbb4ed1c308"}, + {file = "debugpy-1.8.11-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce291a5aca4985d82875d6779f61375e959208cdf09fcec40001e65fb0a54768"}, + {file = "debugpy-1.8.11-cp312-cp312-win32.whl", hash = "sha256:28e45b3f827d3bf2592f3cf7ae63282e859f3259db44ed2b129093ca0ac7940b"}, + {file = "debugpy-1.8.11-cp312-cp312-win_amd64.whl", hash = "sha256:44b1b8e6253bceada11f714acf4309ffb98bfa9ac55e4fce14f9e5d4484287a1"}, + {file = "debugpy-1.8.11-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:8988f7163e4381b0da7696f37eec7aca19deb02e500245df68a7159739bbd0d3"}, + {file = "debugpy-1.8.11-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c1f6a173d1140e557347419767d2b14ac1c9cd847e0b4c5444c7f3144697e4e"}, + {file = "debugpy-1.8.11-cp313-cp313-win32.whl", hash = "sha256:bb3b15e25891f38da3ca0740271e63ab9db61f41d4d8541745cfc1824252cb28"}, + {file = "debugpy-1.8.11-cp313-cp313-win_amd64.whl", hash = "sha256:d8768edcbeb34da9e11bcb8b5c2e0958d25218df7a6e56adf415ef262cd7b6d1"}, + {file = "debugpy-1.8.11-cp38-cp38-macosx_14_0_x86_64.whl", hash = "sha256:ad7efe588c8f5cf940f40c3de0cd683cc5b76819446abaa50dc0829a30c094db"}, + {file = "debugpy-1.8.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:189058d03a40103a57144752652b3ab08ff02b7595d0ce1f651b9acc3a3a35a0"}, + {file = "debugpy-1.8.11-cp38-cp38-win32.whl", hash = "sha256:32db46ba45849daed7ccf3f2e26f7a386867b077f39b2a974bb5c4c2c3b0a280"}, + {file = "debugpy-1.8.11-cp38-cp38-win_amd64.whl", hash = "sha256:116bf8342062246ca749013df4f6ea106f23bc159305843491f64672a55af2e5"}, + {file = "debugpy-1.8.11-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:654130ca6ad5de73d978057eaf9e582244ff72d4574b3e106fb8d3d2a0d32458"}, + {file = "debugpy-1.8.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23dc34c5e03b0212fa3c49a874df2b8b1b8fda95160bd79c01eb3ab51ea8d851"}, + {file = "debugpy-1.8.11-cp39-cp39-win32.whl", hash = "sha256:52d8a3166c9f2815bfae05f386114b0b2d274456980d41f320299a8d9a5615a7"}, + {file = "debugpy-1.8.11-cp39-cp39-win_amd64.whl", hash = "sha256:52c3cf9ecda273a19cc092961ee34eb9ba8687d67ba34cc7b79a521c1c64c4c0"}, + {file = "debugpy-1.8.11-py2.py3-none-any.whl", hash = "sha256:0e22f846f4211383e6a416d04b4c13ed174d24cc5d43f5fd52e7821d0ebc8920"}, + {file = "debugpy-1.8.11.tar.gz", hash = "sha256:6ad2688b69235c43b020e04fecccdf6a96c8943ca9c2fb340b8adc103c655e57"}, ] [[package]] @@ -1321,13 +1305,13 @@ dev = ["freezegun", "mock"] [[package]] name = "gitdb" -version = "4.0.11" +version = "4.0.12" description = "Git Object Database" optional = false python-versions = ">=3.7" files = [ - {file = "gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4"}, - {file = "gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b"}, + {file = "gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf"}, + {file = "gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571"}, ] [package.dependencies] @@ -1335,20 +1319,20 @@ smmap = ">=3.0.1,<6" [[package]] name = "gitpython" -version = "3.1.43" +version = "3.1.44" description = "GitPython is a Python library used to interact with Git repositories" optional = false python-versions = ">=3.7" files = [ - {file = "GitPython-3.1.43-py3-none-any.whl", hash = "sha256:eec7ec56b92aad751f9912a73404bc02ba212a23adb2c7098ee668417051a1ff"}, - {file = "GitPython-3.1.43.tar.gz", hash = "sha256:35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"}, + {file = "GitPython-3.1.44-py3-none-any.whl", hash = "sha256:9e0e10cda9bed1ee64bc9a6de50e7e38a9c9943241cd7f585f6df3ed28011110"}, + {file = "gitpython-3.1.44.tar.gz", hash = "sha256:c87e30b26253bf5418b01b0660f818967f3c503193838337fe5e573331249269"}, ] [package.dependencies] gitdb = ">=4.0.1,<5" [package.extras] -doc = ["sphinx (==4.3.2)", "sphinx-autodoc-typehints", "sphinx-rtd-theme", "sphinxcontrib-applehelp (>=1.0.2,<=1.0.4)", "sphinxcontrib-devhelp (==1.0.2)", "sphinxcontrib-htmlhelp (>=2.0.0,<=2.0.1)", "sphinxcontrib-qthelp (==1.0.3)", "sphinxcontrib-serializinghtml (==1.1.5)"] +doc = ["sphinx (>=7.1.2,<7.2)", "sphinx-autodoc-typehints", "sphinx_rtd_theme"] test = ["coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "typing-extensions"] [[package]] @@ -1364,25 +1348,25 @@ files = [ [[package]] name = "google-api-core" -version = "2.23.0" +version = "2.24.0" description = "Google API client core library" optional = false python-versions = ">=3.7" files = [ - {file = "google_api_core-2.23.0-py3-none-any.whl", hash = "sha256:c20100d4c4c41070cf365f1d8ddf5365915291b5eb11b83829fbd1c999b5122f"}, - {file = "google_api_core-2.23.0.tar.gz", hash = "sha256:2ceb087315e6af43f256704b871d99326b1f12a9d6ce99beaedec99ba26a0ace"}, + {file = "google_api_core-2.24.0-py3-none-any.whl", hash = "sha256:10d82ac0fca69c82a25b3efdeefccf6f28e02ebb97925a8cce8edbfe379929d9"}, + {file = "google_api_core-2.24.0.tar.gz", hash = "sha256:e255640547a597a4da010876d333208ddac417d60add22b6851a0c66a831fcaf"}, ] [package.dependencies] google-auth = ">=2.14.1,<3.0.dev0" googleapis-common-protos = ">=1.56.2,<2.0.dev0" grpcio = [ - {version = ">=1.33.2,<2.0dev", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""}, {version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, + {version = ">=1.33.2,<2.0dev", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""}, ] grpcio-status = [ - {version = ">=1.33.2,<2.0.dev0", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""}, {version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, + {version = ">=1.33.2,<2.0.dev0", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""}, ] proto-plus = ">=1.22.3,<2.0.0dev" protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0.dev0" @@ -1417,13 +1401,13 @@ testing = ["mock (>=1.0.1)"] [[package]] name = "google-auth" -version = "2.36.0" +version = "2.37.0" description = "Google Authentication Library" optional = false python-versions = ">=3.7" files = [ - {file = "google_auth-2.36.0-py2.py3-none-any.whl", hash = "sha256:51a15d47028b66fd36e5c64a82d2d57480075bccc7da37cde257fc94177a61fb"}, - {file = "google_auth-2.36.0.tar.gz", hash = "sha256:545e9618f2df0bcbb7dcbc45a546485b1212624716975a1ea5ae8149ce769ab1"}, + {file = "google_auth-2.37.0-py2.py3-none-any.whl", hash = "sha256:42664f18290a6be591be5329a96fe30184be1a1badb7292a7f686a9659de9ca0"}, + {file = "google_auth-2.37.0.tar.gz", hash = "sha256:0054623abf1f9c83492c63d3f47e77f0a544caa3d40b2d98e099a611c2dd5d00"}, ] [package.dependencies] @@ -1436,6 +1420,7 @@ rsa = ">=3.1.4,<5" [package.extras] aiohttp = ["aiohttp (>=3.6.2,<4.0.0.dev0)", "requests (>=2.20.0,<3.0.0.dev0)"] enterprise-cert = ["cryptography", "pyopenssl"] +pyjwt = ["cryptography (>=38.0.3)", "pyjwt (>=2.0)"] pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] requests = ["requests (>=2.20.0,<3.0.0.dev0)"] @@ -1460,13 +1445,13 @@ grpc = ["grpcio (>=1.38.0,<2.0dev)", "grpcio-status (>=1.38.0,<2.0.dev0)"] [[package]] name = "google-cloud-secret-manager" -version = "2.21.1" +version = "2.22.0" description = "Google Cloud Secret Manager API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google_cloud_secret_manager-2.21.1-py2.py3-none-any.whl", hash = "sha256:a259932a3c0951f061b60cacfbc20831af92a67fd8cd7396a9f59504bc5cc251"}, - {file = "google_cloud_secret_manager-2.21.1.tar.gz", hash = "sha256:f104f002751345cba39152cef3aed3f4375edf0b2542c8bd1b7712d44fe975b6"}, + {file = "google_cloud_secret_manager-2.22.0-py2.py3-none-any.whl", hash = "sha256:9e23a8165ed718de56543723b1e21c394f2cee9ababddcac8ceecc9f427d2696"}, + {file = "google_cloud_secret_manager-2.22.0.tar.gz", hash = "sha256:5dd95ac6243687f86fd803316c0768f507028958b8a2e69b3aa0ace7ac654bf4"}, ] [package.dependencies] @@ -1478,13 +1463,13 @@ protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4 [[package]] name = "google-cloud-storage" -version = "2.18.2" +version = "2.19.0" description = "Google Cloud Storage API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google_cloud_storage-2.18.2-py2.py3-none-any.whl", hash = "sha256:97a4d45c368b7d401ed48c4fdfe86e1e1cb96401c9e199e419d289e2c0370166"}, - {file = "google_cloud_storage-2.18.2.tar.gz", hash = "sha256:aaf7acd70cdad9f274d29332673fcab98708d0e1f4dceb5a5356aaef06af4d99"}, + {file = "google_cloud_storage-2.19.0-py2.py3-none-any.whl", hash = "sha256:aeb971b5c29cf8ab98445082cbfe7b161a1f48ed275822f59ed3f1524ea54fba"}, + {file = "google_cloud_storage-2.19.0.tar.gz", hash = "sha256:cd05e9e7191ba6cb68934d8eb76054d9be4562aa89dbc4236feee4d7d51342b2"}, ] [package.dependencies] @@ -1609,70 +1594,70 @@ protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4 [[package]] name = "grpcio" -version = "1.68.0" +version = "1.68.1" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.8" files = [ - {file = "grpcio-1.68.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:619b5d0f29f4f5351440e9343224c3e19912c21aeda44e0c49d0d147a8d01544"}, - {file = "grpcio-1.68.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:a59f5822f9459bed098ffbceb2713abbf7c6fd13f2b9243461da5c338d0cd6c3"}, - {file = "grpcio-1.68.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:c03d89df516128febc5a7e760d675b478ba25802447624edf7aa13b1e7b11e2a"}, - {file = "grpcio-1.68.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44bcbebb24363d587472089b89e2ea0ab2e2b4df0e4856ba4c0b087c82412121"}, - {file = "grpcio-1.68.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79f81b7fbfb136247b70465bd836fa1733043fdee539cd6031cb499e9608a110"}, - {file = "grpcio-1.68.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:88fb2925789cfe6daa20900260ef0a1d0a61283dfb2d2fffe6194396a354c618"}, - {file = "grpcio-1.68.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:99f06232b5c9138593ae6f2e355054318717d32a9c09cdc5a2885540835067a1"}, - {file = "grpcio-1.68.0-cp310-cp310-win32.whl", hash = "sha256:a6213d2f7a22c3c30a479fb5e249b6b7e648e17f364598ff64d08a5136fe488b"}, - {file = "grpcio-1.68.0-cp310-cp310-win_amd64.whl", hash = "sha256:15327ab81131ef9b94cb9f45b5bd98803a179c7c61205c8c0ac9aff9d6c4e82a"}, - {file = "grpcio-1.68.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:3b2b559beb2d433129441783e5f42e3be40a9e1a89ec906efabf26591c5cd415"}, - {file = "grpcio-1.68.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e46541de8425a4d6829ac6c5d9b16c03c292105fe9ebf78cb1c31e8d242f9155"}, - {file = "grpcio-1.68.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:c1245651f3c9ea92a2db4f95d37b7597db6b246d5892bca6ee8c0e90d76fb73c"}, - {file = "grpcio-1.68.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f1931c7aa85be0fa6cea6af388e576f3bf6baee9e5d481c586980c774debcb4"}, - {file = "grpcio-1.68.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b0ff09c81e3aded7a183bc6473639b46b6caa9c1901d6f5e2cba24b95e59e30"}, - {file = "grpcio-1.68.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8c73f9fbbaee1a132487e31585aa83987ddf626426d703ebcb9a528cf231c9b1"}, - {file = "grpcio-1.68.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6b2f98165ea2790ea159393a2246b56f580d24d7da0d0342c18a085299c40a75"}, - {file = "grpcio-1.68.0-cp311-cp311-win32.whl", hash = "sha256:e1e7ed311afb351ff0d0e583a66fcb39675be112d61e7cfd6c8269884a98afbc"}, - {file = "grpcio-1.68.0-cp311-cp311-win_amd64.whl", hash = "sha256:e0d2f68eaa0a755edd9a47d40e50dba6df2bceda66960dee1218da81a2834d27"}, - {file = "grpcio-1.68.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:8af6137cc4ae8e421690d276e7627cfc726d4293f6607acf9ea7260bd8fc3d7d"}, - {file = "grpcio-1.68.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:4028b8e9a3bff6f377698587d642e24bd221810c06579a18420a17688e421af7"}, - {file = "grpcio-1.68.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:f60fa2adf281fd73ae3a50677572521edca34ba373a45b457b5ebe87c2d01e1d"}, - {file = "grpcio-1.68.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e18589e747c1e70b60fab6767ff99b2d0c359ea1db8a2cb524477f93cdbedf5b"}, - {file = "grpcio-1.68.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0d30f3fee9372796f54d3100b31ee70972eaadcc87314be369360248a3dcffe"}, - {file = "grpcio-1.68.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:7e0a3e72c0e9a1acab77bef14a73a416630b7fd2cbd893c0a873edc47c42c8cd"}, - {file = "grpcio-1.68.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a831dcc343440969aaa812004685ed322cdb526cd197112d0db303b0da1e8659"}, - {file = "grpcio-1.68.0-cp312-cp312-win32.whl", hash = "sha256:5a180328e92b9a0050958ced34dddcb86fec5a8b332f5a229e353dafc16cd332"}, - {file = "grpcio-1.68.0-cp312-cp312-win_amd64.whl", hash = "sha256:2bddd04a790b69f7a7385f6a112f46ea0b34c4746f361ebafe9ca0be567c78e9"}, - {file = "grpcio-1.68.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:fc05759ffbd7875e0ff2bd877be1438dfe97c9312bbc558c8284a9afa1d0f40e"}, - {file = "grpcio-1.68.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:15fa1fe25d365a13bc6d52fcac0e3ee1f9baebdde2c9b3b2425f8a4979fccea1"}, - {file = "grpcio-1.68.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:32a9cb4686eb2e89d97022ecb9e1606d132f85c444354c17a7dbde4a455e4a3b"}, - {file = "grpcio-1.68.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dba037ff8d284c8e7ea9a510c8ae0f5b016004f13c3648f72411c464b67ff2fb"}, - {file = "grpcio-1.68.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0efbbd849867e0e569af09e165363ade75cf84f5229b2698d53cf22c7a4f9e21"}, - {file = "grpcio-1.68.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:4e300e6978df0b65cc2d100c54e097c10dfc7018b9bd890bbbf08022d47f766d"}, - {file = "grpcio-1.68.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:6f9c7ad1a23e1047f827385f4713b5b8c6c7d325705be1dd3e31fb00dcb2f665"}, - {file = "grpcio-1.68.0-cp313-cp313-win32.whl", hash = "sha256:3ac7f10850fd0487fcce169c3c55509101c3bde2a3b454869639df2176b60a03"}, - {file = "grpcio-1.68.0-cp313-cp313-win_amd64.whl", hash = "sha256:afbf45a62ba85a720491bfe9b2642f8761ff348006f5ef67e4622621f116b04a"}, - {file = "grpcio-1.68.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:f8f695d9576ce836eab27ba7401c60acaf9ef6cf2f70dfe5462055ba3df02cc3"}, - {file = "grpcio-1.68.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9fe1b141cda52f2ca73e17d2d3c6a9f3f3a0c255c216b50ce616e9dca7e3441d"}, - {file = "grpcio-1.68.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:4df81d78fd1646bf94ced4fb4cd0a7fe2e91608089c522ef17bc7db26e64effd"}, - {file = "grpcio-1.68.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:46a2d74d4dd8993151c6cd585594c082abe74112c8e4175ddda4106f2ceb022f"}, - {file = "grpcio-1.68.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a17278d977746472698460c63abf333e1d806bd41f2224f90dbe9460101c9796"}, - {file = "grpcio-1.68.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:15377bce516b1c861c35e18eaa1c280692bf563264836cece693c0f169b48829"}, - {file = "grpcio-1.68.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cc5f0a4f5904b8c25729a0498886b797feb817d1fd3812554ffa39551112c161"}, - {file = "grpcio-1.68.0-cp38-cp38-win32.whl", hash = "sha256:def1a60a111d24376e4b753db39705adbe9483ef4ca4761f825639d884d5da78"}, - {file = "grpcio-1.68.0-cp38-cp38-win_amd64.whl", hash = "sha256:55d3b52fd41ec5772a953612db4e70ae741a6d6ed640c4c89a64f017a1ac02b5"}, - {file = "grpcio-1.68.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:0d230852ba97654453d290e98d6aa61cb48fa5fafb474fb4c4298d8721809354"}, - {file = "grpcio-1.68.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:50992f214264e207e07222703c17d9cfdcc2c46ed5a1ea86843d440148ebbe10"}, - {file = "grpcio-1.68.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:14331e5c27ed3545360464a139ed279aa09db088f6e9502e95ad4bfa852bb116"}, - {file = "grpcio-1.68.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f84890b205692ea813653ece4ac9afa2139eae136e419231b0eec7c39fdbe4c2"}, - {file = "grpcio-1.68.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0cf343c6f4f6aa44863e13ec9ddfe299e0be68f87d68e777328bff785897b05"}, - {file = "grpcio-1.68.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:fd2c2d47969daa0e27eadaf15c13b5e92605c5e5953d23c06d0b5239a2f176d3"}, - {file = "grpcio-1.68.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:18668e36e7f4045820f069997834e94e8275910b1f03e078a6020bd464cb2363"}, - {file = "grpcio-1.68.0-cp39-cp39-win32.whl", hash = "sha256:2af76ab7c427aaa26aa9187c3e3c42f38d3771f91a20f99657d992afada2294a"}, - {file = "grpcio-1.68.0-cp39-cp39-win_amd64.whl", hash = "sha256:e694b5928b7b33ca2d3b4d5f9bf8b5888906f181daff6b406f4938f3a997a490"}, - {file = "grpcio-1.68.0.tar.gz", hash = "sha256:7e7483d39b4a4fddb9906671e9ea21aaad4f031cdfc349fec76bdfa1e404543a"}, + {file = "grpcio-1.68.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:d35740e3f45f60f3c37b1e6f2f4702c23867b9ce21c6410254c9c682237da68d"}, + {file = "grpcio-1.68.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:d99abcd61760ebb34bdff37e5a3ba333c5cc09feda8c1ad42547bea0416ada78"}, + {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:f8261fa2a5f679abeb2a0a93ad056d765cdca1c47745eda3f2d87f874ff4b8c9"}, + {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0feb02205a27caca128627bd1df4ee7212db051019a9afa76f4bb6a1a80ca95e"}, + {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:919d7f18f63bcad3a0f81146188e90274fde800a94e35d42ffe9eadf6a9a6330"}, + {file = "grpcio-1.68.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:963cc8d7d79b12c56008aabd8b457f400952dbea8997dd185f155e2f228db079"}, + {file = "grpcio-1.68.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ccf2ebd2de2d6661e2520dae293298a3803a98ebfc099275f113ce1f6c2a80f1"}, + {file = "grpcio-1.68.1-cp310-cp310-win32.whl", hash = "sha256:2cc1fd04af8399971bcd4f43bd98c22d01029ea2e56e69c34daf2bf8470e47f5"}, + {file = "grpcio-1.68.1-cp310-cp310-win_amd64.whl", hash = "sha256:ee2e743e51cb964b4975de572aa8fb95b633f496f9fcb5e257893df3be854746"}, + {file = "grpcio-1.68.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:55857c71641064f01ff0541a1776bfe04a59db5558e82897d35a7793e525774c"}, + {file = "grpcio-1.68.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4b177f5547f1b995826ef529d2eef89cca2f830dd8b2c99ffd5fde4da734ba73"}, + {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:3522c77d7e6606d6665ec8d50e867f13f946a4e00c7df46768f1c85089eae515"}, + {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d1fae6bbf0816415b81db1e82fb3bf56f7857273c84dcbe68cbe046e58e1ccd"}, + {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:298ee7f80e26f9483f0b6f94cc0a046caf54400a11b644713bb5b3d8eb387600"}, + {file = "grpcio-1.68.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cbb5780e2e740b6b4f2d208e90453591036ff80c02cc605fea1af8e6fc6b1bbe"}, + {file = "grpcio-1.68.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ddda1aa22495d8acd9dfbafff2866438d12faec4d024ebc2e656784d96328ad0"}, + {file = "grpcio-1.68.1-cp311-cp311-win32.whl", hash = "sha256:b33bd114fa5a83f03ec6b7b262ef9f5cac549d4126f1dc702078767b10c46ed9"}, + {file = "grpcio-1.68.1-cp311-cp311-win_amd64.whl", hash = "sha256:7f20ebec257af55694d8f993e162ddf0d36bd82d4e57f74b31c67b3c6d63d8b2"}, + {file = "grpcio-1.68.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:8829924fffb25386995a31998ccbbeaa7367223e647e0122043dfc485a87c666"}, + {file = "grpcio-1.68.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3aed6544e4d523cd6b3119b0916cef3d15ef2da51e088211e4d1eb91a6c7f4f1"}, + {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:4efac5481c696d5cb124ff1c119a78bddbfdd13fc499e3bc0ca81e95fc573684"}, + {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ab2d912ca39c51f46baf2a0d92aa265aa96b2443266fc50d234fa88bf877d8e"}, + {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c87ce2a97434dffe7327a4071839ab8e8bffd0054cc74cbe971fba98aedd60"}, + {file = "grpcio-1.68.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e4842e4872ae4ae0f5497bf60a0498fa778c192cc7a9e87877abd2814aca9475"}, + {file = "grpcio-1.68.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:255b1635b0ed81e9f91da4fcc8d43b7ea5520090b9a9ad9340d147066d1d3613"}, + {file = "grpcio-1.68.1-cp312-cp312-win32.whl", hash = "sha256:7dfc914cc31c906297b30463dde0b9be48e36939575eaf2a0a22a8096e69afe5"}, + {file = "grpcio-1.68.1-cp312-cp312-win_amd64.whl", hash = "sha256:a0c8ddabef9c8f41617f213e527254c41e8b96ea9d387c632af878d05db9229c"}, + {file = "grpcio-1.68.1-cp313-cp313-linux_armv7l.whl", hash = "sha256:a47faedc9ea2e7a3b6569795c040aae5895a19dde0c728a48d3c5d7995fda385"}, + {file = "grpcio-1.68.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:390eee4225a661c5cd133c09f5da1ee3c84498dc265fd292a6912b65c421c78c"}, + {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:66a24f3d45c33550703f0abb8b656515b0ab777970fa275693a2f6dc8e35f1c1"}, + {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c08079b4934b0bf0a8847f42c197b1d12cba6495a3d43febd7e99ecd1cdc8d54"}, + {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8720c25cd9ac25dd04ee02b69256d0ce35bf8a0f29e20577427355272230965a"}, + {file = "grpcio-1.68.1-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:04cfd68bf4f38f5bb959ee2361a7546916bd9a50f78617a346b3aeb2b42e2161"}, + {file = "grpcio-1.68.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c28848761a6520c5c6071d2904a18d339a796ebe6b800adc8b3f474c5ce3c3ad"}, + {file = "grpcio-1.68.1-cp313-cp313-win32.whl", hash = "sha256:77d65165fc35cff6e954e7fd4229e05ec76102d4406d4576528d3a3635fc6172"}, + {file = "grpcio-1.68.1-cp313-cp313-win_amd64.whl", hash = "sha256:a8040f85dcb9830d8bbb033ae66d272614cec6faceee88d37a88a9bd1a7a704e"}, + {file = "grpcio-1.68.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:eeb38ff04ab6e5756a2aef6ad8d94e89bb4a51ef96e20f45c44ba190fa0bcaad"}, + {file = "grpcio-1.68.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8a3869a6661ec8f81d93f4597da50336718bde9eb13267a699ac7e0a1d6d0bea"}, + {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:2c4cec6177bf325eb6faa6bd834d2ff6aa8bb3b29012cceb4937b86f8b74323c"}, + {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12941d533f3cd45d46f202e3667be8ebf6bcb3573629c7ec12c3e211d99cfccf"}, + {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80af6f1e69c5e68a2be529990684abdd31ed6622e988bf18850075c81bb1ad6e"}, + {file = "grpcio-1.68.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e8dbe3e00771bfe3d04feed8210fc6617006d06d9a2679b74605b9fed3e8362c"}, + {file = "grpcio-1.68.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:83bbf5807dc3ee94ce1de2dfe8a356e1d74101e4b9d7aa8c720cc4818a34aded"}, + {file = "grpcio-1.68.1-cp38-cp38-win32.whl", hash = "sha256:8cb620037a2fd9eeee97b4531880e439ebfcd6d7d78f2e7dcc3726428ab5ef63"}, + {file = "grpcio-1.68.1-cp38-cp38-win_amd64.whl", hash = "sha256:52fbf85aa71263380d330f4fce9f013c0798242e31ede05fcee7fbe40ccfc20d"}, + {file = "grpcio-1.68.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:cb400138e73969eb5e0535d1d06cae6a6f7a15f2cc74add320e2130b8179211a"}, + {file = "grpcio-1.68.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a1b988b40f2fd9de5c820f3a701a43339d8dcf2cb2f1ca137e2c02671cc83ac1"}, + {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:96f473cdacfdd506008a5d7579c9f6a7ff245a9ade92c3c0265eb76cc591914f"}, + {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:37ea3be171f3cf3e7b7e412a98b77685eba9d4fd67421f4a34686a63a65d99f9"}, + {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ceb56c4285754e33bb3c2fa777d055e96e6932351a3082ce3559be47f8024f0"}, + {file = "grpcio-1.68.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:dffd29a2961f3263a16d73945b57cd44a8fd0b235740cb14056f0612329b345e"}, + {file = "grpcio-1.68.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:025f790c056815b3bf53da850dd70ebb849fd755a4b1ac822cb65cd631e37d43"}, + {file = "grpcio-1.68.1-cp39-cp39-win32.whl", hash = "sha256:1098f03dedc3b9810810568060dea4ac0822b4062f537b0f53aa015269be0a76"}, + {file = "grpcio-1.68.1-cp39-cp39-win_amd64.whl", hash = "sha256:334ab917792904245a028f10e803fcd5b6f36a7b2173a820c0b5b076555825e1"}, + {file = "grpcio-1.68.1.tar.gz", hash = "sha256:44a8502dd5de653ae6a73e2de50a401d84184f0331d0ac3daeb044e66d5c5054"}, ] [package.extras] -protobuf = ["grpcio-tools (>=1.68.0)"] +protobuf = ["grpcio-tools (>=1.68.1)"] [[package]] name = "grpcio-status" @@ -1792,13 +1777,13 @@ files = [ [[package]] name = "identify" -version = "2.6.2" +version = "2.6.4" description = "File identification library for Python" optional = false python-versions = ">=3.9" files = [ - {file = "identify-2.6.2-py2.py3-none-any.whl", hash = "sha256:c097384259f49e372f4ea00a19719d95ae27dd5ff0fd77ad630aa891306b82f3"}, - {file = "identify-2.6.2.tar.gz", hash = "sha256:fab5c716c24d7a789775228823797296a2994b075fb6080ac83a102772a98cbd"}, + {file = "identify-2.6.4-py2.py3-none-any.whl", hash = "sha256:993b0f01b97e0568c179bb9196391ff391bfb88a99099dbf5ce392b68f42d0af"}, + {file = "identify-2.6.4.tar.gz", hash = "sha256:285a7d27e397652e8cafe537a6cc97dd470a970f48fb2e9d979aa38eae5513ac"}, ] [package.extras] @@ -2008,13 +1993,13 @@ testing = ["Django", "attrs", "colorama", "docopt", "pytest (<9.0.0)"] [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -2180,13 +2165,13 @@ pyasn1 = ">=0.4.6" [[package]] name = "loguru" -version = "0.7.2" +version = "0.7.3" description = "Python logging made (stupidly) simple" optional = false -python-versions = ">=3.5" +python-versions = "<4.0,>=3.5" files = [ - {file = "loguru-0.7.2-py3-none-any.whl", hash = "sha256:003d71e3d3ed35f0f8984898359d65b79e5b21943f78af86aa5491210429b8eb"}, - {file = "loguru-0.7.2.tar.gz", hash = "sha256:e671a53522515f34fd406340ee968cb9ecafbc4b36c679da03c18fd8d0bd51ac"}, + {file = "loguru-0.7.3-py3-none-any.whl", hash = "sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c"}, + {file = "loguru-0.7.3.tar.gz", hash = "sha256:19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6"}, ] [package.dependencies] @@ -2194,7 +2179,7 @@ colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""} win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""} [package.extras] -dev = ["Sphinx (==7.2.5)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptiongroup (==1.1.3)", "freezegun (==1.1.0)", "freezegun (==1.2.2)", "mypy (==v0.910)", "mypy (==v0.971)", "mypy (==v1.4.1)", "mypy (==v1.5.1)", "pre-commit (==3.4.0)", "pytest (==6.1.2)", "pytest (==7.4.0)", "pytest-cov (==2.12.1)", "pytest-cov (==4.1.0)", "pytest-mypy-plugins (==1.9.3)", "pytest-mypy-plugins (==3.0.0)", "sphinx-autobuild (==2021.3.14)", "sphinx-rtd-theme (==1.3.0)", "tox (==3.27.1)", "tox (==4.11.0)"] +dev = ["Sphinx (==8.1.3)", "build (==1.2.2)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptiongroup (==1.1.3)", "freezegun (==1.1.0)", "freezegun (==1.5.0)", "mypy (==v0.910)", "mypy (==v0.971)", "mypy (==v1.13.0)", "mypy (==v1.4.1)", "myst-parser (==4.0.0)", "pre-commit (==4.0.1)", "pytest (==6.1.2)", "pytest (==8.3.2)", "pytest-cov (==2.12.1)", "pytest-cov (==5.0.0)", "pytest-cov (==6.0.0)", "pytest-mypy-plugins (==1.9.3)", "pytest-mypy-plugins (==3.1.0)", "sphinx-rtd-theme (==3.0.2)", "tox (==3.27.1)", "tox (==4.23.2)", "twine (==6.0.1)"] [[package]] name = "lxml" @@ -2794,21 +2779,21 @@ files = [ [[package]] name = "neo4j" -version = "5.26.0" +version = "5.27.0" description = "Neo4j Bolt driver for Python" optional = false python-versions = ">=3.7" files = [ - {file = "neo4j-5.26.0-py3-none-any.whl", hash = "sha256:511a6a9468ca89b521bf686f885a2070acc462b1d09821d43710bd477acdf11e"}, - {file = "neo4j-5.26.0.tar.gz", hash = "sha256:51b25ba127b7b9fdae1ddf48ae697ddfab331e60f4b6d8488d1fc1f74ec60dcc"}, + {file = "neo4j-5.27.0-py3-none-any.whl", hash = "sha256:929c14b9e5341267324eca170b39d1798b032bffacc26a0529eacaf678ae483f"}, + {file = "neo4j-5.27.0.tar.gz", hash = "sha256:f82ee807cd15b178898d83f41a66372e11719a25dd487fd7bea48fd4b7323765"}, ] [package.dependencies] pytz = "*" [package.extras] -numpy = ["numpy (>=1.7.0,<2.0.0)"] -pandas = ["numpy (>=1.7.0,<2.0.0)", "pandas (>=1.1.0,<3.0.0)"] +numpy = ["numpy (>=1.7.0,<3.0.0)"] +pandas = ["numpy (>=1.7.0,<3.0.0)", "pandas (>=1.1.0,<3.0.0)"] pyarrow = ["pyarrow (>=1.0.0)"] [[package]] @@ -2910,86 +2895,86 @@ dev = ["black", "mypy", "pytest"] [[package]] name = "orjson" -version = "3.10.12" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.12-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ece01a7ec71d9940cc654c482907a6b65df27251255097629d0dea781f255c6d"}, - {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c34ec9aebc04f11f4b978dd6caf697a2df2dd9b47d35aa4cc606cabcb9df69d7"}, - {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fd6ec8658da3480939c79b9e9e27e0db31dffcd4ba69c334e98c9976ac29140e"}, - {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f17e6baf4cf01534c9de8a16c0c611f3d94925d1701bf5f4aff17003677d8ced"}, - {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6402ebb74a14ef96f94a868569f5dccf70d791de49feb73180eb3c6fda2ade56"}, - {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0000758ae7c7853e0a4a6063f534c61656ebff644391e1f81698c1b2d2fc8cd2"}, - {file = "orjson-3.10.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:888442dcee99fd1e5bd37a4abb94930915ca6af4db50e23e746cdf4d1e63db13"}, - {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c1f7a3ce79246aa0e92f5458d86c54f257fb5dfdc14a192651ba7ec2c00f8a05"}, - {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:802a3935f45605c66fb4a586488a38af63cb37aaad1c1d94c982c40dcc452e85"}, - {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1da1ef0113a2be19bb6c557fb0ec2d79c92ebd2fed4cfb1b26bab93f021fb885"}, - {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a3273e99f367f137d5b3fecb5e9f45bcdbfac2a8b2f32fbc72129bbd48789c2"}, - {file = "orjson-3.10.12-cp310-none-win32.whl", hash = "sha256:475661bf249fd7907d9b0a2a2421b4e684355a77ceef85b8352439a9163418c3"}, - {file = "orjson-3.10.12-cp310-none-win_amd64.whl", hash = "sha256:87251dc1fb2b9e5ab91ce65d8f4caf21910d99ba8fb24b49fd0c118b2362d509"}, - {file = "orjson-3.10.12-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a734c62efa42e7df94926d70fe7d37621c783dea9f707a98cdea796964d4cf74"}, - {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:750f8b27259d3409eda8350c2919a58b0cfcd2054ddc1bd317a643afc646ef23"}, - {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb52c22bfffe2857e7aa13b4622afd0dd9d16ea7cc65fd2bf318d3223b1b6252"}, - {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:440d9a337ac8c199ff8251e100c62e9488924c92852362cd27af0e67308c16ef"}, - {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9e15c06491c69997dfa067369baab3bf094ecb74be9912bdc4339972323f252"}, - {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:362d204ad4b0b8724cf370d0cd917bb2dc913c394030da748a3bb632445ce7c4"}, - {file = "orjson-3.10.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2b57cbb4031153db37b41622eac67329c7810e5f480fda4cfd30542186f006ae"}, - {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:165c89b53ef03ce0d7c59ca5c82fa65fe13ddf52eeb22e859e58c237d4e33b9b"}, - {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:5dee91b8dfd54557c1a1596eb90bcd47dbcd26b0baaed919e6861f076583e9da"}, - {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:77a4e1cfb72de6f905bdff061172adfb3caf7a4578ebf481d8f0530879476c07"}, - {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:038d42c7bc0606443459b8fe2d1f121db474c49067d8d14c6a075bbea8bf14dd"}, - {file = "orjson-3.10.12-cp311-none-win32.whl", hash = "sha256:03b553c02ab39bed249bedd4abe37b2118324d1674e639b33fab3d1dafdf4d79"}, - {file = "orjson-3.10.12-cp311-none-win_amd64.whl", hash = "sha256:8b8713b9e46a45b2af6b96f559bfb13b1e02006f4242c156cbadef27800a55a8"}, - {file = "orjson-3.10.12-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:53206d72eb656ca5ac7d3a7141e83c5bbd3ac30d5eccfe019409177a57634b0d"}, - {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac8010afc2150d417ebda810e8df08dd3f544e0dd2acab5370cfa6bcc0662f8f"}, - {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed459b46012ae950dd2e17150e838ab08215421487371fa79d0eced8d1461d70"}, - {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dcb9673f108a93c1b52bfc51b0af422c2d08d4fc710ce9c839faad25020bb69"}, - {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22a51ae77680c5c4652ebc63a83d5255ac7d65582891d9424b566fb3b5375ee9"}, - {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910fdf2ac0637b9a77d1aad65f803bac414f0b06f720073438a7bd8906298192"}, - {file = "orjson-3.10.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:24ce85f7100160936bc2116c09d1a8492639418633119a2224114f67f63a4559"}, - {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a76ba5fc8dd9c913640292df27bff80a685bed3a3c990d59aa6ce24c352f8fc"}, - {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ff70ef093895fd53f4055ca75f93f047e088d1430888ca1229393a7c0521100f"}, - {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f4244b7018b5753ecd10a6d324ec1f347da130c953a9c88432c7fbc8875d13be"}, - {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:16135ccca03445f37921fa4b585cff9a58aa8d81ebcb27622e69bfadd220b32c"}, - {file = "orjson-3.10.12-cp312-none-win32.whl", hash = "sha256:2d879c81172d583e34153d524fcba5d4adafbab8349a7b9f16ae511c2cee8708"}, - {file = "orjson-3.10.12-cp312-none-win_amd64.whl", hash = "sha256:fc23f691fa0f5c140576b8c365bc942d577d861a9ee1142e4db468e4e17094fb"}, - {file = "orjson-3.10.12-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:47962841b2a8aa9a258b377f5188db31ba49af47d4003a32f55d6f8b19006543"}, - {file = "orjson-3.10.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6334730e2532e77b6054e87ca84f3072bee308a45a452ea0bffbbbc40a67e296"}, - {file = "orjson-3.10.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:accfe93f42713c899fdac2747e8d0d5c659592df2792888c6c5f829472e4f85e"}, - {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a7974c490c014c48810d1dede6c754c3cc46598da758c25ca3b4001ac45b703f"}, - {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3f250ce7727b0b2682f834a3facff88e310f52f07a5dcfd852d99637d386e79e"}, - {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f31422ff9486ae484f10ffc51b5ab2a60359e92d0716fcce1b3593d7bb8a9af6"}, - {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5f29c5d282bb2d577c2a6bbde88d8fdcc4919c593f806aac50133f01b733846e"}, - {file = "orjson-3.10.12-cp313-none-win32.whl", hash = "sha256:f45653775f38f63dc0e6cd4f14323984c3149c05d6007b58cb154dd080ddc0dc"}, - {file = "orjson-3.10.12-cp313-none-win_amd64.whl", hash = "sha256:229994d0c376d5bdc91d92b3c9e6be2f1fbabd4cc1b59daae1443a46ee5e9825"}, - {file = "orjson-3.10.12-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7d69af5b54617a5fac5c8e5ed0859eb798e2ce8913262eb522590239db6c6763"}, - {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ed119ea7d2953365724a7059231a44830eb6bbb0cfead33fcbc562f5fd8f935"}, - {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9c5fc1238ef197e7cad5c91415f524aaa51e004be5a9b35a1b8a84ade196f73f"}, - {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43509843990439b05f848539d6f6198d4ac86ff01dd024b2f9a795c0daeeab60"}, - {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f72e27a62041cfb37a3de512247ece9f240a561e6c8662276beaf4d53d406db4"}, - {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a904f9572092bb6742ab7c16c623f0cdccbad9eeb2d14d4aa06284867bddd31"}, - {file = "orjson-3.10.12-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:855c0833999ed5dc62f64552db26f9be767434917d8348d77bacaab84f787d7b"}, - {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:897830244e2320f6184699f598df7fb9db9f5087d6f3f03666ae89d607e4f8ed"}, - {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0b32652eaa4a7539f6f04abc6243619c56f8530c53bf9b023e1269df5f7816dd"}, - {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:36b4aa31e0f6a1aeeb6f8377769ca5d125db000f05c20e54163aef1d3fe8e833"}, - {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5535163054d6cbf2796f93e4f0dbc800f61914c0e3c4ed8499cf6ece22b4a3da"}, - {file = "orjson-3.10.12-cp38-none-win32.whl", hash = "sha256:90a5551f6f5a5fa07010bf3d0b4ca2de21adafbbc0af6cb700b63cd767266cb9"}, - {file = "orjson-3.10.12-cp38-none-win_amd64.whl", hash = "sha256:703a2fb35a06cdd45adf5d733cf613cbc0cb3ae57643472b16bc22d325b5fb6c"}, - {file = "orjson-3.10.12-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:f29de3ef71a42a5822765def1febfb36e0859d33abf5c2ad240acad5c6a1b78d"}, - {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de365a42acc65d74953f05e4772c974dad6c51cfc13c3240899f534d611be967"}, - {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:91a5a0158648a67ff0004cb0df5df7dcc55bfc9ca154d9c01597a23ad54c8d0c"}, - {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c47ce6b8d90fe9646a25b6fb52284a14ff215c9595914af63a5933a49972ce36"}, - {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0eee4c2c5bfb5c1b47a5db80d2ac7aaa7e938956ae88089f098aff2c0f35d5d8"}, - {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35d3081bbe8b86587eb5c98a73b97f13d8f9fea685cf91a579beddacc0d10566"}, - {file = "orjson-3.10.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73c23a6e90383884068bc2dba83d5222c9fcc3b99a0ed2411d38150734236755"}, - {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5472be7dc3269b4b52acba1433dac239215366f89dc1d8d0e64029abac4e714e"}, - {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:7319cda750fca96ae5973efb31b17d97a5c5225ae0bc79bf5bf84df9e1ec2ab6"}, - {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:74d5ca5a255bf20b8def6a2b96b1e18ad37b4a122d59b154c458ee9494377f80"}, - {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ff31d22ecc5fb85ef62c7d4afe8301d10c558d00dd24274d4bbe464380d3cd69"}, - {file = "orjson-3.10.12-cp39-none-win32.whl", hash = "sha256:c22c3ea6fba91d84fcb4cda30e64aff548fcf0c44c876e681f47d61d24b12e6b"}, - {file = "orjson-3.10.12-cp39-none-win_amd64.whl", hash = "sha256:be604f60d45ace6b0b33dd990a66b4526f1a7a186ac411c942674625456ca548"}, - {file = "orjson-3.10.12.tar.gz", hash = "sha256:0a78bbda3aea0f9f079057ee1ee8a1ecf790d4f1af88dd67493c6b8ee52506ff"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -3069,13 +3054,13 @@ files = [ [[package]] name = "pebble" -version = "5.0.7" +version = "5.1.0" description = "Threading and multiprocessing eye-candy." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "Pebble-5.0.7-py3-none-any.whl", hash = "sha256:f1742f2a62e8544e722c7b387211fb1a06038ca8cda322e5d55c84c793fd8d7d"}, - {file = "Pebble-5.0.7.tar.gz", hash = "sha256:2784c147766f06388cea784084b14bec93fdbaa793830f1983155aa330a2a6e4"}, + {file = "Pebble-5.1.0-py3-none-any.whl", hash = "sha256:530a398299ecd3a4ed1baf2e4b8045d8280b1e665560b0b409f8d8e58db60111"}, + {file = "Pebble-5.1.0.tar.gz", hash = "sha256:5c30376f1827b21ecec4126ff90e7f22ad5501cac1ff2b32c86ff2601681f932"}, ] [[package]] @@ -3174,109 +3159,93 @@ wcwidth = "*" [[package]] name = "propcache" -version = "0.2.0" +version = "0.2.1" description = "Accelerated property cache" optional = true -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58"}, - {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b"}, - {file = "propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336"}, - {file = "propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad"}, - {file = "propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b"}, - {file = "propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1"}, - {file = "propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348"}, - {file = "propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5"}, - {file = "propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544"}, - {file = "propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032"}, - {file = "propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed"}, - {file = "propcache-0.2.0-cp38-cp38-win32.whl", hash = "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d"}, - {file = "propcache-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798"}, - {file = "propcache-0.2.0-cp39-cp39-win32.whl", hash = "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9"}, - {file = "propcache-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df"}, - {file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"}, - {file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6b3f39a85d671436ee3d12c017f8fdea38509e4f25b28eb25877293c98c243f6"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d51fbe4285d5db5d92a929e3e21536ea3dd43732c5b177c7ef03f918dff9f2"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6445804cf4ec763dc70de65a3b0d9954e868609e83850a47ca4f0cb64bd79fea"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9479aa06a793c5aeba49ce5c5692ffb51fcd9a7016e017d555d5e2b0045d212"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9631c5e8b5b3a0fda99cb0d29c18133bca1e18aea9effe55adb3da1adef80d3"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3156628250f46a0895f1f36e1d4fbe062a1af8718ec3ebeb746f1d23f0c5dc4d"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b6fb63ae352e13748289f04f37868099e69dba4c2b3e271c46061e82c745634"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:887d9b0a65404929641a9fabb6452b07fe4572b269d901d622d8a34a4e9043b2"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a96dc1fa45bd8c407a0af03b2d5218392729e1822b0c32e62c5bf7eeb5fb3958"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a7e65eb5c003a303b94aa2c3852ef130230ec79e349632d030e9571b87c4698c"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:999779addc413181912e984b942fbcc951be1f5b3663cd80b2687758f434c583"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:19a0f89a7bb9d8048d9c4370c9c543c396e894c76be5525f5e1ad287f1750ddf"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1ac2f5fe02fa75f56e1ad473f1175e11f475606ec9bd0be2e78e4734ad575034"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:574faa3b79e8ebac7cb1d7930f51184ba1ccf69adfdec53a12f319a06030a68b"}, + {file = "propcache-0.2.1-cp310-cp310-win32.whl", hash = "sha256:03ff9d3f665769b2a85e6157ac8b439644f2d7fd17615a82fa55739bc97863f4"}, + {file = "propcache-0.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:2d3af2e79991102678f53e0dbf4c35de99b6b8b58f29a27ca0325816364caaba"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ffc3cca89bb438fb9c95c13fc874012f7b9466b89328c3c8b1aa93cdcfadd16"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f174bbd484294ed9fdf09437f889f95807e5f229d5d93588d34e92106fbf6717"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:70693319e0b8fd35dd863e3e29513875eb15c51945bf32519ef52927ca883bc3"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b480c6a4e1138e1aa137c0079b9b6305ec6dcc1098a8ca5196283e8a49df95a9"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d27b84d5880f6d8aa9ae3edb253c59d9f6642ffbb2c889b78b60361eed449787"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:857112b22acd417c40fa4595db2fe28ab900c8c5fe4670c7989b1c0230955465"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf6c4150f8c0e32d241436526f3c3f9cbd34429492abddbada2ffcff506c51af"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66d4cfda1d8ed687daa4bc0274fcfd5267873db9a5bc0418c2da19273040eeb7"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c2f992c07c0fca81655066705beae35fc95a2fa7366467366db627d9f2ee097f"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:4a571d97dbe66ef38e472703067021b1467025ec85707d57e78711c085984e54"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bb6178c241278d5fe853b3de743087be7f5f4c6f7d6d22a3b524d323eecec505"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ad1af54a62ffe39cf34db1aa6ed1a1873bd548f6401db39d8e7cd060b9211f82"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e7048abd75fe40712005bcfc06bb44b9dfcd8e101dda2ecf2f5aa46115ad07ca"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:160291c60081f23ee43d44b08a7e5fb76681221a8e10b3139618c5a9a291b84e"}, + {file = "propcache-0.2.1-cp311-cp311-win32.whl", hash = "sha256:819ce3b883b7576ca28da3861c7e1a88afd08cc8c96908e08a3f4dd64a228034"}, + {file = "propcache-0.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:edc9fc7051e3350643ad929df55c451899bb9ae6d24998a949d2e4c87fb596d3"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518"}, + {file = "propcache-0.2.1-cp312-cp312-win32.whl", hash = "sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246"}, + {file = "propcache-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aca405706e0b0a44cc6bfd41fbe89919a6a56999157f6de7e182a990c36e37bc"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:12d1083f001ace206fe34b6bdc2cb94be66d57a850866f0b908972f90996b3e9"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d93f3307ad32a27bda2e88ec81134b823c240aa3abb55821a8da553eed8d9439"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba278acf14471d36316159c94a802933d10b6a1e117b8554fe0d0d9b75c9d536"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4e6281aedfca15301c41f74d7005e6e3f4ca143584ba696ac69df4f02f40d629"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b750a8e5a1262434fb1517ddf64b5de58327f1adc3524a5e44c2ca43305eb0b"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf72af5e0fb40e9babf594308911436c8efde3cb5e75b6f206c34ad18be5c052"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2d0a12018b04f4cb820781ec0dffb5f7c7c1d2a5cd22bff7fb055a2cb19ebce"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e800776a79a5aabdb17dcc2346a7d66d0777e942e4cd251defeb084762ecd17d"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4160d9283bd382fa6c0c2b5e017acc95bc183570cd70968b9202ad6d8fc48dce"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:30b43e74f1359353341a7adb783c8f1b1c676367b011709f466f42fda2045e95"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:58791550b27d5488b1bb52bc96328456095d96206a250d28d874fafe11b3dfaf"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0f022d381747f0dfe27e99d928e31bc51a18b65bb9e481ae0af1380a6725dd1f"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:297878dc9d0a334358f9b608b56d02e72899f3b8499fc6044133f0d319e2ec30"}, + {file = "propcache-0.2.1-cp313-cp313-win32.whl", hash = "sha256:ddfab44e4489bd79bda09d84c430677fc7f0a4939a73d2bba3073036f487a0a6"}, + {file = "propcache-0.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:556fc6c10989f19a179e4321e5d678db8eb2924131e64652a51fe83e4c3db0e1"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6a9a8c34fb7bb609419a211e59da8887eeca40d300b5ea8e56af98f6fbbb1541"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ae1aa1cd222c6d205853b3013c69cd04515f9d6ab6de4b0603e2e1c33221303e"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:accb6150ce61c9c4b7738d45550806aa2b71c7668c6942f17b0ac182b6142fd4"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5eee736daafa7af6d0a2dc15cc75e05c64f37fc37bafef2e00d77c14171c2097"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7a31fc1e1bd362874863fdeed71aed92d348f5336fd84f2197ba40c59f061bd"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba4cfa1052819d16699e1d55d18c92b6e094d4517c41dd231a8b9f87b6fa681"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f089118d584e859c62b3da0892b88a83d611c2033ac410e929cb6754eec0ed16"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:781e65134efaf88feb447e8c97a51772aa75e48b794352f94cb7ea717dedda0d"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31f5af773530fd3c658b32b6bdc2d0838543de70eb9a2156c03e410f7b0d3aae"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:a7a078f5d37bee6690959c813977da5291b24286e7b962e62a94cec31aa5188b"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:cea7daf9fc7ae6687cf1e2c049752f19f146fdc37c2cc376e7d0032cf4f25347"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:8b3489ff1ed1e8315674d0775dc7d2195fb13ca17b3808721b54dbe9fd020faf"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9403db39be1393618dd80c746cb22ccda168efce239c73af13c3763ef56ffc04"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5d97151bc92d2b2578ff7ce779cdb9174337390a535953cbb9452fb65164c587"}, + {file = "propcache-0.2.1-cp39-cp39-win32.whl", hash = "sha256:9caac6b54914bdf41bcc91e7eb9147d331d29235a7c967c150ef5df6464fd1bb"}, + {file = "propcache-0.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:92fc4500fcb33899b05ba73276dfb684a20d31caa567b7cb5252d48f896a91b1"}, + {file = "propcache-0.2.1-py3-none-any.whl", hash = "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54"}, + {file = "propcache-0.2.1.tar.gz", hash = "sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64"}, ] [[package]] @@ -3318,32 +3287,32 @@ files = [ [[package]] name = "psutil" -version = "6.1.0" +version = "6.1.1" description = "Cross-platform lib for process and system monitoring in Python." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ - {file = "psutil-6.1.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff34df86226c0227c52f38b919213157588a678d049688eded74c76c8ba4a5d0"}, - {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c0e0c00aa18ca2d3b2b991643b799a15fc8f0563d2ebb6040f64ce8dc027b942"}, - {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:000d1d1ebd634b4efb383f4034437384e44a6d455260aaee2eca1e9c1b55f047"}, - {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5cd2bcdc75b452ba2e10f0e8ecc0b57b827dd5d7aaffbc6821b2a9a242823a76"}, - {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:045f00a43c737f960d273a83973b2511430d61f283a44c96bf13a6e829ba8fdc"}, - {file = "psutil-6.1.0-cp27-none-win32.whl", hash = "sha256:9118f27452b70bb1d9ab3198c1f626c2499384935aaf55388211ad982611407e"}, - {file = "psutil-6.1.0-cp27-none-win_amd64.whl", hash = "sha256:a8506f6119cff7015678e2bce904a4da21025cc70ad283a53b099e7620061d85"}, - {file = "psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688"}, - {file = "psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e"}, - {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38"}, - {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b"}, - {file = "psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a"}, - {file = "psutil-6.1.0-cp36-cp36m-win32.whl", hash = "sha256:6d3fbbc8d23fcdcb500d2c9f94e07b1342df8ed71b948a2649b5cb060a7c94ca"}, - {file = "psutil-6.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1209036fbd0421afde505a4879dee3b2fd7b1e14fee81c0069807adcbbcca747"}, - {file = "psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e"}, - {file = "psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be"}, - {file = "psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a"}, + {file = "psutil-6.1.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9ccc4316f24409159897799b83004cb1e24f9819b0dcf9c0b68bdcb6cefee6a8"}, + {file = "psutil-6.1.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ca9609c77ea3b8481ab005da74ed894035936223422dc591d6772b147421f777"}, + {file = "psutil-6.1.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:8df0178ba8a9e5bc84fed9cfa61d54601b371fbec5c8eebad27575f1e105c0d4"}, + {file = "psutil-6.1.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:1924e659d6c19c647e763e78670a05dbb7feaf44a0e9c94bf9e14dfc6ba50468"}, + {file = "psutil-6.1.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:018aeae2af92d943fdf1da6b58665124897cfc94faa2ca92098838f83e1b1bca"}, + {file = "psutil-6.1.1-cp27-none-win32.whl", hash = "sha256:6d4281f5bbca041e2292be3380ec56a9413b790579b8e593b1784499d0005dac"}, + {file = "psutil-6.1.1-cp27-none-win_amd64.whl", hash = "sha256:c777eb75bb33c47377c9af68f30e9f11bc78e0f07fbf907be4a5d70b2fe5f030"}, + {file = "psutil-6.1.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed7fe2231a444fc219b9c42d0376e0a9a1a72f16c5cfa0f68d19f1a0663e8"}, + {file = "psutil-6.1.1-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0bdd4eab935276290ad3cb718e9809412895ca6b5b334f5a9111ee6d9aff9377"}, + {file = "psutil-6.1.1-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6e06c20c05fe95a3d7302d74e7097756d4ba1247975ad6905441ae1b5b66003"}, + {file = "psutil-6.1.1-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97f7cb9921fbec4904f522d972f0c0e1f4fabbdd4e0287813b21215074a0f160"}, + {file = "psutil-6.1.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33431e84fee02bc84ea36d9e2c4a6d395d479c9dd9bba2376c1f6ee8f3a4e0b3"}, + {file = "psutil-6.1.1-cp36-cp36m-win32.whl", hash = "sha256:384636b1a64b47814437d1173be1427a7c83681b17a450bfc309a1953e329603"}, + {file = "psutil-6.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8be07491f6ebe1a693f17d4f11e69d0dc1811fa082736500f649f79df7735303"}, + {file = "psutil-6.1.1-cp37-abi3-win32.whl", hash = "sha256:eaa912e0b11848c4d9279a93d7e2783df352b082f40111e078388701fd479e53"}, + {file = "psutil-6.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:f35cfccb065fff93529d2afb4a2e89e363fe63ca1e4a5da22b603a85833c2649"}, + {file = "psutil-6.1.1.tar.gz", hash = "sha256:cf8496728c18f2d0b45198f06895be52f36611711746b7f30c464b422b50e2f5"}, ] [package.extras] -dev = ["black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "wheel"] +dev = ["abi3audit", "black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "vulture", "wheel"] test = ["pytest", "pytest-xdist", "setuptools"] [[package]] @@ -3538,13 +3507,13 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pyjwt" -version = "2.10.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false python-versions = ">=3.9" files = [ - {file = "PyJWT-2.10.0-py3-none-any.whl", hash = "sha256:543b77207db656de204372350926bed5a86201c4cbff159f623f79c7bb487a15"}, - {file = "pyjwt-2.10.0.tar.gz", hash = "sha256:7628a7eb7938959ac1b26e819a1df0fd3259505627b575e4bad6d08f76db695c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.dependencies] @@ -3574,22 +3543,22 @@ python-dateutil = ">=2.8.0" [[package]] name = "pylint" -version = "3.3.1" +version = "3.3.3" description = "python code static checker" optional = false python-versions = ">=3.9.0" files = [ - {file = "pylint-3.3.1-py3-none-any.whl", hash = "sha256:2f846a466dd023513240bc140ad2dd73bfc080a5d85a710afdb728c420a5a2b9"}, - {file = "pylint-3.3.1.tar.gz", hash = "sha256:9f3dcc87b1203e612b78d91a896407787e708b3f189b5fa0b307712d49ff0c6e"}, + {file = "pylint-3.3.3-py3-none-any.whl", hash = "sha256:26e271a2bc8bce0fc23833805a9076dd9b4d5194e2a02164942cb3cdc37b4183"}, + {file = "pylint-3.3.3.tar.gz", hash = "sha256:07c607523b17e6d16e2ae0d7ef59602e332caa762af64203c24b41c27139f36a"}, ] [package.dependencies] -astroid = ">=3.3.4,<=3.4.0-dev0" +astroid = ">=3.3.8,<=3.4.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = [ - {version = ">=0.2", markers = "python_version < \"3.11\""}, {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, {version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, + {version = ">=0.2", markers = "python_version < \"3.11\""}, ] isort = ">=4.2.5,<5.13.0 || >5.13.0,<6" mccabe = ">=0.6,<0.8" @@ -3954,6 +3923,20 @@ files = [ {file = "pywin32-308-cp39-cp39-win_amd64.whl", hash = "sha256:71b3322d949b4cc20776436a9c9ba0eeedcbc9c650daa536df63f0ff111bb920"}, ] +[[package]] +name = "pyxdr" +version = "1.0.0" +description = "F.A.C.C.T. XDR REST API Python Bindings" +optional = false +python-versions = "*" +files = [ + {file = "pyxdr-1.0.0-py3-none-any.whl", hash = "sha256:6ead7378aef7dee2c9699721e28fbc374e3be98244071848f7575a809a418305"}, + {file = "pyxdr-1.0.0.tar.gz", hash = "sha256:b4f230513dc1325ee1a301babcee9288f4bc589c12ab9031b5a95353436604b3"}, +] + +[package.dependencies] +requests = "*" + [[package]] name = "pyyaml" version = "6.0.2" @@ -4324,101 +4307,114 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "rpds-py" -version = "0.21.0" +version = "0.22.3" description = "Python bindings to Rust's persistent data structures (rpds)" optional = false python-versions = ">=3.9" files = [ - {file = "rpds_py-0.21.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a017f813f24b9df929674d0332a374d40d7f0162b326562daae8066b502d0590"}, - {file = "rpds_py-0.21.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:20cc1ed0bcc86d8e1a7e968cce15be45178fd16e2ff656a243145e0b439bd250"}, - {file = "rpds_py-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad116dda078d0bc4886cb7840e19811562acdc7a8e296ea6ec37e70326c1b41c"}, - {file = "rpds_py-0.21.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:808f1ac7cf3b44f81c9475475ceb221f982ef548e44e024ad5f9e7060649540e"}, - {file = "rpds_py-0.21.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de552f4a1916e520f2703ec474d2b4d3f86d41f353e7680b597512ffe7eac5d0"}, - {file = "rpds_py-0.21.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:efec946f331349dfc4ae9d0e034c263ddde19414fe5128580f512619abed05f1"}, - {file = "rpds_py-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b80b4690bbff51a034bfde9c9f6bf9357f0a8c61f548942b80f7b66356508bf5"}, - {file = "rpds_py-0.21.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:085ed25baac88953d4283e5b5bd094b155075bb40d07c29c4f073e10623f9f2e"}, - {file = "rpds_py-0.21.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:daa8efac2a1273eed2354397a51216ae1e198ecbce9036fba4e7610b308b6153"}, - {file = "rpds_py-0.21.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:95a5bad1ac8a5c77b4e658671642e4af3707f095d2b78a1fdd08af0dfb647624"}, - {file = "rpds_py-0.21.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3e53861b29a13d5b70116ea4230b5f0f3547b2c222c5daa090eb7c9c82d7f664"}, - {file = "rpds_py-0.21.0-cp310-none-win32.whl", hash = "sha256:ea3a6ac4d74820c98fcc9da4a57847ad2cc36475a8bd9683f32ab6d47a2bd682"}, - {file = "rpds_py-0.21.0-cp310-none-win_amd64.whl", hash = "sha256:b8f107395f2f1d151181880b69a2869c69e87ec079c49c0016ab96860b6acbe5"}, - {file = "rpds_py-0.21.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:5555db3e618a77034954b9dc547eae94166391a98eb867905ec8fcbce1308d95"}, - {file = "rpds_py-0.21.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:97ef67d9bbc3e15584c2f3c74bcf064af36336c10d2e21a2131e123ce0f924c9"}, - {file = "rpds_py-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ab2c2a26d2f69cdf833174f4d9d86118edc781ad9a8fa13970b527bf8236027"}, - {file = "rpds_py-0.21.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4e8921a259f54bfbc755c5bbd60c82bb2339ae0324163f32868f63f0ebb873d9"}, - {file = "rpds_py-0.21.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a7ff941004d74d55a47f916afc38494bd1cfd4b53c482b77c03147c91ac0ac3"}, - {file = "rpds_py-0.21.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5145282a7cd2ac16ea0dc46b82167754d5e103a05614b724457cffe614f25bd8"}, - {file = "rpds_py-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de609a6f1b682f70bb7163da745ee815d8f230d97276db049ab447767466a09d"}, - {file = "rpds_py-0.21.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:40c91c6e34cf016fa8e6b59d75e3dbe354830777fcfd74c58b279dceb7975b75"}, - {file = "rpds_py-0.21.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d2132377f9deef0c4db89e65e8bb28644ff75a18df5293e132a8d67748397b9f"}, - {file = "rpds_py-0.21.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0a9e0759e7be10109645a9fddaaad0619d58c9bf30a3f248a2ea57a7c417173a"}, - {file = "rpds_py-0.21.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9e20da3957bdf7824afdd4b6eeb29510e83e026473e04952dca565170cd1ecc8"}, - {file = "rpds_py-0.21.0-cp311-none-win32.whl", hash = "sha256:f71009b0d5e94c0e86533c0b27ed7cacc1239cb51c178fd239c3cfefefb0400a"}, - {file = "rpds_py-0.21.0-cp311-none-win_amd64.whl", hash = "sha256:e168afe6bf6ab7ab46c8c375606298784ecbe3ba31c0980b7dcbb9631dcba97e"}, - {file = "rpds_py-0.21.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:30b912c965b2aa76ba5168fd610087bad7fcde47f0a8367ee8f1876086ee6d1d"}, - {file = "rpds_py-0.21.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ca9989d5d9b1b300bc18e1801c67b9f6d2c66b8fd9621b36072ed1df2c977f72"}, - {file = "rpds_py-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f54e7106f0001244a5f4cf810ba8d3f9c542e2730821b16e969d6887b664266"}, - {file = "rpds_py-0.21.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fed5dfefdf384d6fe975cc026886aece4f292feaf69d0eeb716cfd3c5a4dd8be"}, - {file = "rpds_py-0.21.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:590ef88db231c9c1eece44dcfefd7515d8bf0d986d64d0caf06a81998a9e8cab"}, - {file = "rpds_py-0.21.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f983e4c2f603c95dde63df633eec42955508eefd8d0f0e6d236d31a044c882d7"}, - {file = "rpds_py-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b229ce052ddf1a01c67d68166c19cb004fb3612424921b81c46e7ea7ccf7c3bf"}, - {file = "rpds_py-0.21.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ebf64e281a06c904a7636781d2e973d1f0926a5b8b480ac658dc0f556e7779f4"}, - {file = "rpds_py-0.21.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:998a8080c4495e4f72132f3d66ff91f5997d799e86cec6ee05342f8f3cda7dca"}, - {file = "rpds_py-0.21.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:98486337f7b4f3c324ab402e83453e25bb844f44418c066623db88e4c56b7c7b"}, - {file = "rpds_py-0.21.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a78d8b634c9df7f8d175451cfeac3810a702ccb85f98ec95797fa98b942cea11"}, - {file = "rpds_py-0.21.0-cp312-none-win32.whl", hash = "sha256:a58ce66847711c4aa2ecfcfaff04cb0327f907fead8945ffc47d9407f41ff952"}, - {file = "rpds_py-0.21.0-cp312-none-win_amd64.whl", hash = "sha256:e860f065cc4ea6f256d6f411aba4b1251255366e48e972f8a347cf88077b24fd"}, - {file = "rpds_py-0.21.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:ee4eafd77cc98d355a0d02f263efc0d3ae3ce4a7c24740010a8b4012bbb24937"}, - {file = "rpds_py-0.21.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:688c93b77e468d72579351a84b95f976bd7b3e84aa6686be6497045ba84be560"}, - {file = "rpds_py-0.21.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c38dbf31c57032667dd5a2f0568ccde66e868e8f78d5a0d27dcc56d70f3fcd3b"}, - {file = "rpds_py-0.21.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2d6129137f43f7fa02d41542ffff4871d4aefa724a5fe38e2c31a4e0fd343fb0"}, - {file = "rpds_py-0.21.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:520ed8b99b0bf86a176271f6fe23024323862ac674b1ce5b02a72bfeff3fff44"}, - {file = "rpds_py-0.21.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aaeb25ccfb9b9014a10eaf70904ebf3f79faaa8e60e99e19eef9f478651b9b74"}, - {file = "rpds_py-0.21.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af04ac89c738e0f0f1b913918024c3eab6e3ace989518ea838807177d38a2e94"}, - {file = "rpds_py-0.21.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b9b76e2afd585803c53c5b29e992ecd183f68285b62fe2668383a18e74abe7a3"}, - {file = "rpds_py-0.21.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5afb5efde74c54724e1a01118c6e5c15e54e642c42a1ba588ab1f03544ac8c7a"}, - {file = "rpds_py-0.21.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:52c041802a6efa625ea18027a0723676a778869481d16803481ef6cc02ea8cb3"}, - {file = "rpds_py-0.21.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ee1e4fc267b437bb89990b2f2abf6c25765b89b72dd4a11e21934df449e0c976"}, - {file = "rpds_py-0.21.0-cp313-none-win32.whl", hash = "sha256:0c025820b78817db6a76413fff6866790786c38f95ea3f3d3c93dbb73b632202"}, - {file = "rpds_py-0.21.0-cp313-none-win_amd64.whl", hash = "sha256:320c808df533695326610a1b6a0a6e98f033e49de55d7dc36a13c8a30cfa756e"}, - {file = "rpds_py-0.21.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:2c51d99c30091f72a3c5d126fad26236c3f75716b8b5e5cf8effb18889ced928"}, - {file = "rpds_py-0.21.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cbd7504a10b0955ea287114f003b7ad62330c9e65ba012c6223dba646f6ffd05"}, - {file = "rpds_py-0.21.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6dcc4949be728ede49e6244eabd04064336012b37f5c2200e8ec8eb2988b209c"}, - {file = "rpds_py-0.21.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f414da5c51bf350e4b7960644617c130140423882305f7574b6cf65a3081cecb"}, - {file = "rpds_py-0.21.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9afe42102b40007f588666bc7de82451e10c6788f6f70984629db193849dced1"}, - {file = "rpds_py-0.21.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b929c2bb6e29ab31f12a1117c39f7e6d6450419ab7464a4ea9b0b417174f044"}, - {file = "rpds_py-0.21.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8404b3717da03cbf773a1d275d01fec84ea007754ed380f63dfc24fb76ce4592"}, - {file = "rpds_py-0.21.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e12bb09678f38b7597b8346983d2323a6482dcd59e423d9448108c1be37cac9d"}, - {file = "rpds_py-0.21.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:58a0e345be4b18e6b8501d3b0aa540dad90caeed814c515e5206bb2ec26736fd"}, - {file = "rpds_py-0.21.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c3761f62fcfccf0864cc4665b6e7c3f0c626f0380b41b8bd1ce322103fa3ef87"}, - {file = "rpds_py-0.21.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c2b2f71c6ad6c2e4fc9ed9401080badd1469fa9889657ec3abea42a3d6b2e1ed"}, - {file = "rpds_py-0.21.0-cp39-none-win32.whl", hash = "sha256:b21747f79f360e790525e6f6438c7569ddbfb1b3197b9e65043f25c3c9b489d8"}, - {file = "rpds_py-0.21.0-cp39-none-win_amd64.whl", hash = "sha256:0626238a43152918f9e72ede9a3b6ccc9e299adc8ade0d67c5e142d564c9a83d"}, - {file = "rpds_py-0.21.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6b4ef7725386dc0762857097f6b7266a6cdd62bfd209664da6712cb26acef035"}, - {file = "rpds_py-0.21.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:6bc0e697d4d79ab1aacbf20ee5f0df80359ecf55db33ff41481cf3e24f206919"}, - {file = "rpds_py-0.21.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da52d62a96e61c1c444f3998c434e8b263c384f6d68aca8274d2e08d1906325c"}, - {file = "rpds_py-0.21.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:98e4fe5db40db87ce1c65031463a760ec7906ab230ad2249b4572c2fc3ef1f9f"}, - {file = "rpds_py-0.21.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30bdc973f10d28e0337f71d202ff29345320f8bc49a31c90e6c257e1ccef4333"}, - {file = "rpds_py-0.21.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:faa5e8496c530f9c71f2b4e1c49758b06e5f4055e17144906245c99fa6d45356"}, - {file = "rpds_py-0.21.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32eb88c30b6a4f0605508023b7141d043a79b14acb3b969aa0b4f99b25bc7d4a"}, - {file = "rpds_py-0.21.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a89a8ce9e4e75aeb7fa5d8ad0f3fecdee813802592f4f46a15754dcb2fd6b061"}, - {file = "rpds_py-0.21.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:241e6c125568493f553c3d0fdbb38c74babf54b45cef86439d4cd97ff8feb34d"}, - {file = "rpds_py-0.21.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:3b766a9f57663396e4f34f5140b3595b233a7b146e94777b97a8413a1da1be18"}, - {file = "rpds_py-0.21.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:af4a644bf890f56e41e74be7d34e9511e4954894d544ec6b8efe1e21a1a8da6c"}, - {file = "rpds_py-0.21.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3e30a69a706e8ea20444b98a49f386c17b26f860aa9245329bab0851ed100677"}, - {file = "rpds_py-0.21.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:031819f906bb146561af051c7cef4ba2003d28cff07efacef59da973ff7969ba"}, - {file = "rpds_py-0.21.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b876f2bc27ab5954e2fd88890c071bd0ed18b9c50f6ec3de3c50a5ece612f7a6"}, - {file = "rpds_py-0.21.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc5695c321e518d9f03b7ea6abb5ea3af4567766f9852ad1560f501b17588c7b"}, - {file = "rpds_py-0.21.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b4de1da871b5c0fd5537b26a6fc6814c3cc05cabe0c941db6e9044ffbb12f04a"}, - {file = "rpds_py-0.21.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:878f6fea96621fda5303a2867887686d7a198d9e0f8a40be100a63f5d60c88c9"}, - {file = "rpds_py-0.21.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8eeec67590e94189f434c6d11c426892e396ae59e4801d17a93ac96b8c02a6c"}, - {file = "rpds_py-0.21.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ff2eba7f6c0cb523d7e9cff0903f2fe1feff8f0b2ceb6bd71c0e20a4dcee271"}, - {file = "rpds_py-0.21.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a429b99337062877d7875e4ff1a51fe788424d522bd64a8c0a20ef3021fdb6ed"}, - {file = "rpds_py-0.21.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:d167e4dbbdac48bd58893c7e446684ad5d425b407f9336e04ab52e8b9194e2ed"}, - {file = "rpds_py-0.21.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:4eb2de8a147ffe0626bfdc275fc6563aa7bf4b6db59cf0d44f0ccd6ca625a24e"}, - {file = "rpds_py-0.21.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:e78868e98f34f34a88e23ee9ccaeeec460e4eaf6db16d51d7a9b883e5e785a5e"}, - {file = "rpds_py-0.21.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4991ca61656e3160cdaca4851151fd3f4a92e9eba5c7a530ab030d6aee96ec89"}, - {file = "rpds_py-0.21.0.tar.gz", hash = "sha256:ed6378c9d66d0de903763e7706383d60c33829581f0adff47b6535f1802fa6db"}, + {file = "rpds_py-0.22.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:6c7b99ca52c2c1752b544e310101b98a659b720b21db00e65edca34483259967"}, + {file = "rpds_py-0.22.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:be2eb3f2495ba669d2a985f9b426c1797b7d48d6963899276d22f23e33d47e37"}, + {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70eb60b3ae9245ddea20f8a4190bd79c705a22f8028aaf8bbdebe4716c3fab24"}, + {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4041711832360a9b75cfb11b25a6a97c8fb49c07b8bd43d0d02b45d0b499a4ff"}, + {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:64607d4cbf1b7e3c3c8a14948b99345eda0e161b852e122c6bb71aab6d1d798c"}, + {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e69b0a0e2537f26d73b4e43ad7bc8c8efb39621639b4434b76a3de50c6966e"}, + {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc27863442d388870c1809a87507727b799c8460573cfbb6dc0eeaef5a11b5ec"}, + {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e79dd39f1e8c3504be0607e5fc6e86bb60fe3584bec8b782578c3b0fde8d932c"}, + {file = "rpds_py-0.22.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e0fa2d4ec53dc51cf7d3bb22e0aa0143966119f42a0c3e4998293a3dd2856b09"}, + {file = "rpds_py-0.22.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fda7cb070f442bf80b642cd56483b5548e43d366fe3f39b98e67cce780cded00"}, + {file = "rpds_py-0.22.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cff63a0272fcd259dcc3be1657b07c929c466b067ceb1c20060e8d10af56f5bf"}, + {file = "rpds_py-0.22.3-cp310-cp310-win32.whl", hash = "sha256:9bd7228827ec7bb817089e2eb301d907c0d9827a9e558f22f762bb690b131652"}, + {file = "rpds_py-0.22.3-cp310-cp310-win_amd64.whl", hash = "sha256:9beeb01d8c190d7581a4d59522cd3d4b6887040dcfc744af99aa59fef3e041a8"}, + {file = "rpds_py-0.22.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d20cfb4e099748ea39e6f7b16c91ab057989712d31761d3300d43134e26e165f"}, + {file = "rpds_py-0.22.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:68049202f67380ff9aa52f12e92b1c30115f32e6895cd7198fa2a7961621fc5a"}, + {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb4f868f712b2dd4bcc538b0a0c1f63a2b1d584c925e69a224d759e7070a12d5"}, + {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bc51abd01f08117283c5ebf64844a35144a0843ff7b2983e0648e4d3d9f10dbb"}, + {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f3cec041684de9a4684b1572fe28c7267410e02450f4561700ca5a3bc6695a2"}, + {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7ef9d9da710be50ff6809fed8f1963fecdfecc8b86656cadfca3bc24289414b0"}, + {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59f4a79c19232a5774aee369a0c296712ad0e77f24e62cad53160312b1c1eaa1"}, + {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a60bce91f81ddaac922a40bbb571a12c1070cb20ebd6d49c48e0b101d87300d"}, + {file = "rpds_py-0.22.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e89391e6d60251560f0a8f4bd32137b077a80d9b7dbe6d5cab1cd80d2746f648"}, + {file = "rpds_py-0.22.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e3fb866d9932a3d7d0c82da76d816996d1667c44891bd861a0f97ba27e84fc74"}, + {file = "rpds_py-0.22.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1352ae4f7c717ae8cba93421a63373e582d19d55d2ee2cbb184344c82d2ae55a"}, + {file = "rpds_py-0.22.3-cp311-cp311-win32.whl", hash = "sha256:b0b4136a252cadfa1adb705bb81524eee47d9f6aab4f2ee4fa1e9d3cd4581f64"}, + {file = "rpds_py-0.22.3-cp311-cp311-win_amd64.whl", hash = "sha256:8bd7c8cfc0b8247c8799080fbff54e0b9619e17cdfeb0478ba7295d43f635d7c"}, + {file = "rpds_py-0.22.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:27e98004595899949bd7a7b34e91fa7c44d7a97c40fcaf1d874168bb652ec67e"}, + {file = "rpds_py-0.22.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1978d0021e943aae58b9b0b196fb4895a25cc53d3956b8e35e0b7682eefb6d56"}, + {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:655ca44a831ecb238d124e0402d98f6212ac527a0ba6c55ca26f616604e60a45"}, + {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:feea821ee2a9273771bae61194004ee2fc33f8ec7db08117ef9147d4bbcbca8e"}, + {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22bebe05a9ffc70ebfa127efbc429bc26ec9e9b4ee4d15a740033efda515cf3d"}, + {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3af6e48651c4e0d2d166dc1b033b7042ea3f871504b6805ba5f4fe31581d8d38"}, + {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67ba3c290821343c192f7eae1d8fd5999ca2dc99994114643e2f2d3e6138b15"}, + {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:02fbb9c288ae08bcb34fb41d516d5eeb0455ac35b5512d03181d755d80810059"}, + {file = "rpds_py-0.22.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f56a6b404f74ab372da986d240e2e002769a7d7102cc73eb238a4f72eec5284e"}, + {file = "rpds_py-0.22.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0a0461200769ab3b9ab7e513f6013b7a97fdeee41c29b9db343f3c5a8e2b9e61"}, + {file = "rpds_py-0.22.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8633e471c6207a039eff6aa116e35f69f3156b3989ea3e2d755f7bc41754a4a7"}, + {file = "rpds_py-0.22.3-cp312-cp312-win32.whl", hash = "sha256:593eba61ba0c3baae5bc9be2f5232430453fb4432048de28399ca7376de9c627"}, + {file = "rpds_py-0.22.3-cp312-cp312-win_amd64.whl", hash = "sha256:d115bffdd417c6d806ea9069237a4ae02f513b778e3789a359bc5856e0404cc4"}, + {file = "rpds_py-0.22.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:ea7433ce7e4bfc3a85654aeb6747babe3f66eaf9a1d0c1e7a4435bbdf27fea84"}, + {file = "rpds_py-0.22.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6dd9412824c4ce1aca56c47b0991e65bebb7ac3f4edccfd3f156150c96a7bf25"}, + {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20070c65396f7373f5df4005862fa162db5d25d56150bddd0b3e8214e8ef45b4"}, + {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0b09865a9abc0ddff4e50b5ef65467cd94176bf1e0004184eb915cbc10fc05c5"}, + {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3453e8d41fe5f17d1f8e9c383a7473cd46a63661628ec58e07777c2fff7196dc"}, + {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f5d36399a1b96e1a5fdc91e0522544580dbebeb1f77f27b2b0ab25559e103b8b"}, + {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:009de23c9c9ee54bf11303a966edf4d9087cd43a6003672e6aa7def643d06518"}, + {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1aef18820ef3e4587ebe8b3bc9ba6e55892a6d7b93bac6d29d9f631a3b4befbd"}, + {file = "rpds_py-0.22.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f60bd8423be1d9d833f230fdbccf8f57af322d96bcad6599e5a771b151398eb2"}, + {file = "rpds_py-0.22.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:62d9cfcf4948683a18a9aff0ab7e1474d407b7bab2ca03116109f8464698ab16"}, + {file = "rpds_py-0.22.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9253fc214112405f0afa7db88739294295f0e08466987f1d70e29930262b4c8f"}, + {file = "rpds_py-0.22.3-cp313-cp313-win32.whl", hash = "sha256:fb0ba113b4983beac1a2eb16faffd76cb41e176bf58c4afe3e14b9c681f702de"}, + {file = "rpds_py-0.22.3-cp313-cp313-win_amd64.whl", hash = "sha256:c58e2339def52ef6b71b8f36d13c3688ea23fa093353f3a4fee2556e62086ec9"}, + {file = "rpds_py-0.22.3-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:f82a116a1d03628a8ace4859556fb39fd1424c933341a08ea3ed6de1edb0283b"}, + {file = "rpds_py-0.22.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3dfcbc95bd7992b16f3f7ba05af8a64ca694331bd24f9157b49dadeeb287493b"}, + {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59259dc58e57b10e7e18ce02c311804c10c5a793e6568f8af4dead03264584d1"}, + {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5725dd9cc02068996d4438d397e255dcb1df776b7ceea3b9cb972bdb11260a83"}, + {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99b37292234e61325e7a5bb9689e55e48c3f5f603af88b1642666277a81f1fbd"}, + {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:27b1d3b3915a99208fee9ab092b8184c420f2905b7d7feb4aeb5e4a9c509b8a1"}, + {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f612463ac081803f243ff13cccc648578e2279295048f2a8d5eb430af2bae6e3"}, + {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f73d3fef726b3243a811121de45193c0ca75f6407fe66f3f4e183c983573e130"}, + {file = "rpds_py-0.22.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3f21f0495edea7fdbaaa87e633a8689cd285f8f4af5c869f27bc8074638ad69c"}, + {file = "rpds_py-0.22.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:1e9663daaf7a63ceccbbb8e3808fe90415b0757e2abddbfc2e06c857bf8c5e2b"}, + {file = "rpds_py-0.22.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a76e42402542b1fae59798fab64432b2d015ab9d0c8c47ba7addddbaf7952333"}, + {file = "rpds_py-0.22.3-cp313-cp313t-win32.whl", hash = "sha256:69803198097467ee7282750acb507fba35ca22cc3b85f16cf45fb01cb9097730"}, + {file = "rpds_py-0.22.3-cp313-cp313t-win_amd64.whl", hash = "sha256:f5cf2a0c2bdadf3791b5c205d55a37a54025c6e18a71c71f82bb536cf9a454bf"}, + {file = "rpds_py-0.22.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:378753b4a4de2a7b34063d6f95ae81bfa7b15f2c1a04a9518e8644e81807ebea"}, + {file = "rpds_py-0.22.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3445e07bf2e8ecfeef6ef67ac83de670358abf2996916039b16a218e3d95e97e"}, + {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b2513ba235829860b13faa931f3b6846548021846ac808455301c23a101689d"}, + {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eaf16ae9ae519a0e237a0f528fd9f0197b9bb70f40263ee57ae53c2b8d48aeb3"}, + {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:583f6a1993ca3369e0f80ba99d796d8e6b1a3a2a442dd4e1a79e652116413091"}, + {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4617e1915a539a0d9a9567795023de41a87106522ff83fbfaf1f6baf8e85437e"}, + {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c150c7a61ed4a4f4955a96626574e9baf1adf772c2fb61ef6a5027e52803543"}, + {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2fa4331c200c2521512595253f5bb70858b90f750d39b8cbfd67465f8d1b596d"}, + {file = "rpds_py-0.22.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:214b7a953d73b5e87f0ebece4a32a5bd83c60a3ecc9d4ec8f1dca968a2d91e99"}, + {file = "rpds_py-0.22.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f47ad3d5f3258bd7058d2d506852217865afefe6153a36eb4b6928758041d831"}, + {file = "rpds_py-0.22.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f276b245347e6e36526cbd4a266a417796fc531ddf391e43574cf6466c492520"}, + {file = "rpds_py-0.22.3-cp39-cp39-win32.whl", hash = "sha256:bbb232860e3d03d544bc03ac57855cd82ddf19c7a07651a7c0fdb95e9efea8b9"}, + {file = "rpds_py-0.22.3-cp39-cp39-win_amd64.whl", hash = "sha256:cfbc454a2880389dbb9b5b398e50d439e2e58669160f27b60e5eca11f68ae17c"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d48424e39c2611ee1b84ad0f44fb3b2b53d473e65de061e3f460fc0be5f1939d"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:24e8abb5878e250f2eb0d7859a8e561846f98910326d06c0d51381fed59357bd"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b232061ca880db21fa14defe219840ad9b74b6158adb52ddf0e87bead9e8493"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac0a03221cdb5058ce0167ecc92a8c89e8d0decdc9e99a2ec23380793c4dcb96"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb0c341fa71df5a4595f9501df4ac5abfb5a09580081dffbd1ddd4654e6e9123"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf9db5488121b596dbfc6718c76092fda77b703c1f7533a226a5a9f65248f8ad"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b8db6b5b2d4491ad5b6bdc2bc7c017eec108acbf4e6785f42a9eb0ba234f4c9"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b3d504047aba448d70cf6fa22e06cb09f7cbd761939fdd47604f5e007675c24e"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:e61b02c3f7a1e0b75e20c3978f7135fd13cb6cf551bf4a6d29b999a88830a338"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:e35ba67d65d49080e8e5a1dd40101fccdd9798adb9b050ff670b7d74fa41c566"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:26fd7cac7dd51011a245f29a2cc6489c4608b5a8ce8d75661bb4a1066c52dfbe"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:177c7c0fce2855833819c98e43c262007f42ce86651ffbb84f37883308cb0e7d"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bb47271f60660803ad11f4c61b42242b8c1312a31c98c578f79ef9387bbde21c"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:70fb28128acbfd264eda9bf47015537ba3fe86e40d046eb2963d75024be4d055"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44d61b4b7d0c2c9ac019c314e52d7cbda0ae31078aabd0f22e583af3e0d79723"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f0e260eaf54380380ac3808aa4ebe2d8ca28b9087cf411649f96bad6900c728"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b25bc607423935079e05619d7de556c91fb6adeae9d5f80868dde3468657994b"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fb6116dfb8d1925cbdb52595560584db42a7f664617a1f7d7f6e32f138cdf37d"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a63cbdd98acef6570c62b92a1e43266f9e8b21e699c363c0fef13bd530799c11"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2b8f60e1b739a74bab7e01fcbe3dddd4657ec685caa04681df9d562ef15b625f"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2e8b55d8517a2fda8d95cb45d62a5a8bbf9dd0ad39c5b25c8833efea07b880ca"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:2de29005e11637e7a2361fa151f780ff8eb2543a0da1413bb951e9f14b699ef3"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:666ecce376999bf619756a24ce15bb14c5bfaf04bf00abc7e663ce17c3f34fe7"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:5246b14ca64a8675e0a7161f7af68fe3e910e6b90542b4bfb5439ba752191df6"}, + {file = "rpds_py-0.22.3.tar.gz", hash = "sha256:e32fee8ab45d3c2db6da19a5323bc3362237c8b653c70194414b892fd06a080d"}, ] [[package]] @@ -4563,38 +4559,38 @@ files = [ [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] name = "slack-sdk" -version = "3.33.4" +version = "3.34.0" description = "The Slack API Platform SDK for Python" optional = false python-versions = ">=3.6" files = [ - {file = "slack_sdk-3.33.4-py2.py3-none-any.whl", hash = "sha256:9f30cb3c9c07b441c49d53fc27f9f1837ad1592a7e9d4ca431f53cdad8826cc6"}, - {file = "slack_sdk-3.33.4.tar.gz", hash = "sha256:5e109847f6b6a22d227609226ba4ed936109dc00675bddeb7e0bee502d3ee7e0"}, + {file = "slack_sdk-3.34.0-py2.py3-none-any.whl", hash = "sha256:c61f57f310d85be83466db5a98ab6ae3bb2e5587437b54fa0daa8fae6a0feffa"}, + {file = "slack_sdk-3.34.0.tar.gz", hash = "sha256:ff61db7012160eed742285ea91f11c72b7a38a6500a7f6c5335662b4bc6b853d"}, ] [package.extras] -optional = ["SQLAlchemy (>=1.4,<3)", "aiodns (>1.0)", "aiohttp (>=3.7.3,<4)", "boto3 (<=2)", "websocket-client (>=1,<2)", "websockets (>=9.1,<14)"] +optional = ["SQLAlchemy (>=1.4,<3)", "aiodns (>1.0)", "aiohttp (>=3.7.3,<4)", "boto3 (<=2)", "websocket-client (>=1,<2)", "websockets (>=9.1,<15)"] [[package]] name = "smmap" -version = "5.0.1" +version = "5.0.2" description = "A pure Python implementation of a sliding window memory map manager" optional = false python-versions = ">=3.7" files = [ - {file = "smmap-5.0.1-py3-none-any.whl", hash = "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da"}, - {file = "smmap-5.0.1.tar.gz", hash = "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62"}, + {file = "smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e"}, + {file = "smmap-5.0.2.tar.gz", hash = "sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5"}, ] [[package]] @@ -4708,13 +4704,43 @@ files = [ [[package]] name = "tomli" -version = "2.1.0" +version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "tomli-2.1.0-py3-none-any.whl", hash = "sha256:a5c57c3d1c56f5ccdf89f6523458f60ef716e210fc47c4cfb188c5ba473e0391"}, - {file = "tomli-2.1.0.tar.gz", hash = "sha256:3f646cae2aec94e17d04973e4249548320197cfabdf130015d023de4b74d8ab8"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] [[package]] @@ -4886,24 +4912,24 @@ files = [ [[package]] name = "types-python-dateutil" -version = "2.9.0.20241003" +version = "2.9.0.20241206" description = "Typing stubs for python-dateutil" optional = false python-versions = ">=3.8" files = [ - {file = "types-python-dateutil-2.9.0.20241003.tar.gz", hash = "sha256:58cb85449b2a56d6684e41aeefb4c4280631246a0da1a719bdbe6f3fb0317446"}, - {file = "types_python_dateutil-2.9.0.20241003-py3-none-any.whl", hash = "sha256:250e1d8e80e7bbc3a6c99b907762711d1a1cdd00e978ad39cb5940f6f0a87f3d"}, + {file = "types_python_dateutil-2.9.0.20241206-py3-none-any.whl", hash = "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53"}, + {file = "types_python_dateutil-2.9.0.20241206.tar.gz", hash = "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb"}, ] [[package]] name = "types-pytz" -version = "2024.2.0.20241003" +version = "2024.2.0.20241221" description = "Typing stubs for pytz" optional = false python-versions = ">=3.8" files = [ - {file = "types-pytz-2024.2.0.20241003.tar.gz", hash = "sha256:575dc38f385a922a212bac00a7d6d2e16e141132a3c955078f4a4fd13ed6cb44"}, - {file = "types_pytz-2024.2.0.20241003-py3-none-any.whl", hash = "sha256:3e22df1336c0c6ad1d29163c8fda82736909eb977281cb823c57f8bae07118b7"}, + {file = "types_pytz-2024.2.0.20241221-py3-none-any.whl", hash = "sha256:8fc03195329c43637ed4f593663df721fef919b60a969066e22606edf0b53ad5"}, + {file = "types_pytz-2024.2.0.20241221.tar.gz", hash = "sha256:06d7cde9613e9f7504766a0554a270c369434b50e00975b3a4a0f6eed0f2c1a9"}, ] [[package]] @@ -4922,24 +4948,24 @@ urllib3 = ">=2" [[package]] name = "types-setuptools" -version = "75.5.0.20241122" +version = "75.6.0.20241223" description = "Typing stubs for setuptools" optional = false python-versions = ">=3.8" files = [ - {file = "types_setuptools-75.5.0.20241122-py3-none-any.whl", hash = "sha256:d69c445f7bdd5e49d1b2441aadcee1388febcc9ad9d9d5fd33648b555e0b1c31"}, - {file = "types_setuptools-75.5.0.20241122.tar.gz", hash = "sha256:196aaf1811cbc1c77ac1d4c4879d5308b6fdf426e56b73baadbca2a1827dadef"}, + {file = "types_setuptools-75.6.0.20241223-py3-none-any.whl", hash = "sha256:7cbfd3bf2944f88bbcdd321b86ddd878232a277be95d44c78a53585d78ebc2f6"}, + {file = "types_setuptools-75.6.0.20241223.tar.gz", hash = "sha256:d9478a985057ed48a994c707f548e55aababa85fe1c9b212f43ab5a1fffd3211"}, ] [[package]] name = "types-tabulate" -version = "0.9.0.20240106" +version = "0.9.0.20241207" description = "Typing stubs for tabulate" optional = false python-versions = ">=3.8" files = [ - {file = "types-tabulate-0.9.0.20240106.tar.gz", hash = "sha256:c9b6db10dd7fcf55bd1712dd3537f86ddce72a08fd62bb1af4338c7096ce947e"}, - {file = "types_tabulate-0.9.0.20240106-py3-none-any.whl", hash = "sha256:0378b7b6fe0ccb4986299496d027a6d4c218298ecad67199bbd0e2d7e9d335a1"}, + {file = "types_tabulate-0.9.0.20241207-py3-none-any.whl", hash = "sha256:b8dad1343c2a8ba5861c5441370c3e35908edd234ff036d4298708a1d4cf8a85"}, + {file = "types_tabulate-0.9.0.20241207.tar.gz", hash = "sha256:ac1ac174750c0a385dfd248edc6279fa328aaf4ea317915ab879a2ec47833230"}, ] [[package]] @@ -5093,13 +5119,13 @@ files = [ [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -5147,13 +5173,13 @@ files = [ [[package]] name = "virtualenv" -version = "20.27.1" +version = "20.28.0" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.8" files = [ - {file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"}, - {file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"}, + {file = "virtualenv-20.28.0-py3-none-any.whl", hash = "sha256:23eae1b4516ecd610481eda647f3a7c09aea295055337331bb4e6892ecce47b0"}, + {file = "virtualenv-20.28.0.tar.gz", hash = "sha256:2c9c3262bb8e7b87ea801d715fae4495e6032450c71d2309be9550e7364049aa"}, ] [package.dependencies] @@ -5167,13 +5193,13 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess [[package]] name = "vulture" -version = "2.13" +version = "2.14" description = "Find dead code" optional = false python-versions = ">=3.8" files = [ - {file = "vulture-2.13-py2.py3-none-any.whl", hash = "sha256:34793ba60488e7cccbecdef3a7fe151656372ef94fdac9fe004c52a4000a6d44"}, - {file = "vulture-2.13.tar.gz", hash = "sha256:78248bf58f5eaffcc2ade306141ead73f437339950f80045dce7f8b078e5a1aa"}, + {file = "vulture-2.14-py2.py3-none-any.whl", hash = "sha256:d9a90dba89607489548a49d557f8bac8112bd25d3cbc8aeef23e860811bd5ed9"}, + {file = "vulture-2.14.tar.gz", hash = "sha256:cb8277902a1138deeab796ec5bef7076a6e0248ca3607a3f3dee0b6d9e9b8415"}, ] [package.dependencies] @@ -5223,13 +5249,13 @@ watchdog = ["watchdog (>=2.3)"] [[package]] name = "win32-setctime" -version = "1.1.0" +version = "1.2.0" description = "A small Python utility to set file creation time on Windows" optional = false python-versions = ">=3.5" files = [ - {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"}, - {file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"}, + {file = "win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390"}, + {file = "win32_setctime-1.2.0.tar.gz", hash = "sha256:ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0"}, ] [package.extras] @@ -5339,93 +5365,93 @@ pyyaml = "*" [[package]] name = "yarl" -version = "1.18.0" +version = "1.18.3" description = "Yet another URL library" optional = true python-versions = ">=3.9" files = [ - {file = "yarl-1.18.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:074fee89caab89a97e18ef5f29060ef61ba3cae6cd77673acc54bfdd3214b7b7"}, - {file = "yarl-1.18.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b026cf2c32daf48d90c0c4e406815c3f8f4cfe0c6dfccb094a9add1ff6a0e41a"}, - {file = "yarl-1.18.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ae38bd86eae3ba3d2ce5636cc9e23c80c9db2e9cb557e40b98153ed102b5a736"}, - {file = "yarl-1.18.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:685cc37f3f307c6a8e879986c6d85328f4c637f002e219f50e2ef66f7e062c1d"}, - {file = "yarl-1.18.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8254dbfce84ee5d1e81051ee7a0f1536c108ba294c0fdb5933476398df0654f3"}, - {file = "yarl-1.18.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20de4a8b04de70c49698dc2390b7fd2d18d424d3b876371f9b775e2b462d4b41"}, - {file = "yarl-1.18.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0a2074a37285570d54b55820687de3d2f2b9ecf1b714e482e48c9e7c0402038"}, - {file = "yarl-1.18.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f576ed278860df2721a5d57da3381040176ef1d07def9688a385c8330db61a1"}, - {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3a3709450a574d61be6ac53d582496014342ea34876af8dc17cc16da32826c9a"}, - {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:bd80ed29761490c622edde5dd70537ca8c992c2952eb62ed46984f8eff66d6e8"}, - {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:32141e13a1d5a48525e519c9197d3f4d9744d818d5c7d6547524cc9eccc8971e"}, - {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8b8d3e4e014fb4274f1c5bf61511d2199e263909fb0b8bda2a7428b0894e8dc6"}, - {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:701bb4a8f4de191c8c0cc9a1e6d5142f4df880e9d1210e333b829ca9425570ed"}, - {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a45d94075ac0647621eaaf693c8751813a3eccac455d423f473ffed38c8ac5c9"}, - {file = "yarl-1.18.0-cp310-cp310-win32.whl", hash = "sha256:34176bfb082add67cb2a20abd85854165540891147f88b687a5ed0dc225750a0"}, - {file = "yarl-1.18.0-cp310-cp310-win_amd64.whl", hash = "sha256:73553bbeea7d6ec88c08ad8027f4e992798f0abc459361bf06641c71972794dc"}, - {file = "yarl-1.18.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b8e8c516dc4e1a51d86ac975b0350735007e554c962281c432eaa5822aa9765c"}, - {file = "yarl-1.18.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2e6b4466714a73f5251d84b471475850954f1fa6acce4d3f404da1d55d644c34"}, - {file = "yarl-1.18.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c893f8c1a6d48b25961e00922724732d00b39de8bb0b451307482dc87bddcd74"}, - {file = "yarl-1.18.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13aaf2bdbc8c86ddce48626b15f4987f22e80d898818d735b20bd58f17292ee8"}, - {file = "yarl-1.18.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd21c0128e301851de51bc607b0a6da50e82dc34e9601f4b508d08cc89ee7929"}, - {file = "yarl-1.18.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:205de377bd23365cd85562c9c6c33844050a93661640fda38e0567d2826b50df"}, - {file = "yarl-1.18.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed69af4fe2a0949b1ea1d012bf065c77b4c7822bad4737f17807af2adb15a73c"}, - {file = "yarl-1.18.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e1c18890091aa3cc8a77967943476b729dc2016f4cfe11e45d89b12519d4a93"}, - {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:91b8fb9427e33f83ca2ba9501221ffaac1ecf0407f758c4d2f283c523da185ee"}, - {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:536a7a8a53b75b2e98ff96edb2dfb91a26b81c4fed82782035767db5a465be46"}, - {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a64619a9c47c25582190af38e9eb382279ad42e1f06034f14d794670796016c0"}, - {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c73a6bbc97ba1b5a0c3c992ae93d721c395bdbb120492759b94cc1ac71bc6350"}, - {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a173401d7821a2a81c7b47d4e7d5c4021375a1441af0c58611c1957445055056"}, - {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7520e799b1f84e095cce919bd6c23c9d49472deeef25fe1ef960b04cca51c3fc"}, - {file = "yarl-1.18.0-cp311-cp311-win32.whl", hash = "sha256:c4cb992d8090d5ae5f7afa6754d7211c578be0c45f54d3d94f7781c495d56716"}, - {file = "yarl-1.18.0-cp311-cp311-win_amd64.whl", hash = "sha256:52c136f348605974c9b1c878addd6b7a60e3bf2245833e370862009b86fa4689"}, - {file = "yarl-1.18.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1ece25e2251c28bab737bdf0519c88189b3dd9492dc086a1d77336d940c28ced"}, - {file = "yarl-1.18.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:454902dc1830d935c90b5b53c863ba2a98dcde0fbaa31ca2ed1ad33b2a7171c6"}, - {file = "yarl-1.18.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:01be8688fc211dc237e628fcc209dda412d35de7642453059a0553747018d075"}, - {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d26f1fa9fa2167bb238f6f4b20218eb4e88dd3ef21bb8f97439fa6b5313e30d"}, - {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b234a4a9248a9f000b7a5dfe84b8cb6210ee5120ae70eb72a4dcbdb4c528f72f"}, - {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe94d1de77c4cd8caff1bd5480e22342dbd54c93929f5943495d9c1e8abe9f42"}, - {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b4c90c5363c6b0a54188122b61edb919c2cd1119684999d08cd5e538813a28e"}, - {file = "yarl-1.18.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a98ecadc5a241c9ba06de08127ee4796e1009555efd791bac514207862b43d"}, - {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9106025c7f261f9f5144f9aa7681d43867eed06349a7cfb297a1bc804de2f0d1"}, - {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f275ede6199d0f1ed4ea5d55a7b7573ccd40d97aee7808559e1298fe6efc8dbd"}, - {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f7edeb1dcc7f50a2c8e08b9dc13a413903b7817e72273f00878cb70e766bdb3b"}, - {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c083f6dd6951b86e484ebfc9c3524b49bcaa9c420cb4b2a78ef9f7a512bfcc85"}, - {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:80741ec5b471fbdfb997821b2842c59660a1c930ceb42f8a84ba8ca0f25a66aa"}, - {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b1a3297b9cad594e1ff0c040d2881d7d3a74124a3c73e00c3c71526a1234a9f7"}, - {file = "yarl-1.18.0-cp312-cp312-win32.whl", hash = "sha256:cd6ab7d6776c186f544f893b45ee0c883542b35e8a493db74665d2e594d3ca75"}, - {file = "yarl-1.18.0-cp312-cp312-win_amd64.whl", hash = "sha256:039c299a0864d1f43c3e31570045635034ea7021db41bf4842693a72aca8df3a"}, - {file = "yarl-1.18.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6fb64dd45453225f57d82c4764818d7a205ee31ce193e9f0086e493916bd4f72"}, - {file = "yarl-1.18.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3adaaf9c6b1b4fc258584f4443f24d775a2086aee82d1387e48a8b4f3d6aecf6"}, - {file = "yarl-1.18.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:da206d1ec78438a563c5429ab808a2b23ad7bc025c8adbf08540dde202be37d5"}, - {file = "yarl-1.18.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:576d258b21c1db4c6449b1c572c75d03f16a482eb380be8003682bdbe7db2f28"}, - {file = "yarl-1.18.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c60e547c0a375c4bfcdd60eef82e7e0e8698bf84c239d715f5c1278a73050393"}, - {file = "yarl-1.18.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3818eabaefb90adeb5e0f62f047310079d426387991106d4fbf3519eec7d90a"}, - {file = "yarl-1.18.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5f72421246c21af6a92fbc8c13b6d4c5427dfd949049b937c3b731f2f9076bd"}, - {file = "yarl-1.18.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7fa7d37f2ada0f42e0723632993ed422f2a679af0e200874d9d861720a54f53e"}, - {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:42ba84e2ac26a3f252715f8ec17e6fdc0cbf95b9617c5367579fafcd7fba50eb"}, - {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:6a49ad0102c0f0ba839628d0bf45973c86ce7b590cdedf7540d5b1833ddc6f00"}, - {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:96404e8d5e1bbe36bdaa84ef89dc36f0e75939e060ca5cd45451aba01db02902"}, - {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a0509475d714df8f6d498935b3f307cd122c4ca76f7d426c7e1bb791bcd87eda"}, - {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:1ff116f0285b5c8b3b9a2680aeca29a858b3b9e0402fc79fd850b32c2bcb9f8b"}, - {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e2580c1d7e66e6d29d6e11855e3b1c6381971e0edd9a5066e6c14d79bc8967af"}, - {file = "yarl-1.18.0-cp313-cp313-win32.whl", hash = "sha256:14408cc4d34e202caba7b5ac9cc84700e3421a9e2d1b157d744d101b061a4a88"}, - {file = "yarl-1.18.0-cp313-cp313-win_amd64.whl", hash = "sha256:1db1537e9cb846eb0ff206eac667f627794be8b71368c1ab3207ec7b6f8c5afc"}, - {file = "yarl-1.18.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fa2c9cb607e0f660d48c54a63de7a9b36fef62f6b8bd50ff592ce1137e73ac7d"}, - {file = "yarl-1.18.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c0f4808644baf0a434a3442df5e0bedf8d05208f0719cedcd499e168b23bfdc4"}, - {file = "yarl-1.18.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7db9584235895a1dffca17e1c634b13870852094f6389b68dcc6338086aa7b08"}, - {file = "yarl-1.18.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:309f8d27d6f93ceeeb80aa6980e883aa57895270f7f41842b92247e65d7aeddf"}, - {file = "yarl-1.18.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:609ffd44fed2ed88d9b4ef62ee860cf86446cf066333ad4ce4123505b819e581"}, - {file = "yarl-1.18.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f172b8b2c72a13a06ea49225a9c47079549036ad1b34afa12d5491b881f5b993"}, - {file = "yarl-1.18.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d89ae7de94631b60d468412c18290d358a9d805182373d804ec839978b120422"}, - {file = "yarl-1.18.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:466d31fd043ef9af822ee3f1df8fdff4e8c199a7f4012c2642006af240eade17"}, - {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7609b8462351c4836b3edce4201acb6dd46187b207c589b30a87ffd1813b48dc"}, - {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:d9d4f5e471e8dc49b593a80766c2328257e405f943c56a3dc985c125732bc4cf"}, - {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:67b336c15e564d76869c9a21316f90edf546809a5796a083b8f57c845056bc01"}, - {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b212452b80cae26cb767aa045b051740e464c5129b7bd739c58fbb7deb339e7b"}, - {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:38b39b7b3e692b6c92b986b00137a3891eddb66311b229d1940dcbd4f025083c"}, - {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a7ee6884a8848792d58b854946b685521f41d8871afa65e0d4a774954e9c9e89"}, - {file = "yarl-1.18.0-cp39-cp39-win32.whl", hash = "sha256:b4095c5019bb889aa866bf12ed4c85c0daea5aafcb7c20d1519f02a1e738f07f"}, - {file = "yarl-1.18.0-cp39-cp39-win_amd64.whl", hash = "sha256:2d90f2e4d16a5b0915ee065218b435d2ef619dd228973b1b47d262a6f7cd8fa5"}, - {file = "yarl-1.18.0-py3-none-any.whl", hash = "sha256:dbf53db46f7cf176ee01d8d98c39381440776fcda13779d269a8ba664f69bec0"}, - {file = "yarl-1.18.0.tar.gz", hash = "sha256:20d95535e7d833889982bfe7cc321b7f63bf8879788fee982c76ae2b24cfb715"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7df647e8edd71f000a5208fe6ff8c382a1de8edfbccdbbfe649d263de07d8c34"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c69697d3adff5aa4f874b19c0e4ed65180ceed6318ec856ebc423aa5850d84f7"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:602d98f2c2d929f8e697ed274fbadc09902c4025c5a9963bf4e9edfc3ab6f7ed"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c654d5207c78e0bd6d749f6dae1dcbbfde3403ad3a4b11f3c5544d9906969dde"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5094d9206c64181d0f6e76ebd8fb2f8fe274950a63890ee9e0ebfd58bf9d787b"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35098b24e0327fc4ebdc8ffe336cee0a87a700c24ffed13161af80124b7dc8e5"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3236da9272872443f81fedc389bace88408f64f89f75d1bdb2256069a8730ccc"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2c08cc9b16f4f4bc522771d96734c7901e7ebef70c6c5c35dd0f10845270bcd"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80316a8bd5109320d38eef8833ccf5f89608c9107d02d2a7f985f98ed6876990"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c1e1cc06da1491e6734f0ea1e6294ce00792193c463350626571c287c9a704db"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fea09ca13323376a2fdfb353a5fa2e59f90cd18d7ca4eaa1fd31f0a8b4f91e62"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e3b9fd71836999aad54084906f8663dffcd2a7fb5cdafd6c37713b2e72be1760"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:757e81cae69244257d125ff31663249b3013b5dc0a8520d73694aed497fb195b"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b1771de9944d875f1b98a745bc547e684b863abf8f8287da8466cf470ef52690"}, + {file = "yarl-1.18.3-cp310-cp310-win32.whl", hash = "sha256:8874027a53e3aea659a6d62751800cf6e63314c160fd607489ba5c2edd753cf6"}, + {file = "yarl-1.18.3-cp310-cp310-win_amd64.whl", hash = "sha256:93b2e109287f93db79210f86deb6b9bbb81ac32fc97236b16f7433db7fc437d8"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8503ad47387b8ebd39cbbbdf0bf113e17330ffd339ba1144074da24c545f0069"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:02ddb6756f8f4517a2d5e99d8b2f272488e18dd0bfbc802f31c16c6c20f22193"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:67a283dd2882ac98cc6318384f565bffc751ab564605959df4752d42483ad889"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d980e0325b6eddc81331d3f4551e2a333999fb176fd153e075c6d1c2530aa8a8"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b643562c12680b01e17239be267bc306bbc6aac1f34f6444d1bded0c5ce438ca"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c017a3b6df3a1bd45b9fa49a0f54005e53fbcad16633870104b66fa1a30a29d8"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75674776d96d7b851b6498f17824ba17849d790a44d282929c42dbb77d4f17ae"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ccaa3a4b521b780a7e771cc336a2dba389a0861592bbce09a476190bb0c8b4b3"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2d06d3005e668744e11ed80812e61efd77d70bb7f03e33c1598c301eea20efbb"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:9d41beda9dc97ca9ab0b9888cb71f7539124bc05df02c0cff6e5acc5a19dcc6e"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ba23302c0c61a9999784e73809427c9dbedd79f66a13d84ad1b1943802eaaf59"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6748dbf9bfa5ba1afcc7556b71cda0d7ce5f24768043a02a58846e4a443d808d"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0b0cad37311123211dc91eadcb322ef4d4a66008d3e1bdc404808992260e1a0e"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0fb2171a4486bb075316ee754c6d8382ea6eb8b399d4ec62fde2b591f879778a"}, + {file = "yarl-1.18.3-cp311-cp311-win32.whl", hash = "sha256:61b1a825a13bef4a5f10b1885245377d3cd0bf87cba068e1d9a88c2ae36880e1"}, + {file = "yarl-1.18.3-cp311-cp311-win_amd64.whl", hash = "sha256:b9d60031cf568c627d028239693fd718025719c02c9f55df0a53e587aab951b5"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1dd4bdd05407ced96fed3d7f25dbbf88d2ffb045a0db60dbc247f5b3c5c25d50"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7c33dd1931a95e5d9a772d0ac5e44cac8957eaf58e3c8da8c1414de7dd27c576"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b411eddcfd56a2f0cd6a384e9f4f7aa3efee14b188de13048c25b5e91f1640"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436c4fc0a4d66b2badc6c5fc5ef4e47bb10e4fd9bf0c79524ac719a01f3607c2"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e35ef8683211db69ffe129a25d5634319a677570ab6b2eba4afa860f54eeaf75"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84b2deecba4a3f1a398df819151eb72d29bfeb3b69abb145a00ddc8d30094512"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e5a1fea0fd4f5bfa7440a47eff01d9822a65b4488f7cff83155a0f31a2ecba"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0e883008013c0e4aef84dcfe2a0b172c4d23c2669412cf5b3371003941f72bb"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5a3f356548e34a70b0172d8890006c37be92995f62d95a07b4a42e90fba54272"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ccd17349166b1bee6e529b4add61727d3f55edb7babbe4069b5764c9587a8cc6"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b958ddd075ddba5b09bb0be8a6d9906d2ce933aee81100db289badbeb966f54e"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c7d79f7d9aabd6011004e33b22bc13056a3e3fb54794d138af57f5ee9d9032cb"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4891ed92157e5430874dad17b15eb1fda57627710756c27422200c52d8a4e393"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ce1af883b94304f493698b00d0f006d56aea98aeb49d75ec7d98cd4a777e9285"}, + {file = "yarl-1.18.3-cp312-cp312-win32.whl", hash = "sha256:f91c4803173928a25e1a55b943c81f55b8872f0018be83e3ad4938adffb77dd2"}, + {file = "yarl-1.18.3-cp312-cp312-win_amd64.whl", hash = "sha256:7e2ee16578af3b52ac2f334c3b1f92262f47e02cc6193c598502bd46f5cd1477"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:90adb47ad432332d4f0bc28f83a5963f426ce9a1a8809f5e584e704b82685dcb"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:913829534200eb0f789d45349e55203a091f45c37a2674678744ae52fae23efa"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ef9f7768395923c3039055c14334ba4d926f3baf7b776c923c93d80195624782"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a19f62ff30117e706ebc9090b8ecc79aeb77d0b1f5ec10d2d27a12bc9f66d0"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e17c9361d46a4d5addf777c6dd5eab0715a7684c2f11b88c67ac37edfba6c482"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a74a13a4c857a84a845505fd2d68e54826a2cd01935a96efb1e9d86c728e186"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41f7ce59d6ee7741af71d82020346af364949314ed3d87553763a2df1829cc58"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f52a265001d830bc425f82ca9eabda94a64a4d753b07d623a9f2863fde532b53"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:82123d0c954dc58db301f5021a01854a85bf1f3bb7d12ae0c01afc414a882ca2"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2ec9bbba33b2d00999af4631a3397d1fd78290c48e2a3e52d8dd72db3a067ac8"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fbd6748e8ab9b41171bb95c6142faf068f5ef1511935a0aa07025438dd9a9bc1"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:877d209b6aebeb5b16c42cbb377f5f94d9e556626b1bfff66d7b0d115be88d0a"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b464c4ab4bfcb41e3bfd3f1c26600d038376c2de3297760dfe064d2cb7ea8e10"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8d39d351e7faf01483cc7ff7c0213c412e38e5a340238826be7e0e4da450fdc8"}, + {file = "yarl-1.18.3-cp313-cp313-win32.whl", hash = "sha256:61ee62ead9b68b9123ec24bc866cbef297dd266175d53296e2db5e7f797f902d"}, + {file = "yarl-1.18.3-cp313-cp313-win_amd64.whl", hash = "sha256:578e281c393af575879990861823ef19d66e2b1d0098414855dd367e234f5b3c"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:61e5e68cb65ac8f547f6b5ef933f510134a6bf31bb178be428994b0cb46c2a04"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe57328fbc1bfd0bd0514470ac692630f3901c0ee39052ae47acd1d90a436719"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a440a2a624683108a1b454705ecd7afc1c3438a08e890a1513d468671d90a04e"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09c7907c8548bcd6ab860e5f513e727c53b4a714f459b084f6580b49fa1b9cee"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4f6450109834af88cb4cc5ecddfc5380ebb9c228695afc11915a0bf82116789"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9ca04806f3be0ac6d558fffc2fdf8fcef767e0489d2684a21912cc4ed0cd1b8"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77a6e85b90a7641d2e07184df5557132a337f136250caafc9ccaa4a2a998ca2c"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6333c5a377c8e2f5fae35e7b8f145c617b02c939d04110c76f29ee3676b5f9a5"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0b3c92fa08759dbf12b3a59579a4096ba9af8dd344d9a813fc7f5070d86bbab1"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4ac515b860c36becb81bb84b667466885096b5fc85596948548b667da3bf9f24"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:045b8482ce9483ada4f3f23b3774f4e1bf4f23a2d5c912ed5170f68efb053318"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:a4bb030cf46a434ec0225bddbebd4b89e6471814ca851abb8696170adb163985"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:54d6921f07555713b9300bee9c50fb46e57e2e639027089b1d795ecd9f7fa910"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1d407181cfa6e70077df3377938c08012d18893f9f20e92f7d2f314a437c30b1"}, + {file = "yarl-1.18.3-cp39-cp39-win32.whl", hash = "sha256:ac36703a585e0929b032fbaab0707b75dc12703766d0b53486eabd5139ebadd5"}, + {file = "yarl-1.18.3-cp39-cp39-win_amd64.whl", hash = "sha256:ba87babd629f8af77f557b61e49e7c7cac36f22f871156b91e10a6e9d4f829e9"}, + {file = "yarl-1.18.3-py3-none-any.whl", hash = "sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b"}, + {file = "yarl-1.18.3.tar.gz", hash = "sha256:ac1801c45cbf77b6c99242eeff4fffb5e4e73a800b5c4ad4fc0be5def634d2e1"}, ] [package.dependencies] @@ -5435,18 +5461,18 @@ propcache = ">=0.2.0" [[package]] name = "z3-solver" -version = "4.13.3.0" +version = "4.13.4.0" description = "an efficient SMT solver library" optional = true python-versions = "*" files = [ - {file = "z3_solver-4.13.3.0-py3-none-macosx_13_0_arm64.whl", hash = "sha256:cae621cb47ebcf055f6a27285343d5c932f4c282b15c5d2840327e73e15a86a4"}, - {file = "z3_solver-4.13.3.0-py3-none-macosx_13_0_x86_64.whl", hash = "sha256:7900fbd1917164c938a20bea7845f7b95fcb431d0ade474d408f979196bccb8f"}, - {file = "z3_solver-4.13.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:794843e4946ade1561e40a75ffc1163b45d36b493fd6cc269ad1d6a65bddb8e5"}, - {file = "z3_solver-4.13.3.0-py3-none-manylinux_2_34_aarch64.whl", hash = "sha256:ab5057cb1f4680406a232d2c1d968daaf69fae10685baa0887b85ca8e938a5cf"}, - {file = "z3_solver-4.13.3.0-py3-none-win32.whl", hash = "sha256:ba465489e9ab609f1cf0f232cbc102165b89a507347a6093c2ac3224cf161aa3"}, - {file = "z3_solver-4.13.3.0-py3-none-win_amd64.whl", hash = "sha256:d55e4793fa48230af766c7f6f7f033198b2d9df150d89ec65b07fd7b87998897"}, - {file = "z3_solver-4.13.3.0.tar.gz", hash = "sha256:4c27466455bac65d3c512f4bb4841ac79e05e121d3f98ddc99ac27ab4bc27e05"}, + {file = "z3_solver-4.13.4.0-py3-none-macosx_13_0_arm64.whl", hash = "sha256:39ba75b867d6afadabc4812b999c9d96656da07d152510452e71ae9374e98926"}, + {file = "z3_solver-4.13.4.0-py3-none-macosx_13_0_x86_64.whl", hash = "sha256:6f3d3eff878b5b3c0d6e7f4237c869a489288fbdd8a2d878046ce977339a1a7a"}, + {file = "z3_solver-4.13.4.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fb8a857adf1064f89581c424fd729ee3e8bad95f4ebf0fb4c1210f65b831f37"}, + {file = "z3_solver-4.13.4.0-py3-none-manylinux_2_34_aarch64.whl", hash = "sha256:f674d758c199006fa0a527bdf78cb31b4ba5baaaef6c6c0fa80fb063d3834a6c"}, + {file = "z3_solver-4.13.4.0-py3-none-win32.whl", hash = "sha256:d23cb6d7c67ce3a4e57b8715e2be0c0fa350a282e641475e5e559521651471a0"}, + {file = "z3_solver-4.13.4.0-py3-none-win_amd64.whl", hash = "sha256:fafb65d7bb04db93e4a46f4357042fd53b420b412db66f0a0053612ed15024ca"}, + {file = "z3_solver-4.13.4.0.tar.gz", hash = "sha256:66944689398d19f831f94524e95e99961d998afa27cfef1918a5a441029ea73f"}, ] [[package]] @@ -5534,4 +5560,4 @@ generate-unit-tests = ["klara"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "daabfeea7cb561d816da9c41866ce10d183fd5d44232ef4bfa40208ed5a17e91" +content-hash = "a1b6a07f9e2676fb20cd8ab2808cb79c25bea6608392b1b2f2d517199b7765cf" diff --git a/pyproject.toml b/pyproject.toml index eb28c57caae..4411142f3eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -106,6 +106,8 @@ werkzeug = "^2.2.0" # Added as mitmproxy8 -> flask<2.1 loguru = "^0.7.2" pygithub = "^2.2.0" setuptools = "^75.5.0" +pyxdr = "^1.0" + [tool.poetry.extras] build = ["gsutil"] From c8d9fb8a3321fe96bec5cba3396ce7d7030fc5ec Mon Sep 17 00:00:00 2001 From: epintzov Date: Sun, 5 Jan 2025 09:19:47 +0200 Subject: [PATCH 52/58] poetry --- poetry.lock | 142 ++++++++++++++++++++++++------------------------- pyproject.toml | 4 +- 2 files changed, 73 insertions(+), 73 deletions(-) diff --git a/poetry.lock b/poetry.lock index 09371e42a6d..93bf989523e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1578,13 +1578,13 @@ grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] [[package]] name = "grpc-google-iam-v1" -version = "0.13.1" +version = "0.14.0" description = "IAM API client library" optional = false python-versions = ">=3.7" files = [ - {file = "grpc-google-iam-v1-0.13.1.tar.gz", hash = "sha256:3ff4b2fd9d990965e410965253c0da6f66205d5a8291c4c31c6ebecca18a9001"}, - {file = "grpc_google_iam_v1-0.13.1-py2.py3-none-any.whl", hash = "sha256:c3e86151a981811f30d5e7330f271cee53e73bb87755e88cc3b6f0c7b5fe374e"}, + {file = "grpc_google_iam_v1-0.14.0-py2.py3-none-any.whl", hash = "sha256:fb4a084b30099ba3ab07d61d620a0d4429570b13ff53bd37bac75235f98b7da4"}, + {file = "grpc_google_iam_v1-0.14.0.tar.gz", hash = "sha256:c66e07aa642e39bb37950f9e7f491f70dad150ac9801263b42b2814307c2df99"}, ] [package.dependencies] @@ -1594,70 +1594,70 @@ protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4 [[package]] name = "grpcio" -version = "1.68.1" +version = "1.69.0" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.8" files = [ - {file = "grpcio-1.68.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:d35740e3f45f60f3c37b1e6f2f4702c23867b9ce21c6410254c9c682237da68d"}, - {file = "grpcio-1.68.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:d99abcd61760ebb34bdff37e5a3ba333c5cc09feda8c1ad42547bea0416ada78"}, - {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:f8261fa2a5f679abeb2a0a93ad056d765cdca1c47745eda3f2d87f874ff4b8c9"}, - {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0feb02205a27caca128627bd1df4ee7212db051019a9afa76f4bb6a1a80ca95e"}, - {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:919d7f18f63bcad3a0f81146188e90274fde800a94e35d42ffe9eadf6a9a6330"}, - {file = "grpcio-1.68.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:963cc8d7d79b12c56008aabd8b457f400952dbea8997dd185f155e2f228db079"}, - {file = "grpcio-1.68.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ccf2ebd2de2d6661e2520dae293298a3803a98ebfc099275f113ce1f6c2a80f1"}, - {file = "grpcio-1.68.1-cp310-cp310-win32.whl", hash = "sha256:2cc1fd04af8399971bcd4f43bd98c22d01029ea2e56e69c34daf2bf8470e47f5"}, - {file = "grpcio-1.68.1-cp310-cp310-win_amd64.whl", hash = "sha256:ee2e743e51cb964b4975de572aa8fb95b633f496f9fcb5e257893df3be854746"}, - {file = "grpcio-1.68.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:55857c71641064f01ff0541a1776bfe04a59db5558e82897d35a7793e525774c"}, - {file = "grpcio-1.68.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4b177f5547f1b995826ef529d2eef89cca2f830dd8b2c99ffd5fde4da734ba73"}, - {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:3522c77d7e6606d6665ec8d50e867f13f946a4e00c7df46768f1c85089eae515"}, - {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d1fae6bbf0816415b81db1e82fb3bf56f7857273c84dcbe68cbe046e58e1ccd"}, - {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:298ee7f80e26f9483f0b6f94cc0a046caf54400a11b644713bb5b3d8eb387600"}, - {file = "grpcio-1.68.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cbb5780e2e740b6b4f2d208e90453591036ff80c02cc605fea1af8e6fc6b1bbe"}, - {file = "grpcio-1.68.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ddda1aa22495d8acd9dfbafff2866438d12faec4d024ebc2e656784d96328ad0"}, - {file = "grpcio-1.68.1-cp311-cp311-win32.whl", hash = "sha256:b33bd114fa5a83f03ec6b7b262ef9f5cac549d4126f1dc702078767b10c46ed9"}, - {file = "grpcio-1.68.1-cp311-cp311-win_amd64.whl", hash = "sha256:7f20ebec257af55694d8f993e162ddf0d36bd82d4e57f74b31c67b3c6d63d8b2"}, - {file = "grpcio-1.68.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:8829924fffb25386995a31998ccbbeaa7367223e647e0122043dfc485a87c666"}, - {file = "grpcio-1.68.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3aed6544e4d523cd6b3119b0916cef3d15ef2da51e088211e4d1eb91a6c7f4f1"}, - {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:4efac5481c696d5cb124ff1c119a78bddbfdd13fc499e3bc0ca81e95fc573684"}, - {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ab2d912ca39c51f46baf2a0d92aa265aa96b2443266fc50d234fa88bf877d8e"}, - {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c87ce2a97434dffe7327a4071839ab8e8bffd0054cc74cbe971fba98aedd60"}, - {file = "grpcio-1.68.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e4842e4872ae4ae0f5497bf60a0498fa778c192cc7a9e87877abd2814aca9475"}, - {file = "grpcio-1.68.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:255b1635b0ed81e9f91da4fcc8d43b7ea5520090b9a9ad9340d147066d1d3613"}, - {file = "grpcio-1.68.1-cp312-cp312-win32.whl", hash = "sha256:7dfc914cc31c906297b30463dde0b9be48e36939575eaf2a0a22a8096e69afe5"}, - {file = "grpcio-1.68.1-cp312-cp312-win_amd64.whl", hash = "sha256:a0c8ddabef9c8f41617f213e527254c41e8b96ea9d387c632af878d05db9229c"}, - {file = "grpcio-1.68.1-cp313-cp313-linux_armv7l.whl", hash = "sha256:a47faedc9ea2e7a3b6569795c040aae5895a19dde0c728a48d3c5d7995fda385"}, - {file = "grpcio-1.68.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:390eee4225a661c5cd133c09f5da1ee3c84498dc265fd292a6912b65c421c78c"}, - {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:66a24f3d45c33550703f0abb8b656515b0ab777970fa275693a2f6dc8e35f1c1"}, - {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c08079b4934b0bf0a8847f42c197b1d12cba6495a3d43febd7e99ecd1cdc8d54"}, - {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8720c25cd9ac25dd04ee02b69256d0ce35bf8a0f29e20577427355272230965a"}, - {file = "grpcio-1.68.1-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:04cfd68bf4f38f5bb959ee2361a7546916bd9a50f78617a346b3aeb2b42e2161"}, - {file = "grpcio-1.68.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c28848761a6520c5c6071d2904a18d339a796ebe6b800adc8b3f474c5ce3c3ad"}, - {file = "grpcio-1.68.1-cp313-cp313-win32.whl", hash = "sha256:77d65165fc35cff6e954e7fd4229e05ec76102d4406d4576528d3a3635fc6172"}, - {file = "grpcio-1.68.1-cp313-cp313-win_amd64.whl", hash = "sha256:a8040f85dcb9830d8bbb033ae66d272614cec6faceee88d37a88a9bd1a7a704e"}, - {file = "grpcio-1.68.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:eeb38ff04ab6e5756a2aef6ad8d94e89bb4a51ef96e20f45c44ba190fa0bcaad"}, - {file = "grpcio-1.68.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8a3869a6661ec8f81d93f4597da50336718bde9eb13267a699ac7e0a1d6d0bea"}, - {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:2c4cec6177bf325eb6faa6bd834d2ff6aa8bb3b29012cceb4937b86f8b74323c"}, - {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12941d533f3cd45d46f202e3667be8ebf6bcb3573629c7ec12c3e211d99cfccf"}, - {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80af6f1e69c5e68a2be529990684abdd31ed6622e988bf18850075c81bb1ad6e"}, - {file = "grpcio-1.68.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e8dbe3e00771bfe3d04feed8210fc6617006d06d9a2679b74605b9fed3e8362c"}, - {file = "grpcio-1.68.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:83bbf5807dc3ee94ce1de2dfe8a356e1d74101e4b9d7aa8c720cc4818a34aded"}, - {file = "grpcio-1.68.1-cp38-cp38-win32.whl", hash = "sha256:8cb620037a2fd9eeee97b4531880e439ebfcd6d7d78f2e7dcc3726428ab5ef63"}, - {file = "grpcio-1.68.1-cp38-cp38-win_amd64.whl", hash = "sha256:52fbf85aa71263380d330f4fce9f013c0798242e31ede05fcee7fbe40ccfc20d"}, - {file = "grpcio-1.68.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:cb400138e73969eb5e0535d1d06cae6a6f7a15f2cc74add320e2130b8179211a"}, - {file = "grpcio-1.68.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a1b988b40f2fd9de5c820f3a701a43339d8dcf2cb2f1ca137e2c02671cc83ac1"}, - {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:96f473cdacfdd506008a5d7579c9f6a7ff245a9ade92c3c0265eb76cc591914f"}, - {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:37ea3be171f3cf3e7b7e412a98b77685eba9d4fd67421f4a34686a63a65d99f9"}, - {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ceb56c4285754e33bb3c2fa777d055e96e6932351a3082ce3559be47f8024f0"}, - {file = "grpcio-1.68.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:dffd29a2961f3263a16d73945b57cd44a8fd0b235740cb14056f0612329b345e"}, - {file = "grpcio-1.68.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:025f790c056815b3bf53da850dd70ebb849fd755a4b1ac822cb65cd631e37d43"}, - {file = "grpcio-1.68.1-cp39-cp39-win32.whl", hash = "sha256:1098f03dedc3b9810810568060dea4ac0822b4062f537b0f53aa015269be0a76"}, - {file = "grpcio-1.68.1-cp39-cp39-win_amd64.whl", hash = "sha256:334ab917792904245a028f10e803fcd5b6f36a7b2173a820c0b5b076555825e1"}, - {file = "grpcio-1.68.1.tar.gz", hash = "sha256:44a8502dd5de653ae6a73e2de50a401d84184f0331d0ac3daeb044e66d5c5054"}, + {file = "grpcio-1.69.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:2060ca95a8db295ae828d0fc1c7f38fb26ccd5edf9aa51a0f44251f5da332e97"}, + {file = "grpcio-1.69.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:2e52e107261fd8fa8fa457fe44bfadb904ae869d87c1280bf60f93ecd3e79278"}, + {file = "grpcio-1.69.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:316463c0832d5fcdb5e35ff2826d9aa3f26758d29cdfb59a368c1d6c39615a11"}, + {file = "grpcio-1.69.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:26c9a9c4ac917efab4704b18eed9082ed3b6ad19595f047e8173b5182fec0d5e"}, + {file = "grpcio-1.69.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90b3646ced2eae3a0599658eeccc5ba7f303bf51b82514c50715bdd2b109e5ec"}, + {file = "grpcio-1.69.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3b75aea7c6cb91b341c85e7c1d9db1e09e1dd630b0717f836be94971e015031e"}, + {file = "grpcio-1.69.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5cfd14175f9db33d4b74d63de87c64bb0ee29ce475ce3c00c01ad2a3dc2a9e51"}, + {file = "grpcio-1.69.0-cp310-cp310-win32.whl", hash = "sha256:9031069d36cb949205293cf0e243abd5e64d6c93e01b078c37921493a41b72dc"}, + {file = "grpcio-1.69.0-cp310-cp310-win_amd64.whl", hash = "sha256:cc89b6c29f3dccbe12d7a3b3f1b3999db4882ae076c1c1f6df231d55dbd767a5"}, + {file = "grpcio-1.69.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:8de1b192c29b8ce45ee26a700044717bcbbd21c697fa1124d440548964328561"}, + {file = "grpcio-1.69.0-cp311-cp311-macosx_10_14_universal2.whl", hash = "sha256:7e76accf38808f5c5c752b0ab3fd919eb14ff8fafb8db520ad1cc12afff74de6"}, + {file = "grpcio-1.69.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:d5658c3c2660417d82db51e168b277e0ff036d0b0f859fa7576c0ffd2aec1442"}, + {file = "grpcio-1.69.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5494d0e52bf77a2f7eb17c6da662886ca0a731e56c1c85b93505bece8dc6cf4c"}, + {file = "grpcio-1.69.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ed866f9edb574fd9be71bf64c954ce1b88fc93b2a4cbf94af221e9426eb14d6"}, + {file = "grpcio-1.69.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c5ba38aeac7a2fe353615c6b4213d1fbb3a3c34f86b4aaa8be08baaaee8cc56d"}, + {file = "grpcio-1.69.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f79e05f5bbf551c4057c227d1b041ace0e78462ac8128e2ad39ec58a382536d2"}, + {file = "grpcio-1.69.0-cp311-cp311-win32.whl", hash = "sha256:bf1f8be0da3fcdb2c1e9f374f3c2d043d606d69f425cd685110dd6d0d2d61258"}, + {file = "grpcio-1.69.0-cp311-cp311-win_amd64.whl", hash = "sha256:fb9302afc3a0e4ba0b225cd651ef8e478bf0070cf11a529175caecd5ea2474e7"}, + {file = "grpcio-1.69.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:fc18a4de8c33491ad6f70022af5c460b39611e39578a4d84de0fe92f12d5d47b"}, + {file = "grpcio-1.69.0-cp312-cp312-macosx_10_14_universal2.whl", hash = "sha256:0f0270bd9ffbff6961fe1da487bdcd594407ad390cc7960e738725d4807b18c4"}, + {file = "grpcio-1.69.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:dc48f99cc05e0698e689b51a05933253c69a8c8559a47f605cff83801b03af0e"}, + {file = "grpcio-1.69.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e925954b18d41aeb5ae250262116d0970893b38232689c4240024e4333ac084"}, + {file = "grpcio-1.69.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87d222569273720366f68a99cb62e6194681eb763ee1d3b1005840678d4884f9"}, + {file = "grpcio-1.69.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b62b0f41e6e01a3e5082000b612064c87c93a49b05f7602fe1b7aa9fd5171a1d"}, + {file = "grpcio-1.69.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:db6f9fd2578dbe37db4b2994c94a1d9c93552ed77dca80e1657bb8a05b898b55"}, + {file = "grpcio-1.69.0-cp312-cp312-win32.whl", hash = "sha256:b192b81076073ed46f4b4dd612b8897d9a1e39d4eabd822e5da7b38497ed77e1"}, + {file = "grpcio-1.69.0-cp312-cp312-win_amd64.whl", hash = "sha256:1227ff7836f7b3a4ab04e5754f1d001fa52a730685d3dc894ed8bc262cc96c01"}, + {file = "grpcio-1.69.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:a78a06911d4081a24a1761d16215a08e9b6d4d29cdbb7e427e6c7e17b06bcc5d"}, + {file = "grpcio-1.69.0-cp313-cp313-macosx_10_14_universal2.whl", hash = "sha256:dc5a351927d605b2721cbb46158e431dd49ce66ffbacb03e709dc07a491dde35"}, + {file = "grpcio-1.69.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:3629d8a8185f5139869a6a17865d03113a260e311e78fbe313f1a71603617589"}, + {file = "grpcio-1.69.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9a281878feeb9ae26db0622a19add03922a028d4db684658f16d546601a4870"}, + {file = "grpcio-1.69.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cc614e895177ab7e4b70f154d1a7c97e152577ea101d76026d132b7aaba003b"}, + {file = "grpcio-1.69.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:1ee76cd7e2e49cf9264f6812d8c9ac1b85dda0eaea063af07292400f9191750e"}, + {file = "grpcio-1.69.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:0470fa911c503af59ec8bc4c82b371ee4303ececbbdc055f55ce48e38b20fd67"}, + {file = "grpcio-1.69.0-cp313-cp313-win32.whl", hash = "sha256:b650f34aceac8b2d08a4c8d7dc3e8a593f4d9e26d86751ebf74ebf5107d927de"}, + {file = "grpcio-1.69.0-cp313-cp313-win_amd64.whl", hash = "sha256:028337786f11fecb5d7b7fa660475a06aabf7e5e52b5ac2df47414878c0ce7ea"}, + {file = "grpcio-1.69.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:b7f693db593d6bf285e015d5538bf1c86cf9c60ed30b6f7da04a00ed052fe2f3"}, + {file = "grpcio-1.69.0-cp38-cp38-macosx_10_14_universal2.whl", hash = "sha256:8b94e83f66dbf6fd642415faca0608590bc5e8d30e2c012b31d7d1b91b1de2fd"}, + {file = "grpcio-1.69.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:b634851b92c090763dde61df0868c730376cdb73a91bcc821af56ae043b09596"}, + {file = "grpcio-1.69.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bf5f680d3ed08c15330d7830d06bc65f58ca40c9999309517fd62880d70cb06e"}, + {file = "grpcio-1.69.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:200e48a6e7b00f804cf00a1c26292a5baa96507c7749e70a3ec10ca1a288936e"}, + {file = "grpcio-1.69.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:45a4704339b6e5b24b0e136dea9ad3815a94f30eb4f1e1d44c4ac484ef11d8dd"}, + {file = "grpcio-1.69.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:85d347cb8237751b23539981dbd2d9d8f6e9ff90082b427b13022b948eb6347a"}, + {file = "grpcio-1.69.0-cp38-cp38-win32.whl", hash = "sha256:60e5de105dc02832dc8f120056306d0ef80932bcf1c0e2b4ca3b676de6dc6505"}, + {file = "grpcio-1.69.0-cp38-cp38-win_amd64.whl", hash = "sha256:282f47d0928e40f25d007f24eb8fa051cb22551e3c74b8248bc9f9bea9c35fe0"}, + {file = "grpcio-1.69.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:dd034d68a2905464c49479b0c209c773737a4245d616234c79c975c7c90eca03"}, + {file = "grpcio-1.69.0-cp39-cp39-macosx_10_14_universal2.whl", hash = "sha256:01f834732c22a130bdf3dc154d1053bdbc887eb3ccb7f3e6285cfbfc33d9d5cc"}, + {file = "grpcio-1.69.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:a7f4ed0dcf202a70fe661329f8874bc3775c14bb3911d020d07c82c766ce0eb1"}, + {file = "grpcio-1.69.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd7ea241b10bc5f0bb0f82c0d7896822b7ed122b3ab35c9851b440c1ccf81588"}, + {file = "grpcio-1.69.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f03dc9b4da4c0dc8a1db7a5420f575251d7319b7a839004d8916257ddbe4816"}, + {file = "grpcio-1.69.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ca71d73a270dff052fe4edf74fef142d6ddd1f84175d9ac4a14b7280572ac519"}, + {file = "grpcio-1.69.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ccbed100dc43704e94ccff9e07680b540d64e4cc89213ab2832b51b4f68a520"}, + {file = "grpcio-1.69.0-cp39-cp39-win32.whl", hash = "sha256:1514341def9c6ec4b7f0b9628be95f620f9d4b99331b7ef0a1845fd33d9b579c"}, + {file = "grpcio-1.69.0-cp39-cp39-win_amd64.whl", hash = "sha256:c1fea55d26d647346acb0069b08dca70984101f2dc95066e003019207212e303"}, + {file = "grpcio-1.69.0.tar.gz", hash = "sha256:936fa44241b5379c5afc344e1260d467bee495747eaf478de825bab2791da6f5"}, ] [package.extras] -protobuf = ["grpcio-tools (>=1.68.1)"] +protobuf = ["grpcio-tools (>=1.69.0)"] [[package]] name = "grpcio-status" @@ -1777,13 +1777,13 @@ files = [ [[package]] name = "identify" -version = "2.6.4" +version = "2.6.5" description = "File identification library for Python" optional = false python-versions = ">=3.9" files = [ - {file = "identify-2.6.4-py2.py3-none-any.whl", hash = "sha256:993b0f01b97e0568c179bb9196391ff391bfb88a99099dbf5ce392b68f42d0af"}, - {file = "identify-2.6.4.tar.gz", hash = "sha256:285a7d27e397652e8cafe537a6cc97dd470a970f48fb2e9d979aa38eae5513ac"}, + {file = "identify-2.6.5-py2.py3-none-any.whl", hash = "sha256:14181a47091eb75b337af4c23078c9d09225cd4c48929f521f3bf16b09d02566"}, + {file = "identify-2.6.5.tar.gz", hash = "sha256:c10b33f250e5bba374fae86fb57f3adcebf1161bce7cdf92031915fd480c13bc"}, ] [package.extras] @@ -3794,13 +3794,13 @@ dev = ["pre-commit", "pytest-asyncio", "tox"] [[package]] name = "pytest-subprocess" -version = "1.5.2" +version = "1.5.3" description = "A plugin to fake subprocess for pytest" optional = false python-versions = ">=3.6" files = [ - {file = "pytest_subprocess-1.5.2-py3-none-any.whl", hash = "sha256:23ac7732aa8bd45f1757265b1316eb72a7f55b41fb21e2ca22e149ba3629fa46"}, - {file = "pytest_subprocess-1.5.2.tar.gz", hash = "sha256:ad3ca8a35e798bf9c82d9f16d88700b30d98c5a28236117b86c5d6e581a8ed97"}, + {file = "pytest_subprocess-1.5.3-py3-none-any.whl", hash = "sha256:b62580f5a84335fb9f2ec65d49e56a3c93f4722c148fe1771a002835d310a75b"}, + {file = "pytest_subprocess-1.5.3.tar.gz", hash = "sha256:c00b1140fb0211b3153e09500d770db10770baccbe6e05ee9c140036d1d811d5"}, ] [package.dependencies] @@ -3809,7 +3809,7 @@ pytest = ">=4.0.0" [package.extras] dev = ["changelogd", "nox"] docs = ["changelogd", "furo", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-napoleon"] -test = ["Pygments (>=2.0)", "anyio", "coverage", "docutils (>=0.12)", "pytest (>=4.0)", "pytest-asyncio (>=0.15.1)", "pytest-rerunfailures", "pytest-timeout"] +test = ["Pygments (>=2.0)", "anyio", "docutils (>=0.12)", "pytest (>=4.0)", "pytest-asyncio (>=0.15.1)", "pytest-rerunfailures", "pytest-timeout"] [[package]] name = "pytest-sugar" @@ -5173,13 +5173,13 @@ files = [ [[package]] name = "virtualenv" -version = "20.28.0" +version = "20.28.1" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.8" files = [ - {file = "virtualenv-20.28.0-py3-none-any.whl", hash = "sha256:23eae1b4516ecd610481eda647f3a7c09aea295055337331bb4e6892ecce47b0"}, - {file = "virtualenv-20.28.0.tar.gz", hash = "sha256:2c9c3262bb8e7b87ea801d715fae4495e6032450c71d2309be9550e7364049aa"}, + {file = "virtualenv-20.28.1-py3-none-any.whl", hash = "sha256:412773c85d4dab0409b83ec36f7a6499e72eaf08c80e81e9576bca61831c71cb"}, + {file = "virtualenv-20.28.1.tar.gz", hash = "sha256:5d34ab240fdb5d21549b76f9e8ff3af28252f5499fb6d6f031adac4e5a8c5329"}, ] [package.dependencies] @@ -5560,4 +5560,4 @@ generate-unit-tests = ["klara"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "a1b6a07f9e2676fb20cd8ab2808cb79c25bea6608392b1b2f2d517199b7765cf" +content-hash = "63d2d10834d998f630e040cbd74e84b5fa11ffb52164edb60d2a09c2c352721d" diff --git a/pyproject.toml b/pyproject.toml index 4411142f3eb..385529a0b13 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -106,8 +106,6 @@ werkzeug = "^2.2.0" # Added as mitmproxy8 -> flask<2.1 loguru = "^0.7.2" pygithub = "^2.2.0" setuptools = "^75.5.0" -pyxdr = "^1.0" - [tool.poetry.extras] build = ["gsutil"] @@ -127,6 +125,8 @@ ruff = "^0.6.6" pytest-github-actions-annotate-failures = "^0.2.0" pytest-sugar = "^1.0.0" pytest-loguru = "^0.4.0" +pyxdr = "^1.0" + [tool.poetry.group.types.dependencies] types-requests = "^2.31.0.20240311" From 8e364b4221a6bd6c586f53c7bd72b0df3d44d286 Mon Sep 17 00:00:00 2001 From: epintzov Date: Sun, 5 Jan 2025 14:14:59 +0200 Subject: [PATCH 53/58] poetry and installing the pyxdr --- .../test_use_case/test_use_case.py | 308 ++++++++++-------- poetry.lock | 16 +- pyproject.toml | 1 - 3 files changed, 165 insertions(+), 160 deletions(-) diff --git a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py index 66bbb1c426d..c64b5af286b 100644 --- a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py +++ b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py @@ -5,6 +5,7 @@ from pathlib import Path from threading import Thread from typing import Any, List, Optional, Tuple, Union +import subprocess import demisto_client import pytest @@ -66,6 +67,17 @@ def copy_conftest(test_dir): shutil.copy(source_conftest, dest_conftest) +def run_command(command): + """Run a shell command and capture the output.""" + try: + result = subprocess.run(command, shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + return result.stdout.decode('utf-8').strip() + except subprocess.CalledProcessError as e: + logging.error( + f"Error executing command: {e}\nCommand: {command}\nOutput: {e.output.decode('utf-8')}\nError: {e.stderr.decode('utf-8')}") + return None + + # ============================================== Classes ============================================ # class TestResultCapture: """ @@ -112,9 +124,9 @@ def _sanitize_sensitive_data(self, text): class TestResults: def __init__( - self, - service_account: str = None, - artifacts_bucket: str = None, + self, + service_account: str = None, + artifacts_bucket: str = None, ): self.test_results_xml_file = JUnitXml() self.errors = False @@ -122,11 +134,11 @@ def __init__( self.artifacts_bucket = artifacts_bucket def upload_result_json_to_bucket( - self, - repository_name: str, - file_name, - original_file_path: Path, - logging_module: Union[Any, ParallelLoggingManager] = logging, + self, + repository_name: str, + file_name, + original_file_path: Path, + logging_module: Union[Any, ParallelLoggingManager] = logging, ): """Uploads a JSON object to a specified path in the GCP bucket. @@ -154,21 +166,21 @@ def upload_result_json_to_bucket( class BuildContext: def __init__( - self, - nightly: bool, - build_number: Optional[str], - logging_module: ParallelLoggingManager, - cloud_servers_path: str, - cloud_servers_api_keys: str, - service_account: Optional[str], - artifacts_bucket: Optional[str], - cloud_url: Optional[str], - api_key: Optional[str], - auth_id: Optional[str], - inputs: Optional[List[Path]], - machine_assignment: str, - lcas_id: str, - ctx: typer.Context, + self, + nightly: bool, + build_number: Optional[str], + logging_module: ParallelLoggingManager, + cloud_servers_path: str, + cloud_servers_api_keys: str, + service_account: Optional[str], + artifacts_bucket: Optional[str], + cloud_url: Optional[str], + api_key: Optional[str], + auth_id: Optional[str], + inputs: Optional[List[Path]], + machine_assignment: str, + lcas_id: str, + ctx: typer.Context, ): self.logging_module: ParallelLoggingManager = logging_module self.ctx = ctx @@ -201,6 +213,14 @@ def __init__( self.servers = self.create_servers() + # --------------------------- Env Setup ------------------------------- + + logger.info("installing pyxdr...") + + run_command( + f"pip install pyxdr --index-url https://__token__:{os.environ.get('PYXDR_TOKEN')}@gitlab.xdr.pan.local/" + f"api/v4/projects/213/packages/pypi/simple --trusted-host gitlab.xdr.pan.local") + @staticmethod def edit_prefix(path_str: Union[str, Path]) -> Path: path = Path(path_str) @@ -258,13 +278,13 @@ def create_servers(self): class CloudServerContext: def __init__( - self, - build_context: BuildContext, - base_url: str, - api_key: str, - auth_id: str, - ui_url: str, - tests: List[Path], + self, + build_context: BuildContext, + base_url: str, + api_key: str, + auth_id: str, + ui_url: str, + tests: List[Path], ): self.build_context = build_context self.client = None @@ -355,10 +375,10 @@ def execute_tests(self): def run_test_use_case_pytest( - test_use_case_directory: Path, - cloud_client: XsoarClient, - durations: int = 5, - lcas_id: str = None, + test_use_case_directory: Path, + cloud_client: XsoarClient, + durations: int = 5, + lcas_id: str = None, ) -> Tuple[bool, Union[TestSuite, None]]: """Runs a test use case @@ -419,116 +439,116 @@ def run_test_use_case_pytest( }, ) def run_test_use_case( - ctx: typer.Context, - inputs: List[Path] = typer.Argument( - None, - exists=True, - dir_okay=True, - resolve_path=True, - show_default=False, - help="The path to a directory of a test use cases. May pass multiple paths to test multiple test use cases.", - ), - xsiam_url: Optional[str] = typer.Option( - None, - envvar="DEMISTO_BASE_URL", - help="The base url to the cloud tenant.", - rich_help_panel="Cloud Tenant Configuration", - show_default=False, - callback=tenant_config_cb, - ), - api_key: Optional[str] = typer.Option( - None, - envvar="DEMISTO_API_KEY", - help="The api key for the cloud tenant.", - rich_help_panel="XSIAM Tenant Configuration", - show_default=False, - callback=tenant_config_cb, - ), - auth_id: Optional[str] = typer.Option( - None, - envvar="XSIAM_AUTH_ID", - help="The auth id associated with the cloud api key being used.", - rich_help_panel="XSIAM Tenant Configuration", - show_default=False, - callback=tenant_config_cb, - ), - output_junit_file: Optional[Path] = typer.Option( - None, "-jp", "--junit-path", help="Path to the output JUnit XML file." - ), - service_account: Optional[str] = typer.Option( - None, - "-sa", - "--service_account", - envvar="GCP_SERVICE_ACCOUNT", - help="GCP service account.", - show_default=False, - ), - cloud_servers_path: str = typer.Option( - "", - "-csp", - "--cloud_servers_path", - help="Path to secret cloud server metadata file.", - show_default=False, - ), - cloud_servers_api_keys: str = typer.Option( - "", - "-csak", - "--cloud_servers_api_keys", - help="Path to file with cloud Servers api keys.", - show_default=False, - ), - machine_assignment: str = typer.Option( - "", - "-ma", - "--machine_assignment", - help="the path to the machine assignment file.", - show_default=False, - ), - build_number: str = typer.Option( - "", - "-bn", - "--build_number", - help="The build number.", - show_default=True, - ), - nightly: str = typer.Option( - "false", - "--nightly", - "-n", - help="Whether the command is being run in nightly mode.", - ), - artifacts_bucket: str = typer.Option( - None, - "-ab", - "--artifacts_bucket", - help="The artifacts bucket name to upload the results to", - show_default=False, - ), - lacs_id: str = typer.Option( - None, - "-li", - "--lcas_id", - help="The machine LCAS ID", - show_default=False, - ), - console_log_threshold: str = typer.Option( - "INFO", - "-clt", - "--console-log-threshold", - help="Minimum logging threshold for the console logger.", - ), - file_log_threshold: str = typer.Option( - "DEBUG", - "-flt", - "--file-log-threshold", - help="Minimum logging threshold for the file logger.", - ), - log_file_path: Optional[str] = typer.Option( - None, - "-lp", - "--log-file-path", - help="Path to save log files onto.", - ), + ctx: typer.Context, + inputs: List[Path] = typer.Argument( + None, + exists=True, + dir_okay=True, + resolve_path=True, + show_default=False, + help="The path to a directory of a test use cases. May pass multiple paths to test multiple test use cases.", + ), + xsiam_url: Optional[str] = typer.Option( + None, + envvar="DEMISTO_BASE_URL", + help="The base url to the cloud tenant.", + rich_help_panel="Cloud Tenant Configuration", + show_default=False, + callback=tenant_config_cb, + ), + api_key: Optional[str] = typer.Option( + None, + envvar="DEMISTO_API_KEY", + help="The api key for the cloud tenant.", + rich_help_panel="XSIAM Tenant Configuration", + show_default=False, + callback=tenant_config_cb, + ), + auth_id: Optional[str] = typer.Option( + None, + envvar="XSIAM_AUTH_ID", + help="The auth id associated with the cloud api key being used.", + rich_help_panel="XSIAM Tenant Configuration", + show_default=False, + callback=tenant_config_cb, + ), + output_junit_file: Optional[Path] = typer.Option( + None, "-jp", "--junit-path", help="Path to the output JUnit XML file." + ), + service_account: Optional[str] = typer.Option( + None, + "-sa", + "--service_account", + envvar="GCP_SERVICE_ACCOUNT", + help="GCP service account.", + show_default=False, + ), + cloud_servers_path: str = typer.Option( + "", + "-csp", + "--cloud_servers_path", + help="Path to secret cloud server metadata file.", + show_default=False, + ), + cloud_servers_api_keys: str = typer.Option( + "", + "-csak", + "--cloud_servers_api_keys", + help="Path to file with cloud Servers api keys.", + show_default=False, + ), + machine_assignment: str = typer.Option( + "", + "-ma", + "--machine_assignment", + help="the path to the machine assignment file.", + show_default=False, + ), + build_number: str = typer.Option( + "", + "-bn", + "--build_number", + help="The build number.", + show_default=True, + ), + nightly: str = typer.Option( + "false", + "--nightly", + "-n", + help="Whether the command is being run in nightly mode.", + ), + artifacts_bucket: str = typer.Option( + None, + "-ab", + "--artifacts_bucket", + help="The artifacts bucket name to upload the results to", + show_default=False, + ), + lacs_id: str = typer.Option( + None, + "-li", + "--lcas_id", + help="The machine LCAS ID", + show_default=False, + ), + console_log_threshold: str = typer.Option( + "INFO", + "-clt", + "--console-log-threshold", + help="Minimum logging threshold for the console logger.", + ), + file_log_threshold: str = typer.Option( + "DEBUG", + "-flt", + "--file-log-threshold", + help="Minimum logging threshold for the file logger.", + ), + log_file_path: Optional[str] = typer.Option( + None, + "-lp", + "--log-file-path", + help="Path to save log files onto.", + ), ): """ Test a test use case against an XSIAM tenant diff --git a/poetry.lock b/poetry.lock index 93bf989523e..6ffea393047 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3923,20 +3923,6 @@ files = [ {file = "pywin32-308-cp39-cp39-win_amd64.whl", hash = "sha256:71b3322d949b4cc20776436a9c9ba0eeedcbc9c650daa536df63f0ff111bb920"}, ] -[[package]] -name = "pyxdr" -version = "1.0.0" -description = "F.A.C.C.T. XDR REST API Python Bindings" -optional = false -python-versions = "*" -files = [ - {file = "pyxdr-1.0.0-py3-none-any.whl", hash = "sha256:6ead7378aef7dee2c9699721e28fbc374e3be98244071848f7575a809a418305"}, - {file = "pyxdr-1.0.0.tar.gz", hash = "sha256:b4f230513dc1325ee1a301babcee9288f4bc589c12ab9031b5a95353436604b3"}, -] - -[package.dependencies] -requests = "*" - [[package]] name = "pyyaml" version = "6.0.2" @@ -5560,4 +5546,4 @@ generate-unit-tests = ["klara"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "63d2d10834d998f630e040cbd74e84b5fa11ffb52164edb60d2a09c2c352721d" +content-hash = "daabfeea7cb561d816da9c41866ce10d183fd5d44232ef4bfa40208ed5a17e91" diff --git a/pyproject.toml b/pyproject.toml index 385529a0b13..a23f0277016 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -125,7 +125,6 @@ ruff = "^0.6.6" pytest-github-actions-annotate-failures = "^0.2.0" pytest-sugar = "^1.0.0" pytest-loguru = "^0.4.0" -pyxdr = "^1.0" [tool.poetry.group.types.dependencies] From af45921ee63488a9c4cfa63b4ea2af6c2d3124e6 Mon Sep 17 00:00:00 2001 From: epintzov Date: Mon, 6 Jan 2025 16:54:29 +0200 Subject: [PATCH 54/58] code review --- demisto_sdk/__main__.py | 6 +- .../commands/common/clients/__init__.py | 12 +- .../commands/common/clients/configs.py | 4 +- .../common/clients/xsiam/xsiam_api_client.py | 44 - .../common/clients/xsoar/xsoar_api_client.py | 204 ++- .../xsoar_saas/xsoar_saas_api_client.py | 2 +- demisto_sdk/commands/common/constants.py | 4 +- .../test_use_case/test_use_case.py | 204 +-- .../test_use_case/test_use_case_setup.py | 125 ++ .../test_use_case/tests/test_use_case_test.py | 17 - poetry.lock | 1566 ++++++++--------- pyproject.toml | 4 +- 12 files changed, 1087 insertions(+), 1105 deletions(-) create mode 100644 demisto_sdk/commands/test_content/test_use_case/test_use_case_setup.py diff --git a/demisto_sdk/__main__.py b/demisto_sdk/__main__.py index c63ca7d55cc..23738d23fdc 100644 --- a/demisto_sdk/__main__.py +++ b/demisto_sdk/__main__.py @@ -67,8 +67,8 @@ from demisto_sdk.commands.test_content.test_modeling_rule.modeling_rules_setup import ( modeling_rules_app, ) -from demisto_sdk.commands.test_content.test_use_case.test_use_case import ( - run_test_use_case, +from demisto_sdk.commands.test_content.test_use_case.test_use_case_setup import ( + test_use_case, ) from demisto_sdk.commands.update_release_notes.update_release_notes_setup import ( update_release_notes, @@ -208,7 +208,7 @@ ) app.command( name="test-use-case", hidden=True, no_args_is_help=True, help="Test Use Cases." -)(run_test_use_case) +)(test_use_case) app.command( name="lint", help="Deprecated, use demisto-sdk pre-commit instead.", hidden=True )(lint) diff --git a/demisto_sdk/commands/common/clients/__init__.py b/demisto_sdk/commands/common/clients/__init__.py index 163f2047fae..23ae9ca31af 100644 --- a/demisto_sdk/commands/common/clients/__init__.py +++ b/demisto_sdk/commands/common/clients/__init__.py @@ -27,7 +27,7 @@ DEMISTO_PASSWORD, DEMISTO_USERNAME, DEMISTO_VERIFY_SSL, - LCAS_ID, + PROJECT_ID, MarketplaceVersions, ) from demisto_sdk.commands.common.logger import logger @@ -133,7 +133,7 @@ def get_client_from_server_type( auth_id: Optional[str] = None, username: Optional[str] = None, password: Optional[str] = None, - lcas_id: Optional[str] = None, + project_id: Optional[str] = None, verify_ssl: Optional[bool] = None, raise_if_server_not_healthy: bool = True, ) -> XsoarClient: @@ -146,7 +146,7 @@ def get_client_from_server_type( auth_id: the auth ID, if not provided will take from XSIAM_AUTH_ID env var username: the username to authenticate, relevant only for xsoar on prem password: the password to authenticate, relevant only for xsoar on prem - lcas_id: the lcas id of the current cloud machine. + project_id: the project id of the current cloud machine. verify_ssl: whether in each request SSL should be verified, True if yes, False if not, if verify_ssl = None, will take the SSL verification from DEMISTO_VERIFY_SSL env var raise_if_server_not_healthy: whether to raise an exception if the server is not healthy @@ -159,7 +159,7 @@ def get_client_from_server_type( _auth_id = auth_id or os.getenv(AUTH_ID) _username = username or os.getenv(DEMISTO_USERNAME, "") _password = password or os.getenv(DEMISTO_PASSWORD, "") - _lcas_id = lcas_id or os.getenv(LCAS_ID, "") + _project_id = project_id or os.getenv(PROJECT_ID, "") _verify_ssl = ( verify_ssl if verify_ssl is not None @@ -192,7 +192,7 @@ def get_client_from_server_type( api_key=_api_key, auth_id=_auth_id, verify_ssl=_verify_ssl, - lcas_id=_lcas_id, + project_id=_project_id, ), should_validate_server_type=should_validate_server_type, raise_if_server_not_healthy=raise_if_server_not_healthy, @@ -207,7 +207,7 @@ def get_client_from_server_type( api_key=_api_key, auth_id=_auth_id, verify_ssl=_verify_ssl, - lcas_id=_lcas_id, + project_id=_project_id, ), should_validate_server_type=should_validate_server_type, raise_if_server_not_healthy=raise_if_server_not_healthy, diff --git a/demisto_sdk/commands/common/clients/configs.py b/demisto_sdk/commands/common/clients/configs.py index fb910e659a9..3e899604771 100644 --- a/demisto_sdk/commands/common/clients/configs.py +++ b/demisto_sdk/commands/common/clients/configs.py @@ -10,7 +10,7 @@ DEMISTO_PASSWORD, DEMISTO_USERNAME, DEMISTO_VERIFY_SSL, - LCAS_ID, + PROJECT_ID, XSIAM_COLLECTOR_TOKEN, XSIAM_TOKEN, ) @@ -73,7 +73,7 @@ def __eq__(self, other): class XsoarSaasClientConfig(XsoarClientConfig): auth_id: str = Field(default=os.getenv(AUTH_ID), description="XSOAR/XSIAM Auth ID") - lcas_id: str = Field(default=os.getenv(LCAS_ID), description="XSOAR/XSIAM LCAS ID") + project_id: str = Field(default=os.getenv(PROJECT_ID), description="XSOAR/XSIAM Project ID") @root_validator() def validate_auth_params(cls, values: Dict[str, Any]): diff --git a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py index b22bbf457cb..dc7dfc82240 100644 --- a/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py +++ b/demisto_sdk/commands/common/clients/xsiam/xsiam_api_client.py @@ -46,31 +46,6 @@ def server_type(self) -> ServerType: def marketplace(self) -> MarketplaceVersions: return MarketplaceVersions.MarketplaceV2 - """ - ############################# - Helper methods - ############################# - """ - - def _process_response(self, response, status_code, expected_status=200): - """Process the HTTP response coming from the XSOAR client.""" - if status_code == expected_status: - if response: - try: - return json.loads(response) - except json.JSONDecodeError: - api_response = ( - response.replace("'", '"') - .replace("False", "false") - .replace("True", "true") - .replace("None", "null") - ) - return json.loads(api_response) - return {} - else: - error_message = f"Expected status {expected_status}, but got {status_code}. Response: {response}" - raise Exception(error_message) - """ ############################# xsoar related methods @@ -314,23 +289,4 @@ def search_alerts_by_uuid(self, alert_uuids: list = None, filters: list = None): return alert_ids - """ - ############################# - Playbooks related methods - ############################# - """ - - def get_playbook_data(self, playbook_id: int) -> dict: - playbook_endpoint = f"/playbook/{playbook_id}" - response, status_code, _ = self._xsoar_client.generic_request( - playbook_endpoint, method="GET", accept="application/json" - ) - return self._process_response(response, status_code, 200) - - def update_playbook_input(self, playbook_id: str, new_inputs: dict): - saving_inputs_path = f"/playbook/inputs/{playbook_id}" - response, status_code, _ = self._xsoar_client.generic_request( - saving_inputs_path, method="POST", body={"inputs": new_inputs} - ) - return self._process_response(response, status_code, 200) diff --git a/demisto_sdk/commands/common/clients/xsoar/xsoar_api_client.py b/demisto_sdk/commands/common/clients/xsoar/xsoar_api_client.py index fe746775b8b..580b4b77276 100644 --- a/demisto_sdk/commands/common/clients/xsoar/xsoar_api_client.py +++ b/demisto_sdk/commands/common/clients/xsoar/xsoar_api_client.py @@ -59,11 +59,11 @@ class XsoarClient: _ENTRY_TYPE_ERROR: int = 4 def __init__( - self, - config: XsoarClientConfig, - client: Optional[DefaultApi] = None, - raise_if_server_not_healthy: bool = True, - should_validate_server_type: bool = False, + self, + config: XsoarClientConfig, + client: Optional[DefaultApi] = None, + raise_if_server_not_healthy: bool = True, + should_validate_server_type: bool = False, ): self.server_config = config self._xsoar_client = client or demisto_client.configure( @@ -110,8 +110,8 @@ def is_server_type(self) -> bool: """ about = self.about is_xsoar_on_prem = ( - about.product_mode == "xsoar" and about.deployment_mode == "opp" - ) or bool((self.version and self.version < Version(MINIMUM_XSOAR_SAAS_VERSION))) + about.product_mode == "xsoar" and about.deployment_mode == "opp" + ) or bool((self.version and self.version < Version(MINIMUM_XSOAR_SAAS_VERSION))) if not is_xsoar_on_prem: logger.debug(f"{self} is not {self.server_type} server") return False @@ -206,6 +206,31 @@ def external_base_url(self) -> str: # url that its purpose is to expose apis of integrations outside from xsoar/xsiam return self.server_config.config.base_api_url + """ + ############################# + Helper methods + ############################# + """ + + def _process_response(self, response, status_code, expected_status=200): + """Process the HTTP response coming from the XSOAR client.""" + if status_code == expected_status: + if response: + try: + return json.loads(response) + except json.JSONDecodeError: + api_response = ( + response.replace("'", '"') + .replace("False", "false") + .replace("True", "true") + .replace("None", "null") + ) + return json.loads(api_response) + return {} + else: + error_message = f"Expected status {expected_status}, but got {status_code}. Response: {response}" + raise Exception(error_message) + """ ############################# marketplace related methods @@ -305,7 +330,7 @@ def uninstall_marketplace_packs(self, pack_ids: List[str]): @retry(exceptions=ApiException) def upload_marketplace_packs( - self, zipped_packs_path: Union[Path, str], skip_validation: bool = True + self, zipped_packs_path: Union[Path, str], skip_validation: bool = True ): """ Uploads packs to the marketplace. @@ -325,7 +350,7 @@ def upload_marketplace_packs( @retry(exceptions=ApiException) def install_marketplace_packs( - self, packs: List[Dict[str, Any]], ignore_warnings: bool = True + self, packs: List[Dict[str, Any]], ignore_warnings: bool = True ): """ Installs packs from the marketplace. @@ -365,15 +390,15 @@ def sync_marketplace(self): @retry(exceptions=ApiException) def create_integration_instance( - self, - _id: str, - instance_name: str, - integration_instance_config: Dict, - integration_log_level: Optional[str] = None, - is_long_running: bool = False, - should_enable: str = "true", - response_type: str = "object", - should_test: bool = False, + self, + _id: str, + instance_name: str, + integration_instance_config: Dict, + integration_log_level: Optional[str] = None, + is_long_running: bool = False, + should_enable: str = "true", + response_type: str = "object", + should_test: bool = False, ): """ Creates an integration instance. @@ -443,8 +468,8 @@ def create_integration_instance( default_value = param_conf["defaultValue"] if ( - display in integration_instance_config - or name in integration_instance_config + display in integration_instance_config + or name in integration_instance_config ): key = display if display in integration_instance_config else name if key in {"credentials", "creds_apikey"}: @@ -527,7 +552,7 @@ def test_module(self, _id: str, instance_name: str): @retry(exceptions=ApiException) def delete_integration_instance( - self, instance_id: str, response_type: str = "object" + self, instance_id: str, response_type: str = "object" ): """ Deletes integration instance. @@ -549,9 +574,9 @@ def delete_integration_instance( @retry(exceptions=ApiException) def get_integrations_module_configuration( - self, - _id: Optional[str] = None, - response_type: str = "object", + self, + _id: Optional[str] = None, + response_type: str = "object", ): """ Get the integration(s) module configuration(s) @@ -604,10 +629,10 @@ def get_integration_instance(self, instance_name: str): @retry(exceptions=ApiException) def create_incident( - self, - name: str, - should_create_investigation: bool = True, - attached_playbook_id: Optional[str] = None, + self, + name: str, + should_create_investigation: bool = True, + attached_playbook_id: Optional[str] = None, ): """ Args: @@ -636,14 +661,14 @@ def create_incident( @retry(exceptions=ApiException) def search_incidents( - self, - incident_ids: Optional[Union[List, str]] = None, - from_date: Optional[str] = None, - incident_types: Optional[Union[List, str]] = None, - source_instance_name: Optional[str] = None, - page: int = 0, - size: int = 50, - response_type: str = "object", + self, + incident_ids: Optional[Union[List, str]] = None, + from_date: Optional[str] = None, + incident_types: Optional[Union[List, str]] = None, + source_instance_name: Optional[str] = None, + page: int = 0, + size: int = 50, + response_type: str = "object", ): """ Args: @@ -693,10 +718,10 @@ def search_incidents( return raw_response def poll_incident_state( - self, - incident_id: str, - expected_states: Tuple[IncidentState, ...] = (IncidentState.CLOSED,), - timeout: int = 120, + self, + incident_id: str, + expected_states: Tuple[IncidentState, ...] = (IncidentState.CLOSED,), + timeout: int = 120, ): """ Polls for an incident state @@ -745,11 +770,11 @@ def poll_incident_state( @retry(exceptions=ApiException) def delete_incidents( - self, - incident_ids: Union[str, List[str]], - filters: Dict[str, Any] = None, - _all: bool = False, - response_type: str = "object", + self, + incident_ids: Union[str, List[str]], + filters: Dict[str, Any] = None, + _all: bool = False, + response_type: str = "object", ): """ Args: @@ -791,11 +816,11 @@ def get_incident_work_plan_url(self, incident_id: str) -> str: @retry(exceptions=ApiException) def create_indicator( - self, - value: str, - indicator_type: str, - score: int = 0, - response_type: str = "object", + self, + value: str, + indicator_type: str, + score: int = 0, + response_type: str = "object", ): """ Args: @@ -814,7 +839,7 @@ def create_indicator( raise ApiException( status=400, reason=f"Cannot create the indicator={value} type={indicator_type} " - f"because it is in the exclusion list", + f"because it is in the exclusion list", ) # if raw_response = None and status_code = 200, it means the indicator is in the exclusion list @@ -836,12 +861,12 @@ def create_indicator( @retry(exceptions=ApiException) def delete_indicators( - self, - indicator_ids: Union[str, List[str]], - filters: Dict[str, Any] = None, - _all: bool = False, - should_exclude: bool = False, - response_type: str = "object", + self, + indicator_ids: Union[str, List[str]], + filters: Dict[str, Any] = None, + _all: bool = False, + should_exclude: bool = False, + response_type: str = "object", ): """ Deletes indicators from xsoar/xsiam @@ -886,11 +911,11 @@ def delete_indicators( @retry(exceptions=ApiException) def list_indicators( - self, - page: int = 0, - size: int = 50, - query: str = "", - response_type: str = "object", + self, + page: int = 0, + size: int = 50, + query: str = "", + response_type: str = "object", ): """ Args: @@ -930,7 +955,7 @@ def get_indicators_whitelist(self, response_type: str = "object"): @retry(exceptions=ApiException) def delete_indicators_from_whitelist( - self, indicator_ids: List[str], response_type: str = "object" + self, indicator_ids: List[str], response_type: str = "object" ): """ Args: @@ -963,12 +988,12 @@ def delete_indicators_from_whitelist( @retry(times=20, exceptions=RequestException) def do_long_running_instance_request( - self, - instance_name: str, - url_suffix: str = "", - headers: Optional[Dict[str, Any]] = None, - username: Optional[str] = None, - password: Optional[str] = None, + self, + instance_name: str, + url_suffix: str = "", + headers: Optional[Dict[str, Any]] = None, + username: Optional[str] = None, + password: Optional[str] = None, ) -> requests.Response: """ @@ -999,11 +1024,11 @@ def do_long_running_instance_request( @retry(exceptions=ApiException) def run_cli_command( - self, - command: str, - investigation_id: Optional[str] = None, - should_delete_context: bool = True, - response_type: str = "object", + self, + command: str, + investigation_id: Optional[str] = None, + should_delete_context: bool = True, + response_type: str = "object", ) -> Tuple[List[Entry], Dict[str, Any]]: """ Args: @@ -1127,7 +1152,7 @@ def filter_by_creating_user_id(playground): @retry(exceptions=ApiException) def get_investigation_context( - self, investigation_id: str, response_type: str = "object" + self, investigation_id: str, response_type: str = "object" ): """ Args: @@ -1166,7 +1191,7 @@ def get_investigation_status(self, incident_id: str): @retry(exceptions=ApiException) def start_incident_investigation( - self, incident_id: str, response_type: str = "object" + self, incident_id: str, response_type: str = "object" ): """ Args: @@ -1254,12 +1279,12 @@ def get_playbook_state(self, incident_id: str, response_type: str = "object"): return raw_response def poll_playbook_state( - self, - incident_id: str, - expected_states: Tuple[InvestigationPlaybookState, ...] = ( - InvestigationPlaybookState.COMPLETED, - ), - timeout: int = 120, + self, + incident_id: str, + expected_states: Tuple[InvestigationPlaybookState, ...] = ( + InvestigationPlaybookState.COMPLETED, + ), + timeout: int = 120, ): """ Polls for a playbook state until it reaches into an expected state. @@ -1306,3 +1331,18 @@ def poll_playbook_state( else None ), ) + + def get_playbook_data(self, playbook_id: int) -> dict: + playbook_endpoint = f"/playbook/{playbook_id}" + + response, status_code, _ = self._xsoar_client.generic_request( + playbook_endpoint, method="GET", accept="application/json" + ) + return self._process_response(response, status_code, 200) + + def update_playbook_input(self, playbook_id: str, new_inputs: dict): + saving_inputs_path = f"/playbook/inputs/{playbook_id}" + response, status_code, _ = self._xsoar_client.generic_request( + saving_inputs_path, method="POST", body={"inputs": new_inputs} + ) + return self._process_response(response, status_code, 200) diff --git a/demisto_sdk/commands/common/clients/xsoar_saas/xsoar_saas_api_client.py b/demisto_sdk/commands/common/clients/xsoar_saas/xsoar_saas_api_client.py index 3bfdd8110f2..01e8d0a830e 100644 --- a/demisto_sdk/commands/common/clients/xsoar_saas/xsoar_saas_api_client.py +++ b/demisto_sdk/commands/common/clients/xsoar_saas/xsoar_saas_api_client.py @@ -42,7 +42,7 @@ def __init__( "Content-Type": "application/json", } ) - self.lcas_id = config.lcas_id + self.project_id = config.project_id super().__init__( config, client=client, diff --git a/demisto_sdk/commands/common/constants.py b/demisto_sdk/commands/common/constants.py index 4db61fd7eca..bf7dedbff46 100644 --- a/demisto_sdk/commands/common/constants.py +++ b/demisto_sdk/commands/common/constants.py @@ -52,7 +52,7 @@ XSIAM_TOKEN = "XSIAM_TOKEN" XSIAM_COLLECTOR_TOKEN = "XSIAM_COLLECTOR_TOKEN" DEMISTO_VERIFY_SSL = "DEMISTO_VERIFY_SSL" -LCAS_ID = "LCAS_ID" +PROJECT_ID = "PROJECT_ID" # Logging DEMISTO_SDK_LOG_FILE_PATH = "DEMISTO_SDK_LOG_FILE_PATH" @@ -2219,4 +2219,4 @@ class PlaybookTaskType(StrEnum): # Test types: TEST_PLAYBOOKS = "TestPlaybooks" TEST_MODELING_RULES = "TestModelingRules" -Test_Use_Cases = "TestUseCases" +TEST_USE_CASES = "TestUseCases" diff --git a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py index c64b5af286b..565f894e218 100644 --- a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py +++ b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py @@ -18,7 +18,7 @@ from demisto_sdk.commands.common.clients.xsoar.xsoar_api_client import XsoarClient from demisto_sdk.commands.common.constants import ( XSIAM_SERVER_TYPE, - Test_Use_Cases, + TEST_USE_CASES, ) from demisto_sdk.commands.common.content_constant_paths import CONTENT_PATH from demisto_sdk.commands.common.logger import ( @@ -28,7 +28,7 @@ ) from demisto_sdk.commands.common.tools import ( get_json_file, - string_to_bool, + string_to_bool, get_pack_name, ) from demisto_sdk.commands.test_content.ParallelLoggingManager import ( ParallelLoggingManager, @@ -46,21 +46,11 @@ app = typer.Typer() -def get_containing_pack(use_case_path: Path) -> str: - """Get pack object that contains the content entity. - - Args: - use_case_path: path to the use case - - Returns: - Pack: Pack object that contains the content entity. - """ - while use_case_path.parent.name.casefold() != "packs": - use_case_path = use_case_path.parent - return str(use_case_path) - - def copy_conftest(test_dir): + """ + copy content's conftest.py file into the use case directory in order to be able to pass new custom + pytest argument (client_conf) + """ source_conftest = Path(f"{CONTENT_PATH}/Tests/scripts/dev_envs/pytest/conftest.py") dest_conftest = test_dir / "conftest.py" @@ -148,7 +138,7 @@ def upload_result_json_to_bucket( file_name: The desired filename for the uploaded JSON data. logging_module: Logging module to use for upload_result_json_to_bucket. """ - logging_module.info("Start uploading test use case results file to bucket") + logging_module.debug("Start uploading test use case results file to bucket") storage_client = storage.Client.from_service_account_json(self.service_account) storage_bucket = storage_client.bucket(self.artifacts_bucket) @@ -161,7 +151,7 @@ def upload_result_json_to_bucket( content_type="application/xml", ) - logging_module.info("Finished uploading test use case results file to bucket") + logging_module.debug("Finished uploading test use case results file to bucket") class BuildContext: @@ -179,7 +169,7 @@ def __init__( auth_id: Optional[str], inputs: Optional[List[Path]], machine_assignment: str, - lcas_id: str, + project_id: str, ctx: typer.Context, ): self.logging_module: ParallelLoggingManager = logging_module @@ -188,7 +178,7 @@ def __init__( # --------------------------- overall build configuration ------------------------------- self.is_nightly = nightly self.build_number = build_number - self.lcas_id = lcas_id + self.project_id = project_id # -------------------------- Manual run on a single instance -------------------------- self.cloud_url = cloud_url @@ -215,18 +205,21 @@ def __init__( # --------------------------- Env Setup ------------------------------- - logger.info("installing pyxdr...") + logger.debug("installing pyxdr...") run_command( f"pip install pyxdr --index-url https://__token__:{os.environ.get('PYXDR_TOKEN')}@gitlab.xdr.pan.local/" f"api/v4/projects/213/packages/pypi/simple --trusted-host gitlab.xdr.pan.local") - @staticmethod - def edit_prefix(path_str: Union[str, Path]) -> Path: - path = Path(path_str) - if path.parts[0] == "Packs": - return path - return Path("Packs") / path + # @staticmethod + # def edit_prefix(path_str: Union[str, Path]) -> Path: + # """ + # Remove + # """ + # path = Path(path_str) + # if path.parts[0] == "Packs": + # return path + # return Path("Packs") / path def create_servers(self): """ @@ -241,7 +234,7 @@ def create_servers(self): api_key=self.api_key, # type: ignore[arg-type] auth_id=self.auth_id, # type: ignore[arg-type] ui_url=get_ui_url(self.cloud_url), - tests=[BuildContext.edit_prefix(test) for test in self.inputs] + tests=[test for test in self.inputs] if self.inputs else [], ) @@ -249,8 +242,8 @@ def create_servers(self): servers_list = [] for machine, assignment in self.machine_assignment_json.items(): tests = [ - BuildContext.edit_prefix(test) - for test in assignment.get("tests", {}).get(Test_Use_Cases, []) + test + for test in assignment.get("tests", {}).get(TEST_USE_CASES, []) ] if not tests: logger.info(f"No test use cases found for machine {machine}") @@ -334,7 +327,7 @@ def execute_tests(self): success, test_use_case_test_suite = run_test_use_case_pytest( test_use_case_directory, cloud_client=cloud_client, - lcas_id=self.build_context.lcas_id, + project_id=self.build_context.project_id, ) if success: @@ -378,7 +371,7 @@ def run_test_use_case_pytest( test_use_case_directory: Path, cloud_client: XsoarClient, durations: int = 5, - lcas_id: str = None, + project_id: str = None, ) -> Tuple[bool, Union[TestSuite, None]]: """Runs a test use case @@ -389,7 +382,7 @@ def run_test_use_case_pytest( """ # Creating an instance of your results collector test_use_case_suite = TestSuite("Test Use Case") - containing_pack = get_containing_pack(test_use_case_directory) + containing_pack = get_pack_name(test_use_case_directory) test_use_case_suite.add_property("file_name", str(test_use_case_directory.name)) test_use_case_suite.add_property("pack_id", containing_pack) @@ -399,12 +392,12 @@ def run_test_use_case_pytest( test_dir = test_use_case_directory.parent copy_conftest(test_dir) - logger.info(f"before sending pytest {str(cloud_client.base_url)}") + logger.debug(f"before sending pytest {str(cloud_client.base_url)}") pytest_args = [ f"--client_conf=base_url={str(cloud_client.server_config.base_api_url)}," f"api_key={cloud_client.server_config.api_key.get_secret_value()}," f"auth_id={cloud_client.server_config.auth_id}," - f"lcas_id={lcas_id}", + f"project_id={project_id}", str(test_use_case_directory), f"--durations={str(durations)}", "--log-cli-level=CRITICAL", @@ -430,125 +423,25 @@ def run_test_use_case_pytest( raise Exception(f"Pytest failed with {status_code=}") -@app.command( - no_args_is_help=True, - context_settings={ - "allow_extra_args": True, - "ignore_unknown_options": True, - "help_option_names": ["-h", "--help"], - }, -) def run_test_use_case( ctx: typer.Context, - inputs: List[Path] = typer.Argument( - None, - exists=True, - dir_okay=True, - resolve_path=True, - show_default=False, - help="The path to a directory of a test use cases. May pass multiple paths to test multiple test use cases.", - ), - xsiam_url: Optional[str] = typer.Option( - None, - envvar="DEMISTO_BASE_URL", - help="The base url to the cloud tenant.", - rich_help_panel="Cloud Tenant Configuration", - show_default=False, - callback=tenant_config_cb, - ), - api_key: Optional[str] = typer.Option( - None, - envvar="DEMISTO_API_KEY", - help="The api key for the cloud tenant.", - rich_help_panel="XSIAM Tenant Configuration", - show_default=False, - callback=tenant_config_cb, - ), - auth_id: Optional[str] = typer.Option( - None, - envvar="XSIAM_AUTH_ID", - help="The auth id associated with the cloud api key being used.", - rich_help_panel="XSIAM Tenant Configuration", - show_default=False, - callback=tenant_config_cb, - ), - output_junit_file: Optional[Path] = typer.Option( - None, "-jp", "--junit-path", help="Path to the output JUnit XML file." - ), - service_account: Optional[str] = typer.Option( - None, - "-sa", - "--service_account", - envvar="GCP_SERVICE_ACCOUNT", - help="GCP service account.", - show_default=False, - ), - cloud_servers_path: str = typer.Option( - "", - "-csp", - "--cloud_servers_path", - help="Path to secret cloud server metadata file.", - show_default=False, - ), - cloud_servers_api_keys: str = typer.Option( - "", - "-csak", - "--cloud_servers_api_keys", - help="Path to file with cloud Servers api keys.", - show_default=False, - ), - machine_assignment: str = typer.Option( - "", - "-ma", - "--machine_assignment", - help="the path to the machine assignment file.", - show_default=False, - ), - build_number: str = typer.Option( - "", - "-bn", - "--build_number", - help="The build number.", - show_default=True, - ), - nightly: str = typer.Option( - "false", - "--nightly", - "-n", - help="Whether the command is being run in nightly mode.", - ), - artifacts_bucket: str = typer.Option( - None, - "-ab", - "--artifacts_bucket", - help="The artifacts bucket name to upload the results to", - show_default=False, - ), - lacs_id: str = typer.Option( - None, - "-li", - "--lcas_id", - help="The machine LCAS ID", - show_default=False, - ), - console_log_threshold: str = typer.Option( - "INFO", - "-clt", - "--console-log-threshold", - help="Minimum logging threshold for the console logger.", - ), - file_log_threshold: str = typer.Option( - "DEBUG", - "-flt", - "--file-log-threshold", - help="Minimum logging threshold for the file logger.", - ), - log_file_path: Optional[str] = typer.Option( - None, - "-lp", - "--log-file-path", - help="Path to save log files onto.", - ), + inputs: List[Path], + xsiam_url: Optional[str], + api_key: Optional[str], + auth_id: Optional[str], + output_junit_file: Optional[Path], + service_account: Optional[str], + cloud_servers_path: str, + cloud_servers_api_keys: str, + machine_assignment: str, + build_number: str, + nightly: str, + artifacts_bucket: str, + project_id: str, + console_log_threshold: str, + file_log_threshold: str, + log_file_path: Optional[str], + **kwargs ): """ Test a test use case against an XSIAM tenant @@ -593,10 +486,10 @@ def run_test_use_case( api_key=api_key, auth_id=auth_id, inputs=inputs, - lcas_id=lacs_id, + project_id=project_id, ) - logging_module.info( + logging_module.debug( "test use cases to test:", ) @@ -657,5 +550,4 @@ def run_test_use_case( ) -if __name__ == "__main__": - app() + diff --git a/demisto_sdk/commands/test_content/test_use_case/test_use_case_setup.py b/demisto_sdk/commands/test_content/test_use_case/test_use_case_setup.py new file mode 100644 index 00000000000..00b6796260e --- /dev/null +++ b/demisto_sdk/commands/test_content/test_use_case/test_use_case_setup.py @@ -0,0 +1,125 @@ +from pathlib import Path +from typing import List, Optional + +import typer +from demisto_sdk.commands.common.logger import logging_setup_decorator +from demisto_sdk.commands.test_content.tools import tenant_config_cb + + +@logging_setup_decorator +def test_use_case( + ctx: typer.Context, + inputs: List[Path] = typer.Argument( + None, + exists=True, + dir_okay=True, + resolve_path=True, + show_default=False, + help="The path to a directory of a test use cases. May pass multiple paths to test multiple test use cases.", + ), + xsiam_url: Optional[str] = typer.Option( + None, + envvar="DEMISTO_BASE_URL", + help="The base url to the cloud tenant.", + rich_help_panel="Cloud Tenant Configuration", + show_default=False, + callback=tenant_config_cb, + ), + api_key: Optional[str] = typer.Option( + None, + envvar="DEMISTO_API_KEY", + help="The api key for the cloud tenant.", + rich_help_panel="XSIAM Tenant Configuration", + show_default=False, + callback=tenant_config_cb, + ), + auth_id: Optional[str] = typer.Option( + None, + envvar="XSIAM_AUTH_ID", + help="The auth id associated with the cloud api key being used.", + rich_help_panel="XSIAM Tenant Configuration", + show_default=False, + callback=tenant_config_cb, + ), + output_junit_file: Optional[Path] = typer.Option( + None, "-jp", "--junit-path", help="Path to the output JUnit XML file." + ), + service_account: Optional[str] = typer.Option( + None, + "-sa", + "--service_account", + envvar="GCP_SERVICE_ACCOUNT", + help="GCP service account.", + show_default=False, + ), + cloud_servers_path: str = typer.Option( + "", + "-csp", + "--cloud_servers_path", + help="Path to secret cloud server metadata file.", + show_default=False, + ), + cloud_servers_api_keys: str = typer.Option( + "", + "-csak", + "--cloud_servers_api_keys", + help="Path to file with cloud Servers api keys.", + show_default=False, + ), + machine_assignment: str = typer.Option( + "", + "-ma", + "--machine_assignment", + help="the path to the machine assignment file.", + show_default=False, + ), + build_number: str = typer.Option( + "", + "-bn", + "--build_number", + help="The build number.", + show_default=True, + ), + nightly: str = typer.Option( + "false", + "--nightly", + "-n", + help="Whether the command is being run in nightly mode.", + ), + artifacts_bucket: str = typer.Option( + None, + "-ab", + "--artifacts_bucket", + help="The artifacts bucket name to upload the results to", + show_default=False, + ), + project_id: str = typer.Option( + None, + "-pi", + "--project_id", + help="The machine project ID", + show_default=False, + ), + console_log_threshold: str = typer.Option( + "INFO", + "-clt", + "--console-log-threshold", + help="Minimum logging threshold for the console logger.", + ), + file_log_threshold: str = typer.Option( + "DEBUG", + "-flt", + "--file-log-threshold", + help="Minimum logging threshold for the file logger.", + ), + log_file_path: Optional[str] = typer.Option( + None, + "-lp", + "--log-file-path", + help="Path to save log files onto.", + ), +): + from demisto_sdk.commands.test_content.test_use_case.test_use_case import run_test_use_case + + kwargs = locals() + run_test_use_case(**kwargs) \ No newline at end of file diff --git a/demisto_sdk/commands/test_content/test_use_case/tests/test_use_case_test.py b/demisto_sdk/commands/test_content/test_use_case/tests/test_use_case_test.py index 2348fa81622..41ce0e10cfc 100644 --- a/demisto_sdk/commands/test_content/test_use_case/tests/test_use_case_test.py +++ b/demisto_sdk/commands/test_content/test_use_case/tests/test_use_case_test.py @@ -71,23 +71,6 @@ def test_run_test_use_case_pytest( mocker_cloud_client.server_config.api_key.get_secret_value.assert_called_once() -def test_get_containing_pack(): - """ - Given: path to use case file - When: running the test_use_case command. - Then: validate the correct path to the pack dir is returned. - """ - # Test case 1: Use case path is directly inside the "packs" directory - use_case_path = Path("/path/to/packs/pack1/use_case.py") - expected_result = "/path/to/packs/pack1" - assert get_containing_pack(use_case_path) == expected_result - - # Test case 2: Use case path is multiple levels deep inside the "packs" directory - use_case_path = Path("/path/to/packs/pack1/subdir1/subdir2/use_case.py") - expected_result = "/path/to/packs/pack1" - assert get_containing_pack(use_case_path) == expected_result - - def test_pytest_runtest_logreport_passed(mocker): """ When: pytest_runtest_logreport is called with a passing test, diff --git a/poetry.lock b/poetry.lock index 6ffea393047..67ec38c06c5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2,98 +2,98 @@ [[package]] name = "aiohappyeyeballs" -version = "2.4.4" +version = "2.4.3" description = "Happy Eyeballs for asyncio" optional = true python-versions = ">=3.8" files = [ - {file = "aiohappyeyeballs-2.4.4-py3-none-any.whl", hash = "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8"}, - {file = "aiohappyeyeballs-2.4.4.tar.gz", hash = "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745"}, + {file = "aiohappyeyeballs-2.4.3-py3-none-any.whl", hash = "sha256:8a7a83727b2756f394ab2895ea0765a0a8c475e3c71e98d43d76f22b4b435572"}, + {file = "aiohappyeyeballs-2.4.3.tar.gz", hash = "sha256:75cf88a15106a5002a8eb1dab212525c00d1f4c0fa96e551c9fbe6f09a621586"}, ] [[package]] name = "aiohttp" -version = "3.11.11" +version = "3.11.7" description = "Async http client/server framework (asyncio)" optional = true python-versions = ">=3.9" files = [ - {file = "aiohttp-3.11.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a60804bff28662cbcf340a4d61598891f12eea3a66af48ecfdc975ceec21e3c8"}, - {file = "aiohttp-3.11.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4b4fa1cb5f270fb3eab079536b764ad740bb749ce69a94d4ec30ceee1b5940d5"}, - {file = "aiohttp-3.11.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:731468f555656767cda219ab42e033355fe48c85fbe3ba83a349631541715ba2"}, - {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb23d8bb86282b342481cad4370ea0853a39e4a32a0042bb52ca6bdde132df43"}, - {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f047569d655f81cb70ea5be942ee5d4421b6219c3f05d131f64088c73bb0917f"}, - {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd7659baae9ccf94ae5fe8bfaa2c7bc2e94d24611528395ce88d009107e00c6d"}, - {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af01e42ad87ae24932138f154105e88da13ce7d202a6de93fafdafb2883a00ef"}, - {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5854be2f3e5a729800bac57a8d76af464e160f19676ab6aea74bde18ad19d438"}, - {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6526e5fb4e14f4bbf30411216780c9967c20c5a55f2f51d3abd6de68320cc2f3"}, - {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:85992ee30a31835fc482468637b3e5bd085fa8fe9392ba0bdcbdc1ef5e9e3c55"}, - {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:88a12ad8ccf325a8a5ed80e6d7c3bdc247d66175afedbe104ee2aaca72960d8e"}, - {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0a6d3fbf2232e3a08c41eca81ae4f1dff3d8f1a30bae415ebe0af2d2458b8a33"}, - {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:84a585799c58b795573c7fa9b84c455adf3e1d72f19a2bf498b54a95ae0d194c"}, - {file = "aiohttp-3.11.11-cp310-cp310-win32.whl", hash = "sha256:bfde76a8f430cf5c5584553adf9926534352251d379dcb266ad2b93c54a29745"}, - {file = "aiohttp-3.11.11-cp310-cp310-win_amd64.whl", hash = "sha256:0fd82b8e9c383af11d2b26f27a478640b6b83d669440c0a71481f7c865a51da9"}, - {file = "aiohttp-3.11.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ba74ec819177af1ef7f59063c6d35a214a8fde6f987f7661f4f0eecc468a8f76"}, - {file = "aiohttp-3.11.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4af57160800b7a815f3fe0eba9b46bf28aafc195555f1824555fa2cfab6c1538"}, - {file = "aiohttp-3.11.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ffa336210cf9cd8ed117011085817d00abe4c08f99968deef0013ea283547204"}, - {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81b8fe282183e4a3c7a1b72f5ade1094ed1c6345a8f153506d114af5bf8accd9"}, - {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3af41686ccec6a0f2bdc66686dc0f403c41ac2089f80e2214a0f82d001052c03"}, - {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70d1f9dde0e5dd9e292a6d4d00058737052b01f3532f69c0c65818dac26dc287"}, - {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:249cc6912405917344192b9f9ea5cd5b139d49e0d2f5c7f70bdfaf6b4dbf3a2e"}, - {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0eb98d90b6690827dcc84c246811feeb4e1eea683c0eac6caed7549be9c84665"}, - {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec82bf1fda6cecce7f7b915f9196601a1bd1a3079796b76d16ae4cce6d0ef89b"}, - {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9fd46ce0845cfe28f108888b3ab17abff84ff695e01e73657eec3f96d72eef34"}, - {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:bd176afcf8f5d2aed50c3647d4925d0db0579d96f75a31e77cbaf67d8a87742d"}, - {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ec2aa89305006fba9ffb98970db6c8221541be7bee4c1d027421d6f6df7d1ce2"}, - {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:92cde43018a2e17d48bb09c79e4d4cb0e236de5063ce897a5e40ac7cb4878773"}, - {file = "aiohttp-3.11.11-cp311-cp311-win32.whl", hash = "sha256:aba807f9569455cba566882c8938f1a549f205ee43c27b126e5450dc9f83cc62"}, - {file = "aiohttp-3.11.11-cp311-cp311-win_amd64.whl", hash = "sha256:ae545f31489548c87b0cced5755cfe5a5308d00407000e72c4fa30b19c3220ac"}, - {file = "aiohttp-3.11.11-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e595c591a48bbc295ebf47cb91aebf9bd32f3ff76749ecf282ea7f9f6bb73886"}, - {file = "aiohttp-3.11.11-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3ea1b59dc06396b0b424740a10a0a63974c725b1c64736ff788a3689d36c02d2"}, - {file = "aiohttp-3.11.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8811f3f098a78ffa16e0ea36dffd577eb031aea797cbdba81be039a4169e242c"}, - {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7227b87a355ce1f4bf83bfae4399b1f5bb42e0259cb9405824bd03d2f4336a"}, - {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d40f9da8cabbf295d3a9dae1295c69975b86d941bc20f0a087f0477fa0a66231"}, - {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffb3dc385f6bb1568aa974fe65da84723210e5d9707e360e9ecb51f59406cd2e"}, - {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8f5f7515f3552d899c61202d99dcb17d6e3b0de777900405611cd747cecd1b8"}, - {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3499c7ffbfd9c6a3d8d6a2b01c26639da7e43d47c7b4f788016226b1e711caa8"}, - {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8e2bf8029dbf0810c7bfbc3e594b51c4cc9101fbffb583a3923aea184724203c"}, - {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b6212a60e5c482ef90f2d788835387070a88d52cf6241d3916733c9176d39eab"}, - {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d119fafe7b634dbfa25a8c597718e69a930e4847f0b88e172744be24515140da"}, - {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:6fba278063559acc730abf49845d0e9a9e1ba74f85f0ee6efd5803f08b285853"}, - {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:92fc484e34b733704ad77210c7957679c5c3877bd1e6b6d74b185e9320cc716e"}, - {file = "aiohttp-3.11.11-cp312-cp312-win32.whl", hash = "sha256:9f5b3c1ed63c8fa937a920b6c1bec78b74ee09593b3f5b979ab2ae5ef60d7600"}, - {file = "aiohttp-3.11.11-cp312-cp312-win_amd64.whl", hash = "sha256:1e69966ea6ef0c14ee53ef7a3d68b564cc408121ea56c0caa2dc918c1b2f553d"}, - {file = "aiohttp-3.11.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:541d823548ab69d13d23730a06f97460f4238ad2e5ed966aaf850d7c369782d9"}, - {file = "aiohttp-3.11.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:929f3ed33743a49ab127c58c3e0a827de0664bfcda566108989a14068f820194"}, - {file = "aiohttp-3.11.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0882c2820fd0132240edbb4a51eb8ceb6eef8181db9ad5291ab3332e0d71df5f"}, - {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b63de12e44935d5aca7ed7ed98a255a11e5cb47f83a9fded7a5e41c40277d104"}, - {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa54f8ef31d23c506910c21163f22b124facb573bff73930735cf9fe38bf7dff"}, - {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a344d5dc18074e3872777b62f5f7d584ae4344cd6006c17ba12103759d407af3"}, - {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b7fb429ab1aafa1f48578eb315ca45bd46e9c37de11fe45c7f5f4138091e2f1"}, - {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c341c7d868750e31961d6d8e60ff040fb9d3d3a46d77fd85e1ab8e76c3e9a5c4"}, - {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ed9ee95614a71e87f1a70bc81603f6c6760128b140bc4030abe6abaa988f1c3d"}, - {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:de8d38f1c2810fa2a4f1d995a2e9c70bb8737b18da04ac2afbf3971f65781d87"}, - {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a9b7371665d4f00deb8f32208c7c5e652059b0fda41cf6dbcac6114a041f1cc2"}, - {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:620598717fce1b3bd14dd09947ea53e1ad510317c85dda2c9c65b622edc96b12"}, - {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bf8d9bfee991d8acc72d060d53860f356e07a50f0e0d09a8dfedea1c554dd0d5"}, - {file = "aiohttp-3.11.11-cp313-cp313-win32.whl", hash = "sha256:9d73ee3725b7a737ad86c2eac5c57a4a97793d9f442599bea5ec67ac9f4bdc3d"}, - {file = "aiohttp-3.11.11-cp313-cp313-win_amd64.whl", hash = "sha256:c7a06301c2fb096bdb0bd25fe2011531c1453b9f2c163c8031600ec73af1cc99"}, - {file = "aiohttp-3.11.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3e23419d832d969f659c208557de4a123e30a10d26e1e14b73431d3c13444c2e"}, - {file = "aiohttp-3.11.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:21fef42317cf02e05d3b09c028712e1d73a9606f02467fd803f7c1f39cc59add"}, - {file = "aiohttp-3.11.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1f21bb8d0235fc10c09ce1d11ffbd40fc50d3f08a89e4cf3a0c503dc2562247a"}, - {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1642eceeaa5ab6c9b6dfeaaa626ae314d808188ab23ae196a34c9d97efb68350"}, - {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2170816e34e10f2fd120f603e951630f8a112e1be3b60963a1f159f5699059a6"}, - {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8be8508d110d93061197fd2d6a74f7401f73b6d12f8822bbcd6d74f2b55d71b1"}, - {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4eed954b161e6b9b65f6be446ed448ed3921763cc432053ceb606f89d793927e"}, - {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6c9af134da4bc9b3bd3e6a70072509f295d10ee60c697826225b60b9959acdd"}, - {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:44167fc6a763d534a6908bdb2592269b4bf30a03239bcb1654781adf5e49caf1"}, - {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:479b8c6ebd12aedfe64563b85920525d05d394b85f166b7873c8bde6da612f9c"}, - {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:10b4ff0ad793d98605958089fabfa350e8e62bd5d40aa65cdc69d6785859f94e"}, - {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:b540bd67cfb54e6f0865ceccd9979687210d7ed1a1cc8c01f8e67e2f1e883d28"}, - {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dac54e8ce2ed83b1f6b1a54005c87dfed139cf3f777fdc8afc76e7841101226"}, - {file = "aiohttp-3.11.11-cp39-cp39-win32.whl", hash = "sha256:568c1236b2fde93b7720f95a890741854c1200fba4a3471ff48b2934d2d93fd3"}, - {file = "aiohttp-3.11.11-cp39-cp39-win_amd64.whl", hash = "sha256:943a8b052e54dfd6439fd7989f67fc6a7f2138d0a2cf0a7de5f18aa4fe7eb3b1"}, - {file = "aiohttp-3.11.11.tar.gz", hash = "sha256:bb49c7f1e6ebf3821a42d81d494f538107610c3a705987f53068546b0e90303e"}, + {file = "aiohttp-3.11.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8bedb1f6cb919af3b6353921c71281b1491f948ca64408871465d889b4ee1b66"}, + {file = "aiohttp-3.11.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f5022504adab881e2d801a88b748ea63f2a9d130e0b2c430824682a96f6534be"}, + {file = "aiohttp-3.11.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e22d1721c978a6494adc824e0916f9d187fa57baeda34b55140315fa2f740184"}, + {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e993676c71288618eb07e20622572b1250d8713e7e00ab3aabae28cb70f3640d"}, + {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e13a05db87d3b241c186d0936808d0e4e12decc267c617d54e9c643807e968b6"}, + {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ba8d043fed7ffa117024d7ba66fdea011c0e7602327c6d73cacaea38abe4491"}, + {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dda3ed0a7869d2fa16aa41f9961ade73aa2c2e3b2fcb0a352524e7b744881889"}, + {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43bfd25113c1e98aec6c70e26d5f4331efbf4aa9037ba9ad88f090853bf64d7f"}, + {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3dd3e7e7c9ef3e7214f014f1ae260892286647b3cf7c7f1b644a568fd410f8ca"}, + {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:78c657ece7a73b976905ab9ec8be9ef2df12ed8984c24598a1791c58ce3b4ce4"}, + {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:db70a47987e34494b451a334605bee57a126fe8d290511349e86810b4be53b01"}, + {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:9e67531370a3b07e49b280c1f8c2df67985c790ad2834d1b288a2f13cd341c5f"}, + {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9202f184cc0582b1db15056f2225ab4c1e3dac4d9ade50dd0613ac3c46352ac2"}, + {file = "aiohttp-3.11.7-cp310-cp310-win32.whl", hash = "sha256:2257bdd5cf54a4039a4337162cd8048f05a724380a2283df34620f55d4e29341"}, + {file = "aiohttp-3.11.7-cp310-cp310-win_amd64.whl", hash = "sha256:b7215bf2b53bc6cb35808149980c2ae80a4ae4e273890ac85459c014d5aa60ac"}, + {file = "aiohttp-3.11.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cea52d11e02123f125f9055dfe0ccf1c3857225fb879e4a944fae12989e2aef2"}, + {file = "aiohttp-3.11.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3ce18f703b7298e7f7633efd6a90138d99a3f9a656cb52c1201e76cb5d79cf08"}, + {file = "aiohttp-3.11.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:670847ee6aeb3a569cd7cdfbe0c3bec1d44828bbfbe78c5d305f7f804870ef9e"}, + {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dda726f89bfa5c465ba45b76515135a3ece0088dfa2da49b8bb278f3bdeea12"}, + {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25b74a811dba37c7ea6a14d99eb9402d89c8d739d50748a75f3cf994cf19c43"}, + {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5522ee72f95661e79db691310290c4618b86dff2d9b90baedf343fd7a08bf79"}, + {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fbf41a6bbc319a7816ae0f0177c265b62f2a59ad301a0e49b395746eb2a9884"}, + {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:59ee1925b5a5efdf6c4e7be51deee93984d0ac14a6897bd521b498b9916f1544"}, + {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:24054fce8c6d6f33a3e35d1c603ef1b91bbcba73e3f04a22b4f2f27dac59b347"}, + {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:351849aca2c6f814575c1a485c01c17a4240413f960df1bf9f5deb0003c61a53"}, + {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:12724f3a211fa243570e601f65a8831372caf1a149d2f1859f68479f07efec3d"}, + {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:7ea4490360b605804bea8173d2d086b6c379d6bb22ac434de605a9cbce006e7d"}, + {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e0bf378db07df0a713a1e32381a1b277e62ad106d0dbe17b5479e76ec706d720"}, + {file = "aiohttp-3.11.7-cp311-cp311-win32.whl", hash = "sha256:cd8d62cab363dfe713067027a5adb4907515861f1e4ce63e7be810b83668b847"}, + {file = "aiohttp-3.11.7-cp311-cp311-win_amd64.whl", hash = "sha256:bf0e6cce113596377cadda4e3ac5fb89f095bd492226e46d91b4baef1dd16f60"}, + {file = "aiohttp-3.11.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4bb7493c3e3a36d3012b8564bd0e2783259ddd7ef3a81a74f0dbfa000fce48b7"}, + {file = "aiohttp-3.11.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e143b0ef9cb1a2b4f74f56d4fbe50caa7c2bb93390aff52f9398d21d89bc73ea"}, + {file = "aiohttp-3.11.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f7c58a240260822dc07f6ae32a0293dd5bccd618bb2d0f36d51c5dbd526f89c0"}, + {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d20cfe63a1c135d26bde8c1d0ea46fd1200884afbc523466d2f1cf517d1fe33"}, + {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12e4d45847a174f77b2b9919719203769f220058f642b08504cf8b1cf185dacf"}, + {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf4efa2d01f697a7dbd0509891a286a4af0d86902fc594e20e3b1712c28c0106"}, + {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee6a4cdcbf54b8083dc9723cdf5f41f722c00db40ccf9ec2616e27869151129"}, + {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c6095aaf852c34f42e1bd0cf0dc32d1e4b48a90bfb5054abdbb9d64b36acadcb"}, + {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1cf03d27885f8c5ebf3993a220cc84fc66375e1e6e812731f51aab2b2748f4a6"}, + {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:1a17f6a230f81eb53282503823f59d61dff14fb2a93847bf0399dc8e87817307"}, + {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:481f10a1a45c5f4c4a578bbd74cff22eb64460a6549819242a87a80788461fba"}, + {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:db37248535d1ae40735d15bdf26ad43be19e3d93ab3f3dad8507eb0f85bb8124"}, + {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9d18a8b44ec8502a7fde91446cd9c9b95ce7c49f1eacc1fb2358b8907d4369fd"}, + {file = "aiohttp-3.11.7-cp312-cp312-win32.whl", hash = "sha256:3d1c9c15d3999107cbb9b2d76ca6172e6710a12fda22434ee8bd3f432b7b17e8"}, + {file = "aiohttp-3.11.7-cp312-cp312-win_amd64.whl", hash = "sha256:018f1b04883a12e77e7fc161934c0f298865d3a484aea536a6a2ca8d909f0ba0"}, + {file = "aiohttp-3.11.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:241a6ca732d2766836d62c58c49ca7a93d08251daef0c1e3c850df1d1ca0cbc4"}, + {file = "aiohttp-3.11.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:aa3705a8d14de39898da0fbad920b2a37b7547c3afd2a18b9b81f0223b7d0f68"}, + {file = "aiohttp-3.11.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9acfc7f652b31853eed3b92095b0acf06fd5597eeea42e939bd23a17137679d5"}, + {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcefcf2915a2dbdbce37e2fc1622129a1918abfe3d06721ce9f6cdac9b6d2eaa"}, + {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c1f6490dd1862af5aae6cfcf2a274bffa9a5b32a8f5acb519a7ecf5a99a88866"}, + {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac5462582d6561c1c1708853a9faf612ff4e5ea5e679e99be36143d6eabd8e"}, + {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c1a6309005acc4b2bcc577ba3b9169fea52638709ffacbd071f3503264620da"}, + {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5b973cce96793725ef63eb449adfb74f99c043c718acb76e0d2a447ae369962"}, + {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ce91a24aac80de6be8512fb1c4838a9881aa713f44f4e91dd7bb3b34061b497d"}, + {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:875f7100ce0e74af51d4139495eec4025affa1a605280f23990b6434b81df1bd"}, + {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c171fc35d3174bbf4787381716564042a4cbc008824d8195eede3d9b938e29a8"}, + {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ee9afa1b0d2293c46954f47f33e150798ad68b78925e3710044e0d67a9487791"}, + {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8360c7cc620abb320e1b8d603c39095101391a82b1d0be05fb2225471c9c5c52"}, + {file = "aiohttp-3.11.7-cp313-cp313-win32.whl", hash = "sha256:7a9318da4b4ada9a67c1dd84d1c0834123081e746bee311a16bb449f363d965e"}, + {file = "aiohttp-3.11.7-cp313-cp313-win_amd64.whl", hash = "sha256:fc6da202068e0a268e298d7cd09b6e9f3997736cd9b060e2750963754552a0a9"}, + {file = "aiohttp-3.11.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:17829f37c0d31d89aa6b8b010475a10233774771f9b6dc2cc352ea4f8ce95d9a"}, + {file = "aiohttp-3.11.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d6177077a31b1aecfc3c9070bd2f11419dbb4a70f30f4c65b124714f525c2e48"}, + {file = "aiohttp-3.11.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:badda65ac99555791eed75e234afb94686ed2317670c68bff8a4498acdaee935"}, + {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0de6466b9d742b4ee56fe1b2440706e225eb48c77c63152b1584864a236e7a50"}, + {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04b0cc74d5a882c9dacaeeccc1444f0233212b6f5be8bc90833feef1e1ce14b9"}, + {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c7af3e50e5903d21d7b935aceed901cc2475463bc16ddd5587653548661fdb"}, + {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c63f898f683d1379b9be5afc3dd139e20b30b0b1e0bf69a3fc3681f364cf1629"}, + {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fdadc3f6a32d6eca45f9a900a254757fd7855dfb2d8f8dcf0e88f0fae3ff8eb1"}, + {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d329300fb23e14ed1f8c6d688dfd867d1dcc3b1d7cd49b7f8c5b44e797ce0932"}, + {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:5578cf40440eafcb054cf859964bc120ab52ebe0e0562d2b898126d868749629"}, + {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:7b2f8107a3c329789f3c00b2daad0e35f548d0a55cda6291579136622099a46e"}, + {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:43dd89a6194f6ab02a3fe36b09e42e2df19c211fc2050ce37374d96f39604997"}, + {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d2fa6fc7cc865d26ff42480ac9b52b8c9b7da30a10a6442a9cdf429de840e949"}, + {file = "aiohttp-3.11.7-cp39-cp39-win32.whl", hash = "sha256:a7d9a606355655617fee25dd7e54d3af50804d002f1fd3118dd6312d26692d70"}, + {file = "aiohttp-3.11.7-cp39-cp39-win_amd64.whl", hash = "sha256:53c921b58fdc6485d6b2603e0132bb01cd59b8f0620ffc0907f525e0ba071687"}, + {file = "aiohttp-3.11.7.tar.gz", hash = "sha256:01a8aca4af3da85cea5c90141d23f4b0eee3cbecfd33b029a45a80f28c66c668"}, ] [package.dependencies] @@ -111,13 +111,13 @@ speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"] [[package]] name = "aiosignal" -version = "1.3.2" +version = "1.3.1" description = "aiosignal: a list of registered asynchronous callbacks" optional = true -python-versions = ">=3.9" +python-versions = ">=3.7" files = [ - {file = "aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5"}, - {file = "aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54"}, + {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, + {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, ] [package.dependencies] @@ -136,13 +136,13 @@ files = [ [[package]] name = "argcomplete" -version = "3.5.3" +version = "3.5.1" description = "Bash tab completion for argparse" optional = true python-versions = ">=3.8" files = [ - {file = "argcomplete-3.5.3-py3-none-any.whl", hash = "sha256:2ab2c4a215c59fd6caaff41a869480a23e8f6a5f910b266c1808037f4e375b61"}, - {file = "argcomplete-3.5.3.tar.gz", hash = "sha256:c12bf50eded8aebb298c7b7da7a5ff3ee24dffd9f5281867dfe1424b58c55392"}, + {file = "argcomplete-3.5.1-py3-none-any.whl", hash = "sha256:1a1d148bdaa3e3b93454900163403df41448a248af01b6e849edc5ac08e6c363"}, + {file = "argcomplete-3.5.1.tar.gz", hash = "sha256:eb1ee355aa2557bd3d0145de7b06b2a45b0ce461e1e7813f5d066039ab4177b4"}, ] [package.extras] @@ -175,13 +175,13 @@ files = [ [[package]] name = "astroid" -version = "3.3.8" +version = "3.3.5" description = "An abstract syntax tree for Python with inference support." optional = false python-versions = ">=3.9.0" files = [ - {file = "astroid-3.3.8-py3-none-any.whl", hash = "sha256:187ccc0c248bfbba564826c26f070494f7bc964fd286b6d9fff4420e55de828c"}, - {file = "astroid-3.3.8.tar.gz", hash = "sha256:a88c7994f914a4ea8572fac479459f4955eeccc877be3f2d959a33273b0cf40b"}, + {file = "astroid-3.3.5-py3-none-any.whl", hash = "sha256:a9d1c946ada25098d790e079ba2a1b112157278f3fb7e718ae6a9252f5835dc8"}, + {file = "astroid-3.3.5.tar.gz", hash = "sha256:5cfc40ae9f68311075d27ef68a4841bdc5cc7f6cf86671b49f00607d30188e2d"}, ] [package.dependencies] @@ -189,18 +189,21 @@ typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} [[package]] name = "asttokens" -version = "3.0.0" +version = "2.4.1" description = "Annotate AST trees with source code positions" optional = false -python-versions = ">=3.8" +python-versions = "*" files = [ - {file = "asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2"}, - {file = "asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7"}, + {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, + {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, ] +[package.dependencies] +six = ">=1.12.0" + [package.extras] -astroid = ["astroid (>=2,<4)"] -test = ["astroid (>=2,<4)", "pytest", "pytest-cov", "pytest-xdist"] +astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] +test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] [[package]] name = "async-timeout" @@ -215,19 +218,19 @@ files = [ [[package]] name = "attrs" -version = "24.3.0" +version = "24.2.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, - {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, + {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, + {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -249,13 +252,13 @@ tomli = {version = "*", markers = "python_version < \"3.11\""} [[package]] name = "bandit" -version = "1.8.0" +version = "1.7.10" description = "Security oriented static analyser for python code." optional = false -python-versions = ">=3.9" +python-versions = ">=3.8" files = [ - {file = "bandit-1.8.0-py3-none-any.whl", hash = "sha256:b1a61d829c0968aed625381e426aa378904b996529d048f8d908fa28f6b13e38"}, - {file = "bandit-1.8.0.tar.gz", hash = "sha256:b5bfe55a095abd9fe20099178a7c6c060f844bfd4fe4c76d28e35e4c52b9d31e"}, + {file = "bandit-1.7.10-py3-none-any.whl", hash = "sha256:665721d7bebbb4485a339c55161ac0eedde27d51e638000d91c8c2d68343ad02"}, + {file = "bandit-1.7.10.tar.gz", hash = "sha256:59ed5caf5d92b6ada4bf65bc6437feea4a9da1093384445fed4d472acc6cff7b"}, ] [package.dependencies] @@ -466,13 +469,13 @@ files = [ [[package]] name = "certifi" -version = "2024.12.14" +version = "2024.8.30" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, - {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, ] [[package]] @@ -578,114 +581,127 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.4.1" +version = "3.4.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7" +python-versions = ">=3.7.0" files = [ - {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, - {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, - {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, + {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, + {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, ] [[package]] name = "click" -version = "8.1.8" +version = "8.1.7" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, - {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, ] [package.dependencies] @@ -909,37 +925,37 @@ langdetect = ["langdetect"] [[package]] name = "debugpy" -version = "1.8.11" +version = "1.8.9" description = "An implementation of the Debug Adapter Protocol for Python" optional = false python-versions = ">=3.8" files = [ - {file = "debugpy-1.8.11-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:2b26fefc4e31ff85593d68b9022e35e8925714a10ab4858fb1b577a8a48cb8cd"}, - {file = "debugpy-1.8.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61bc8b3b265e6949855300e84dc93d02d7a3a637f2aec6d382afd4ceb9120c9f"}, - {file = "debugpy-1.8.11-cp310-cp310-win32.whl", hash = "sha256:c928bbf47f65288574b78518449edaa46c82572d340e2750889bbf8cd92f3737"}, - {file = "debugpy-1.8.11-cp310-cp310-win_amd64.whl", hash = "sha256:8da1db4ca4f22583e834dcabdc7832e56fe16275253ee53ba66627b86e304da1"}, - {file = "debugpy-1.8.11-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:85de8474ad53ad546ff1c7c7c89230db215b9b8a02754d41cb5a76f70d0be296"}, - {file = "debugpy-1.8.11-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ffc382e4afa4aee367bf413f55ed17bd91b191dcaf979890af239dda435f2a1"}, - {file = "debugpy-1.8.11-cp311-cp311-win32.whl", hash = "sha256:40499a9979c55f72f4eb2fc38695419546b62594f8af194b879d2a18439c97a9"}, - {file = "debugpy-1.8.11-cp311-cp311-win_amd64.whl", hash = "sha256:987bce16e86efa86f747d5151c54e91b3c1e36acc03ce1ddb50f9d09d16ded0e"}, - {file = "debugpy-1.8.11-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:84e511a7545d11683d32cdb8f809ef63fc17ea2a00455cc62d0a4dbb4ed1c308"}, - {file = "debugpy-1.8.11-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce291a5aca4985d82875d6779f61375e959208cdf09fcec40001e65fb0a54768"}, - {file = "debugpy-1.8.11-cp312-cp312-win32.whl", hash = "sha256:28e45b3f827d3bf2592f3cf7ae63282e859f3259db44ed2b129093ca0ac7940b"}, - {file = "debugpy-1.8.11-cp312-cp312-win_amd64.whl", hash = "sha256:44b1b8e6253bceada11f714acf4309ffb98bfa9ac55e4fce14f9e5d4484287a1"}, - {file = "debugpy-1.8.11-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:8988f7163e4381b0da7696f37eec7aca19deb02e500245df68a7159739bbd0d3"}, - {file = "debugpy-1.8.11-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c1f6a173d1140e557347419767d2b14ac1c9cd847e0b4c5444c7f3144697e4e"}, - {file = "debugpy-1.8.11-cp313-cp313-win32.whl", hash = "sha256:bb3b15e25891f38da3ca0740271e63ab9db61f41d4d8541745cfc1824252cb28"}, - {file = "debugpy-1.8.11-cp313-cp313-win_amd64.whl", hash = "sha256:d8768edcbeb34da9e11bcb8b5c2e0958d25218df7a6e56adf415ef262cd7b6d1"}, - {file = "debugpy-1.8.11-cp38-cp38-macosx_14_0_x86_64.whl", hash = "sha256:ad7efe588c8f5cf940f40c3de0cd683cc5b76819446abaa50dc0829a30c094db"}, - {file = "debugpy-1.8.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:189058d03a40103a57144752652b3ab08ff02b7595d0ce1f651b9acc3a3a35a0"}, - {file = "debugpy-1.8.11-cp38-cp38-win32.whl", hash = "sha256:32db46ba45849daed7ccf3f2e26f7a386867b077f39b2a974bb5c4c2c3b0a280"}, - {file = "debugpy-1.8.11-cp38-cp38-win_amd64.whl", hash = "sha256:116bf8342062246ca749013df4f6ea106f23bc159305843491f64672a55af2e5"}, - {file = "debugpy-1.8.11-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:654130ca6ad5de73d978057eaf9e582244ff72d4574b3e106fb8d3d2a0d32458"}, - {file = "debugpy-1.8.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23dc34c5e03b0212fa3c49a874df2b8b1b8fda95160bd79c01eb3ab51ea8d851"}, - {file = "debugpy-1.8.11-cp39-cp39-win32.whl", hash = "sha256:52d8a3166c9f2815bfae05f386114b0b2d274456980d41f320299a8d9a5615a7"}, - {file = "debugpy-1.8.11-cp39-cp39-win_amd64.whl", hash = "sha256:52c3cf9ecda273a19cc092961ee34eb9ba8687d67ba34cc7b79a521c1c64c4c0"}, - {file = "debugpy-1.8.11-py2.py3-none-any.whl", hash = "sha256:0e22f846f4211383e6a416d04b4c13ed174d24cc5d43f5fd52e7821d0ebc8920"}, - {file = "debugpy-1.8.11.tar.gz", hash = "sha256:6ad2688b69235c43b020e04fecccdf6a96c8943ca9c2fb340b8adc103c655e57"}, + {file = "debugpy-1.8.9-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:cfe1e6c6ad7178265f74981edf1154ffce97b69005212fbc90ca22ddfe3d017e"}, + {file = "debugpy-1.8.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ada7fb65102a4d2c9ab62e8908e9e9f12aed9d76ef44880367bc9308ebe49a0f"}, + {file = "debugpy-1.8.9-cp310-cp310-win32.whl", hash = "sha256:c36856343cbaa448171cba62a721531e10e7ffb0abff838004701454149bc037"}, + {file = "debugpy-1.8.9-cp310-cp310-win_amd64.whl", hash = "sha256:17c5e0297678442511cf00a745c9709e928ea4ca263d764e90d233208889a19e"}, + {file = "debugpy-1.8.9-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:b74a49753e21e33e7cf030883a92fa607bddc4ede1aa4145172debc637780040"}, + {file = "debugpy-1.8.9-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62d22dacdb0e296966d7d74a7141aaab4bec123fa43d1a35ddcb39bf9fd29d70"}, + {file = "debugpy-1.8.9-cp311-cp311-win32.whl", hash = "sha256:8138efff315cd09b8dcd14226a21afda4ca582284bf4215126d87342bba1cc66"}, + {file = "debugpy-1.8.9-cp311-cp311-win_amd64.whl", hash = "sha256:ff54ef77ad9f5c425398efb150239f6fe8e20c53ae2f68367eba7ece1e96226d"}, + {file = "debugpy-1.8.9-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:957363d9a7a6612a37458d9a15e72d03a635047f946e5fceee74b50d52a9c8e2"}, + {file = "debugpy-1.8.9-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e565fc54b680292b418bb809f1386f17081d1346dca9a871bf69a8ac4071afe"}, + {file = "debugpy-1.8.9-cp312-cp312-win32.whl", hash = "sha256:3e59842d6c4569c65ceb3751075ff8d7e6a6ada209ceca6308c9bde932bcef11"}, + {file = "debugpy-1.8.9-cp312-cp312-win_amd64.whl", hash = "sha256:66eeae42f3137eb428ea3a86d4a55f28da9bd5a4a3d369ba95ecc3a92c1bba53"}, + {file = "debugpy-1.8.9-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:957ecffff80d47cafa9b6545de9e016ae8c9547c98a538ee96ab5947115fb3dd"}, + {file = "debugpy-1.8.9-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1efbb3ff61487e2c16b3e033bc8595aea578222c08aaf3c4bf0f93fadbd662ee"}, + {file = "debugpy-1.8.9-cp313-cp313-win32.whl", hash = "sha256:7c4d65d03bee875bcb211c76c1d8f10f600c305dbd734beaed4077e902606fee"}, + {file = "debugpy-1.8.9-cp313-cp313-win_amd64.whl", hash = "sha256:e46b420dc1bea64e5bbedd678148be512442bc589b0111bd799367cde051e71a"}, + {file = "debugpy-1.8.9-cp38-cp38-macosx_14_0_x86_64.whl", hash = "sha256:472a3994999fe6c0756945ffa359e9e7e2d690fb55d251639d07208dbc37caea"}, + {file = "debugpy-1.8.9-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:365e556a4772d7d0d151d7eb0e77ec4db03bcd95f26b67b15742b88cacff88e9"}, + {file = "debugpy-1.8.9-cp38-cp38-win32.whl", hash = "sha256:54a7e6d3014c408eb37b0b06021366ee985f1539e12fe49ca2ee0d392d9ceca5"}, + {file = "debugpy-1.8.9-cp38-cp38-win_amd64.whl", hash = "sha256:8e99c0b1cc7bf86d83fb95d5ccdc4ad0586d4432d489d1f54e4055bcc795f693"}, + {file = "debugpy-1.8.9-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:7e8b079323a56f719977fde9d8115590cb5e7a1cba2fcee0986ef8817116e7c1"}, + {file = "debugpy-1.8.9-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6953b335b804a41f16a192fa2e7851bdcfd92173cbb2f9f777bb934f49baab65"}, + {file = "debugpy-1.8.9-cp39-cp39-win32.whl", hash = "sha256:7e646e62d4602bb8956db88b1e72fe63172148c1e25c041e03b103a25f36673c"}, + {file = "debugpy-1.8.9-cp39-cp39-win_amd64.whl", hash = "sha256:3d9755e77a2d680ce3d2c5394a444cf42be4a592caaf246dbfbdd100ffcf7ae5"}, + {file = "debugpy-1.8.9-py2.py3-none-any.whl", hash = "sha256:cc37a6c9987ad743d9c3a14fa1b1a14b7e4e6041f9dd0c8abf8895fe7a97b899"}, + {file = "debugpy-1.8.9.zip", hash = "sha256:1339e14c7d980407248f09824d1b25ff5c5616651689f1e0f0e51bdead3ea13e"}, ] [[package]] @@ -1305,13 +1321,13 @@ dev = ["freezegun", "mock"] [[package]] name = "gitdb" -version = "4.0.12" +version = "4.0.11" description = "Git Object Database" optional = false python-versions = ">=3.7" files = [ - {file = "gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf"}, - {file = "gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571"}, + {file = "gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4"}, + {file = "gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b"}, ] [package.dependencies] @@ -1319,20 +1335,20 @@ smmap = ">=3.0.1,<6" [[package]] name = "gitpython" -version = "3.1.44" +version = "3.1.43" description = "GitPython is a Python library used to interact with Git repositories" optional = false python-versions = ">=3.7" files = [ - {file = "GitPython-3.1.44-py3-none-any.whl", hash = "sha256:9e0e10cda9bed1ee64bc9a6de50e7e38a9c9943241cd7f585f6df3ed28011110"}, - {file = "gitpython-3.1.44.tar.gz", hash = "sha256:c87e30b26253bf5418b01b0660f818967f3c503193838337fe5e573331249269"}, + {file = "GitPython-3.1.43-py3-none-any.whl", hash = "sha256:eec7ec56b92aad751f9912a73404bc02ba212a23adb2c7098ee668417051a1ff"}, + {file = "GitPython-3.1.43.tar.gz", hash = "sha256:35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"}, ] [package.dependencies] gitdb = ">=4.0.1,<5" [package.extras] -doc = ["sphinx (>=7.1.2,<7.2)", "sphinx-autodoc-typehints", "sphinx_rtd_theme"] +doc = ["sphinx (==4.3.2)", "sphinx-autodoc-typehints", "sphinx-rtd-theme", "sphinxcontrib-applehelp (>=1.0.2,<=1.0.4)", "sphinxcontrib-devhelp (==1.0.2)", "sphinxcontrib-htmlhelp (>=2.0.0,<=2.0.1)", "sphinxcontrib-qthelp (==1.0.3)", "sphinxcontrib-serializinghtml (==1.1.5)"] test = ["coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "typing-extensions"] [[package]] @@ -1348,25 +1364,25 @@ files = [ [[package]] name = "google-api-core" -version = "2.24.0" +version = "2.23.0" description = "Google API client core library" optional = false python-versions = ">=3.7" files = [ - {file = "google_api_core-2.24.0-py3-none-any.whl", hash = "sha256:10d82ac0fca69c82a25b3efdeefccf6f28e02ebb97925a8cce8edbfe379929d9"}, - {file = "google_api_core-2.24.0.tar.gz", hash = "sha256:e255640547a597a4da010876d333208ddac417d60add22b6851a0c66a831fcaf"}, + {file = "google_api_core-2.23.0-py3-none-any.whl", hash = "sha256:c20100d4c4c41070cf365f1d8ddf5365915291b5eb11b83829fbd1c999b5122f"}, + {file = "google_api_core-2.23.0.tar.gz", hash = "sha256:2ceb087315e6af43f256704b871d99326b1f12a9d6ce99beaedec99ba26a0ace"}, ] [package.dependencies] google-auth = ">=2.14.1,<3.0.dev0" googleapis-common-protos = ">=1.56.2,<2.0.dev0" grpcio = [ - {version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, {version = ">=1.33.2,<2.0dev", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""}, + {version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, ] grpcio-status = [ - {version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, {version = ">=1.33.2,<2.0.dev0", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""}, + {version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, ] proto-plus = ">=1.22.3,<2.0.0dev" protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0.dev0" @@ -1401,13 +1417,13 @@ testing = ["mock (>=1.0.1)"] [[package]] name = "google-auth" -version = "2.37.0" +version = "2.36.0" description = "Google Authentication Library" optional = false python-versions = ">=3.7" files = [ - {file = "google_auth-2.37.0-py2.py3-none-any.whl", hash = "sha256:42664f18290a6be591be5329a96fe30184be1a1badb7292a7f686a9659de9ca0"}, - {file = "google_auth-2.37.0.tar.gz", hash = "sha256:0054623abf1f9c83492c63d3f47e77f0a544caa3d40b2d98e099a611c2dd5d00"}, + {file = "google_auth-2.36.0-py2.py3-none-any.whl", hash = "sha256:51a15d47028b66fd36e5c64a82d2d57480075bccc7da37cde257fc94177a61fb"}, + {file = "google_auth-2.36.0.tar.gz", hash = "sha256:545e9618f2df0bcbb7dcbc45a546485b1212624716975a1ea5ae8149ce769ab1"}, ] [package.dependencies] @@ -1420,7 +1436,6 @@ rsa = ">=3.1.4,<5" [package.extras] aiohttp = ["aiohttp (>=3.6.2,<4.0.0.dev0)", "requests (>=2.20.0,<3.0.0.dev0)"] enterprise-cert = ["cryptography", "pyopenssl"] -pyjwt = ["cryptography (>=38.0.3)", "pyjwt (>=2.0)"] pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] requests = ["requests (>=2.20.0,<3.0.0.dev0)"] @@ -1445,13 +1460,13 @@ grpc = ["grpcio (>=1.38.0,<2.0dev)", "grpcio-status (>=1.38.0,<2.0.dev0)"] [[package]] name = "google-cloud-secret-manager" -version = "2.22.0" +version = "2.21.1" description = "Google Cloud Secret Manager API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google_cloud_secret_manager-2.22.0-py2.py3-none-any.whl", hash = "sha256:9e23a8165ed718de56543723b1e21c394f2cee9ababddcac8ceecc9f427d2696"}, - {file = "google_cloud_secret_manager-2.22.0.tar.gz", hash = "sha256:5dd95ac6243687f86fd803316c0768f507028958b8a2e69b3aa0ace7ac654bf4"}, + {file = "google_cloud_secret_manager-2.21.1-py2.py3-none-any.whl", hash = "sha256:a259932a3c0951f061b60cacfbc20831af92a67fd8cd7396a9f59504bc5cc251"}, + {file = "google_cloud_secret_manager-2.21.1.tar.gz", hash = "sha256:f104f002751345cba39152cef3aed3f4375edf0b2542c8bd1b7712d44fe975b6"}, ] [package.dependencies] @@ -1463,13 +1478,13 @@ protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4 [[package]] name = "google-cloud-storage" -version = "2.19.0" +version = "2.18.2" description = "Google Cloud Storage API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google_cloud_storage-2.19.0-py2.py3-none-any.whl", hash = "sha256:aeb971b5c29cf8ab98445082cbfe7b161a1f48ed275822f59ed3f1524ea54fba"}, - {file = "google_cloud_storage-2.19.0.tar.gz", hash = "sha256:cd05e9e7191ba6cb68934d8eb76054d9be4562aa89dbc4236feee4d7d51342b2"}, + {file = "google_cloud_storage-2.18.2-py2.py3-none-any.whl", hash = "sha256:97a4d45c368b7d401ed48c4fdfe86e1e1cb96401c9e199e419d289e2c0370166"}, + {file = "google_cloud_storage-2.18.2.tar.gz", hash = "sha256:aaf7acd70cdad9f274d29332673fcab98708d0e1f4dceb5a5356aaef06af4d99"}, ] [package.dependencies] @@ -1578,13 +1593,13 @@ grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] [[package]] name = "grpc-google-iam-v1" -version = "0.14.0" +version = "0.13.1" description = "IAM API client library" optional = false python-versions = ">=3.7" files = [ - {file = "grpc_google_iam_v1-0.14.0-py2.py3-none-any.whl", hash = "sha256:fb4a084b30099ba3ab07d61d620a0d4429570b13ff53bd37bac75235f98b7da4"}, - {file = "grpc_google_iam_v1-0.14.0.tar.gz", hash = "sha256:c66e07aa642e39bb37950f9e7f491f70dad150ac9801263b42b2814307c2df99"}, + {file = "grpc-google-iam-v1-0.13.1.tar.gz", hash = "sha256:3ff4b2fd9d990965e410965253c0da6f66205d5a8291c4c31c6ebecca18a9001"}, + {file = "grpc_google_iam_v1-0.13.1-py2.py3-none-any.whl", hash = "sha256:c3e86151a981811f30d5e7330f271cee53e73bb87755e88cc3b6f0c7b5fe374e"}, ] [package.dependencies] @@ -1594,70 +1609,70 @@ protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4 [[package]] name = "grpcio" -version = "1.69.0" +version = "1.68.0" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.8" files = [ - {file = "grpcio-1.69.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:2060ca95a8db295ae828d0fc1c7f38fb26ccd5edf9aa51a0f44251f5da332e97"}, - {file = "grpcio-1.69.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:2e52e107261fd8fa8fa457fe44bfadb904ae869d87c1280bf60f93ecd3e79278"}, - {file = "grpcio-1.69.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:316463c0832d5fcdb5e35ff2826d9aa3f26758d29cdfb59a368c1d6c39615a11"}, - {file = "grpcio-1.69.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:26c9a9c4ac917efab4704b18eed9082ed3b6ad19595f047e8173b5182fec0d5e"}, - {file = "grpcio-1.69.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90b3646ced2eae3a0599658eeccc5ba7f303bf51b82514c50715bdd2b109e5ec"}, - {file = "grpcio-1.69.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3b75aea7c6cb91b341c85e7c1d9db1e09e1dd630b0717f836be94971e015031e"}, - {file = "grpcio-1.69.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5cfd14175f9db33d4b74d63de87c64bb0ee29ce475ce3c00c01ad2a3dc2a9e51"}, - {file = "grpcio-1.69.0-cp310-cp310-win32.whl", hash = "sha256:9031069d36cb949205293cf0e243abd5e64d6c93e01b078c37921493a41b72dc"}, - {file = "grpcio-1.69.0-cp310-cp310-win_amd64.whl", hash = "sha256:cc89b6c29f3dccbe12d7a3b3f1b3999db4882ae076c1c1f6df231d55dbd767a5"}, - {file = "grpcio-1.69.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:8de1b192c29b8ce45ee26a700044717bcbbd21c697fa1124d440548964328561"}, - {file = "grpcio-1.69.0-cp311-cp311-macosx_10_14_universal2.whl", hash = "sha256:7e76accf38808f5c5c752b0ab3fd919eb14ff8fafb8db520ad1cc12afff74de6"}, - {file = "grpcio-1.69.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:d5658c3c2660417d82db51e168b277e0ff036d0b0f859fa7576c0ffd2aec1442"}, - {file = "grpcio-1.69.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5494d0e52bf77a2f7eb17c6da662886ca0a731e56c1c85b93505bece8dc6cf4c"}, - {file = "grpcio-1.69.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ed866f9edb574fd9be71bf64c954ce1b88fc93b2a4cbf94af221e9426eb14d6"}, - {file = "grpcio-1.69.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c5ba38aeac7a2fe353615c6b4213d1fbb3a3c34f86b4aaa8be08baaaee8cc56d"}, - {file = "grpcio-1.69.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f79e05f5bbf551c4057c227d1b041ace0e78462ac8128e2ad39ec58a382536d2"}, - {file = "grpcio-1.69.0-cp311-cp311-win32.whl", hash = "sha256:bf1f8be0da3fcdb2c1e9f374f3c2d043d606d69f425cd685110dd6d0d2d61258"}, - {file = "grpcio-1.69.0-cp311-cp311-win_amd64.whl", hash = "sha256:fb9302afc3a0e4ba0b225cd651ef8e478bf0070cf11a529175caecd5ea2474e7"}, - {file = "grpcio-1.69.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:fc18a4de8c33491ad6f70022af5c460b39611e39578a4d84de0fe92f12d5d47b"}, - {file = "grpcio-1.69.0-cp312-cp312-macosx_10_14_universal2.whl", hash = "sha256:0f0270bd9ffbff6961fe1da487bdcd594407ad390cc7960e738725d4807b18c4"}, - {file = "grpcio-1.69.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:dc48f99cc05e0698e689b51a05933253c69a8c8559a47f605cff83801b03af0e"}, - {file = "grpcio-1.69.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e925954b18d41aeb5ae250262116d0970893b38232689c4240024e4333ac084"}, - {file = "grpcio-1.69.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87d222569273720366f68a99cb62e6194681eb763ee1d3b1005840678d4884f9"}, - {file = "grpcio-1.69.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b62b0f41e6e01a3e5082000b612064c87c93a49b05f7602fe1b7aa9fd5171a1d"}, - {file = "grpcio-1.69.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:db6f9fd2578dbe37db4b2994c94a1d9c93552ed77dca80e1657bb8a05b898b55"}, - {file = "grpcio-1.69.0-cp312-cp312-win32.whl", hash = "sha256:b192b81076073ed46f4b4dd612b8897d9a1e39d4eabd822e5da7b38497ed77e1"}, - {file = "grpcio-1.69.0-cp312-cp312-win_amd64.whl", hash = "sha256:1227ff7836f7b3a4ab04e5754f1d001fa52a730685d3dc894ed8bc262cc96c01"}, - {file = "grpcio-1.69.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:a78a06911d4081a24a1761d16215a08e9b6d4d29cdbb7e427e6c7e17b06bcc5d"}, - {file = "grpcio-1.69.0-cp313-cp313-macosx_10_14_universal2.whl", hash = "sha256:dc5a351927d605b2721cbb46158e431dd49ce66ffbacb03e709dc07a491dde35"}, - {file = "grpcio-1.69.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:3629d8a8185f5139869a6a17865d03113a260e311e78fbe313f1a71603617589"}, - {file = "grpcio-1.69.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9a281878feeb9ae26db0622a19add03922a028d4db684658f16d546601a4870"}, - {file = "grpcio-1.69.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cc614e895177ab7e4b70f154d1a7c97e152577ea101d76026d132b7aaba003b"}, - {file = "grpcio-1.69.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:1ee76cd7e2e49cf9264f6812d8c9ac1b85dda0eaea063af07292400f9191750e"}, - {file = "grpcio-1.69.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:0470fa911c503af59ec8bc4c82b371ee4303ececbbdc055f55ce48e38b20fd67"}, - {file = "grpcio-1.69.0-cp313-cp313-win32.whl", hash = "sha256:b650f34aceac8b2d08a4c8d7dc3e8a593f4d9e26d86751ebf74ebf5107d927de"}, - {file = "grpcio-1.69.0-cp313-cp313-win_amd64.whl", hash = "sha256:028337786f11fecb5d7b7fa660475a06aabf7e5e52b5ac2df47414878c0ce7ea"}, - {file = "grpcio-1.69.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:b7f693db593d6bf285e015d5538bf1c86cf9c60ed30b6f7da04a00ed052fe2f3"}, - {file = "grpcio-1.69.0-cp38-cp38-macosx_10_14_universal2.whl", hash = "sha256:8b94e83f66dbf6fd642415faca0608590bc5e8d30e2c012b31d7d1b91b1de2fd"}, - {file = "grpcio-1.69.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:b634851b92c090763dde61df0868c730376cdb73a91bcc821af56ae043b09596"}, - {file = "grpcio-1.69.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bf5f680d3ed08c15330d7830d06bc65f58ca40c9999309517fd62880d70cb06e"}, - {file = "grpcio-1.69.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:200e48a6e7b00f804cf00a1c26292a5baa96507c7749e70a3ec10ca1a288936e"}, - {file = "grpcio-1.69.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:45a4704339b6e5b24b0e136dea9ad3815a94f30eb4f1e1d44c4ac484ef11d8dd"}, - {file = "grpcio-1.69.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:85d347cb8237751b23539981dbd2d9d8f6e9ff90082b427b13022b948eb6347a"}, - {file = "grpcio-1.69.0-cp38-cp38-win32.whl", hash = "sha256:60e5de105dc02832dc8f120056306d0ef80932bcf1c0e2b4ca3b676de6dc6505"}, - {file = "grpcio-1.69.0-cp38-cp38-win_amd64.whl", hash = "sha256:282f47d0928e40f25d007f24eb8fa051cb22551e3c74b8248bc9f9bea9c35fe0"}, - {file = "grpcio-1.69.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:dd034d68a2905464c49479b0c209c773737a4245d616234c79c975c7c90eca03"}, - {file = "grpcio-1.69.0-cp39-cp39-macosx_10_14_universal2.whl", hash = "sha256:01f834732c22a130bdf3dc154d1053bdbc887eb3ccb7f3e6285cfbfc33d9d5cc"}, - {file = "grpcio-1.69.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:a7f4ed0dcf202a70fe661329f8874bc3775c14bb3911d020d07c82c766ce0eb1"}, - {file = "grpcio-1.69.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd7ea241b10bc5f0bb0f82c0d7896822b7ed122b3ab35c9851b440c1ccf81588"}, - {file = "grpcio-1.69.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f03dc9b4da4c0dc8a1db7a5420f575251d7319b7a839004d8916257ddbe4816"}, - {file = "grpcio-1.69.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ca71d73a270dff052fe4edf74fef142d6ddd1f84175d9ac4a14b7280572ac519"}, - {file = "grpcio-1.69.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ccbed100dc43704e94ccff9e07680b540d64e4cc89213ab2832b51b4f68a520"}, - {file = "grpcio-1.69.0-cp39-cp39-win32.whl", hash = "sha256:1514341def9c6ec4b7f0b9628be95f620f9d4b99331b7ef0a1845fd33d9b579c"}, - {file = "grpcio-1.69.0-cp39-cp39-win_amd64.whl", hash = "sha256:c1fea55d26d647346acb0069b08dca70984101f2dc95066e003019207212e303"}, - {file = "grpcio-1.69.0.tar.gz", hash = "sha256:936fa44241b5379c5afc344e1260d467bee495747eaf478de825bab2791da6f5"}, + {file = "grpcio-1.68.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:619b5d0f29f4f5351440e9343224c3e19912c21aeda44e0c49d0d147a8d01544"}, + {file = "grpcio-1.68.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:a59f5822f9459bed098ffbceb2713abbf7c6fd13f2b9243461da5c338d0cd6c3"}, + {file = "grpcio-1.68.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:c03d89df516128febc5a7e760d675b478ba25802447624edf7aa13b1e7b11e2a"}, + {file = "grpcio-1.68.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44bcbebb24363d587472089b89e2ea0ab2e2b4df0e4856ba4c0b087c82412121"}, + {file = "grpcio-1.68.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79f81b7fbfb136247b70465bd836fa1733043fdee539cd6031cb499e9608a110"}, + {file = "grpcio-1.68.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:88fb2925789cfe6daa20900260ef0a1d0a61283dfb2d2fffe6194396a354c618"}, + {file = "grpcio-1.68.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:99f06232b5c9138593ae6f2e355054318717d32a9c09cdc5a2885540835067a1"}, + {file = "grpcio-1.68.0-cp310-cp310-win32.whl", hash = "sha256:a6213d2f7a22c3c30a479fb5e249b6b7e648e17f364598ff64d08a5136fe488b"}, + {file = "grpcio-1.68.0-cp310-cp310-win_amd64.whl", hash = "sha256:15327ab81131ef9b94cb9f45b5bd98803a179c7c61205c8c0ac9aff9d6c4e82a"}, + {file = "grpcio-1.68.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:3b2b559beb2d433129441783e5f42e3be40a9e1a89ec906efabf26591c5cd415"}, + {file = "grpcio-1.68.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e46541de8425a4d6829ac6c5d9b16c03c292105fe9ebf78cb1c31e8d242f9155"}, + {file = "grpcio-1.68.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:c1245651f3c9ea92a2db4f95d37b7597db6b246d5892bca6ee8c0e90d76fb73c"}, + {file = "grpcio-1.68.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f1931c7aa85be0fa6cea6af388e576f3bf6baee9e5d481c586980c774debcb4"}, + {file = "grpcio-1.68.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b0ff09c81e3aded7a183bc6473639b46b6caa9c1901d6f5e2cba24b95e59e30"}, + {file = "grpcio-1.68.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8c73f9fbbaee1a132487e31585aa83987ddf626426d703ebcb9a528cf231c9b1"}, + {file = "grpcio-1.68.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6b2f98165ea2790ea159393a2246b56f580d24d7da0d0342c18a085299c40a75"}, + {file = "grpcio-1.68.0-cp311-cp311-win32.whl", hash = "sha256:e1e7ed311afb351ff0d0e583a66fcb39675be112d61e7cfd6c8269884a98afbc"}, + {file = "grpcio-1.68.0-cp311-cp311-win_amd64.whl", hash = "sha256:e0d2f68eaa0a755edd9a47d40e50dba6df2bceda66960dee1218da81a2834d27"}, + {file = "grpcio-1.68.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:8af6137cc4ae8e421690d276e7627cfc726d4293f6607acf9ea7260bd8fc3d7d"}, + {file = "grpcio-1.68.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:4028b8e9a3bff6f377698587d642e24bd221810c06579a18420a17688e421af7"}, + {file = "grpcio-1.68.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:f60fa2adf281fd73ae3a50677572521edca34ba373a45b457b5ebe87c2d01e1d"}, + {file = "grpcio-1.68.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e18589e747c1e70b60fab6767ff99b2d0c359ea1db8a2cb524477f93cdbedf5b"}, + {file = "grpcio-1.68.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0d30f3fee9372796f54d3100b31ee70972eaadcc87314be369360248a3dcffe"}, + {file = "grpcio-1.68.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:7e0a3e72c0e9a1acab77bef14a73a416630b7fd2cbd893c0a873edc47c42c8cd"}, + {file = "grpcio-1.68.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a831dcc343440969aaa812004685ed322cdb526cd197112d0db303b0da1e8659"}, + {file = "grpcio-1.68.0-cp312-cp312-win32.whl", hash = "sha256:5a180328e92b9a0050958ced34dddcb86fec5a8b332f5a229e353dafc16cd332"}, + {file = "grpcio-1.68.0-cp312-cp312-win_amd64.whl", hash = "sha256:2bddd04a790b69f7a7385f6a112f46ea0b34c4746f361ebafe9ca0be567c78e9"}, + {file = "grpcio-1.68.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:fc05759ffbd7875e0ff2bd877be1438dfe97c9312bbc558c8284a9afa1d0f40e"}, + {file = "grpcio-1.68.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:15fa1fe25d365a13bc6d52fcac0e3ee1f9baebdde2c9b3b2425f8a4979fccea1"}, + {file = "grpcio-1.68.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:32a9cb4686eb2e89d97022ecb9e1606d132f85c444354c17a7dbde4a455e4a3b"}, + {file = "grpcio-1.68.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dba037ff8d284c8e7ea9a510c8ae0f5b016004f13c3648f72411c464b67ff2fb"}, + {file = "grpcio-1.68.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0efbbd849867e0e569af09e165363ade75cf84f5229b2698d53cf22c7a4f9e21"}, + {file = "grpcio-1.68.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:4e300e6978df0b65cc2d100c54e097c10dfc7018b9bd890bbbf08022d47f766d"}, + {file = "grpcio-1.68.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:6f9c7ad1a23e1047f827385f4713b5b8c6c7d325705be1dd3e31fb00dcb2f665"}, + {file = "grpcio-1.68.0-cp313-cp313-win32.whl", hash = "sha256:3ac7f10850fd0487fcce169c3c55509101c3bde2a3b454869639df2176b60a03"}, + {file = "grpcio-1.68.0-cp313-cp313-win_amd64.whl", hash = "sha256:afbf45a62ba85a720491bfe9b2642f8761ff348006f5ef67e4622621f116b04a"}, + {file = "grpcio-1.68.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:f8f695d9576ce836eab27ba7401c60acaf9ef6cf2f70dfe5462055ba3df02cc3"}, + {file = "grpcio-1.68.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9fe1b141cda52f2ca73e17d2d3c6a9f3f3a0c255c216b50ce616e9dca7e3441d"}, + {file = "grpcio-1.68.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:4df81d78fd1646bf94ced4fb4cd0a7fe2e91608089c522ef17bc7db26e64effd"}, + {file = "grpcio-1.68.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:46a2d74d4dd8993151c6cd585594c082abe74112c8e4175ddda4106f2ceb022f"}, + {file = "grpcio-1.68.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a17278d977746472698460c63abf333e1d806bd41f2224f90dbe9460101c9796"}, + {file = "grpcio-1.68.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:15377bce516b1c861c35e18eaa1c280692bf563264836cece693c0f169b48829"}, + {file = "grpcio-1.68.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cc5f0a4f5904b8c25729a0498886b797feb817d1fd3812554ffa39551112c161"}, + {file = "grpcio-1.68.0-cp38-cp38-win32.whl", hash = "sha256:def1a60a111d24376e4b753db39705adbe9483ef4ca4761f825639d884d5da78"}, + {file = "grpcio-1.68.0-cp38-cp38-win_amd64.whl", hash = "sha256:55d3b52fd41ec5772a953612db4e70ae741a6d6ed640c4c89a64f017a1ac02b5"}, + {file = "grpcio-1.68.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:0d230852ba97654453d290e98d6aa61cb48fa5fafb474fb4c4298d8721809354"}, + {file = "grpcio-1.68.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:50992f214264e207e07222703c17d9cfdcc2c46ed5a1ea86843d440148ebbe10"}, + {file = "grpcio-1.68.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:14331e5c27ed3545360464a139ed279aa09db088f6e9502e95ad4bfa852bb116"}, + {file = "grpcio-1.68.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f84890b205692ea813653ece4ac9afa2139eae136e419231b0eec7c39fdbe4c2"}, + {file = "grpcio-1.68.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0cf343c6f4f6aa44863e13ec9ddfe299e0be68f87d68e777328bff785897b05"}, + {file = "grpcio-1.68.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:fd2c2d47969daa0e27eadaf15c13b5e92605c5e5953d23c06d0b5239a2f176d3"}, + {file = "grpcio-1.68.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:18668e36e7f4045820f069997834e94e8275910b1f03e078a6020bd464cb2363"}, + {file = "grpcio-1.68.0-cp39-cp39-win32.whl", hash = "sha256:2af76ab7c427aaa26aa9187c3e3c42f38d3771f91a20f99657d992afada2294a"}, + {file = "grpcio-1.68.0-cp39-cp39-win_amd64.whl", hash = "sha256:e694b5928b7b33ca2d3b4d5f9bf8b5888906f181daff6b406f4938f3a997a490"}, + {file = "grpcio-1.68.0.tar.gz", hash = "sha256:7e7483d39b4a4fddb9906671e9ea21aaad4f031cdfc349fec76bdfa1e404543a"}, ] [package.extras] -protobuf = ["grpcio-tools (>=1.69.0)"] +protobuf = ["grpcio-tools (>=1.68.0)"] [[package]] name = "grpcio-status" @@ -1777,13 +1792,13 @@ files = [ [[package]] name = "identify" -version = "2.6.5" +version = "2.6.2" description = "File identification library for Python" optional = false python-versions = ">=3.9" files = [ - {file = "identify-2.6.5-py2.py3-none-any.whl", hash = "sha256:14181a47091eb75b337af4c23078c9d09225cd4c48929f521f3bf16b09d02566"}, - {file = "identify-2.6.5.tar.gz", hash = "sha256:c10b33f250e5bba374fae86fb57f3adcebf1161bce7cdf92031915fd480c13bc"}, + {file = "identify-2.6.2-py2.py3-none-any.whl", hash = "sha256:c097384259f49e372f4ea00a19719d95ae27dd5ff0fd77ad630aa891306b82f3"}, + {file = "identify-2.6.2.tar.gz", hash = "sha256:fab5c716c24d7a789775228823797296a2994b075fb6080ac83a102772a98cbd"}, ] [package.extras] @@ -1993,13 +2008,13 @@ testing = ["Django", "attrs", "colorama", "docopt", "pytest (<9.0.0)"] [[package]] name = "jinja2" -version = "3.1.5" +version = "3.1.4" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, - {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, ] [package.dependencies] @@ -2165,13 +2180,13 @@ pyasn1 = ">=0.4.6" [[package]] name = "loguru" -version = "0.7.3" +version = "0.7.2" description = "Python logging made (stupidly) simple" optional = false -python-versions = "<4.0,>=3.5" +python-versions = ">=3.5" files = [ - {file = "loguru-0.7.3-py3-none-any.whl", hash = "sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c"}, - {file = "loguru-0.7.3.tar.gz", hash = "sha256:19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6"}, + {file = "loguru-0.7.2-py3-none-any.whl", hash = "sha256:003d71e3d3ed35f0f8984898359d65b79e5b21943f78af86aa5491210429b8eb"}, + {file = "loguru-0.7.2.tar.gz", hash = "sha256:e671a53522515f34fd406340ee968cb9ecafbc4b36c679da03c18fd8d0bd51ac"}, ] [package.dependencies] @@ -2179,7 +2194,7 @@ colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""} win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""} [package.extras] -dev = ["Sphinx (==8.1.3)", "build (==1.2.2)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptiongroup (==1.1.3)", "freezegun (==1.1.0)", "freezegun (==1.5.0)", "mypy (==v0.910)", "mypy (==v0.971)", "mypy (==v1.13.0)", "mypy (==v1.4.1)", "myst-parser (==4.0.0)", "pre-commit (==4.0.1)", "pytest (==6.1.2)", "pytest (==8.3.2)", "pytest-cov (==2.12.1)", "pytest-cov (==5.0.0)", "pytest-cov (==6.0.0)", "pytest-mypy-plugins (==1.9.3)", "pytest-mypy-plugins (==3.1.0)", "sphinx-rtd-theme (==3.0.2)", "tox (==3.27.1)", "tox (==4.23.2)", "twine (==6.0.1)"] +dev = ["Sphinx (==7.2.5)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptiongroup (==1.1.3)", "freezegun (==1.1.0)", "freezegun (==1.2.2)", "mypy (==v0.910)", "mypy (==v0.971)", "mypy (==v1.4.1)", "mypy (==v1.5.1)", "pre-commit (==3.4.0)", "pytest (==6.1.2)", "pytest (==7.4.0)", "pytest-cov (==2.12.1)", "pytest-cov (==4.1.0)", "pytest-mypy-plugins (==1.9.3)", "pytest-mypy-plugins (==3.0.0)", "sphinx-autobuild (==2021.3.14)", "sphinx-rtd-theme (==1.3.0)", "tox (==3.27.1)", "tox (==4.11.0)"] [[package]] name = "lxml" @@ -2779,21 +2794,21 @@ files = [ [[package]] name = "neo4j" -version = "5.27.0" +version = "5.26.0" description = "Neo4j Bolt driver for Python" optional = false python-versions = ">=3.7" files = [ - {file = "neo4j-5.27.0-py3-none-any.whl", hash = "sha256:929c14b9e5341267324eca170b39d1798b032bffacc26a0529eacaf678ae483f"}, - {file = "neo4j-5.27.0.tar.gz", hash = "sha256:f82ee807cd15b178898d83f41a66372e11719a25dd487fd7bea48fd4b7323765"}, + {file = "neo4j-5.26.0-py3-none-any.whl", hash = "sha256:511a6a9468ca89b521bf686f885a2070acc462b1d09821d43710bd477acdf11e"}, + {file = "neo4j-5.26.0.tar.gz", hash = "sha256:51b25ba127b7b9fdae1ddf48ae697ddfab331e60f4b6d8488d1fc1f74ec60dcc"}, ] [package.dependencies] pytz = "*" [package.extras] -numpy = ["numpy (>=1.7.0,<3.0.0)"] -pandas = ["numpy (>=1.7.0,<3.0.0)", "pandas (>=1.1.0,<3.0.0)"] +numpy = ["numpy (>=1.7.0,<2.0.0)"] +pandas = ["numpy (>=1.7.0,<2.0.0)", "pandas (>=1.1.0,<3.0.0)"] pyarrow = ["pyarrow (>=1.0.0)"] [[package]] @@ -2895,86 +2910,86 @@ dev = ["black", "mypy", "pytest"] [[package]] name = "orjson" -version = "3.10.13" +version = "3.10.12" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, - {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, - {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, - {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, - {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, - {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, - {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, - {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, - {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, - {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, - {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, - {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, - {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, - {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, - {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, - {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, - {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, - {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, - {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, - {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, - {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, - {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, - {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, - {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, - {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, - {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, - {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, - {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, - {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, - {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, - {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, - {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, - {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, - {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, - {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, - {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, - {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, - {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, - {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, - {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, - {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, - {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, - {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, - {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, - {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, - {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, - {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, - {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, - {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, - {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, - {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, - {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, - {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, - {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, - {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, - {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, - {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, - {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, - {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, - {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, - {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, - {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, - {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, - {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, - {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, - {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, - {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, - {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, - {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, - {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, - {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, - {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, - {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, - {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, - {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, + {file = "orjson-3.10.12-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ece01a7ec71d9940cc654c482907a6b65df27251255097629d0dea781f255c6d"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c34ec9aebc04f11f4b978dd6caf697a2df2dd9b47d35aa4cc606cabcb9df69d7"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fd6ec8658da3480939c79b9e9e27e0db31dffcd4ba69c334e98c9976ac29140e"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f17e6baf4cf01534c9de8a16c0c611f3d94925d1701bf5f4aff17003677d8ced"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6402ebb74a14ef96f94a868569f5dccf70d791de49feb73180eb3c6fda2ade56"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0000758ae7c7853e0a4a6063f534c61656ebff644391e1f81698c1b2d2fc8cd2"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:888442dcee99fd1e5bd37a4abb94930915ca6af4db50e23e746cdf4d1e63db13"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c1f7a3ce79246aa0e92f5458d86c54f257fb5dfdc14a192651ba7ec2c00f8a05"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:802a3935f45605c66fb4a586488a38af63cb37aaad1c1d94c982c40dcc452e85"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1da1ef0113a2be19bb6c557fb0ec2d79c92ebd2fed4cfb1b26bab93f021fb885"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a3273e99f367f137d5b3fecb5e9f45bcdbfac2a8b2f32fbc72129bbd48789c2"}, + {file = "orjson-3.10.12-cp310-none-win32.whl", hash = "sha256:475661bf249fd7907d9b0a2a2421b4e684355a77ceef85b8352439a9163418c3"}, + {file = "orjson-3.10.12-cp310-none-win_amd64.whl", hash = "sha256:87251dc1fb2b9e5ab91ce65d8f4caf21910d99ba8fb24b49fd0c118b2362d509"}, + {file = "orjson-3.10.12-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a734c62efa42e7df94926d70fe7d37621c783dea9f707a98cdea796964d4cf74"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:750f8b27259d3409eda8350c2919a58b0cfcd2054ddc1bd317a643afc646ef23"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb52c22bfffe2857e7aa13b4622afd0dd9d16ea7cc65fd2bf318d3223b1b6252"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:440d9a337ac8c199ff8251e100c62e9488924c92852362cd27af0e67308c16ef"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9e15c06491c69997dfa067369baab3bf094ecb74be9912bdc4339972323f252"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:362d204ad4b0b8724cf370d0cd917bb2dc913c394030da748a3bb632445ce7c4"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2b57cbb4031153db37b41622eac67329c7810e5f480fda4cfd30542186f006ae"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:165c89b53ef03ce0d7c59ca5c82fa65fe13ddf52eeb22e859e58c237d4e33b9b"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:5dee91b8dfd54557c1a1596eb90bcd47dbcd26b0baaed919e6861f076583e9da"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:77a4e1cfb72de6f905bdff061172adfb3caf7a4578ebf481d8f0530879476c07"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:038d42c7bc0606443459b8fe2d1f121db474c49067d8d14c6a075bbea8bf14dd"}, + {file = "orjson-3.10.12-cp311-none-win32.whl", hash = "sha256:03b553c02ab39bed249bedd4abe37b2118324d1674e639b33fab3d1dafdf4d79"}, + {file = "orjson-3.10.12-cp311-none-win_amd64.whl", hash = "sha256:8b8713b9e46a45b2af6b96f559bfb13b1e02006f4242c156cbadef27800a55a8"}, + {file = "orjson-3.10.12-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:53206d72eb656ca5ac7d3a7141e83c5bbd3ac30d5eccfe019409177a57634b0d"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac8010afc2150d417ebda810e8df08dd3f544e0dd2acab5370cfa6bcc0662f8f"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed459b46012ae950dd2e17150e838ab08215421487371fa79d0eced8d1461d70"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dcb9673f108a93c1b52bfc51b0af422c2d08d4fc710ce9c839faad25020bb69"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22a51ae77680c5c4652ebc63a83d5255ac7d65582891d9424b566fb3b5375ee9"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910fdf2ac0637b9a77d1aad65f803bac414f0b06f720073438a7bd8906298192"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:24ce85f7100160936bc2116c09d1a8492639418633119a2224114f67f63a4559"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a76ba5fc8dd9c913640292df27bff80a685bed3a3c990d59aa6ce24c352f8fc"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ff70ef093895fd53f4055ca75f93f047e088d1430888ca1229393a7c0521100f"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f4244b7018b5753ecd10a6d324ec1f347da130c953a9c88432c7fbc8875d13be"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:16135ccca03445f37921fa4b585cff9a58aa8d81ebcb27622e69bfadd220b32c"}, + {file = "orjson-3.10.12-cp312-none-win32.whl", hash = "sha256:2d879c81172d583e34153d524fcba5d4adafbab8349a7b9f16ae511c2cee8708"}, + {file = "orjson-3.10.12-cp312-none-win_amd64.whl", hash = "sha256:fc23f691fa0f5c140576b8c365bc942d577d861a9ee1142e4db468e4e17094fb"}, + {file = "orjson-3.10.12-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:47962841b2a8aa9a258b377f5188db31ba49af47d4003a32f55d6f8b19006543"}, + {file = "orjson-3.10.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6334730e2532e77b6054e87ca84f3072bee308a45a452ea0bffbbbc40a67e296"}, + {file = "orjson-3.10.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:accfe93f42713c899fdac2747e8d0d5c659592df2792888c6c5f829472e4f85e"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a7974c490c014c48810d1dede6c754c3cc46598da758c25ca3b4001ac45b703f"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3f250ce7727b0b2682f834a3facff88e310f52f07a5dcfd852d99637d386e79e"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f31422ff9486ae484f10ffc51b5ab2a60359e92d0716fcce1b3593d7bb8a9af6"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5f29c5d282bb2d577c2a6bbde88d8fdcc4919c593f806aac50133f01b733846e"}, + {file = "orjson-3.10.12-cp313-none-win32.whl", hash = "sha256:f45653775f38f63dc0e6cd4f14323984c3149c05d6007b58cb154dd080ddc0dc"}, + {file = "orjson-3.10.12-cp313-none-win_amd64.whl", hash = "sha256:229994d0c376d5bdc91d92b3c9e6be2f1fbabd4cc1b59daae1443a46ee5e9825"}, + {file = "orjson-3.10.12-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7d69af5b54617a5fac5c8e5ed0859eb798e2ce8913262eb522590239db6c6763"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ed119ea7d2953365724a7059231a44830eb6bbb0cfead33fcbc562f5fd8f935"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9c5fc1238ef197e7cad5c91415f524aaa51e004be5a9b35a1b8a84ade196f73f"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43509843990439b05f848539d6f6198d4ac86ff01dd024b2f9a795c0daeeab60"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f72e27a62041cfb37a3de512247ece9f240a561e6c8662276beaf4d53d406db4"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a904f9572092bb6742ab7c16c623f0cdccbad9eeb2d14d4aa06284867bddd31"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:855c0833999ed5dc62f64552db26f9be767434917d8348d77bacaab84f787d7b"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:897830244e2320f6184699f598df7fb9db9f5087d6f3f03666ae89d607e4f8ed"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0b32652eaa4a7539f6f04abc6243619c56f8530c53bf9b023e1269df5f7816dd"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:36b4aa31e0f6a1aeeb6f8377769ca5d125db000f05c20e54163aef1d3fe8e833"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5535163054d6cbf2796f93e4f0dbc800f61914c0e3c4ed8499cf6ece22b4a3da"}, + {file = "orjson-3.10.12-cp38-none-win32.whl", hash = "sha256:90a5551f6f5a5fa07010bf3d0b4ca2de21adafbbc0af6cb700b63cd767266cb9"}, + {file = "orjson-3.10.12-cp38-none-win_amd64.whl", hash = "sha256:703a2fb35a06cdd45adf5d733cf613cbc0cb3ae57643472b16bc22d325b5fb6c"}, + {file = "orjson-3.10.12-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:f29de3ef71a42a5822765def1febfb36e0859d33abf5c2ad240acad5c6a1b78d"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de365a42acc65d74953f05e4772c974dad6c51cfc13c3240899f534d611be967"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:91a5a0158648a67ff0004cb0df5df7dcc55bfc9ca154d9c01597a23ad54c8d0c"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c47ce6b8d90fe9646a25b6fb52284a14ff215c9595914af63a5933a49972ce36"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0eee4c2c5bfb5c1b47a5db80d2ac7aaa7e938956ae88089f098aff2c0f35d5d8"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35d3081bbe8b86587eb5c98a73b97f13d8f9fea685cf91a579beddacc0d10566"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73c23a6e90383884068bc2dba83d5222c9fcc3b99a0ed2411d38150734236755"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5472be7dc3269b4b52acba1433dac239215366f89dc1d8d0e64029abac4e714e"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:7319cda750fca96ae5973efb31b17d97a5c5225ae0bc79bf5bf84df9e1ec2ab6"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:74d5ca5a255bf20b8def6a2b96b1e18ad37b4a122d59b154c458ee9494377f80"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ff31d22ecc5fb85ef62c7d4afe8301d10c558d00dd24274d4bbe464380d3cd69"}, + {file = "orjson-3.10.12-cp39-none-win32.whl", hash = "sha256:c22c3ea6fba91d84fcb4cda30e64aff548fcf0c44c876e681f47d61d24b12e6b"}, + {file = "orjson-3.10.12-cp39-none-win_amd64.whl", hash = "sha256:be604f60d45ace6b0b33dd990a66b4526f1a7a186ac411c942674625456ca548"}, + {file = "orjson-3.10.12.tar.gz", hash = "sha256:0a78bbda3aea0f9f079057ee1ee8a1ecf790d4f1af88dd67493c6b8ee52506ff"}, ] [[package]] @@ -3054,13 +3069,13 @@ files = [ [[package]] name = "pebble" -version = "5.1.0" +version = "5.0.7" description = "Threading and multiprocessing eye-candy." optional = false -python-versions = ">=3.8" +python-versions = ">=3.6" files = [ - {file = "Pebble-5.1.0-py3-none-any.whl", hash = "sha256:530a398299ecd3a4ed1baf2e4b8045d8280b1e665560b0b409f8d8e58db60111"}, - {file = "Pebble-5.1.0.tar.gz", hash = "sha256:5c30376f1827b21ecec4126ff90e7f22ad5501cac1ff2b32c86ff2601681f932"}, + {file = "Pebble-5.0.7-py3-none-any.whl", hash = "sha256:f1742f2a62e8544e722c7b387211fb1a06038ca8cda322e5d55c84c793fd8d7d"}, + {file = "Pebble-5.0.7.tar.gz", hash = "sha256:2784c147766f06388cea784084b14bec93fdbaa793830f1983155aa330a2a6e4"}, ] [[package]] @@ -3159,93 +3174,109 @@ wcwidth = "*" [[package]] name = "propcache" -version = "0.2.1" +version = "0.2.0" description = "Accelerated property cache" optional = true -python-versions = ">=3.9" +python-versions = ">=3.8" files = [ - {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6b3f39a85d671436ee3d12c017f8fdea38509e4f25b28eb25877293c98c243f6"}, - {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d51fbe4285d5db5d92a929e3e21536ea3dd43732c5b177c7ef03f918dff9f2"}, - {file = "propcache-0.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6445804cf4ec763dc70de65a3b0d9954e868609e83850a47ca4f0cb64bd79fea"}, - {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9479aa06a793c5aeba49ce5c5692ffb51fcd9a7016e017d555d5e2b0045d212"}, - {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9631c5e8b5b3a0fda99cb0d29c18133bca1e18aea9effe55adb3da1adef80d3"}, - {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3156628250f46a0895f1f36e1d4fbe062a1af8718ec3ebeb746f1d23f0c5dc4d"}, - {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b6fb63ae352e13748289f04f37868099e69dba4c2b3e271c46061e82c745634"}, - {file = "propcache-0.2.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:887d9b0a65404929641a9fabb6452b07fe4572b269d901d622d8a34a4e9043b2"}, - {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a96dc1fa45bd8c407a0af03b2d5218392729e1822b0c32e62c5bf7eeb5fb3958"}, - {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a7e65eb5c003a303b94aa2c3852ef130230ec79e349632d030e9571b87c4698c"}, - {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:999779addc413181912e984b942fbcc951be1f5b3663cd80b2687758f434c583"}, - {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:19a0f89a7bb9d8048d9c4370c9c543c396e894c76be5525f5e1ad287f1750ddf"}, - {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1ac2f5fe02fa75f56e1ad473f1175e11f475606ec9bd0be2e78e4734ad575034"}, - {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:574faa3b79e8ebac7cb1d7930f51184ba1ccf69adfdec53a12f319a06030a68b"}, - {file = "propcache-0.2.1-cp310-cp310-win32.whl", hash = "sha256:03ff9d3f665769b2a85e6157ac8b439644f2d7fd17615a82fa55739bc97863f4"}, - {file = "propcache-0.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:2d3af2e79991102678f53e0dbf4c35de99b6b8b58f29a27ca0325816364caaba"}, - {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ffc3cca89bb438fb9c95c13fc874012f7b9466b89328c3c8b1aa93cdcfadd16"}, - {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f174bbd484294ed9fdf09437f889f95807e5f229d5d93588d34e92106fbf6717"}, - {file = "propcache-0.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:70693319e0b8fd35dd863e3e29513875eb15c51945bf32519ef52927ca883bc3"}, - {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b480c6a4e1138e1aa137c0079b9b6305ec6dcc1098a8ca5196283e8a49df95a9"}, - {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d27b84d5880f6d8aa9ae3edb253c59d9f6642ffbb2c889b78b60361eed449787"}, - {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:857112b22acd417c40fa4595db2fe28ab900c8c5fe4670c7989b1c0230955465"}, - {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf6c4150f8c0e32d241436526f3c3f9cbd34429492abddbada2ffcff506c51af"}, - {file = "propcache-0.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66d4cfda1d8ed687daa4bc0274fcfd5267873db9a5bc0418c2da19273040eeb7"}, - {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c2f992c07c0fca81655066705beae35fc95a2fa7366467366db627d9f2ee097f"}, - {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:4a571d97dbe66ef38e472703067021b1467025ec85707d57e78711c085984e54"}, - {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bb6178c241278d5fe853b3de743087be7f5f4c6f7d6d22a3b524d323eecec505"}, - {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ad1af54a62ffe39cf34db1aa6ed1a1873bd548f6401db39d8e7cd060b9211f82"}, - {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e7048abd75fe40712005bcfc06bb44b9dfcd8e101dda2ecf2f5aa46115ad07ca"}, - {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:160291c60081f23ee43d44b08a7e5fb76681221a8e10b3139618c5a9a291b84e"}, - {file = "propcache-0.2.1-cp311-cp311-win32.whl", hash = "sha256:819ce3b883b7576ca28da3861c7e1a88afd08cc8c96908e08a3f4dd64a228034"}, - {file = "propcache-0.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:edc9fc7051e3350643ad929df55c451899bb9ae6d24998a949d2e4c87fb596d3"}, - {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a"}, - {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0"}, - {file = "propcache-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d"}, - {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4"}, - {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d"}, - {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5"}, - {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24"}, - {file = "propcache-0.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff"}, - {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f"}, - {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec"}, - {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348"}, - {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6"}, - {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6"}, - {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518"}, - {file = "propcache-0.2.1-cp312-cp312-win32.whl", hash = "sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246"}, - {file = "propcache-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1"}, - {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aca405706e0b0a44cc6bfd41fbe89919a6a56999157f6de7e182a990c36e37bc"}, - {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:12d1083f001ace206fe34b6bdc2cb94be66d57a850866f0b908972f90996b3e9"}, - {file = "propcache-0.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d93f3307ad32a27bda2e88ec81134b823c240aa3abb55821a8da553eed8d9439"}, - {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba278acf14471d36316159c94a802933d10b6a1e117b8554fe0d0d9b75c9d536"}, - {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4e6281aedfca15301c41f74d7005e6e3f4ca143584ba696ac69df4f02f40d629"}, - {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b750a8e5a1262434fb1517ddf64b5de58327f1adc3524a5e44c2ca43305eb0b"}, - {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf72af5e0fb40e9babf594308911436c8efde3cb5e75b6f206c34ad18be5c052"}, - {file = "propcache-0.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2d0a12018b04f4cb820781ec0dffb5f7c7c1d2a5cd22bff7fb055a2cb19ebce"}, - {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e800776a79a5aabdb17dcc2346a7d66d0777e942e4cd251defeb084762ecd17d"}, - {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4160d9283bd382fa6c0c2b5e017acc95bc183570cd70968b9202ad6d8fc48dce"}, - {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:30b43e74f1359353341a7adb783c8f1b1c676367b011709f466f42fda2045e95"}, - {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:58791550b27d5488b1bb52bc96328456095d96206a250d28d874fafe11b3dfaf"}, - {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0f022d381747f0dfe27e99d928e31bc51a18b65bb9e481ae0af1380a6725dd1f"}, - {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:297878dc9d0a334358f9b608b56d02e72899f3b8499fc6044133f0d319e2ec30"}, - {file = "propcache-0.2.1-cp313-cp313-win32.whl", hash = "sha256:ddfab44e4489bd79bda09d84c430677fc7f0a4939a73d2bba3073036f487a0a6"}, - {file = "propcache-0.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:556fc6c10989f19a179e4321e5d678db8eb2924131e64652a51fe83e4c3db0e1"}, - {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6a9a8c34fb7bb609419a211e59da8887eeca40d300b5ea8e56af98f6fbbb1541"}, - {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ae1aa1cd222c6d205853b3013c69cd04515f9d6ab6de4b0603e2e1c33221303e"}, - {file = "propcache-0.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:accb6150ce61c9c4b7738d45550806aa2b71c7668c6942f17b0ac182b6142fd4"}, - {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5eee736daafa7af6d0a2dc15cc75e05c64f37fc37bafef2e00d77c14171c2097"}, - {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7a31fc1e1bd362874863fdeed71aed92d348f5336fd84f2197ba40c59f061bd"}, - {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba4cfa1052819d16699e1d55d18c92b6e094d4517c41dd231a8b9f87b6fa681"}, - {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f089118d584e859c62b3da0892b88a83d611c2033ac410e929cb6754eec0ed16"}, - {file = "propcache-0.2.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:781e65134efaf88feb447e8c97a51772aa75e48b794352f94cb7ea717dedda0d"}, - {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31f5af773530fd3c658b32b6bdc2d0838543de70eb9a2156c03e410f7b0d3aae"}, - {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:a7a078f5d37bee6690959c813977da5291b24286e7b962e62a94cec31aa5188b"}, - {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:cea7daf9fc7ae6687cf1e2c049752f19f146fdc37c2cc376e7d0032cf4f25347"}, - {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:8b3489ff1ed1e8315674d0775dc7d2195fb13ca17b3808721b54dbe9fd020faf"}, - {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9403db39be1393618dd80c746cb22ccda168efce239c73af13c3763ef56ffc04"}, - {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5d97151bc92d2b2578ff7ce779cdb9174337390a535953cbb9452fb65164c587"}, - {file = "propcache-0.2.1-cp39-cp39-win32.whl", hash = "sha256:9caac6b54914bdf41bcc91e7eb9147d331d29235a7c967c150ef5df6464fd1bb"}, - {file = "propcache-0.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:92fc4500fcb33899b05ba73276dfb684a20d31caa567b7cb5252d48f896a91b1"}, - {file = "propcache-0.2.1-py3-none-any.whl", hash = "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54"}, - {file = "propcache-0.2.1.tar.gz", hash = "sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64"}, + {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58"}, + {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b"}, + {file = "propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336"}, + {file = "propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad"}, + {file = "propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99"}, + {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354"}, + {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de"}, + {file = "propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b"}, + {file = "propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1"}, + {file = "propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348"}, + {file = "propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5"}, + {file = "propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3"}, + {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7"}, + {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763"}, + {file = "propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544"}, + {file = "propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032"}, + {file = "propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e"}, + {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861"}, + {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6"}, + {file = "propcache-0.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed"}, + {file = "propcache-0.2.0-cp38-cp38-win32.whl", hash = "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d"}, + {file = "propcache-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5"}, + {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6"}, + {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638"}, + {file = "propcache-0.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798"}, + {file = "propcache-0.2.0-cp39-cp39-win32.whl", hash = "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9"}, + {file = "propcache-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df"}, + {file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"}, + {file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"}, ] [[package]] @@ -3287,32 +3318,32 @@ files = [ [[package]] name = "psutil" -version = "6.1.1" +version = "6.1.0" description = "Cross-platform lib for process and system monitoring in Python." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ - {file = "psutil-6.1.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9ccc4316f24409159897799b83004cb1e24f9819b0dcf9c0b68bdcb6cefee6a8"}, - {file = "psutil-6.1.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ca9609c77ea3b8481ab005da74ed894035936223422dc591d6772b147421f777"}, - {file = "psutil-6.1.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:8df0178ba8a9e5bc84fed9cfa61d54601b371fbec5c8eebad27575f1e105c0d4"}, - {file = "psutil-6.1.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:1924e659d6c19c647e763e78670a05dbb7feaf44a0e9c94bf9e14dfc6ba50468"}, - {file = "psutil-6.1.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:018aeae2af92d943fdf1da6b58665124897cfc94faa2ca92098838f83e1b1bca"}, - {file = "psutil-6.1.1-cp27-none-win32.whl", hash = "sha256:6d4281f5bbca041e2292be3380ec56a9413b790579b8e593b1784499d0005dac"}, - {file = "psutil-6.1.1-cp27-none-win_amd64.whl", hash = "sha256:c777eb75bb33c47377c9af68f30e9f11bc78e0f07fbf907be4a5d70b2fe5f030"}, - {file = "psutil-6.1.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed7fe2231a444fc219b9c42d0376e0a9a1a72f16c5cfa0f68d19f1a0663e8"}, - {file = "psutil-6.1.1-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0bdd4eab935276290ad3cb718e9809412895ca6b5b334f5a9111ee6d9aff9377"}, - {file = "psutil-6.1.1-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6e06c20c05fe95a3d7302d74e7097756d4ba1247975ad6905441ae1b5b66003"}, - {file = "psutil-6.1.1-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97f7cb9921fbec4904f522d972f0c0e1f4fabbdd4e0287813b21215074a0f160"}, - {file = "psutil-6.1.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33431e84fee02bc84ea36d9e2c4a6d395d479c9dd9bba2376c1f6ee8f3a4e0b3"}, - {file = "psutil-6.1.1-cp36-cp36m-win32.whl", hash = "sha256:384636b1a64b47814437d1173be1427a7c83681b17a450bfc309a1953e329603"}, - {file = "psutil-6.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8be07491f6ebe1a693f17d4f11e69d0dc1811fa082736500f649f79df7735303"}, - {file = "psutil-6.1.1-cp37-abi3-win32.whl", hash = "sha256:eaa912e0b11848c4d9279a93d7e2783df352b082f40111e078388701fd479e53"}, - {file = "psutil-6.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:f35cfccb065fff93529d2afb4a2e89e363fe63ca1e4a5da22b603a85833c2649"}, - {file = "psutil-6.1.1.tar.gz", hash = "sha256:cf8496728c18f2d0b45198f06895be52f36611711746b7f30c464b422b50e2f5"}, + {file = "psutil-6.1.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff34df86226c0227c52f38b919213157588a678d049688eded74c76c8ba4a5d0"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c0e0c00aa18ca2d3b2b991643b799a15fc8f0563d2ebb6040f64ce8dc027b942"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:000d1d1ebd634b4efb383f4034437384e44a6d455260aaee2eca1e9c1b55f047"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5cd2bcdc75b452ba2e10f0e8ecc0b57b827dd5d7aaffbc6821b2a9a242823a76"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:045f00a43c737f960d273a83973b2511430d61f283a44c96bf13a6e829ba8fdc"}, + {file = "psutil-6.1.0-cp27-none-win32.whl", hash = "sha256:9118f27452b70bb1d9ab3198c1f626c2499384935aaf55388211ad982611407e"}, + {file = "psutil-6.1.0-cp27-none-win_amd64.whl", hash = "sha256:a8506f6119cff7015678e2bce904a4da21025cc70ad283a53b099e7620061d85"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a"}, + {file = "psutil-6.1.0-cp36-cp36m-win32.whl", hash = "sha256:6d3fbbc8d23fcdcb500d2c9f94e07b1342df8ed71b948a2649b5cb060a7c94ca"}, + {file = "psutil-6.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1209036fbd0421afde505a4879dee3b2fd7b1e14fee81c0069807adcbbcca747"}, + {file = "psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e"}, + {file = "psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be"}, + {file = "psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a"}, ] [package.extras] -dev = ["abi3audit", "black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "vulture", "wheel"] +dev = ["black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "wheel"] test = ["pytest", "pytest-xdist", "setuptools"] [[package]] @@ -3507,13 +3538,13 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pyjwt" -version = "2.10.1" +version = "2.10.0" description = "JSON Web Token implementation in Python" optional = false python-versions = ">=3.9" files = [ - {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, - {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, + {file = "PyJWT-2.10.0-py3-none-any.whl", hash = "sha256:543b77207db656de204372350926bed5a86201c4cbff159f623f79c7bb487a15"}, + {file = "pyjwt-2.10.0.tar.gz", hash = "sha256:7628a7eb7938959ac1b26e819a1df0fd3259505627b575e4bad6d08f76db695c"}, ] [package.dependencies] @@ -3543,22 +3574,22 @@ python-dateutil = ">=2.8.0" [[package]] name = "pylint" -version = "3.3.3" +version = "3.3.1" description = "python code static checker" optional = false python-versions = ">=3.9.0" files = [ - {file = "pylint-3.3.3-py3-none-any.whl", hash = "sha256:26e271a2bc8bce0fc23833805a9076dd9b4d5194e2a02164942cb3cdc37b4183"}, - {file = "pylint-3.3.3.tar.gz", hash = "sha256:07c607523b17e6d16e2ae0d7ef59602e332caa762af64203c24b41c27139f36a"}, + {file = "pylint-3.3.1-py3-none-any.whl", hash = "sha256:2f846a466dd023513240bc140ad2dd73bfc080a5d85a710afdb728c420a5a2b9"}, + {file = "pylint-3.3.1.tar.gz", hash = "sha256:9f3dcc87b1203e612b78d91a896407787e708b3f189b5fa0b307712d49ff0c6e"}, ] [package.dependencies] -astroid = ">=3.3.8,<=3.4.0-dev0" +astroid = ">=3.3.4,<=3.4.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = [ + {version = ">=0.2", markers = "python_version < \"3.11\""}, {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, {version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, - {version = ">=0.2", markers = "python_version < \"3.11\""}, ] isort = ">=4.2.5,<5.13.0 || >5.13.0,<6" mccabe = ">=0.6,<0.8" @@ -3794,13 +3825,13 @@ dev = ["pre-commit", "pytest-asyncio", "tox"] [[package]] name = "pytest-subprocess" -version = "1.5.3" +version = "1.5.2" description = "A plugin to fake subprocess for pytest" optional = false python-versions = ">=3.6" files = [ - {file = "pytest_subprocess-1.5.3-py3-none-any.whl", hash = "sha256:b62580f5a84335fb9f2ec65d49e56a3c93f4722c148fe1771a002835d310a75b"}, - {file = "pytest_subprocess-1.5.3.tar.gz", hash = "sha256:c00b1140fb0211b3153e09500d770db10770baccbe6e05ee9c140036d1d811d5"}, + {file = "pytest_subprocess-1.5.2-py3-none-any.whl", hash = "sha256:23ac7732aa8bd45f1757265b1316eb72a7f55b41fb21e2ca22e149ba3629fa46"}, + {file = "pytest_subprocess-1.5.2.tar.gz", hash = "sha256:ad3ca8a35e798bf9c82d9f16d88700b30d98c5a28236117b86c5d6e581a8ed97"}, ] [package.dependencies] @@ -3809,7 +3840,7 @@ pytest = ">=4.0.0" [package.extras] dev = ["changelogd", "nox"] docs = ["changelogd", "furo", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-napoleon"] -test = ["Pygments (>=2.0)", "anyio", "docutils (>=0.12)", "pytest (>=4.0)", "pytest-asyncio (>=0.15.1)", "pytest-rerunfailures", "pytest-timeout"] +test = ["Pygments (>=2.0)", "anyio", "coverage", "docutils (>=0.12)", "pytest (>=4.0)", "pytest-asyncio (>=0.15.1)", "pytest-rerunfailures", "pytest-timeout"] [[package]] name = "pytest-sugar" @@ -4293,114 +4324,101 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "rpds-py" -version = "0.22.3" +version = "0.21.0" description = "Python bindings to Rust's persistent data structures (rpds)" optional = false python-versions = ">=3.9" files = [ - {file = "rpds_py-0.22.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:6c7b99ca52c2c1752b544e310101b98a659b720b21db00e65edca34483259967"}, - {file = "rpds_py-0.22.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:be2eb3f2495ba669d2a985f9b426c1797b7d48d6963899276d22f23e33d47e37"}, - {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70eb60b3ae9245ddea20f8a4190bd79c705a22f8028aaf8bbdebe4716c3fab24"}, - {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4041711832360a9b75cfb11b25a6a97c8fb49c07b8bd43d0d02b45d0b499a4ff"}, - {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:64607d4cbf1b7e3c3c8a14948b99345eda0e161b852e122c6bb71aab6d1d798c"}, - {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e69b0a0e2537f26d73b4e43ad7bc8c8efb39621639b4434b76a3de50c6966e"}, - {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc27863442d388870c1809a87507727b799c8460573cfbb6dc0eeaef5a11b5ec"}, - {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e79dd39f1e8c3504be0607e5fc6e86bb60fe3584bec8b782578c3b0fde8d932c"}, - {file = "rpds_py-0.22.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e0fa2d4ec53dc51cf7d3bb22e0aa0143966119f42a0c3e4998293a3dd2856b09"}, - {file = "rpds_py-0.22.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fda7cb070f442bf80b642cd56483b5548e43d366fe3f39b98e67cce780cded00"}, - {file = "rpds_py-0.22.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cff63a0272fcd259dcc3be1657b07c929c466b067ceb1c20060e8d10af56f5bf"}, - {file = "rpds_py-0.22.3-cp310-cp310-win32.whl", hash = "sha256:9bd7228827ec7bb817089e2eb301d907c0d9827a9e558f22f762bb690b131652"}, - {file = "rpds_py-0.22.3-cp310-cp310-win_amd64.whl", hash = "sha256:9beeb01d8c190d7581a4d59522cd3d4b6887040dcfc744af99aa59fef3e041a8"}, - {file = "rpds_py-0.22.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d20cfb4e099748ea39e6f7b16c91ab057989712d31761d3300d43134e26e165f"}, - {file = "rpds_py-0.22.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:68049202f67380ff9aa52f12e92b1c30115f32e6895cd7198fa2a7961621fc5a"}, - {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb4f868f712b2dd4bcc538b0a0c1f63a2b1d584c925e69a224d759e7070a12d5"}, - {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bc51abd01f08117283c5ebf64844a35144a0843ff7b2983e0648e4d3d9f10dbb"}, - {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f3cec041684de9a4684b1572fe28c7267410e02450f4561700ca5a3bc6695a2"}, - {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7ef9d9da710be50ff6809fed8f1963fecdfecc8b86656cadfca3bc24289414b0"}, - {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59f4a79c19232a5774aee369a0c296712ad0e77f24e62cad53160312b1c1eaa1"}, - {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a60bce91f81ddaac922a40bbb571a12c1070cb20ebd6d49c48e0b101d87300d"}, - {file = "rpds_py-0.22.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e89391e6d60251560f0a8f4bd32137b077a80d9b7dbe6d5cab1cd80d2746f648"}, - {file = "rpds_py-0.22.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e3fb866d9932a3d7d0c82da76d816996d1667c44891bd861a0f97ba27e84fc74"}, - {file = "rpds_py-0.22.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1352ae4f7c717ae8cba93421a63373e582d19d55d2ee2cbb184344c82d2ae55a"}, - {file = "rpds_py-0.22.3-cp311-cp311-win32.whl", hash = "sha256:b0b4136a252cadfa1adb705bb81524eee47d9f6aab4f2ee4fa1e9d3cd4581f64"}, - {file = "rpds_py-0.22.3-cp311-cp311-win_amd64.whl", hash = "sha256:8bd7c8cfc0b8247c8799080fbff54e0b9619e17cdfeb0478ba7295d43f635d7c"}, - {file = "rpds_py-0.22.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:27e98004595899949bd7a7b34e91fa7c44d7a97c40fcaf1d874168bb652ec67e"}, - {file = "rpds_py-0.22.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1978d0021e943aae58b9b0b196fb4895a25cc53d3956b8e35e0b7682eefb6d56"}, - {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:655ca44a831ecb238d124e0402d98f6212ac527a0ba6c55ca26f616604e60a45"}, - {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:feea821ee2a9273771bae61194004ee2fc33f8ec7db08117ef9147d4bbcbca8e"}, - {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22bebe05a9ffc70ebfa127efbc429bc26ec9e9b4ee4d15a740033efda515cf3d"}, - {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3af6e48651c4e0d2d166dc1b033b7042ea3f871504b6805ba5f4fe31581d8d38"}, - {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67ba3c290821343c192f7eae1d8fd5999ca2dc99994114643e2f2d3e6138b15"}, - {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:02fbb9c288ae08bcb34fb41d516d5eeb0455ac35b5512d03181d755d80810059"}, - {file = "rpds_py-0.22.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f56a6b404f74ab372da986d240e2e002769a7d7102cc73eb238a4f72eec5284e"}, - {file = "rpds_py-0.22.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0a0461200769ab3b9ab7e513f6013b7a97fdeee41c29b9db343f3c5a8e2b9e61"}, - {file = "rpds_py-0.22.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8633e471c6207a039eff6aa116e35f69f3156b3989ea3e2d755f7bc41754a4a7"}, - {file = "rpds_py-0.22.3-cp312-cp312-win32.whl", hash = "sha256:593eba61ba0c3baae5bc9be2f5232430453fb4432048de28399ca7376de9c627"}, - {file = "rpds_py-0.22.3-cp312-cp312-win_amd64.whl", hash = "sha256:d115bffdd417c6d806ea9069237a4ae02f513b778e3789a359bc5856e0404cc4"}, - {file = "rpds_py-0.22.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:ea7433ce7e4bfc3a85654aeb6747babe3f66eaf9a1d0c1e7a4435bbdf27fea84"}, - {file = "rpds_py-0.22.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6dd9412824c4ce1aca56c47b0991e65bebb7ac3f4edccfd3f156150c96a7bf25"}, - {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20070c65396f7373f5df4005862fa162db5d25d56150bddd0b3e8214e8ef45b4"}, - {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0b09865a9abc0ddff4e50b5ef65467cd94176bf1e0004184eb915cbc10fc05c5"}, - {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3453e8d41fe5f17d1f8e9c383a7473cd46a63661628ec58e07777c2fff7196dc"}, - {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f5d36399a1b96e1a5fdc91e0522544580dbebeb1f77f27b2b0ab25559e103b8b"}, - {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:009de23c9c9ee54bf11303a966edf4d9087cd43a6003672e6aa7def643d06518"}, - {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1aef18820ef3e4587ebe8b3bc9ba6e55892a6d7b93bac6d29d9f631a3b4befbd"}, - {file = "rpds_py-0.22.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f60bd8423be1d9d833f230fdbccf8f57af322d96bcad6599e5a771b151398eb2"}, - {file = "rpds_py-0.22.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:62d9cfcf4948683a18a9aff0ab7e1474d407b7bab2ca03116109f8464698ab16"}, - {file = "rpds_py-0.22.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9253fc214112405f0afa7db88739294295f0e08466987f1d70e29930262b4c8f"}, - {file = "rpds_py-0.22.3-cp313-cp313-win32.whl", hash = "sha256:fb0ba113b4983beac1a2eb16faffd76cb41e176bf58c4afe3e14b9c681f702de"}, - {file = "rpds_py-0.22.3-cp313-cp313-win_amd64.whl", hash = "sha256:c58e2339def52ef6b71b8f36d13c3688ea23fa093353f3a4fee2556e62086ec9"}, - {file = "rpds_py-0.22.3-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:f82a116a1d03628a8ace4859556fb39fd1424c933341a08ea3ed6de1edb0283b"}, - {file = "rpds_py-0.22.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3dfcbc95bd7992b16f3f7ba05af8a64ca694331bd24f9157b49dadeeb287493b"}, - {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59259dc58e57b10e7e18ce02c311804c10c5a793e6568f8af4dead03264584d1"}, - {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5725dd9cc02068996d4438d397e255dcb1df776b7ceea3b9cb972bdb11260a83"}, - {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99b37292234e61325e7a5bb9689e55e48c3f5f603af88b1642666277a81f1fbd"}, - {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:27b1d3b3915a99208fee9ab092b8184c420f2905b7d7feb4aeb5e4a9c509b8a1"}, - {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f612463ac081803f243ff13cccc648578e2279295048f2a8d5eb430af2bae6e3"}, - {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f73d3fef726b3243a811121de45193c0ca75f6407fe66f3f4e183c983573e130"}, - {file = "rpds_py-0.22.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3f21f0495edea7fdbaaa87e633a8689cd285f8f4af5c869f27bc8074638ad69c"}, - {file = "rpds_py-0.22.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:1e9663daaf7a63ceccbbb8e3808fe90415b0757e2abddbfc2e06c857bf8c5e2b"}, - {file = "rpds_py-0.22.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a76e42402542b1fae59798fab64432b2d015ab9d0c8c47ba7addddbaf7952333"}, - {file = "rpds_py-0.22.3-cp313-cp313t-win32.whl", hash = "sha256:69803198097467ee7282750acb507fba35ca22cc3b85f16cf45fb01cb9097730"}, - {file = "rpds_py-0.22.3-cp313-cp313t-win_amd64.whl", hash = "sha256:f5cf2a0c2bdadf3791b5c205d55a37a54025c6e18a71c71f82bb536cf9a454bf"}, - {file = "rpds_py-0.22.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:378753b4a4de2a7b34063d6f95ae81bfa7b15f2c1a04a9518e8644e81807ebea"}, - {file = "rpds_py-0.22.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3445e07bf2e8ecfeef6ef67ac83de670358abf2996916039b16a218e3d95e97e"}, - {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b2513ba235829860b13faa931f3b6846548021846ac808455301c23a101689d"}, - {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eaf16ae9ae519a0e237a0f528fd9f0197b9bb70f40263ee57ae53c2b8d48aeb3"}, - {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:583f6a1993ca3369e0f80ba99d796d8e6b1a3a2a442dd4e1a79e652116413091"}, - {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4617e1915a539a0d9a9567795023de41a87106522ff83fbfaf1f6baf8e85437e"}, - {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c150c7a61ed4a4f4955a96626574e9baf1adf772c2fb61ef6a5027e52803543"}, - {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2fa4331c200c2521512595253f5bb70858b90f750d39b8cbfd67465f8d1b596d"}, - {file = "rpds_py-0.22.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:214b7a953d73b5e87f0ebece4a32a5bd83c60a3ecc9d4ec8f1dca968a2d91e99"}, - {file = "rpds_py-0.22.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f47ad3d5f3258bd7058d2d506852217865afefe6153a36eb4b6928758041d831"}, - {file = "rpds_py-0.22.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f276b245347e6e36526cbd4a266a417796fc531ddf391e43574cf6466c492520"}, - {file = "rpds_py-0.22.3-cp39-cp39-win32.whl", hash = "sha256:bbb232860e3d03d544bc03ac57855cd82ddf19c7a07651a7c0fdb95e9efea8b9"}, - {file = "rpds_py-0.22.3-cp39-cp39-win_amd64.whl", hash = "sha256:cfbc454a2880389dbb9b5b398e50d439e2e58669160f27b60e5eca11f68ae17c"}, - {file = "rpds_py-0.22.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d48424e39c2611ee1b84ad0f44fb3b2b53d473e65de061e3f460fc0be5f1939d"}, - {file = "rpds_py-0.22.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:24e8abb5878e250f2eb0d7859a8e561846f98910326d06c0d51381fed59357bd"}, - {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b232061ca880db21fa14defe219840ad9b74b6158adb52ddf0e87bead9e8493"}, - {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac0a03221cdb5058ce0167ecc92a8c89e8d0decdc9e99a2ec23380793c4dcb96"}, - {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb0c341fa71df5a4595f9501df4ac5abfb5a09580081dffbd1ddd4654e6e9123"}, - {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf9db5488121b596dbfc6718c76092fda77b703c1f7533a226a5a9f65248f8ad"}, - {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b8db6b5b2d4491ad5b6bdc2bc7c017eec108acbf4e6785f42a9eb0ba234f4c9"}, - {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b3d504047aba448d70cf6fa22e06cb09f7cbd761939fdd47604f5e007675c24e"}, - {file = "rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:e61b02c3f7a1e0b75e20c3978f7135fd13cb6cf551bf4a6d29b999a88830a338"}, - {file = "rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:e35ba67d65d49080e8e5a1dd40101fccdd9798adb9b050ff670b7d74fa41c566"}, - {file = "rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:26fd7cac7dd51011a245f29a2cc6489c4608b5a8ce8d75661bb4a1066c52dfbe"}, - {file = "rpds_py-0.22.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:177c7c0fce2855833819c98e43c262007f42ce86651ffbb84f37883308cb0e7d"}, - {file = "rpds_py-0.22.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bb47271f60660803ad11f4c61b42242b8c1312a31c98c578f79ef9387bbde21c"}, - {file = "rpds_py-0.22.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:70fb28128acbfd264eda9bf47015537ba3fe86e40d046eb2963d75024be4d055"}, - {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44d61b4b7d0c2c9ac019c314e52d7cbda0ae31078aabd0f22e583af3e0d79723"}, - {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f0e260eaf54380380ac3808aa4ebe2d8ca28b9087cf411649f96bad6900c728"}, - {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b25bc607423935079e05619d7de556c91fb6adeae9d5f80868dde3468657994b"}, - {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fb6116dfb8d1925cbdb52595560584db42a7f664617a1f7d7f6e32f138cdf37d"}, - {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a63cbdd98acef6570c62b92a1e43266f9e8b21e699c363c0fef13bd530799c11"}, - {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2b8f60e1b739a74bab7e01fcbe3dddd4657ec685caa04681df9d562ef15b625f"}, - {file = "rpds_py-0.22.3-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2e8b55d8517a2fda8d95cb45d62a5a8bbf9dd0ad39c5b25c8833efea07b880ca"}, - {file = "rpds_py-0.22.3-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:2de29005e11637e7a2361fa151f780ff8eb2543a0da1413bb951e9f14b699ef3"}, - {file = "rpds_py-0.22.3-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:666ecce376999bf619756a24ce15bb14c5bfaf04bf00abc7e663ce17c3f34fe7"}, - {file = "rpds_py-0.22.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:5246b14ca64a8675e0a7161f7af68fe3e910e6b90542b4bfb5439ba752191df6"}, - {file = "rpds_py-0.22.3.tar.gz", hash = "sha256:e32fee8ab45d3c2db6da19a5323bc3362237c8b653c70194414b892fd06a080d"}, + {file = "rpds_py-0.21.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a017f813f24b9df929674d0332a374d40d7f0162b326562daae8066b502d0590"}, + {file = "rpds_py-0.21.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:20cc1ed0bcc86d8e1a7e968cce15be45178fd16e2ff656a243145e0b439bd250"}, + {file = "rpds_py-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad116dda078d0bc4886cb7840e19811562acdc7a8e296ea6ec37e70326c1b41c"}, + {file = "rpds_py-0.21.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:808f1ac7cf3b44f81c9475475ceb221f982ef548e44e024ad5f9e7060649540e"}, + {file = "rpds_py-0.21.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de552f4a1916e520f2703ec474d2b4d3f86d41f353e7680b597512ffe7eac5d0"}, + {file = "rpds_py-0.21.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:efec946f331349dfc4ae9d0e034c263ddde19414fe5128580f512619abed05f1"}, + {file = "rpds_py-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b80b4690bbff51a034bfde9c9f6bf9357f0a8c61f548942b80f7b66356508bf5"}, + {file = "rpds_py-0.21.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:085ed25baac88953d4283e5b5bd094b155075bb40d07c29c4f073e10623f9f2e"}, + {file = "rpds_py-0.21.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:daa8efac2a1273eed2354397a51216ae1e198ecbce9036fba4e7610b308b6153"}, + {file = "rpds_py-0.21.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:95a5bad1ac8a5c77b4e658671642e4af3707f095d2b78a1fdd08af0dfb647624"}, + {file = "rpds_py-0.21.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3e53861b29a13d5b70116ea4230b5f0f3547b2c222c5daa090eb7c9c82d7f664"}, + {file = "rpds_py-0.21.0-cp310-none-win32.whl", hash = "sha256:ea3a6ac4d74820c98fcc9da4a57847ad2cc36475a8bd9683f32ab6d47a2bd682"}, + {file = "rpds_py-0.21.0-cp310-none-win_amd64.whl", hash = "sha256:b8f107395f2f1d151181880b69a2869c69e87ec079c49c0016ab96860b6acbe5"}, + {file = "rpds_py-0.21.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:5555db3e618a77034954b9dc547eae94166391a98eb867905ec8fcbce1308d95"}, + {file = "rpds_py-0.21.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:97ef67d9bbc3e15584c2f3c74bcf064af36336c10d2e21a2131e123ce0f924c9"}, + {file = "rpds_py-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ab2c2a26d2f69cdf833174f4d9d86118edc781ad9a8fa13970b527bf8236027"}, + {file = "rpds_py-0.21.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4e8921a259f54bfbc755c5bbd60c82bb2339ae0324163f32868f63f0ebb873d9"}, + {file = "rpds_py-0.21.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a7ff941004d74d55a47f916afc38494bd1cfd4b53c482b77c03147c91ac0ac3"}, + {file = "rpds_py-0.21.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5145282a7cd2ac16ea0dc46b82167754d5e103a05614b724457cffe614f25bd8"}, + {file = "rpds_py-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de609a6f1b682f70bb7163da745ee815d8f230d97276db049ab447767466a09d"}, + {file = "rpds_py-0.21.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:40c91c6e34cf016fa8e6b59d75e3dbe354830777fcfd74c58b279dceb7975b75"}, + {file = "rpds_py-0.21.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d2132377f9deef0c4db89e65e8bb28644ff75a18df5293e132a8d67748397b9f"}, + {file = "rpds_py-0.21.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0a9e0759e7be10109645a9fddaaad0619d58c9bf30a3f248a2ea57a7c417173a"}, + {file = "rpds_py-0.21.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9e20da3957bdf7824afdd4b6eeb29510e83e026473e04952dca565170cd1ecc8"}, + {file = "rpds_py-0.21.0-cp311-none-win32.whl", hash = "sha256:f71009b0d5e94c0e86533c0b27ed7cacc1239cb51c178fd239c3cfefefb0400a"}, + {file = "rpds_py-0.21.0-cp311-none-win_amd64.whl", hash = "sha256:e168afe6bf6ab7ab46c8c375606298784ecbe3ba31c0980b7dcbb9631dcba97e"}, + {file = "rpds_py-0.21.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:30b912c965b2aa76ba5168fd610087bad7fcde47f0a8367ee8f1876086ee6d1d"}, + {file = "rpds_py-0.21.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ca9989d5d9b1b300bc18e1801c67b9f6d2c66b8fd9621b36072ed1df2c977f72"}, + {file = "rpds_py-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f54e7106f0001244a5f4cf810ba8d3f9c542e2730821b16e969d6887b664266"}, + {file = "rpds_py-0.21.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fed5dfefdf384d6fe975cc026886aece4f292feaf69d0eeb716cfd3c5a4dd8be"}, + {file = "rpds_py-0.21.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:590ef88db231c9c1eece44dcfefd7515d8bf0d986d64d0caf06a81998a9e8cab"}, + {file = "rpds_py-0.21.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f983e4c2f603c95dde63df633eec42955508eefd8d0f0e6d236d31a044c882d7"}, + {file = "rpds_py-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b229ce052ddf1a01c67d68166c19cb004fb3612424921b81c46e7ea7ccf7c3bf"}, + {file = "rpds_py-0.21.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ebf64e281a06c904a7636781d2e973d1f0926a5b8b480ac658dc0f556e7779f4"}, + {file = "rpds_py-0.21.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:998a8080c4495e4f72132f3d66ff91f5997d799e86cec6ee05342f8f3cda7dca"}, + {file = "rpds_py-0.21.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:98486337f7b4f3c324ab402e83453e25bb844f44418c066623db88e4c56b7c7b"}, + {file = "rpds_py-0.21.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a78d8b634c9df7f8d175451cfeac3810a702ccb85f98ec95797fa98b942cea11"}, + {file = "rpds_py-0.21.0-cp312-none-win32.whl", hash = "sha256:a58ce66847711c4aa2ecfcfaff04cb0327f907fead8945ffc47d9407f41ff952"}, + {file = "rpds_py-0.21.0-cp312-none-win_amd64.whl", hash = "sha256:e860f065cc4ea6f256d6f411aba4b1251255366e48e972f8a347cf88077b24fd"}, + {file = "rpds_py-0.21.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:ee4eafd77cc98d355a0d02f263efc0d3ae3ce4a7c24740010a8b4012bbb24937"}, + {file = "rpds_py-0.21.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:688c93b77e468d72579351a84b95f976bd7b3e84aa6686be6497045ba84be560"}, + {file = "rpds_py-0.21.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c38dbf31c57032667dd5a2f0568ccde66e868e8f78d5a0d27dcc56d70f3fcd3b"}, + {file = "rpds_py-0.21.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2d6129137f43f7fa02d41542ffff4871d4aefa724a5fe38e2c31a4e0fd343fb0"}, + {file = "rpds_py-0.21.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:520ed8b99b0bf86a176271f6fe23024323862ac674b1ce5b02a72bfeff3fff44"}, + {file = "rpds_py-0.21.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aaeb25ccfb9b9014a10eaf70904ebf3f79faaa8e60e99e19eef9f478651b9b74"}, + {file = "rpds_py-0.21.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af04ac89c738e0f0f1b913918024c3eab6e3ace989518ea838807177d38a2e94"}, + {file = "rpds_py-0.21.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b9b76e2afd585803c53c5b29e992ecd183f68285b62fe2668383a18e74abe7a3"}, + {file = "rpds_py-0.21.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5afb5efde74c54724e1a01118c6e5c15e54e642c42a1ba588ab1f03544ac8c7a"}, + {file = "rpds_py-0.21.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:52c041802a6efa625ea18027a0723676a778869481d16803481ef6cc02ea8cb3"}, + {file = "rpds_py-0.21.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ee1e4fc267b437bb89990b2f2abf6c25765b89b72dd4a11e21934df449e0c976"}, + {file = "rpds_py-0.21.0-cp313-none-win32.whl", hash = "sha256:0c025820b78817db6a76413fff6866790786c38f95ea3f3d3c93dbb73b632202"}, + {file = "rpds_py-0.21.0-cp313-none-win_amd64.whl", hash = "sha256:320c808df533695326610a1b6a0a6e98f033e49de55d7dc36a13c8a30cfa756e"}, + {file = "rpds_py-0.21.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:2c51d99c30091f72a3c5d126fad26236c3f75716b8b5e5cf8effb18889ced928"}, + {file = "rpds_py-0.21.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cbd7504a10b0955ea287114f003b7ad62330c9e65ba012c6223dba646f6ffd05"}, + {file = "rpds_py-0.21.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6dcc4949be728ede49e6244eabd04064336012b37f5c2200e8ec8eb2988b209c"}, + {file = "rpds_py-0.21.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f414da5c51bf350e4b7960644617c130140423882305f7574b6cf65a3081cecb"}, + {file = "rpds_py-0.21.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9afe42102b40007f588666bc7de82451e10c6788f6f70984629db193849dced1"}, + {file = "rpds_py-0.21.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b929c2bb6e29ab31f12a1117c39f7e6d6450419ab7464a4ea9b0b417174f044"}, + {file = "rpds_py-0.21.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8404b3717da03cbf773a1d275d01fec84ea007754ed380f63dfc24fb76ce4592"}, + {file = "rpds_py-0.21.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e12bb09678f38b7597b8346983d2323a6482dcd59e423d9448108c1be37cac9d"}, + {file = "rpds_py-0.21.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:58a0e345be4b18e6b8501d3b0aa540dad90caeed814c515e5206bb2ec26736fd"}, + {file = "rpds_py-0.21.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c3761f62fcfccf0864cc4665b6e7c3f0c626f0380b41b8bd1ce322103fa3ef87"}, + {file = "rpds_py-0.21.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c2b2f71c6ad6c2e4fc9ed9401080badd1469fa9889657ec3abea42a3d6b2e1ed"}, + {file = "rpds_py-0.21.0-cp39-none-win32.whl", hash = "sha256:b21747f79f360e790525e6f6438c7569ddbfb1b3197b9e65043f25c3c9b489d8"}, + {file = "rpds_py-0.21.0-cp39-none-win_amd64.whl", hash = "sha256:0626238a43152918f9e72ede9a3b6ccc9e299adc8ade0d67c5e142d564c9a83d"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6b4ef7725386dc0762857097f6b7266a6cdd62bfd209664da6712cb26acef035"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:6bc0e697d4d79ab1aacbf20ee5f0df80359ecf55db33ff41481cf3e24f206919"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da52d62a96e61c1c444f3998c434e8b263c384f6d68aca8274d2e08d1906325c"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:98e4fe5db40db87ce1c65031463a760ec7906ab230ad2249b4572c2fc3ef1f9f"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30bdc973f10d28e0337f71d202ff29345320f8bc49a31c90e6c257e1ccef4333"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:faa5e8496c530f9c71f2b4e1c49758b06e5f4055e17144906245c99fa6d45356"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32eb88c30b6a4f0605508023b7141d043a79b14acb3b969aa0b4f99b25bc7d4a"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a89a8ce9e4e75aeb7fa5d8ad0f3fecdee813802592f4f46a15754dcb2fd6b061"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:241e6c125568493f553c3d0fdbb38c74babf54b45cef86439d4cd97ff8feb34d"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:3b766a9f57663396e4f34f5140b3595b233a7b146e94777b97a8413a1da1be18"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:af4a644bf890f56e41e74be7d34e9511e4954894d544ec6b8efe1e21a1a8da6c"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3e30a69a706e8ea20444b98a49f386c17b26f860aa9245329bab0851ed100677"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:031819f906bb146561af051c7cef4ba2003d28cff07efacef59da973ff7969ba"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b876f2bc27ab5954e2fd88890c071bd0ed18b9c50f6ec3de3c50a5ece612f7a6"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc5695c321e518d9f03b7ea6abb5ea3af4567766f9852ad1560f501b17588c7b"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b4de1da871b5c0fd5537b26a6fc6814c3cc05cabe0c941db6e9044ffbb12f04a"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:878f6fea96621fda5303a2867887686d7a198d9e0f8a40be100a63f5d60c88c9"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8eeec67590e94189f434c6d11c426892e396ae59e4801d17a93ac96b8c02a6c"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ff2eba7f6c0cb523d7e9cff0903f2fe1feff8f0b2ceb6bd71c0e20a4dcee271"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a429b99337062877d7875e4ff1a51fe788424d522bd64a8c0a20ef3021fdb6ed"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:d167e4dbbdac48bd58893c7e446684ad5d425b407f9336e04ab52e8b9194e2ed"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:4eb2de8a147ffe0626bfdc275fc6563aa7bf4b6db59cf0d44f0ccd6ca625a24e"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:e78868e98f34f34a88e23ee9ccaeeec460e4eaf6db16d51d7a9b883e5e785a5e"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4991ca61656e3160cdaca4851151fd3f4a92e9eba5c7a530ab030d6aee96ec89"}, + {file = "rpds_py-0.21.0.tar.gz", hash = "sha256:ed6378c9d66d0de903763e7706383d60c33829581f0adff47b6535f1802fa6db"}, ] [[package]] @@ -4545,38 +4563,38 @@ files = [ [[package]] name = "six" -version = "1.17.0" +version = "1.16.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ - {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, - {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] [[package]] name = "slack-sdk" -version = "3.34.0" +version = "3.33.4" description = "The Slack API Platform SDK for Python" optional = false python-versions = ">=3.6" files = [ - {file = "slack_sdk-3.34.0-py2.py3-none-any.whl", hash = "sha256:c61f57f310d85be83466db5a98ab6ae3bb2e5587437b54fa0daa8fae6a0feffa"}, - {file = "slack_sdk-3.34.0.tar.gz", hash = "sha256:ff61db7012160eed742285ea91f11c72b7a38a6500a7f6c5335662b4bc6b853d"}, + {file = "slack_sdk-3.33.4-py2.py3-none-any.whl", hash = "sha256:9f30cb3c9c07b441c49d53fc27f9f1837ad1592a7e9d4ca431f53cdad8826cc6"}, + {file = "slack_sdk-3.33.4.tar.gz", hash = "sha256:5e109847f6b6a22d227609226ba4ed936109dc00675bddeb7e0bee502d3ee7e0"}, ] [package.extras] -optional = ["SQLAlchemy (>=1.4,<3)", "aiodns (>1.0)", "aiohttp (>=3.7.3,<4)", "boto3 (<=2)", "websocket-client (>=1,<2)", "websockets (>=9.1,<15)"] +optional = ["SQLAlchemy (>=1.4,<3)", "aiodns (>1.0)", "aiohttp (>=3.7.3,<4)", "boto3 (<=2)", "websocket-client (>=1,<2)", "websockets (>=9.1,<14)"] [[package]] name = "smmap" -version = "5.0.2" +version = "5.0.1" description = "A pure Python implementation of a sliding window memory map manager" optional = false python-versions = ">=3.7" files = [ - {file = "smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e"}, - {file = "smmap-5.0.2.tar.gz", hash = "sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5"}, + {file = "smmap-5.0.1-py3-none-any.whl", hash = "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da"}, + {file = "smmap-5.0.1.tar.gz", hash = "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62"}, ] [[package]] @@ -4690,43 +4708,13 @@ files = [ [[package]] name = "tomli" -version = "2.2.1" +version = "2.1.0" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, - {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, - {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, - {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, - {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, - {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, - {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, - {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, - {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, - {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, + {file = "tomli-2.1.0-py3-none-any.whl", hash = "sha256:a5c57c3d1c56f5ccdf89f6523458f60ef716e210fc47c4cfb188c5ba473e0391"}, + {file = "tomli-2.1.0.tar.gz", hash = "sha256:3f646cae2aec94e17d04973e4249548320197cfabdf130015d023de4b74d8ab8"}, ] [[package]] @@ -4898,24 +4886,24 @@ files = [ [[package]] name = "types-python-dateutil" -version = "2.9.0.20241206" +version = "2.9.0.20241003" description = "Typing stubs for python-dateutil" optional = false python-versions = ">=3.8" files = [ - {file = "types_python_dateutil-2.9.0.20241206-py3-none-any.whl", hash = "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53"}, - {file = "types_python_dateutil-2.9.0.20241206.tar.gz", hash = "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb"}, + {file = "types-python-dateutil-2.9.0.20241003.tar.gz", hash = "sha256:58cb85449b2a56d6684e41aeefb4c4280631246a0da1a719bdbe6f3fb0317446"}, + {file = "types_python_dateutil-2.9.0.20241003-py3-none-any.whl", hash = "sha256:250e1d8e80e7bbc3a6c99b907762711d1a1cdd00e978ad39cb5940f6f0a87f3d"}, ] [[package]] name = "types-pytz" -version = "2024.2.0.20241221" +version = "2024.2.0.20241003" description = "Typing stubs for pytz" optional = false python-versions = ">=3.8" files = [ - {file = "types_pytz-2024.2.0.20241221-py3-none-any.whl", hash = "sha256:8fc03195329c43637ed4f593663df721fef919b60a969066e22606edf0b53ad5"}, - {file = "types_pytz-2024.2.0.20241221.tar.gz", hash = "sha256:06d7cde9613e9f7504766a0554a270c369434b50e00975b3a4a0f6eed0f2c1a9"}, + {file = "types-pytz-2024.2.0.20241003.tar.gz", hash = "sha256:575dc38f385a922a212bac00a7d6d2e16e141132a3c955078f4a4fd13ed6cb44"}, + {file = "types_pytz-2024.2.0.20241003-py3-none-any.whl", hash = "sha256:3e22df1336c0c6ad1d29163c8fda82736909eb977281cb823c57f8bae07118b7"}, ] [[package]] @@ -4934,24 +4922,24 @@ urllib3 = ">=2" [[package]] name = "types-setuptools" -version = "75.6.0.20241223" +version = "75.5.0.20241122" description = "Typing stubs for setuptools" optional = false python-versions = ">=3.8" files = [ - {file = "types_setuptools-75.6.0.20241223-py3-none-any.whl", hash = "sha256:7cbfd3bf2944f88bbcdd321b86ddd878232a277be95d44c78a53585d78ebc2f6"}, - {file = "types_setuptools-75.6.0.20241223.tar.gz", hash = "sha256:d9478a985057ed48a994c707f548e55aababa85fe1c9b212f43ab5a1fffd3211"}, + {file = "types_setuptools-75.5.0.20241122-py3-none-any.whl", hash = "sha256:d69c445f7bdd5e49d1b2441aadcee1388febcc9ad9d9d5fd33648b555e0b1c31"}, + {file = "types_setuptools-75.5.0.20241122.tar.gz", hash = "sha256:196aaf1811cbc1c77ac1d4c4879d5308b6fdf426e56b73baadbca2a1827dadef"}, ] [[package]] name = "types-tabulate" -version = "0.9.0.20241207" +version = "0.9.0.20240106" description = "Typing stubs for tabulate" optional = false python-versions = ">=3.8" files = [ - {file = "types_tabulate-0.9.0.20241207-py3-none-any.whl", hash = "sha256:b8dad1343c2a8ba5861c5441370c3e35908edd234ff036d4298708a1d4cf8a85"}, - {file = "types_tabulate-0.9.0.20241207.tar.gz", hash = "sha256:ac1ac174750c0a385dfd248edc6279fa328aaf4ea317915ab879a2ec47833230"}, + {file = "types-tabulate-0.9.0.20240106.tar.gz", hash = "sha256:c9b6db10dd7fcf55bd1712dd3537f86ddce72a08fd62bb1af4338c7096ce947e"}, + {file = "types_tabulate-0.9.0.20240106-py3-none-any.whl", hash = "sha256:0378b7b6fe0ccb4986299496d027a6d4c218298ecad67199bbd0e2d7e9d335a1"}, ] [[package]] @@ -5105,13 +5093,13 @@ files = [ [[package]] name = "urllib3" -version = "2.3.0" +version = "2.2.3" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.9" +python-versions = ">=3.8" files = [ - {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, - {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, + {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, + {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, ] [package.extras] @@ -5159,13 +5147,13 @@ files = [ [[package]] name = "virtualenv" -version = "20.28.1" +version = "20.27.1" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.8" files = [ - {file = "virtualenv-20.28.1-py3-none-any.whl", hash = "sha256:412773c85d4dab0409b83ec36f7a6499e72eaf08c80e81e9576bca61831c71cb"}, - {file = "virtualenv-20.28.1.tar.gz", hash = "sha256:5d34ab240fdb5d21549b76f9e8ff3af28252f5499fb6d6f031adac4e5a8c5329"}, + {file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"}, + {file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"}, ] [package.dependencies] @@ -5179,13 +5167,13 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess [[package]] name = "vulture" -version = "2.14" +version = "2.13" description = "Find dead code" optional = false python-versions = ">=3.8" files = [ - {file = "vulture-2.14-py2.py3-none-any.whl", hash = "sha256:d9a90dba89607489548a49d557f8bac8112bd25d3cbc8aeef23e860811bd5ed9"}, - {file = "vulture-2.14.tar.gz", hash = "sha256:cb8277902a1138deeab796ec5bef7076a6e0248ca3607a3f3dee0b6d9e9b8415"}, + {file = "vulture-2.13-py2.py3-none-any.whl", hash = "sha256:34793ba60488e7cccbecdef3a7fe151656372ef94fdac9fe004c52a4000a6d44"}, + {file = "vulture-2.13.tar.gz", hash = "sha256:78248bf58f5eaffcc2ade306141ead73f437339950f80045dce7f8b078e5a1aa"}, ] [package.dependencies] @@ -5235,13 +5223,13 @@ watchdog = ["watchdog (>=2.3)"] [[package]] name = "win32-setctime" -version = "1.2.0" +version = "1.1.0" description = "A small Python utility to set file creation time on Windows" optional = false python-versions = ">=3.5" files = [ - {file = "win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390"}, - {file = "win32_setctime-1.2.0.tar.gz", hash = "sha256:ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0"}, + {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"}, + {file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"}, ] [package.extras] @@ -5351,93 +5339,93 @@ pyyaml = "*" [[package]] name = "yarl" -version = "1.18.3" +version = "1.18.0" description = "Yet another URL library" optional = true python-versions = ">=3.9" files = [ - {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7df647e8edd71f000a5208fe6ff8c382a1de8edfbccdbbfe649d263de07d8c34"}, - {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c69697d3adff5aa4f874b19c0e4ed65180ceed6318ec856ebc423aa5850d84f7"}, - {file = "yarl-1.18.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:602d98f2c2d929f8e697ed274fbadc09902c4025c5a9963bf4e9edfc3ab6f7ed"}, - {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c654d5207c78e0bd6d749f6dae1dcbbfde3403ad3a4b11f3c5544d9906969dde"}, - {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5094d9206c64181d0f6e76ebd8fb2f8fe274950a63890ee9e0ebfd58bf9d787b"}, - {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35098b24e0327fc4ebdc8ffe336cee0a87a700c24ffed13161af80124b7dc8e5"}, - {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3236da9272872443f81fedc389bace88408f64f89f75d1bdb2256069a8730ccc"}, - {file = "yarl-1.18.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2c08cc9b16f4f4bc522771d96734c7901e7ebef70c6c5c35dd0f10845270bcd"}, - {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80316a8bd5109320d38eef8833ccf5f89608c9107d02d2a7f985f98ed6876990"}, - {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c1e1cc06da1491e6734f0ea1e6294ce00792193c463350626571c287c9a704db"}, - {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fea09ca13323376a2fdfb353a5fa2e59f90cd18d7ca4eaa1fd31f0a8b4f91e62"}, - {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e3b9fd71836999aad54084906f8663dffcd2a7fb5cdafd6c37713b2e72be1760"}, - {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:757e81cae69244257d125ff31663249b3013b5dc0a8520d73694aed497fb195b"}, - {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b1771de9944d875f1b98a745bc547e684b863abf8f8287da8466cf470ef52690"}, - {file = "yarl-1.18.3-cp310-cp310-win32.whl", hash = "sha256:8874027a53e3aea659a6d62751800cf6e63314c160fd607489ba5c2edd753cf6"}, - {file = "yarl-1.18.3-cp310-cp310-win_amd64.whl", hash = "sha256:93b2e109287f93db79210f86deb6b9bbb81ac32fc97236b16f7433db7fc437d8"}, - {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8503ad47387b8ebd39cbbbdf0bf113e17330ffd339ba1144074da24c545f0069"}, - {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:02ddb6756f8f4517a2d5e99d8b2f272488e18dd0bfbc802f31c16c6c20f22193"}, - {file = "yarl-1.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:67a283dd2882ac98cc6318384f565bffc751ab564605959df4752d42483ad889"}, - {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d980e0325b6eddc81331d3f4551e2a333999fb176fd153e075c6d1c2530aa8a8"}, - {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b643562c12680b01e17239be267bc306bbc6aac1f34f6444d1bded0c5ce438ca"}, - {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c017a3b6df3a1bd45b9fa49a0f54005e53fbcad16633870104b66fa1a30a29d8"}, - {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75674776d96d7b851b6498f17824ba17849d790a44d282929c42dbb77d4f17ae"}, - {file = "yarl-1.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ccaa3a4b521b780a7e771cc336a2dba389a0861592bbce09a476190bb0c8b4b3"}, - {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2d06d3005e668744e11ed80812e61efd77d70bb7f03e33c1598c301eea20efbb"}, - {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:9d41beda9dc97ca9ab0b9888cb71f7539124bc05df02c0cff6e5acc5a19dcc6e"}, - {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ba23302c0c61a9999784e73809427c9dbedd79f66a13d84ad1b1943802eaaf59"}, - {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6748dbf9bfa5ba1afcc7556b71cda0d7ce5f24768043a02a58846e4a443d808d"}, - {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0b0cad37311123211dc91eadcb322ef4d4a66008d3e1bdc404808992260e1a0e"}, - {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0fb2171a4486bb075316ee754c6d8382ea6eb8b399d4ec62fde2b591f879778a"}, - {file = "yarl-1.18.3-cp311-cp311-win32.whl", hash = "sha256:61b1a825a13bef4a5f10b1885245377d3cd0bf87cba068e1d9a88c2ae36880e1"}, - {file = "yarl-1.18.3-cp311-cp311-win_amd64.whl", hash = "sha256:b9d60031cf568c627d028239693fd718025719c02c9f55df0a53e587aab951b5"}, - {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1dd4bdd05407ced96fed3d7f25dbbf88d2ffb045a0db60dbc247f5b3c5c25d50"}, - {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7c33dd1931a95e5d9a772d0ac5e44cac8957eaf58e3c8da8c1414de7dd27c576"}, - {file = "yarl-1.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b411eddcfd56a2f0cd6a384e9f4f7aa3efee14b188de13048c25b5e91f1640"}, - {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436c4fc0a4d66b2badc6c5fc5ef4e47bb10e4fd9bf0c79524ac719a01f3607c2"}, - {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e35ef8683211db69ffe129a25d5634319a677570ab6b2eba4afa860f54eeaf75"}, - {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84b2deecba4a3f1a398df819151eb72d29bfeb3b69abb145a00ddc8d30094512"}, - {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e5a1fea0fd4f5bfa7440a47eff01d9822a65b4488f7cff83155a0f31a2ecba"}, - {file = "yarl-1.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0e883008013c0e4aef84dcfe2a0b172c4d23c2669412cf5b3371003941f72bb"}, - {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5a3f356548e34a70b0172d8890006c37be92995f62d95a07b4a42e90fba54272"}, - {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ccd17349166b1bee6e529b4add61727d3f55edb7babbe4069b5764c9587a8cc6"}, - {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b958ddd075ddba5b09bb0be8a6d9906d2ce933aee81100db289badbeb966f54e"}, - {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c7d79f7d9aabd6011004e33b22bc13056a3e3fb54794d138af57f5ee9d9032cb"}, - {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4891ed92157e5430874dad17b15eb1fda57627710756c27422200c52d8a4e393"}, - {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ce1af883b94304f493698b00d0f006d56aea98aeb49d75ec7d98cd4a777e9285"}, - {file = "yarl-1.18.3-cp312-cp312-win32.whl", hash = "sha256:f91c4803173928a25e1a55b943c81f55b8872f0018be83e3ad4938adffb77dd2"}, - {file = "yarl-1.18.3-cp312-cp312-win_amd64.whl", hash = "sha256:7e2ee16578af3b52ac2f334c3b1f92262f47e02cc6193c598502bd46f5cd1477"}, - {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:90adb47ad432332d4f0bc28f83a5963f426ce9a1a8809f5e584e704b82685dcb"}, - {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:913829534200eb0f789d45349e55203a091f45c37a2674678744ae52fae23efa"}, - {file = "yarl-1.18.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ef9f7768395923c3039055c14334ba4d926f3baf7b776c923c93d80195624782"}, - {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a19f62ff30117e706ebc9090b8ecc79aeb77d0b1f5ec10d2d27a12bc9f66d0"}, - {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e17c9361d46a4d5addf777c6dd5eab0715a7684c2f11b88c67ac37edfba6c482"}, - {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a74a13a4c857a84a845505fd2d68e54826a2cd01935a96efb1e9d86c728e186"}, - {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41f7ce59d6ee7741af71d82020346af364949314ed3d87553763a2df1829cc58"}, - {file = "yarl-1.18.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f52a265001d830bc425f82ca9eabda94a64a4d753b07d623a9f2863fde532b53"}, - {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:82123d0c954dc58db301f5021a01854a85bf1f3bb7d12ae0c01afc414a882ca2"}, - {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2ec9bbba33b2d00999af4631a3397d1fd78290c48e2a3e52d8dd72db3a067ac8"}, - {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fbd6748e8ab9b41171bb95c6142faf068f5ef1511935a0aa07025438dd9a9bc1"}, - {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:877d209b6aebeb5b16c42cbb377f5f94d9e556626b1bfff66d7b0d115be88d0a"}, - {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b464c4ab4bfcb41e3bfd3f1c26600d038376c2de3297760dfe064d2cb7ea8e10"}, - {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8d39d351e7faf01483cc7ff7c0213c412e38e5a340238826be7e0e4da450fdc8"}, - {file = "yarl-1.18.3-cp313-cp313-win32.whl", hash = "sha256:61ee62ead9b68b9123ec24bc866cbef297dd266175d53296e2db5e7f797f902d"}, - {file = "yarl-1.18.3-cp313-cp313-win_amd64.whl", hash = "sha256:578e281c393af575879990861823ef19d66e2b1d0098414855dd367e234f5b3c"}, - {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:61e5e68cb65ac8f547f6b5ef933f510134a6bf31bb178be428994b0cb46c2a04"}, - {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe57328fbc1bfd0bd0514470ac692630f3901c0ee39052ae47acd1d90a436719"}, - {file = "yarl-1.18.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a440a2a624683108a1b454705ecd7afc1c3438a08e890a1513d468671d90a04e"}, - {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09c7907c8548bcd6ab860e5f513e727c53b4a714f459b084f6580b49fa1b9cee"}, - {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4f6450109834af88cb4cc5ecddfc5380ebb9c228695afc11915a0bf82116789"}, - {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9ca04806f3be0ac6d558fffc2fdf8fcef767e0489d2684a21912cc4ed0cd1b8"}, - {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77a6e85b90a7641d2e07184df5557132a337f136250caafc9ccaa4a2a998ca2c"}, - {file = "yarl-1.18.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6333c5a377c8e2f5fae35e7b8f145c617b02c939d04110c76f29ee3676b5f9a5"}, - {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0b3c92fa08759dbf12b3a59579a4096ba9af8dd344d9a813fc7f5070d86bbab1"}, - {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4ac515b860c36becb81bb84b667466885096b5fc85596948548b667da3bf9f24"}, - {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:045b8482ce9483ada4f3f23b3774f4e1bf4f23a2d5c912ed5170f68efb053318"}, - {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:a4bb030cf46a434ec0225bddbebd4b89e6471814ca851abb8696170adb163985"}, - {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:54d6921f07555713b9300bee9c50fb46e57e2e639027089b1d795ecd9f7fa910"}, - {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1d407181cfa6e70077df3377938c08012d18893f9f20e92f7d2f314a437c30b1"}, - {file = "yarl-1.18.3-cp39-cp39-win32.whl", hash = "sha256:ac36703a585e0929b032fbaab0707b75dc12703766d0b53486eabd5139ebadd5"}, - {file = "yarl-1.18.3-cp39-cp39-win_amd64.whl", hash = "sha256:ba87babd629f8af77f557b61e49e7c7cac36f22f871156b91e10a6e9d4f829e9"}, - {file = "yarl-1.18.3-py3-none-any.whl", hash = "sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b"}, - {file = "yarl-1.18.3.tar.gz", hash = "sha256:ac1801c45cbf77b6c99242eeff4fffb5e4e73a800b5c4ad4fc0be5def634d2e1"}, + {file = "yarl-1.18.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:074fee89caab89a97e18ef5f29060ef61ba3cae6cd77673acc54bfdd3214b7b7"}, + {file = "yarl-1.18.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b026cf2c32daf48d90c0c4e406815c3f8f4cfe0c6dfccb094a9add1ff6a0e41a"}, + {file = "yarl-1.18.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ae38bd86eae3ba3d2ce5636cc9e23c80c9db2e9cb557e40b98153ed102b5a736"}, + {file = "yarl-1.18.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:685cc37f3f307c6a8e879986c6d85328f4c637f002e219f50e2ef66f7e062c1d"}, + {file = "yarl-1.18.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8254dbfce84ee5d1e81051ee7a0f1536c108ba294c0fdb5933476398df0654f3"}, + {file = "yarl-1.18.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20de4a8b04de70c49698dc2390b7fd2d18d424d3b876371f9b775e2b462d4b41"}, + {file = "yarl-1.18.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0a2074a37285570d54b55820687de3d2f2b9ecf1b714e482e48c9e7c0402038"}, + {file = "yarl-1.18.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f576ed278860df2721a5d57da3381040176ef1d07def9688a385c8330db61a1"}, + {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3a3709450a574d61be6ac53d582496014342ea34876af8dc17cc16da32826c9a"}, + {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:bd80ed29761490c622edde5dd70537ca8c992c2952eb62ed46984f8eff66d6e8"}, + {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:32141e13a1d5a48525e519c9197d3f4d9744d818d5c7d6547524cc9eccc8971e"}, + {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8b8d3e4e014fb4274f1c5bf61511d2199e263909fb0b8bda2a7428b0894e8dc6"}, + {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:701bb4a8f4de191c8c0cc9a1e6d5142f4df880e9d1210e333b829ca9425570ed"}, + {file = "yarl-1.18.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a45d94075ac0647621eaaf693c8751813a3eccac455d423f473ffed38c8ac5c9"}, + {file = "yarl-1.18.0-cp310-cp310-win32.whl", hash = "sha256:34176bfb082add67cb2a20abd85854165540891147f88b687a5ed0dc225750a0"}, + {file = "yarl-1.18.0-cp310-cp310-win_amd64.whl", hash = "sha256:73553bbeea7d6ec88c08ad8027f4e992798f0abc459361bf06641c71972794dc"}, + {file = "yarl-1.18.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b8e8c516dc4e1a51d86ac975b0350735007e554c962281c432eaa5822aa9765c"}, + {file = "yarl-1.18.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2e6b4466714a73f5251d84b471475850954f1fa6acce4d3f404da1d55d644c34"}, + {file = "yarl-1.18.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c893f8c1a6d48b25961e00922724732d00b39de8bb0b451307482dc87bddcd74"}, + {file = "yarl-1.18.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13aaf2bdbc8c86ddce48626b15f4987f22e80d898818d735b20bd58f17292ee8"}, + {file = "yarl-1.18.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd21c0128e301851de51bc607b0a6da50e82dc34e9601f4b508d08cc89ee7929"}, + {file = "yarl-1.18.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:205de377bd23365cd85562c9c6c33844050a93661640fda38e0567d2826b50df"}, + {file = "yarl-1.18.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed69af4fe2a0949b1ea1d012bf065c77b4c7822bad4737f17807af2adb15a73c"}, + {file = "yarl-1.18.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e1c18890091aa3cc8a77967943476b729dc2016f4cfe11e45d89b12519d4a93"}, + {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:91b8fb9427e33f83ca2ba9501221ffaac1ecf0407f758c4d2f283c523da185ee"}, + {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:536a7a8a53b75b2e98ff96edb2dfb91a26b81c4fed82782035767db5a465be46"}, + {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a64619a9c47c25582190af38e9eb382279ad42e1f06034f14d794670796016c0"}, + {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c73a6bbc97ba1b5a0c3c992ae93d721c395bdbb120492759b94cc1ac71bc6350"}, + {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a173401d7821a2a81c7b47d4e7d5c4021375a1441af0c58611c1957445055056"}, + {file = "yarl-1.18.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7520e799b1f84e095cce919bd6c23c9d49472deeef25fe1ef960b04cca51c3fc"}, + {file = "yarl-1.18.0-cp311-cp311-win32.whl", hash = "sha256:c4cb992d8090d5ae5f7afa6754d7211c578be0c45f54d3d94f7781c495d56716"}, + {file = "yarl-1.18.0-cp311-cp311-win_amd64.whl", hash = "sha256:52c136f348605974c9b1c878addd6b7a60e3bf2245833e370862009b86fa4689"}, + {file = "yarl-1.18.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1ece25e2251c28bab737bdf0519c88189b3dd9492dc086a1d77336d940c28ced"}, + {file = "yarl-1.18.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:454902dc1830d935c90b5b53c863ba2a98dcde0fbaa31ca2ed1ad33b2a7171c6"}, + {file = "yarl-1.18.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:01be8688fc211dc237e628fcc209dda412d35de7642453059a0553747018d075"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d26f1fa9fa2167bb238f6f4b20218eb4e88dd3ef21bb8f97439fa6b5313e30d"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b234a4a9248a9f000b7a5dfe84b8cb6210ee5120ae70eb72a4dcbdb4c528f72f"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe94d1de77c4cd8caff1bd5480e22342dbd54c93929f5943495d9c1e8abe9f42"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b4c90c5363c6b0a54188122b61edb919c2cd1119684999d08cd5e538813a28e"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a98ecadc5a241c9ba06de08127ee4796e1009555efd791bac514207862b43d"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9106025c7f261f9f5144f9aa7681d43867eed06349a7cfb297a1bc804de2f0d1"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f275ede6199d0f1ed4ea5d55a7b7573ccd40d97aee7808559e1298fe6efc8dbd"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f7edeb1dcc7f50a2c8e08b9dc13a413903b7817e72273f00878cb70e766bdb3b"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c083f6dd6951b86e484ebfc9c3524b49bcaa9c420cb4b2a78ef9f7a512bfcc85"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:80741ec5b471fbdfb997821b2842c59660a1c930ceb42f8a84ba8ca0f25a66aa"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b1a3297b9cad594e1ff0c040d2881d7d3a74124a3c73e00c3c71526a1234a9f7"}, + {file = "yarl-1.18.0-cp312-cp312-win32.whl", hash = "sha256:cd6ab7d6776c186f544f893b45ee0c883542b35e8a493db74665d2e594d3ca75"}, + {file = "yarl-1.18.0-cp312-cp312-win_amd64.whl", hash = "sha256:039c299a0864d1f43c3e31570045635034ea7021db41bf4842693a72aca8df3a"}, + {file = "yarl-1.18.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6fb64dd45453225f57d82c4764818d7a205ee31ce193e9f0086e493916bd4f72"}, + {file = "yarl-1.18.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3adaaf9c6b1b4fc258584f4443f24d775a2086aee82d1387e48a8b4f3d6aecf6"}, + {file = "yarl-1.18.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:da206d1ec78438a563c5429ab808a2b23ad7bc025c8adbf08540dde202be37d5"}, + {file = "yarl-1.18.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:576d258b21c1db4c6449b1c572c75d03f16a482eb380be8003682bdbe7db2f28"}, + {file = "yarl-1.18.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c60e547c0a375c4bfcdd60eef82e7e0e8698bf84c239d715f5c1278a73050393"}, + {file = "yarl-1.18.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3818eabaefb90adeb5e0f62f047310079d426387991106d4fbf3519eec7d90a"}, + {file = "yarl-1.18.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5f72421246c21af6a92fbc8c13b6d4c5427dfd949049b937c3b731f2f9076bd"}, + {file = "yarl-1.18.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7fa7d37f2ada0f42e0723632993ed422f2a679af0e200874d9d861720a54f53e"}, + {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:42ba84e2ac26a3f252715f8ec17e6fdc0cbf95b9617c5367579fafcd7fba50eb"}, + {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:6a49ad0102c0f0ba839628d0bf45973c86ce7b590cdedf7540d5b1833ddc6f00"}, + {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:96404e8d5e1bbe36bdaa84ef89dc36f0e75939e060ca5cd45451aba01db02902"}, + {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a0509475d714df8f6d498935b3f307cd122c4ca76f7d426c7e1bb791bcd87eda"}, + {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:1ff116f0285b5c8b3b9a2680aeca29a858b3b9e0402fc79fd850b32c2bcb9f8b"}, + {file = "yarl-1.18.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e2580c1d7e66e6d29d6e11855e3b1c6381971e0edd9a5066e6c14d79bc8967af"}, + {file = "yarl-1.18.0-cp313-cp313-win32.whl", hash = "sha256:14408cc4d34e202caba7b5ac9cc84700e3421a9e2d1b157d744d101b061a4a88"}, + {file = "yarl-1.18.0-cp313-cp313-win_amd64.whl", hash = "sha256:1db1537e9cb846eb0ff206eac667f627794be8b71368c1ab3207ec7b6f8c5afc"}, + {file = "yarl-1.18.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fa2c9cb607e0f660d48c54a63de7a9b36fef62f6b8bd50ff592ce1137e73ac7d"}, + {file = "yarl-1.18.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c0f4808644baf0a434a3442df5e0bedf8d05208f0719cedcd499e168b23bfdc4"}, + {file = "yarl-1.18.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7db9584235895a1dffca17e1c634b13870852094f6389b68dcc6338086aa7b08"}, + {file = "yarl-1.18.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:309f8d27d6f93ceeeb80aa6980e883aa57895270f7f41842b92247e65d7aeddf"}, + {file = "yarl-1.18.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:609ffd44fed2ed88d9b4ef62ee860cf86446cf066333ad4ce4123505b819e581"}, + {file = "yarl-1.18.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f172b8b2c72a13a06ea49225a9c47079549036ad1b34afa12d5491b881f5b993"}, + {file = "yarl-1.18.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d89ae7de94631b60d468412c18290d358a9d805182373d804ec839978b120422"}, + {file = "yarl-1.18.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:466d31fd043ef9af822ee3f1df8fdff4e8c199a7f4012c2642006af240eade17"}, + {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7609b8462351c4836b3edce4201acb6dd46187b207c589b30a87ffd1813b48dc"}, + {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:d9d4f5e471e8dc49b593a80766c2328257e405f943c56a3dc985c125732bc4cf"}, + {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:67b336c15e564d76869c9a21316f90edf546809a5796a083b8f57c845056bc01"}, + {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b212452b80cae26cb767aa045b051740e464c5129b7bd739c58fbb7deb339e7b"}, + {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:38b39b7b3e692b6c92b986b00137a3891eddb66311b229d1940dcbd4f025083c"}, + {file = "yarl-1.18.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a7ee6884a8848792d58b854946b685521f41d8871afa65e0d4a774954e9c9e89"}, + {file = "yarl-1.18.0-cp39-cp39-win32.whl", hash = "sha256:b4095c5019bb889aa866bf12ed4c85c0daea5aafcb7c20d1519f02a1e738f07f"}, + {file = "yarl-1.18.0-cp39-cp39-win_amd64.whl", hash = "sha256:2d90f2e4d16a5b0915ee065218b435d2ef619dd228973b1b47d262a6f7cd8fa5"}, + {file = "yarl-1.18.0-py3-none-any.whl", hash = "sha256:dbf53db46f7cf176ee01d8d98c39381440776fcda13779d269a8ba664f69bec0"}, + {file = "yarl-1.18.0.tar.gz", hash = "sha256:20d95535e7d833889982bfe7cc321b7f63bf8879788fee982c76ae2b24cfb715"}, ] [package.dependencies] @@ -5447,18 +5435,18 @@ propcache = ">=0.2.0" [[package]] name = "z3-solver" -version = "4.13.4.0" +version = "4.13.3.0" description = "an efficient SMT solver library" optional = true python-versions = "*" files = [ - {file = "z3_solver-4.13.4.0-py3-none-macosx_13_0_arm64.whl", hash = "sha256:39ba75b867d6afadabc4812b999c9d96656da07d152510452e71ae9374e98926"}, - {file = "z3_solver-4.13.4.0-py3-none-macosx_13_0_x86_64.whl", hash = "sha256:6f3d3eff878b5b3c0d6e7f4237c869a489288fbdd8a2d878046ce977339a1a7a"}, - {file = "z3_solver-4.13.4.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fb8a857adf1064f89581c424fd729ee3e8bad95f4ebf0fb4c1210f65b831f37"}, - {file = "z3_solver-4.13.4.0-py3-none-manylinux_2_34_aarch64.whl", hash = "sha256:f674d758c199006fa0a527bdf78cb31b4ba5baaaef6c6c0fa80fb063d3834a6c"}, - {file = "z3_solver-4.13.4.0-py3-none-win32.whl", hash = "sha256:d23cb6d7c67ce3a4e57b8715e2be0c0fa350a282e641475e5e559521651471a0"}, - {file = "z3_solver-4.13.4.0-py3-none-win_amd64.whl", hash = "sha256:fafb65d7bb04db93e4a46f4357042fd53b420b412db66f0a0053612ed15024ca"}, - {file = "z3_solver-4.13.4.0.tar.gz", hash = "sha256:66944689398d19f831f94524e95e99961d998afa27cfef1918a5a441029ea73f"}, + {file = "z3_solver-4.13.3.0-py3-none-macosx_13_0_arm64.whl", hash = "sha256:cae621cb47ebcf055f6a27285343d5c932f4c282b15c5d2840327e73e15a86a4"}, + {file = "z3_solver-4.13.3.0-py3-none-macosx_13_0_x86_64.whl", hash = "sha256:7900fbd1917164c938a20bea7845f7b95fcb431d0ade474d408f979196bccb8f"}, + {file = "z3_solver-4.13.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:794843e4946ade1561e40a75ffc1163b45d36b493fd6cc269ad1d6a65bddb8e5"}, + {file = "z3_solver-4.13.3.0-py3-none-manylinux_2_34_aarch64.whl", hash = "sha256:ab5057cb1f4680406a232d2c1d968daaf69fae10685baa0887b85ca8e938a5cf"}, + {file = "z3_solver-4.13.3.0-py3-none-win32.whl", hash = "sha256:ba465489e9ab609f1cf0f232cbc102165b89a507347a6093c2ac3224cf161aa3"}, + {file = "z3_solver-4.13.3.0-py3-none-win_amd64.whl", hash = "sha256:d55e4793fa48230af766c7f6f7f033198b2d9df150d89ec65b07fd7b87998897"}, + {file = "z3_solver-4.13.3.0.tar.gz", hash = "sha256:4c27466455bac65d3c512f4bb4841ac79e05e121d3f98ddc99ac27ab4bc27e05"}, ] [[package]] diff --git a/pyproject.toml b/pyproject.toml index a23f0277016..05176df847b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ exclude = "tests/.*|demisto_sdk/commands/init/templates/.*" [tool.poetry] name = "demisto-sdk" -version = "1.33.2" +version = "1.32.5" description = "\"A Python library for the Demisto SDK\"" authors = ["Demisto"] license = "MIT" @@ -126,7 +126,6 @@ pytest-github-actions-annotate-failures = "^0.2.0" pytest-sugar = "^1.0.0" pytest-loguru = "^0.4.0" - [tool.poetry.group.types.dependencies] types-requests = "^2.31.0.20240311" types-mock = "^4.0.15" @@ -150,7 +149,6 @@ init-validation = "demisto_sdk.scripts.init_validation_script:main" validate-deleted-files = "demisto_sdk.scripts.validate_deleted_files:main" validate-file-permission-changes = "demisto_sdk.scripts.validate_file_permission_changes:main" prevent-mypy-global-ignore = "demisto_sdk.scripts.prevent_mypy_global_ignore:main" -generate-command-docs = "demisto_sdk.scripts.generate_commands_docs:main" [tool.ruff] exclude = [ From 22b4fa8f9341f49685bd8e4fe934a1b9ed169e6d Mon Sep 17 00:00:00 2001 From: epintzov Date: Mon, 6 Jan 2025 18:45:43 +0200 Subject: [PATCH 55/58] path --- .../commands/test_content/test_use_case/test_use_case.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py index 565f894e218..376b4c0f211 100644 --- a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py +++ b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py @@ -234,7 +234,7 @@ def create_servers(self): api_key=self.api_key, # type: ignore[arg-type] auth_id=self.auth_id, # type: ignore[arg-type] ui_url=get_ui_url(self.cloud_url), - tests=[test for test in self.inputs] + tests=[Path(test) for test in self.inputs] if self.inputs else [], ) @@ -242,7 +242,7 @@ def create_servers(self): servers_list = [] for machine, assignment in self.machine_assignment_json.items(): tests = [ - test + Path(test) for test in assignment.get("tests", {}).get(TEST_USE_CASES, []) ] if not tests: From 9d5daac50ec67e13847af18b79d6515858eeedf1 Mon Sep 17 00:00:00 2001 From: epintzov Date: Tue, 7 Jan 2025 16:57:21 +0200 Subject: [PATCH 56/58] pyxdr --- .../commands/test_content/test_use_case/test_use_case.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py index 376b4c0f211..ffa6a7b15a8 100644 --- a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py +++ b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py @@ -211,6 +211,12 @@ def __init__( f"pip install pyxdr --index-url https://__token__:{os.environ.get('PYXDR_TOKEN')}@gitlab.xdr.pan.local/" f"api/v4/projects/213/packages/pypi/simple --trusted-host gitlab.xdr.pan.local") + logger.info("Runnign gcloud config") + run_command("gcloud auth list") + + logger.info("Running project ID") + run_command("gcloud projects list --format json --filter projectId~qa2-test-9999640926782") + # @staticmethod # def edit_prefix(path_str: Union[str, Path]) -> Path: # """ From 78eb356ac0c47800fd0b44390de7cc875bcb916b Mon Sep 17 00:00:00 2001 From: EyalPintzov <91007713+eyalpalo@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:12:07 +0200 Subject: [PATCH 57/58] Apply suggestions from code review Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com> --- .changelog/4658.yml | 2 +- demisto_sdk/commands/common/clients/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.changelog/4658.yml b/.changelog/4658.yml index 5af4b801685..aa735a1003b 100644 --- a/.changelog/4658.yml +++ b/.changelog/4658.yml @@ -1,4 +1,4 @@ changes: -- description: Adding new command **test-use-case** to test use case flows on cloud machines. +- description: Added the **test-use-case** command to test use-case flows on cloud machines. type: internal pr_number: 4658 diff --git a/demisto_sdk/commands/common/clients/__init__.py b/demisto_sdk/commands/common/clients/__init__.py index 23ae9ca31af..bdfae8d098d 100644 --- a/demisto_sdk/commands/common/clients/__init__.py +++ b/demisto_sdk/commands/common/clients/__init__.py @@ -261,7 +261,7 @@ def get_client_conf_from_pytest_request(request): # Manually parse command-line argument for arg in request.config.invocation_params.args: if isinstance(arg, str) and arg.startswith("--client_conf="): - logger.info("there is --client_conf recognized") + logger.debug("Parsing --client_conf argument") client_conf = arg.replace("--client_conf=", "") return parse_str_to_dict(client_conf) # If a client data was not provided, we proceed to use default. From d6e9ec7a2b828a043f76e1ee661b57a29335628c Mon Sep 17 00:00:00 2001 From: epintzov Date: Wed, 8 Jan 2025 10:25:22 +0200 Subject: [PATCH 58/58] print gcloud auth --- .../commands/test_content/test_use_case/test_use_case.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py index ffa6a7b15a8..5a1c37c7a69 100644 --- a/demisto_sdk/commands/test_content/test_use_case/test_use_case.py +++ b/demisto_sdk/commands/test_content/test_use_case/test_use_case.py @@ -212,10 +212,12 @@ def __init__( f"api/v4/projects/213/packages/pypi/simple --trusted-host gitlab.xdr.pan.local") logger.info("Runnign gcloud config") - run_command("gcloud auth list") + res = run_command("gcloud auth list") + logger.info(res) logger.info("Running project ID") - run_command("gcloud projects list --format json --filter projectId~qa2-test-9999640926782") + res = run_command("gcloud projects list --format json --filter projectId~qa2-test-9999640926782") + logger.info(res) # @staticmethod # def edit_prefix(path_str: Union[str, Path]) -> Path: