From d3f8414f532f33067e803810ffdae4bc1e7fbc54 Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Fri, 7 Feb 2025 13:19:14 -0800 Subject: [PATCH 01/16] Created basic CrewAI implementation. Working on tests, Crew is down. --- python/.env.example | 4 +- .../concepts/plugins/crew_ai_plugin.py | 73 ++++++ .../core_plugins/crew_ai/__init__.py | 11 + .../core_plugins/crew_ai/crew_ai_client.py | 91 +++++++ .../crew_ai/crew_ai_enterprise.py | 227 ++++++++++++++++++ .../core_plugins/crew_ai/crew_ai_models.py | 96 ++++++++ .../core_plugins/crew_ai/crew_ai_settings.py | 35 +++ .../core_plugins/test_crew_ai_enterprise.py | 75 ++++++ 8 files changed, 611 insertions(+), 1 deletion(-) create mode 100644 python/samples/concepts/plugins/crew_ai_plugin.py create mode 100644 python/semantic_kernel/core_plugins/crew_ai/__init__.py create mode 100644 python/semantic_kernel/core_plugins/crew_ai/crew_ai_client.py create mode 100644 python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py create mode 100644 python/semantic_kernel/core_plugins/crew_ai/crew_ai_models.py create mode 100644 python/semantic_kernel/core_plugins/crew_ai/crew_ai_settings.py create mode 100644 python/tests/unit/core_plugins/test_crew_ai_enterprise.py diff --git a/python/.env.example b/python/.env.example index 8e46ec2bb6de..7d9a407dc877 100644 --- a/python/.env.example +++ b/python/.env.example @@ -34,4 +34,6 @@ BOOKING_SAMPLE_CLIENT_ID="" BOOKING_SAMPLE_TENANT_ID="" BOOKING_SAMPLE_CLIENT_SECRET="" BOOKING_SAMPLE_BUSINESS_ID="" -BOOKING_SAMPLE_SERVICE_ID="" \ No newline at end of file +BOOKING_SAMPLE_SERVICE_ID="" +CREW_AI_ENDPOINT="" +CREW_AI_TOKEN="" \ No newline at end of file diff --git a/python/samples/concepts/plugins/crew_ai_plugin.py b/python/samples/concepts/plugins/crew_ai_plugin.py new file mode 100644 index 000000000000..ec592da63925 --- /dev/null +++ b/python/samples/concepts/plugins/crew_ai_plugin.py @@ -0,0 +1,73 @@ +# Copyright (c) Microsoft. All rights reserved. + +import asyncio +import logging + +from semantic_kernel.core_plugins.crew_ai.crew_ai_enterprise import CrewAIEnterprise, InputMetadata +from semantic_kernel.core_plugins.crew_ai.crew_ai_settings import CrewAISettings + +logging.basicConfig(level=logging.INFO) + + +async def using_crew_ai_enterprise(): + settings = CrewAISettings.create() + crew = CrewAIEnterprise(settings=settings) + + # The required inputs for the Crew must be known in advance. This example is modeled after the + # Enterprise Content Marketing Crew Template and requires the following inputs: + inputs = {"company": "CrewAI", "topic": "Agentic products for consumers"} + + # Invoke directly with our inputs + kickoff_id = await crew.kickoff(inputs) + print(f"CrewAI Enterprise Crew kicked off with ID: {kickoff_id}") + + # Wait for completion + result = await crew.wait_for_crew_completion(kickoff_id) + print("CrewAI Enterprise Crew completed with the following result:") + print(result) + + +async def using_crew_ai_enterprise_as_plugin(): + settings = CrewAISettings() + + # Setup the CrewAIEnterprise instance + crew = CrewAIEnterprise( + endpoint=settings.endpoint, auth_token_provider=lambda: settings.auth_token.get_secret_value() + ) + + # The required inputs for the Crew must be known in advance. This example is modeled after the + # Enterprise Content Marketing Crew Template and requires string inputs for the company and topic. + # We need to describe the type and purpose of each input to allow the LLM to invoke the crew as expected. + crew_plugin_definitions = [ + InputMetadata(name="company", type="string", description="The name of the company that should be researched"), + InputMetadata(name="topic", type="string", description="The topic that should be researched"), + ] + + # Create the CrewAI Plugin. This builds a plugin that can be added to the Kernel and invoked like any other plugin. + # The plugin will contain the following functions: + # - kickoff: Starts the Crew with the specified inputs and returns the Id of the scheduled kickoff. + # - kickoff_and_wait: Starts the Crew with the specified inputs and waits for the Crew to complete before returning + # the result. + # - wait_for_completion: Waits for the specified Crew kickoff to complete and returns the result. + # - get_status: Gets the status of the specified Crew kickoff. + crew_description = ( + "Conducts thorough research on the specified company and topic to identify emerging trends," + "analyze competitor strategies, and gather data-driven insights." + ) + + crew_plugin = crew.create_kernel_plugin( + name="EnterpriseContentMarketingCrew", + description=crew_description, + input_metadata=crew_plugin_definitions, + ) + + # Example of invoking the plugin directly + kickoff_and_wait_function = crew_plugin["functions"]["kickoff_and_wait"] + result = await kickoff_and_wait_function({"company": "CrewAI", "topic": "Consumer AI Products"}) + + print(result) + + +if __name__ == "__main__": + asyncio.run(using_crew_ai_enterprise()) + asyncio.run(using_crew_ai_enterprise_as_plugin()) diff --git a/python/semantic_kernel/core_plugins/crew_ai/__init__.py b/python/semantic_kernel/core_plugins/crew_ai/__init__.py new file mode 100644 index 000000000000..08c61da6d2fa --- /dev/null +++ b/python/semantic_kernel/core_plugins/crew_ai/__init__.py @@ -0,0 +1,11 @@ +# Copyright (c) Microsoft. All rights reserved. + +from semantic_kernel.core_plugins.crew_ai.crew_ai_enterprise import CrewAIEnterprise +from semantic_kernel.core_plugins.crew_ai.crew_ai_models import ( + CrewAIStatusResponse, +) +from semantic_kernel.core_plugins.crew_ai.crew_ai_settings import ( + CrewAISettings, +) + +__all__ = ["CrewAIEnterprise", "CrewAISettings", "CrewAIStatusResponse"] diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_client.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_client.py new file mode 100644 index 000000000000..87863805857e --- /dev/null +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_client.py @@ -0,0 +1,91 @@ +# Copyright (c) Microsoft. All rights reserved. + +import json +from collections.abc import Awaitable, Callable +from typing import Any + +import aiohttp + +from semantic_kernel.core_plugins.crew_ai.crew_ai_models import ( + CrewAIKickoffResponse, + CrewAIRequiredInputs, + CrewAIStatusResponse, +) +from semantic_kernel.kernel_pydantic import KernelBaseModel + + +class CrewAIEnterpriseClient(KernelBaseModel): + """Client to interact with the Crew AI Enterprise API.""" + + endpoint: str + auth_token_provider: Callable[..., Awaitable[str]] + + async def get_inputs(self) -> CrewAIRequiredInputs: + """Get the required inputs for Crew AI. + + Returns: + CrewAIRequiredInputs: The required inputs for Crew AI. + """ + async with await self._create_http_client() as client, client.get(f"{self.endpoint}/inputs") as response: + response.raise_for_status() + body = await response.text() + return CrewAIRequiredInputs(**json.loads(body)) + + async def kickoff( + self, + inputs: dict[str, Any] | None = None, + task_webhook_url: str | None = None, + step_webhook_url: str | None = None, + crew_webhook_url: str | None = None, + ) -> CrewAIKickoffResponse: + """Kickoff a new Crew AI task. + + Args: + inputs (Optional[dict[str, Any]], optional): The inputs for the task. Defaults to None. + task_webhook_url (Optional[str], optional): The webhook URL for task updates. Defaults to None. + step_webhook_url (Optional[str], optional): The webhook URL for step updates. Defaults to None. + crew_webhook_url (Optional[str], optional): The webhook URL for crew updates. Defaults to None. + + Returns: + CrewAIKickoffResponse: The response from the kickoff request. + """ + content = { + "inputs": inputs, + "taskWebhookUrl": task_webhook_url, + "stepWebhookUrl": step_webhook_url, + "crewWebhookUrl": crew_webhook_url, + } + async with ( + await self._create_http_client() as client, + client.post(f"{self.endpoint}/kickoff", json=content) as response, + ): + response.raise_for_status() + body = await response.text() + return CrewAIKickoffResponse(**json.loads(body)) + + async def get_status(self, task_id: str) -> CrewAIStatusResponse: + """Get the status of a Crew AI task. + + Args: + task_id (str): The ID of the task. + + Returns: + CrewAIStatusResponse: The status response of the task. + """ + async with ( + await self._create_http_client() as client, + client.get(f"{self.endpoint}/status/{task_id}") as response, + ): + response.raise_for_status() + body = await response.text() + return CrewAIStatusResponse(**json.loads(body)) + + async def _create_http_client(self) -> aiohttp.ClientSession: + """Create an HTTP client session with the necessary headers. + + Returns: + aiohttp.ClientSession: The HTTP client session. + """ + auth_token = await self.auth_token_provider() + headers = {"Authorization": f"Bearer {auth_token}", "Content-Type": "application/json"} + return aiohttp.ClientSession(headers=headers) diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py new file mode 100644 index 000000000000..ec5e706fb503 --- /dev/null +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py @@ -0,0 +1,227 @@ +# Copyright (c) Microsoft. All rights reserved. + +import asyncio +import json +import logging +from collections.abc import Awaitable, Callable +from typing import Any + +from pydantic import Field + +from semantic_kernel.core_plugins.crew_ai.crew_ai_client import CrewAIEnterpriseClient +from semantic_kernel.core_plugins.crew_ai.crew_ai_models import CrewAIStatusResponse, InputMetadata +from semantic_kernel.core_plugins.crew_ai.crew_ai_settings import CrewAISettings +from semantic_kernel.exceptions.function_exceptions import ( + FunctionExecutionException, + FunctionResultError, + PluginInitializationError, +) +from semantic_kernel.functions.kernel_arguments import KernelArguments +from semantic_kernel.functions.kernel_function_from_method import KernelFunctionFromMethod +from semantic_kernel.functions.kernel_parameter_metadata import KernelParameterMetadata +from semantic_kernel.functions.kernel_plugin import KernelPlugin +from semantic_kernel.kernel_pydantic import KernelBaseModel + +logger: logging.Logger = logging.getLogger(__name__) + + +class CrewAIEnterprise(KernelBaseModel): + """Class to interface with Crew.AI Crews from Semantic Kernel.""" + + client: CrewAIEnterpriseClient + polling_interval: float = Field(default=1.0) + + def __init__(self, settings: CrewAISettings, auth_token_provider: Callable[..., Awaitable[str]] | None = None): + """Initialize a new instance of the class. + + Args: + settings (CrewAISettings): The API endpoint. + auth_token_provider (Optional[callable], optional): A callable to provide the authentication token. + """ + if not auth_token_provider: + if not settings.auth_token: + raise PluginInitializationError("An auth token provider or auth token must be provided.") + + async def auth_token_provider() -> Awaitable[str]: + await asyncio.sleep(0) # Yield control to the event loop + return settings.auth_token.get_secret_value() + + client = CrewAIEnterpriseClient(endpoint=settings.endpoint, auth_token_provider=auth_token_provider) + + super().__init__( + client=client, + polling_interval=settings.polling_interval, + ) + + async def kickoff( + self, + inputs: dict[str, Any] | None = None, + task_webhook_url: str | None = None, + step_webhook_url: str | None = None, + crew_webhook_url: str | None = None, + ) -> str: + """Kickoff a new Crew AI task. + + Args: + inputs (dict[str, Any], optional): The inputs for the task. Defaults to None. + task_webhook_url (str | None, optional): The webhook URL for task updates. Defaults to None. + step_webhook_url (str | None, optional): The webhook URL for step updates. Defaults to None. + crew_webhook_url (str | None, optional): The webhook URL for crew updates. Defaults to None. + + Returns: + str: The ID of the kickoff response. + """ + try: + kickoff_response = await self.client.kickoff(inputs, task_webhook_url, step_webhook_url, crew_webhook_url) + self._logger.info(f"CrewAI Crew kicked off with Id: {kickoff_response.kickoff_id}") + return kickoff_response.kickoff_id + except Exception as ex: + raise FunctionExecutionException("Failed to kickoff CrewAI Crew.") from ex + + async def get_crew_kickoff_status(self, kickoff_id: str) -> CrewAIStatusResponse: + """Get the status of a Crew AI task. + + Args: + kickoff_id (str): The ID of the kickoff response. + + Returns: + CrewAIStatusResponse: The status response of the task. + """ + try: + status_response = await self.client.get_status(kickoff_id) + self._logger.info(f"CrewAI Crew status for kickoff Id: {kickoff_id} is {status_response.state}") + return status_response + except Exception as ex: + raise FunctionExecutionException( + f"Failed to get status of CrewAI Crew with kickoff Id: {kickoff_id}." + ) from ex + + async def wait_for_crew_completion(self, kickoff_id: str) -> str: + """Wait for the completion of a Crew AI task. + + Args: + kickoff_id (str): The ID of the kickoff response. + + Returns: + str: The result of the task. + + Raises: + FunctionExecutionException: If the task fails or an error occurs while waiting for completion. + """ + try: + status_response = None + status = "Pending" + while status not in ["Failed", "Failure", "Success", "NotFound"]: + self._logger.info( + f"Waiting for CrewAI Crew with kickoff Id: {kickoff_id} to complete. Current state: {status}" + ) + await asyncio.sleep(self._polling_interval) + status_response = await self.client.get_status(kickoff_id) + status = status_response.state + + self._logger.info( + f"CrewAI Crew with kickoff Id: {kickoff_id} completed with status: {status_response.state}" + ) + if status in ["Failed", "Failure"]: + raise FunctionResultError(f"CrewAI Crew failed with error: {status_response.result}") + return status_response.result or "" + except Exception as ex: + raise FunctionExecutionException( + f"Failed to wait for completion of CrewAI Crew with kickoff Id: {kickoff_id}." + ) from ex + + def create_kernel_plugin( + self, + name: str, + description: str, + input_metadata: list[InputMetadata] | None = None, + task_webhook_url: str | None = None, + step_webhook_url: str | None = None, + crew_webhook_url: str | None = None, + ) -> dict[str, Any]: + """Creates a kernel plugin that can be used to invoke the CrewAI Crew. + + Args: + name (str): The name of the kernel plugin. + description (str): The description of the kernel plugin. + input_metadata (Optional[List[InputMetadata]], optional): The definitions of the Crew's + required inputs. Defaults to None. + task_webhook_url (Optional[str], optional): The task level webhook URL. Defaults to None. + step_webhook_url (Optional[str], optional): The step level webhook URL. Defaults to None. + crew_webhook_url (Optional[str], optional): The crew level webhook URL. Defaults to None. + + Returns: + dict[str, Any]: A dictionary representing the kernel plugin. + """ + parameters = input_metadata.map( + lambda x: KernelParameterMetadata( + name=x.name, description=x.description, default_value=None, type=x.type, is_required=True + ) + ) + + return_parameter = KernelParameterMetadata(type="string", is_required=True) + + async def kickoff(arguments: KernelArguments) -> str: + args = self._build_arguments(input_metadata, arguments) + return await self.kickoff( + inputs=args, + task_webhook_url=task_webhook_url, + step_webhook_url=step_webhook_url, + crew_webhook_url=crew_webhook_url, + ) + + async def kickoff_and_wait(arguments: KernelArguments) -> str: + args = self._build_arguments(input_metadata, arguments) + kickoff_id = await self.kickoff( + inputs=args, + task_webhook_url=task_webhook_url, + step_webhook_url=step_webhook_url, + crew_webhook_url=crew_webhook_url, + ) + return await self.wait_for_crew_completion(kickoff_id) + + return KernelPlugin( + name, + description, + KernelFunctionFromMethod( + kickoff, + "kickoff", + stream_method=None, + parameters=parameters, + return_parameter=return_parameter, + ), + KernelFunctionFromMethod( + kickoff_and_wait, + "kickoff_and_wait", + stream_method=None, + parameters=parameters, + return_parameter=return_parameter, + ), + self.get_crew_kickoff_status, + self.wait_for_crew_completion, + ) + + def _build_arguments( + self, input_metadata: list[InputMetadata] | None, arguments: KernelArguments + ) -> dict[str, Any]: + """Builds the arguments for the CrewAI task from the provided metadata and arguments. + + Args: + input_metadata (Optional[List[InputMetadata]]): The metadata for the inputs. + arguments (dict[str, Any]): The provided arguments. + + Returns: + dict[str, Any]: The built arguments. + """ + args = {} + if input_metadata: + for input in input_metadata: + name = input.name + if name not in arguments: + raise PluginInitializationError(f"Missing required input '{name}' for CrewAI.") + value = arguments[name] + if input.type == "string": + args[name] = value + else: + args[name] = json.loads(value) + return args diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_models.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_models.py new file mode 100644 index 000000000000..99e4f4b476de --- /dev/null +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_models.py @@ -0,0 +1,96 @@ +# Copyright (c) Microsoft. All rights reserved. + +from typing import Any + + +class CrewAIStatusResponse: + """Represents the status response from Crew AI. + + Attributes: + state (str): The current state of the Crew AI. + result (Optional[str]): The result of the last operation, if any. + last_step (Optional[dict[str, Any]]): Details of the last step performed by the Crew AI, if any. + + Args: + state (str): The current state of the Crew AI. + result (Optional[str], optional): The result of the last operation. Defaults to None. + last_step (Optional[dict[str, Any]], optional): Details of the last step performed by the Crew AI. + Defaults to None. + """ + + def __init__(self, state: str, result: str | None = None, last_step: dict[str, Any] | None = None): + """Initialize a new instance of the class. + + Args: + state (str): The current state of the instance. + result (Optional[str], optional): The result of the instance. Defaults to None. + last_step (Optional[dict[str, Any]], optional): The last step information of the instance. Defaults to None. + """ + self.state = state + self.result = result + self.last_step = last_step + + +class CrewAIKickoffResponse: + """Represents the kickoff response from Crew AI. + + Attributes: + kickoff_id (str): The ID of the kickoff response. + + Args: + kickoff_id (str): The ID of the kickoff response. + """ + + def __init__(self, kickoff_id: str): + """Initialize a new instance of the class. + + Args: + kickoff_id (str): The ID of the kickoff response. + """ + self.kickoff_id = kickoff_id + + +class CrewAIRequiredInputs: + """Represents the required inputs for Crew AI. + + Attributes: + inputs (dict[str, str]): The required inputs for Crew AI. + + Args: + inputs (dict[str, str]): The required inputs for Crew AI. + """ + + def __init__(self, inputs: dict[str, str]): + """Initialize a new instance of the class. + + Args: + inputs (dict[str, str]): The required inputs for Crew AI. + """ + self.inputs = inputs + + +class InputMetadata: + """Represents the metadata for an input required by Crew AI. + + Attributes: + name (str): The name of the input. + type (str): The type of the input (e.g., 'string', 'json'). + description (Optional[str]): The description of the input. + + Args: + name (str): The name of the input. + type (str): The type of the input. + description (Optional[str], optional): The description of the input. Defaults to None. + """ + + def __init__(self, name: str, type: str, description: str | None = None): + """Initialize a new instance of the class. + + Args: + name (str): The name of the input. + type (str): The type of the input. + description (Optional[str], optional): The description of the input. Defaults to None. + """ + self.name = name + self.type = type + self.description = description diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_settings.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_settings.py new file mode 100644 index 000000000000..69f13799f25a --- /dev/null +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_settings.py @@ -0,0 +1,35 @@ +# Copyright (c) Microsoft. All rights reserved. + +from typing import ClassVar + +from pydantic import SecretStr + +from semantic_kernel.kernel_pydantic import KernelBaseSettings + + +class CrewAISettings(KernelBaseSettings): + """The Crew.AI settings. + + Required: + - endpoint: str - The API endpoint. + """ + + env_prefix: ClassVar[str] = "CREW_AI_" + + endpoint: str + auth_token: SecretStr | None = None + polling_interval: float = 1.0 + + +class CrewAIClientSettings(KernelBaseSettings): + """The Crew.AI client settings. + + Required: + - endpoint: str - The API endpoint. + """ + + env_prefix: ClassVar[str] = "CREW_AI_CLIENT_" + + endpoint: str + auth_token: SecretStr | None = None + polling_interval: float = 1.0 diff --git a/python/tests/unit/core_plugins/test_crew_ai_enterprise.py b/python/tests/unit/core_plugins/test_crew_ai_enterprise.py new file mode 100644 index 000000000000..347e4ee8365b --- /dev/null +++ b/python/tests/unit/core_plugins/test_crew_ai_enterprise.py @@ -0,0 +1,75 @@ +# Copyright (c) Microsoft. All rights reserved. + + +from unittest.mock import AsyncMock + +import pytest +from crew_ai.crew_ai_enterprise import CrewAIEnterprise +from crew_ai.crew_ai_models import InputMetadata + + +@pytest.fixture +def mock_client(): + return AsyncMock() + + +@pytest.fixture +def auth_token_provider(): + return AsyncMock(return_value="fake_token") + + +@pytest.fixture +def crew_ai_enterprise(mock_client, auth_token_provider): + crew_ai = CrewAIEnterprise(endpoint="http://fake-endpoint", auth_token_provider=auth_token_provider) + crew_ai._crew_client = mock_client + return crew_ai + + +@pytest.mark.asyncio +async def test_kickoff_async(crew_ai_enterprise, mock_client): + mock_client.kickoff_async.return_value = AsyncMock(kickoff_id="12345") + kickoff_id = await crew_ai_enterprise.kickoff_async(inputs={"key": "value"}) + assert kickoff_id == "12345" + mock_client.kickoff_async.assert_called_once_with({"key": "value"}, None, None, None) + + +@pytest.mark.asyncio +async def test_get_crew_kickoff_status_async(crew_ai_enterprise, mock_client): + mock_client.get_status_async.return_value = AsyncMock(state="Success") + status_response = await crew_ai_enterprise.get_crew_kickoff_status_async("12345") + assert status_response.state == "Success" + mock_client.get_status_async.assert_called_once_with("12345") + + +@pytest.mark.asyncio +async def test_wait_for_crew_completion_async(crew_ai_enterprise, mock_client): + mock_client.get_status_async.side_effect = [ + AsyncMock(state="Pending"), + AsyncMock(state="Pending"), + AsyncMock(state="Success", result="Completed"), + ] + result = await crew_ai_enterprise.wait_for_crew_completion_async("12345") + assert result == "Completed" + assert mock_client.get_status_async.call_count == 3 + + +def test_create_kernel_plugin(crew_ai_enterprise): + plugin = crew_ai_enterprise.create_kernel_plugin( + name="test_plugin", description="Test Plugin", input_metadata=[InputMetadata(name="input1", type="string")] + ) + assert plugin.name == "test_plugin" + assert plugin.description == "Test Plugin" + + +def test_build_arguments(crew_ai_enterprise): + input_metadata = [InputMetadata(name="input1", type="string")] + arguments = {"input1": "value1"} + args = crew_ai_enterprise._build_arguments(input_metadata, arguments) + assert args == {"input1": "value1"} + + +def test_build_arguments_missing_input(crew_ai_enterprise): + input_metadata = [InputMetadata(name="input1", type="string")] + arguments = {} + with pytest.raises(Exception, match="Missing required input 'input1' for CrewAI."): + crew_ai_enterprise._build_arguments(input_metadata, arguments) From e091b590a57472c78ceea3174d085dc6ff9634af Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Fri, 7 Feb 2025 16:08:08 -0800 Subject: [PATCH 02/16] Manual verification of concept samples successful. --- .../concepts/plugins/crew_ai_plugin.py | 26 +++-- .../crew_ai/crew_ai_enterprise.py | 78 +++++++------ .../core_plugins/crew_ai/crew_ai_models.py | 104 +++++------------- 3 files changed, 86 insertions(+), 122 deletions(-) diff --git a/python/samples/concepts/plugins/crew_ai_plugin.py b/python/samples/concepts/plugins/crew_ai_plugin.py index ec592da63925..b373a3c4cee9 100644 --- a/python/samples/concepts/plugins/crew_ai_plugin.py +++ b/python/samples/concepts/plugins/crew_ai_plugin.py @@ -5,6 +5,9 @@ from semantic_kernel.core_plugins.crew_ai.crew_ai_enterprise import CrewAIEnterprise, InputMetadata from semantic_kernel.core_plugins.crew_ai.crew_ai_settings import CrewAISettings +from semantic_kernel.functions.kernel_arguments import KernelArguments +from semantic_kernel.functions.kernel_function import KernelFunction +from semantic_kernel.kernel import Kernel logging.basicConfig(level=logging.INFO) @@ -28,11 +31,13 @@ async def using_crew_ai_enterprise(): async def using_crew_ai_enterprise_as_plugin(): - settings = CrewAISettings() + settings = CrewAISettings.create() + crew = CrewAIEnterprise(settings=settings) - # Setup the CrewAIEnterprise instance - crew = CrewAIEnterprise( - endpoint=settings.endpoint, auth_token_provider=lambda: settings.auth_token.get_secret_value() + # Define the description of the Crew. This will used as the semantic description of the plugin. + crew_description = ( + "Conducts thorough research on the specified company and topic to identify emerging trends," + "analyze competitor strategies, and gather data-driven insights." ) # The required inputs for the Crew must be known in advance. This example is modeled after the @@ -50,11 +55,6 @@ async def using_crew_ai_enterprise_as_plugin(): # the result. # - wait_for_completion: Waits for the specified Crew kickoff to complete and returns the result. # - get_status: Gets the status of the specified Crew kickoff. - crew_description = ( - "Conducts thorough research on the specified company and topic to identify emerging trends," - "analyze competitor strategies, and gather data-driven insights." - ) - crew_plugin = crew.create_kernel_plugin( name="EnterpriseContentMarketingCrew", description=crew_description, @@ -62,12 +62,14 @@ async def using_crew_ai_enterprise_as_plugin(): ) # Example of invoking the plugin directly - kickoff_and_wait_function = crew_plugin["functions"]["kickoff_and_wait"] - result = await kickoff_and_wait_function({"company": "CrewAI", "topic": "Consumer AI Products"}) + kickoff_and_wait_function: KernelFunction = crew_plugin["kickoff_and_wait"] + result = await kickoff_and_wait_function.invoke( + kernel=Kernel(), arguments=KernelArguments(company="CrewAI", topic="Consumer AI Products") + ) print(result) if __name__ == "__main__": - asyncio.run(using_crew_ai_enterprise()) + # asyncio.run(using_crew_ai_enterprise()) asyncio.run(using_crew_ai_enterprise_as_plugin()) diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py index ec5e706fb503..ad46dd0fc560 100644 --- a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py @@ -9,13 +9,18 @@ from pydantic import Field from semantic_kernel.core_plugins.crew_ai.crew_ai_client import CrewAIEnterpriseClient -from semantic_kernel.core_plugins.crew_ai.crew_ai_models import CrewAIStatusResponse, InputMetadata +from semantic_kernel.core_plugins.crew_ai.crew_ai_models import ( + CrewAIEnterpriseKickoffState, + CrewAIStatusResponse, + InputMetadata, +) from semantic_kernel.core_plugins.crew_ai.crew_ai_settings import CrewAISettings from semantic_kernel.exceptions.function_exceptions import ( FunctionExecutionException, FunctionResultError, PluginInitializationError, ) +from semantic_kernel.functions import kernel_function from semantic_kernel.functions.kernel_arguments import KernelArguments from semantic_kernel.functions.kernel_function_from_method import KernelFunctionFromMethod from semantic_kernel.functions.kernel_parameter_metadata import KernelParameterMetadata @@ -73,11 +78,12 @@ async def kickoff( """ try: kickoff_response = await self.client.kickoff(inputs, task_webhook_url, step_webhook_url, crew_webhook_url) - self._logger.info(f"CrewAI Crew kicked off with Id: {kickoff_response.kickoff_id}") + logger.info(f"CrewAI Crew kicked off with Id: {kickoff_response.kickoff_id}") return kickoff_response.kickoff_id except Exception as ex: raise FunctionExecutionException("Failed to kickoff CrewAI Crew.") from ex + @kernel_function(description="Get the status of a Crew AI kickoff.") async def get_crew_kickoff_status(self, kickoff_id: str) -> CrewAIStatusResponse: """Get the status of a Crew AI task. @@ -89,13 +95,14 @@ async def get_crew_kickoff_status(self, kickoff_id: str) -> CrewAIStatusResponse """ try: status_response = await self.client.get_status(kickoff_id) - self._logger.info(f"CrewAI Crew status for kickoff Id: {kickoff_id} is {status_response.state}") + logger.info(f"CrewAI Crew status for kickoff Id: {kickoff_id} is {status_response.state}") return status_response except Exception as ex: raise FunctionExecutionException( f"Failed to get status of CrewAI Crew with kickoff Id: {kickoff_id}." ) from ex + @kernel_function(description="Wait for the completion of a Crew AI kickoff.") async def wait_for_crew_completion(self, kickoff_id: str) -> str: """Wait for the completion of a Crew AI task. @@ -110,18 +117,22 @@ async def wait_for_crew_completion(self, kickoff_id: str) -> str: """ try: status_response = None - status = "Pending" - while status not in ["Failed", "Failure", "Success", "NotFound"]: - self._logger.info( + status = CrewAIEnterpriseKickoffState.Pending + while status not in [ + CrewAIEnterpriseKickoffState.Failed, + CrewAIEnterpriseKickoffState.Failure, + CrewAIEnterpriseKickoffState.Success, + CrewAIEnterpriseKickoffState.Not_Found, + ]: + logger.info( f"Waiting for CrewAI Crew with kickoff Id: {kickoff_id} to complete. Current state: {status}" ) - await asyncio.sleep(self._polling_interval) + + await asyncio.sleep(self.polling_interval) status_response = await self.client.get_status(kickoff_id) status = status_response.state - self._logger.info( - f"CrewAI Crew with kickoff Id: {kickoff_id} completed with status: {status_response.state}" - ) + logger.info(f"CrewAI Crew with kickoff Id: {kickoff_id} completed with status: {status_response.state}") if status in ["Failed", "Failure"]: raise FunctionResultError(f"CrewAI Crew failed with error: {status_response.result}") return status_response.result or "" @@ -153,15 +164,23 @@ def create_kernel_plugin( Returns: dict[str, Any]: A dictionary representing the kernel plugin. """ - parameters = input_metadata.map( - lambda x: KernelParameterMetadata( - name=x.name, description=x.description, default_value=None, type=x.type, is_required=True + + def build_metadata(input_metadata: InputMetadata) -> KernelParameterMetadata: + return KernelParameterMetadata( + name=input_metadata.name, + description=input_metadata.description, + default_value=None, + type=input_metadata.type, + is_required=True, ) - ) - return_parameter = KernelParameterMetadata(type="string", is_required=True) + parameters = [ + KernelParameterMetadata(name="arguments", description=None, type="KernelArguments", is_required=True) + ] + parameters.extend([build_metadata(input) for input in input_metadata or []]) - async def kickoff(arguments: KernelArguments) -> str: + @kernel_function(description="Kickoff the CrewAI task.") + async def kickoff(arguments: KernelArguments, **kwargs: Any) -> str: args = self._build_arguments(input_metadata, arguments) return await self.kickoff( inputs=args, @@ -170,7 +189,8 @@ async def kickoff(arguments: KernelArguments) -> str: crew_webhook_url=crew_webhook_url, ) - async def kickoff_and_wait(arguments: KernelArguments) -> str: + @kernel_function(description="Kickoff the CrewAI task and wait for completion.") + async def kickoff_and_wait(arguments: KernelArguments, **kwargs: Any) -> str: args = self._build_arguments(input_metadata, arguments) kickoff_id = await self.kickoff( inputs=args, @@ -183,22 +203,14 @@ async def kickoff_and_wait(arguments: KernelArguments) -> str: return KernelPlugin( name, description, - KernelFunctionFromMethod( - kickoff, - "kickoff", - stream_method=None, - parameters=parameters, - return_parameter=return_parameter, - ), - KernelFunctionFromMethod( - kickoff_and_wait, - "kickoff_and_wait", - stream_method=None, - parameters=parameters, - return_parameter=return_parameter, - ), - self.get_crew_kickoff_status, - self.wait_for_crew_completion, + { + "kickoff": KernelFunctionFromMethod(kickoff, stream_method=None, parameters=parameters), + "kickoff_and_wait": KernelFunctionFromMethod( + kickoff_and_wait, stream_method=None, parameters=parameters + ), + "get_status": self.get_crew_kickoff_status, + "wait_for_completion": self.wait_for_crew_completion, + }, ) def _build_arguments( diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_models.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_models.py index 99e4f4b476de..52bde361b2f8 100644 --- a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_models.py +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_models.py @@ -1,96 +1,46 @@ # Copyright (c) Microsoft. All rights reserved. +from enum import Enum from typing import Any +from semantic_kernel.kernel_pydantic import KernelBaseModel -class CrewAIStatusResponse: - """Represents the status response from Crew AI. - Attributes: - state (str): The current state of the Crew AI. - result (Optional[str]): The result of the last operation, if any. - last_step (Optional[dict[str, Any]]): Details of the last step performed by the Crew AI, if any. +class CrewAIEnterpriseKickoffState(str, Enum): + """The Crew.AI Enterprise kickoff state.""" - Args: - state (str): The current state of the Crew AI. - result (Optional[str], optional): The result of the last operation. Defaults to None. - last_step (Optional[dict[str, Any]], optional): Details of the last step performed by the Crew AI. - Defaults to None. - """ + Pending = "PENDING" + Started = "STARTED" + Running = "RUNNING" + Success = "SUCCESS" + Failed = "FAILED" + Failure = "FAILURE" + Not_Found = "NOT FOUND" - def __init__(self, state: str, result: str | None = None, last_step: dict[str, Any] | None = None): - """Initialize a new instance of the class. - Args: - state (str): The current state of the instance. - result (Optional[str], optional): The result of the instance. Defaults to None. - last_step (Optional[dict[str, Any]], optional): The last step information of the instance. Defaults to None. - """ - self.state = state - self.result = result - self.last_step = last_step +class CrewAIStatusResponse(KernelBaseModel): + """Represents the status response from Crew AI.""" + state: CrewAIEnterpriseKickoffState + result: str | None + last_step: dict[str, Any] | None -class CrewAIKickoffResponse: - """Represents the kickoff response from Crew AI. - Attributes: - kickoff_id (str): The ID of the kickoff response. +class CrewAIKickoffResponse(KernelBaseModel): + """Represents the kickoff response from Crew AI.""" - Args: - kickoff_id (str): The ID of the kickoff response. - """ + kickoff_id: str - def __init__(self, kickoff_id: str): - """Initialize a new instance of the class. - Args: - kickoff_id (str): The ID of the kickoff response. - """ - self.kickoff_id = kickoff_id +class CrewAIRequiredInputs(KernelBaseModel): + """Represents the required inputs for Crew AI.""" + inputs: dict[str, str] -class CrewAIRequiredInputs: - """Represents the required inputs for Crew AI. - Attributes: - inputs (dict[str, str]): The required inputs for Crew AI. +class InputMetadata(KernelBaseModel): + """Represents the metadata for an input required by Crew AI.""" - Args: - inputs (dict[str, str]): The required inputs for Crew AI. - """ - - def __init__(self, inputs: dict[str, str]): - """Initialize a new instance of the class. - - Args: - inputs (dict[str, str]): The required inputs for Crew AI. - """ - self.inputs = inputs - - -class InputMetadata: - """Represents the metadata for an input required by Crew AI. - - Attributes: - name (str): The name of the input. - type (str): The type of the input (e.g., 'string', 'json'). - description (Optional[str]): The description of the input. - - Args: - name (str): The name of the input. - type (str): The type of the input. - description (Optional[str], optional): The description of the input. Defaults to None. - """ - - def __init__(self, name: str, type: str, description: str | None = None): - """Initialize a new instance of the class. - - Args: - name (str): The name of the input. - type (str): The type of the input. - description (Optional[str], optional): The description of the input. Defaults to None. - """ - self.name = name - self.type = type - self.description = description + name: str + type: str + description: str | None From b4069fe7d6a306c31a7ef2c18e38b8d194c40a78 Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Mon, 10 Feb 2025 09:09:29 -0800 Subject: [PATCH 03/16] Simplifying argument handling in generated plugins. --- .../crew_ai/crew_ai_enterprise.py | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py index ad46dd0fc560..326958b01aa0 100644 --- a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py @@ -1,7 +1,6 @@ # Copyright (c) Microsoft. All rights reserved. import asyncio -import json import logging from collections.abc import Awaitable, Callable from typing import Any @@ -21,7 +20,6 @@ PluginInitializationError, ) from semantic_kernel.functions import kernel_function -from semantic_kernel.functions.kernel_arguments import KernelArguments from semantic_kernel.functions.kernel_function_from_method import KernelFunctionFromMethod from semantic_kernel.functions.kernel_parameter_metadata import KernelParameterMetadata from semantic_kernel.functions.kernel_plugin import KernelPlugin @@ -174,14 +172,11 @@ def build_metadata(input_metadata: InputMetadata) -> KernelParameterMetadata: is_required=True, ) - parameters = [ - KernelParameterMetadata(name="arguments", description=None, type="KernelArguments", is_required=True) - ] - parameters.extend([build_metadata(input) for input in input_metadata or []]) + parameters = [build_metadata(input) for input in input_metadata or []] @kernel_function(description="Kickoff the CrewAI task.") - async def kickoff(arguments: KernelArguments, **kwargs: Any) -> str: - args = self._build_arguments(input_metadata, arguments) + async def kickoff(**kwargs: Any) -> str: + args = self._build_arguments(input_metadata, kwargs) return await self.kickoff( inputs=args, task_webhook_url=task_webhook_url, @@ -190,8 +185,8 @@ async def kickoff(arguments: KernelArguments, **kwargs: Any) -> str: ) @kernel_function(description="Kickoff the CrewAI task and wait for completion.") - async def kickoff_and_wait(arguments: KernelArguments, **kwargs: Any) -> str: - args = self._build_arguments(input_metadata, arguments) + async def kickoff_and_wait(**kwargs: Any) -> str: + args = self._build_arguments(input_metadata, kwargs) kickoff_id = await self.kickoff( inputs=args, task_webhook_url=task_webhook_url, @@ -213,9 +208,7 @@ async def kickoff_and_wait(arguments: KernelArguments, **kwargs: Any) -> str: }, ) - def _build_arguments( - self, input_metadata: list[InputMetadata] | None, arguments: KernelArguments - ) -> dict[str, Any]: + def _build_arguments(self, input_metadata: list[InputMetadata] | None, arguments: dict[str, Any]) -> dict[str, Any]: """Builds the arguments for the CrewAI task from the provided metadata and arguments. Args: @@ -231,9 +224,5 @@ def _build_arguments( name = input.name if name not in arguments: raise PluginInitializationError(f"Missing required input '{name}' for CrewAI.") - value = arguments[name] - if input.type == "string": - args[name] = value - else: - args[name] = json.loads(value) + args[name] = arguments[name] return args From 937ea026094800b4e16e282f664da36b3c95e87d Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Mon, 10 Feb 2025 10:35:16 -0800 Subject: [PATCH 04/16] Cleaning up, will add unit tests next. --- .../core_plugins/crew_ai/crew_ai_client.py | 8 +- .../core_plugins/test_crew_ai_enterprise.py | 75 -- python/uv.lock | 720 ++++++++++-------- 3 files changed, 392 insertions(+), 411 deletions(-) delete mode 100644 python/tests/unit/core_plugins/test_crew_ai_enterprise.py diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_client.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_client.py index 87863805857e..3303ff679625 100644 --- a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_client.py +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_client.py @@ -12,6 +12,7 @@ CrewAIStatusResponse, ) from semantic_kernel.kernel_pydantic import KernelBaseModel +from semantic_kernel.utils.telemetry.user_agent import SEMANTIC_KERNEL_USER_AGENT class CrewAIEnterpriseClient(KernelBaseModel): @@ -87,5 +88,10 @@ async def _create_http_client(self) -> aiohttp.ClientSession: aiohttp.ClientSession: The HTTP client session. """ auth_token = await self.auth_token_provider() - headers = {"Authorization": f"Bearer {auth_token}", "Content-Type": "application/json"} + headers = { + "Authorization": f"Bearer {auth_token}", + "Content-Type": "application/json", + "user_agent": SEMANTIC_KERNEL_USER_AGENT, + } + return aiohttp.ClientSession(headers=headers) diff --git a/python/tests/unit/core_plugins/test_crew_ai_enterprise.py b/python/tests/unit/core_plugins/test_crew_ai_enterprise.py deleted file mode 100644 index 347e4ee8365b..000000000000 --- a/python/tests/unit/core_plugins/test_crew_ai_enterprise.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright (c) Microsoft. All rights reserved. - - -from unittest.mock import AsyncMock - -import pytest -from crew_ai.crew_ai_enterprise import CrewAIEnterprise -from crew_ai.crew_ai_models import InputMetadata - - -@pytest.fixture -def mock_client(): - return AsyncMock() - - -@pytest.fixture -def auth_token_provider(): - return AsyncMock(return_value="fake_token") - - -@pytest.fixture -def crew_ai_enterprise(mock_client, auth_token_provider): - crew_ai = CrewAIEnterprise(endpoint="http://fake-endpoint", auth_token_provider=auth_token_provider) - crew_ai._crew_client = mock_client - return crew_ai - - -@pytest.mark.asyncio -async def test_kickoff_async(crew_ai_enterprise, mock_client): - mock_client.kickoff_async.return_value = AsyncMock(kickoff_id="12345") - kickoff_id = await crew_ai_enterprise.kickoff_async(inputs={"key": "value"}) - assert kickoff_id == "12345" - mock_client.kickoff_async.assert_called_once_with({"key": "value"}, None, None, None) - - -@pytest.mark.asyncio -async def test_get_crew_kickoff_status_async(crew_ai_enterprise, mock_client): - mock_client.get_status_async.return_value = AsyncMock(state="Success") - status_response = await crew_ai_enterprise.get_crew_kickoff_status_async("12345") - assert status_response.state == "Success" - mock_client.get_status_async.assert_called_once_with("12345") - - -@pytest.mark.asyncio -async def test_wait_for_crew_completion_async(crew_ai_enterprise, mock_client): - mock_client.get_status_async.side_effect = [ - AsyncMock(state="Pending"), - AsyncMock(state="Pending"), - AsyncMock(state="Success", result="Completed"), - ] - result = await crew_ai_enterprise.wait_for_crew_completion_async("12345") - assert result == "Completed" - assert mock_client.get_status_async.call_count == 3 - - -def test_create_kernel_plugin(crew_ai_enterprise): - plugin = crew_ai_enterprise.create_kernel_plugin( - name="test_plugin", description="Test Plugin", input_metadata=[InputMetadata(name="input1", type="string")] - ) - assert plugin.name == "test_plugin" - assert plugin.description == "Test Plugin" - - -def test_build_arguments(crew_ai_enterprise): - input_metadata = [InputMetadata(name="input1", type="string")] - arguments = {"input1": "value1"} - args = crew_ai_enterprise._build_arguments(input_metadata, arguments) - assert args == {"input1": "value1"} - - -def test_build_arguments_missing_input(crew_ai_enterprise): - input_metadata = [InputMetadata(name="input1", type="string")] - arguments = {} - with pytest.raises(Exception, match="Missing required input 'input1' for CrewAI."): - crew_ai_enterprise._build_arguments(input_metadata, arguments) diff --git a/python/uv.lock b/python/uv.lock index 76db163c5764..66bfad0c8ec3 100644 --- a/python/uv.lock +++ b/python/uv.lock @@ -1,18 +1,18 @@ version = 1 requires-python = ">=3.10" resolution-markers = [ - "python_full_version < '3.11' and sys_platform == 'darwin'", - "python_full_version == '3.11.*' and sys_platform == 'darwin'", - "python_full_version == '3.12.*' and sys_platform == 'darwin'", "python_full_version >= '3.13' and sys_platform == 'darwin'", - "python_full_version < '3.11' and sys_platform == 'linux'", - "python_full_version == '3.11.*' and sys_platform == 'linux'", - "python_full_version == '3.12.*' and sys_platform == 'linux'", + "python_full_version == '3.12.*' and sys_platform == 'darwin'", + "python_full_version == '3.11.*' and sys_platform == 'darwin'", + "python_full_version < '3.11' and sys_platform == 'darwin'", "python_full_version >= '3.13' and sys_platform == 'linux'", - "python_full_version < '3.11' and sys_platform == 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'linux'", + "python_full_version == '3.11.*' and sys_platform == 'linux'", + "python_full_version < '3.11' and sys_platform == 'linux'", "python_full_version >= '3.13' and sys_platform == 'win32'", + "python_full_version == '3.12.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version < '3.11' and sys_platform == 'win32'", ] supported-markers = [ "sys_platform == 'darwin'", @@ -40,16 +40,16 @@ wheels = [ [[package]] name = "aiohappyeyeballs" -version = "2.4.4" +version = "2.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7f/55/e4373e888fdacb15563ef6fa9fa8c8252476ea071e96fb46defac9f18bf2/aiohappyeyeballs-2.4.4.tar.gz", hash = "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745", size = 21977 } +sdist = { url = "https://files.pythonhosted.org/packages/08/07/508f9ebba367fc3370162e53a3cfd12f5652ad79f0e0bfdf9f9847c6f159/aiohappyeyeballs-2.4.6.tar.gz", hash = "sha256:9b05052f9042985d32ecbe4b59a77ae19c006a78f1344d7fdad69d28ded3d0b0", size = 21726 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b9/74/fbb6559de3607b3300b9be3cc64e97548d55678e44623db17820dbd20002/aiohappyeyeballs-2.4.4-py3-none-any.whl", hash = "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8", size = 14756 }, + { url = "https://files.pythonhosted.org/packages/44/4c/03fb05f56551828ec67ceb3665e5dc51638042d204983a03b0a1541475b6/aiohappyeyeballs-2.4.6-py3-none-any.whl", hash = "sha256:147ec992cf873d74f5062644332c539fcd42956dc69453fe5204195e560517e1", size = 14543 }, ] [[package]] name = "aiohttp" -version = "3.11.11" +version = "3.11.12" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, @@ -61,68 +61,72 @@ dependencies = [ { name = "propcache", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "yarl", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fe/ed/f26db39d29cd3cb2f5a3374304c713fe5ab5a0e4c8ee25a0c45cc6adf844/aiohttp-3.11.11.tar.gz", hash = "sha256:bb49c7f1e6ebf3821a42d81d494f538107610c3a705987f53068546b0e90303e", size = 7669618 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/75/7d/ff2e314b8f9e0b1df833e2d4778eaf23eae6b8cc8f922495d110ddcbf9e1/aiohttp-3.11.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a60804bff28662cbcf340a4d61598891f12eea3a66af48ecfdc975ceec21e3c8", size = 708550 }, - { url = "https://files.pythonhosted.org/packages/09/b8/aeb4975d5bba233d6f246941f5957a5ad4e3def8b0855a72742e391925f2/aiohttp-3.11.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4b4fa1cb5f270fb3eab079536b764ad740bb749ce69a94d4ec30ceee1b5940d5", size = 468430 }, - { url = "https://files.pythonhosted.org/packages/9c/5b/5b620279b3df46e597008b09fa1e10027a39467387c2332657288e25811a/aiohttp-3.11.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:731468f555656767cda219ab42e033355fe48c85fbe3ba83a349631541715ba2", size = 455593 }, - { url = "https://files.pythonhosted.org/packages/d8/75/0cdf014b816867d86c0bc26f3d3e3f194198dbf33037890beed629cd4f8f/aiohttp-3.11.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb23d8bb86282b342481cad4370ea0853a39e4a32a0042bb52ca6bdde132df43", size = 1584635 }, - { url = "https://files.pythonhosted.org/packages/df/2f/95b8f4e4dfeb57c1d9ad9fa911ede35a0249d75aa339edd2c2270dc539da/aiohttp-3.11.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f047569d655f81cb70ea5be942ee5d4421b6219c3f05d131f64088c73bb0917f", size = 1632363 }, - { url = "https://files.pythonhosted.org/packages/39/cb/70cf69ea7c50f5b0021a84f4c59c3622b2b3b81695f48a2f0e42ef7eba6e/aiohttp-3.11.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd7659baae9ccf94ae5fe8bfaa2c7bc2e94d24611528395ce88d009107e00c6d", size = 1668315 }, - { url = "https://files.pythonhosted.org/packages/2f/cc/3a3fc7a290eabc59839a7e15289cd48f33dd9337d06e301064e1e7fb26c5/aiohttp-3.11.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af01e42ad87ae24932138f154105e88da13ce7d202a6de93fafdafb2883a00ef", size = 1589546 }, - { url = "https://files.pythonhosted.org/packages/15/b4/0f7b0ed41ac6000e283e7332f0f608d734b675a8509763ca78e93714cfb0/aiohttp-3.11.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5854be2f3e5a729800bac57a8d76af464e160f19676ab6aea74bde18ad19d438", size = 1544581 }, - { url = "https://files.pythonhosted.org/packages/58/b9/4d06470fd85c687b6b0e31935ef73dde6e31767c9576d617309a2206556f/aiohttp-3.11.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6526e5fb4e14f4bbf30411216780c9967c20c5a55f2f51d3abd6de68320cc2f3", size = 1529256 }, - { url = "https://files.pythonhosted.org/packages/61/a2/6958b1b880fc017fd35f5dfb2c26a9a50c755b75fd9ae001dc2236a4fb79/aiohttp-3.11.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:85992ee30a31835fc482468637b3e5bd085fa8fe9392ba0bdcbdc1ef5e9e3c55", size = 1536592 }, - { url = "https://files.pythonhosted.org/packages/0f/dd/b974012a9551fd654f5bb95a6dd3f03d6e6472a17e1a8216dd42e9638d6c/aiohttp-3.11.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:88a12ad8ccf325a8a5ed80e6d7c3bdc247d66175afedbe104ee2aaca72960d8e", size = 1607446 }, - { url = "https://files.pythonhosted.org/packages/e0/d3/6c98fd87e638e51f074a3f2061e81fcb92123bcaf1439ac1b4a896446e40/aiohttp-3.11.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0a6d3fbf2232e3a08c41eca81ae4f1dff3d8f1a30bae415ebe0af2d2458b8a33", size = 1628809 }, - { url = "https://files.pythonhosted.org/packages/a8/2e/86e6f85cbca02be042c268c3d93e7f35977a0e127de56e319bdd1569eaa8/aiohttp-3.11.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:84a585799c58b795573c7fa9b84c455adf3e1d72f19a2bf498b54a95ae0d194c", size = 1564291 }, - { url = "https://files.pythonhosted.org/packages/0b/8d/1f4ef3503b767717f65e1f5178b0173ab03cba1a19997ebf7b052161189f/aiohttp-3.11.11-cp310-cp310-win32.whl", hash = "sha256:bfde76a8f430cf5c5584553adf9926534352251d379dcb266ad2b93c54a29745", size = 416601 }, - { url = "https://files.pythonhosted.org/packages/ad/86/81cb83691b5ace3d9aa148dc42bacc3450d749fc88c5ec1973573c1c1779/aiohttp-3.11.11-cp310-cp310-win_amd64.whl", hash = "sha256:0fd82b8e9c383af11d2b26f27a478640b6b83d669440c0a71481f7c865a51da9", size = 442007 }, - { url = "https://files.pythonhosted.org/packages/34/ae/e8806a9f054e15f1d18b04db75c23ec38ec954a10c0a68d3bd275d7e8be3/aiohttp-3.11.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ba74ec819177af1ef7f59063c6d35a214a8fde6f987f7661f4f0eecc468a8f76", size = 708624 }, - { url = "https://files.pythonhosted.org/packages/c7/e0/313ef1a333fb4d58d0c55a6acb3cd772f5d7756604b455181049e222c020/aiohttp-3.11.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4af57160800b7a815f3fe0eba9b46bf28aafc195555f1824555fa2cfab6c1538", size = 468507 }, - { url = "https://files.pythonhosted.org/packages/a9/60/03455476bf1f467e5b4a32a465c450548b2ce724eec39d69f737191f936a/aiohttp-3.11.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ffa336210cf9cd8ed117011085817d00abe4c08f99968deef0013ea283547204", size = 455571 }, - { url = "https://files.pythonhosted.org/packages/be/f9/469588603bd75bf02c8ffb8c8a0d4b217eed446b49d4a767684685aa33fd/aiohttp-3.11.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81b8fe282183e4a3c7a1b72f5ade1094ed1c6345a8f153506d114af5bf8accd9", size = 1685694 }, - { url = "https://files.pythonhosted.org/packages/88/b9/1b7fa43faf6c8616fa94c568dc1309ffee2b6b68b04ac268e5d64b738688/aiohttp-3.11.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3af41686ccec6a0f2bdc66686dc0f403c41ac2089f80e2214a0f82d001052c03", size = 1743660 }, - { url = "https://files.pythonhosted.org/packages/2a/8b/0248d19dbb16b67222e75f6aecedd014656225733157e5afaf6a6a07e2e8/aiohttp-3.11.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70d1f9dde0e5dd9e292a6d4d00058737052b01f3532f69c0c65818dac26dc287", size = 1785421 }, - { url = "https://files.pythonhosted.org/packages/c4/11/f478e071815a46ca0a5ae974651ff0c7a35898c55063305a896e58aa1247/aiohttp-3.11.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:249cc6912405917344192b9f9ea5cd5b139d49e0d2f5c7f70bdfaf6b4dbf3a2e", size = 1675145 }, - { url = "https://files.pythonhosted.org/packages/26/5d/284d182fecbb5075ae10153ff7374f57314c93a8681666600e3a9e09c505/aiohttp-3.11.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0eb98d90b6690827dcc84c246811feeb4e1eea683c0eac6caed7549be9c84665", size = 1619804 }, - { url = "https://files.pythonhosted.org/packages/1b/78/980064c2ad685c64ce0e8aeeb7ef1e53f43c5b005edcd7d32e60809c4992/aiohttp-3.11.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec82bf1fda6cecce7f7b915f9196601a1bd1a3079796b76d16ae4cce6d0ef89b", size = 1654007 }, - { url = "https://files.pythonhosted.org/packages/21/8d/9e658d63b1438ad42b96f94da227f2e2c1d5c6001c9e8ffcc0bfb22e9105/aiohttp-3.11.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9fd46ce0845cfe28f108888b3ab17abff84ff695e01e73657eec3f96d72eef34", size = 1650022 }, - { url = "https://files.pythonhosted.org/packages/85/fd/a032bf7f2755c2df4f87f9effa34ccc1ef5cea465377dbaeef93bb56bbd6/aiohttp-3.11.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:bd176afcf8f5d2aed50c3647d4925d0db0579d96f75a31e77cbaf67d8a87742d", size = 1732899 }, - { url = "https://files.pythonhosted.org/packages/c5/0c/c2b85fde167dd440c7ba50af2aac20b5a5666392b174df54c00f888c5a75/aiohttp-3.11.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ec2aa89305006fba9ffb98970db6c8221541be7bee4c1d027421d6f6df7d1ce2", size = 1755142 }, - { url = "https://files.pythonhosted.org/packages/bc/78/91ae1a3b3b3bed8b893c5d69c07023e151b1c95d79544ad04cf68f596c2f/aiohttp-3.11.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:92cde43018a2e17d48bb09c79e4d4cb0e236de5063ce897a5e40ac7cb4878773", size = 1692736 }, - { url = "https://files.pythonhosted.org/packages/77/89/a7ef9c4b4cdb546fcc650ca7f7395aaffbd267f0e1f648a436bec33c9b95/aiohttp-3.11.11-cp311-cp311-win32.whl", hash = "sha256:aba807f9569455cba566882c8938f1a549f205ee43c27b126e5450dc9f83cc62", size = 416418 }, - { url = "https://files.pythonhosted.org/packages/fc/db/2192489a8a51b52e06627506f8ac8df69ee221de88ab9bdea77aa793aa6a/aiohttp-3.11.11-cp311-cp311-win_amd64.whl", hash = "sha256:ae545f31489548c87b0cced5755cfe5a5308d00407000e72c4fa30b19c3220ac", size = 442509 }, - { url = "https://files.pythonhosted.org/packages/69/cf/4bda538c502f9738d6b95ada11603c05ec260807246e15e869fc3ec5de97/aiohttp-3.11.11-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e595c591a48bbc295ebf47cb91aebf9bd32f3ff76749ecf282ea7f9f6bb73886", size = 704666 }, - { url = "https://files.pythonhosted.org/packages/46/7b/87fcef2cad2fad420ca77bef981e815df6904047d0a1bd6aeded1b0d1d66/aiohttp-3.11.11-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3ea1b59dc06396b0b424740a10a0a63974c725b1c64736ff788a3689d36c02d2", size = 464057 }, - { url = "https://files.pythonhosted.org/packages/5a/a6/789e1f17a1b6f4a38939fbc39d29e1d960d5f89f73d0629a939410171bc0/aiohttp-3.11.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8811f3f098a78ffa16e0ea36dffd577eb031aea797cbdba81be039a4169e242c", size = 455996 }, - { url = "https://files.pythonhosted.org/packages/b7/dd/485061fbfef33165ce7320db36e530cd7116ee1098e9c3774d15a732b3fd/aiohttp-3.11.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7227b87a355ce1f4bf83bfae4399b1f5bb42e0259cb9405824bd03d2f4336a", size = 1682367 }, - { url = "https://files.pythonhosted.org/packages/e9/d7/9ec5b3ea9ae215c311d88b2093e8da17e67b8856673e4166c994e117ee3e/aiohttp-3.11.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d40f9da8cabbf295d3a9dae1295c69975b86d941bc20f0a087f0477fa0a66231", size = 1736989 }, - { url = "https://files.pythonhosted.org/packages/d6/fb/ea94927f7bfe1d86178c9d3e0a8c54f651a0a655214cce930b3c679b8f64/aiohttp-3.11.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffb3dc385f6bb1568aa974fe65da84723210e5d9707e360e9ecb51f59406cd2e", size = 1793265 }, - { url = "https://files.pythonhosted.org/packages/40/7f/6de218084f9b653026bd7063cd8045123a7ba90c25176465f266976d8c82/aiohttp-3.11.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8f5f7515f3552d899c61202d99dcb17d6e3b0de777900405611cd747cecd1b8", size = 1691841 }, - { url = "https://files.pythonhosted.org/packages/77/e2/992f43d87831cbddb6b09c57ab55499332f60ad6fdbf438ff4419c2925fc/aiohttp-3.11.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3499c7ffbfd9c6a3d8d6a2b01c26639da7e43d47c7b4f788016226b1e711caa8", size = 1619317 }, - { url = "https://files.pythonhosted.org/packages/96/74/879b23cdd816db4133325a201287c95bef4ce669acde37f8f1b8669e1755/aiohttp-3.11.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8e2bf8029dbf0810c7bfbc3e594b51c4cc9101fbffb583a3923aea184724203c", size = 1641416 }, - { url = "https://files.pythonhosted.org/packages/30/98/b123f6b15d87c54e58fd7ae3558ff594f898d7f30a90899718f3215ad328/aiohttp-3.11.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b6212a60e5c482ef90f2d788835387070a88d52cf6241d3916733c9176d39eab", size = 1646514 }, - { url = "https://files.pythonhosted.org/packages/d7/38/257fda3dc99d6978ab943141d5165ec74fd4b4164baa15e9c66fa21da86b/aiohttp-3.11.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d119fafe7b634dbfa25a8c597718e69a930e4847f0b88e172744be24515140da", size = 1702095 }, - { url = "https://files.pythonhosted.org/packages/0c/f4/ddab089053f9fb96654df5505c0a69bde093214b3c3454f6bfdb1845f558/aiohttp-3.11.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:6fba278063559acc730abf49845d0e9a9e1ba74f85f0ee6efd5803f08b285853", size = 1734611 }, - { url = "https://files.pythonhosted.org/packages/c3/d6/f30b2bc520c38c8aa4657ed953186e535ae84abe55c08d0f70acd72ff577/aiohttp-3.11.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:92fc484e34b733704ad77210c7957679c5c3877bd1e6b6d74b185e9320cc716e", size = 1694576 }, - { url = "https://files.pythonhosted.org/packages/bc/97/b0a88c3f4c6d0020b34045ee6d954058abc870814f6e310c4c9b74254116/aiohttp-3.11.11-cp312-cp312-win32.whl", hash = "sha256:9f5b3c1ed63c8fa937a920b6c1bec78b74ee09593b3f5b979ab2ae5ef60d7600", size = 411363 }, - { url = "https://files.pythonhosted.org/packages/7f/23/cc36d9c398980acaeeb443100f0216f50a7cfe20c67a9fd0a2f1a5a846de/aiohttp-3.11.11-cp312-cp312-win_amd64.whl", hash = "sha256:1e69966ea6ef0c14ee53ef7a3d68b564cc408121ea56c0caa2dc918c1b2f553d", size = 437666 }, - { url = "https://files.pythonhosted.org/packages/49/d1/d8af164f400bad432b63e1ac857d74a09311a8334b0481f2f64b158b50eb/aiohttp-3.11.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:541d823548ab69d13d23730a06f97460f4238ad2e5ed966aaf850d7c369782d9", size = 697982 }, - { url = "https://files.pythonhosted.org/packages/92/d1/faad3bf9fa4bfd26b95c69fc2e98937d52b1ff44f7e28131855a98d23a17/aiohttp-3.11.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:929f3ed33743a49ab127c58c3e0a827de0664bfcda566108989a14068f820194", size = 460662 }, - { url = "https://files.pythonhosted.org/packages/db/61/0d71cc66d63909dabc4590f74eba71f91873a77ea52424401c2498d47536/aiohttp-3.11.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0882c2820fd0132240edbb4a51eb8ceb6eef8181db9ad5291ab3332e0d71df5f", size = 452950 }, - { url = "https://files.pythonhosted.org/packages/07/db/6d04bc7fd92784900704e16b745484ef45b77bd04e25f58f6febaadf7983/aiohttp-3.11.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b63de12e44935d5aca7ed7ed98a255a11e5cb47f83a9fded7a5e41c40277d104", size = 1665178 }, - { url = "https://files.pythonhosted.org/packages/54/5c/e95ade9ae29f375411884d9fd98e50535bf9fe316c9feb0f30cd2ac8f508/aiohttp-3.11.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa54f8ef31d23c506910c21163f22b124facb573bff73930735cf9fe38bf7dff", size = 1717939 }, - { url = "https://files.pythonhosted.org/packages/6f/1c/1e7d5c5daea9e409ed70f7986001b8c9e3a49a50b28404498d30860edab6/aiohttp-3.11.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a344d5dc18074e3872777b62f5f7d584ae4344cd6006c17ba12103759d407af3", size = 1775125 }, - { url = "https://files.pythonhosted.org/packages/5d/66/890987e44f7d2f33a130e37e01a164168e6aff06fce15217b6eaf14df4f6/aiohttp-3.11.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b7fb429ab1aafa1f48578eb315ca45bd46e9c37de11fe45c7f5f4138091e2f1", size = 1677176 }, - { url = "https://files.pythonhosted.org/packages/8f/dc/e2ba57d7a52df6cdf1072fd5fa9c6301a68e1cd67415f189805d3eeb031d/aiohttp-3.11.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c341c7d868750e31961d6d8e60ff040fb9d3d3a46d77fd85e1ab8e76c3e9a5c4", size = 1603192 }, - { url = "https://files.pythonhosted.org/packages/6c/9e/8d08a57de79ca3a358da449405555e668f2c8871a7777ecd2f0e3912c272/aiohttp-3.11.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ed9ee95614a71e87f1a70bc81603f6c6760128b140bc4030abe6abaa988f1c3d", size = 1618296 }, - { url = "https://files.pythonhosted.org/packages/56/51/89822e3ec72db352c32e7fc1c690370e24e231837d9abd056490f3a49886/aiohttp-3.11.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:de8d38f1c2810fa2a4f1d995a2e9c70bb8737b18da04ac2afbf3971f65781d87", size = 1616524 }, - { url = "https://files.pythonhosted.org/packages/2c/fa/e2e6d9398f462ffaa095e84717c1732916a57f1814502929ed67dd7568ef/aiohttp-3.11.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a9b7371665d4f00deb8f32208c7c5e652059b0fda41cf6dbcac6114a041f1cc2", size = 1685471 }, - { url = "https://files.pythonhosted.org/packages/ae/5f/6bb976e619ca28a052e2c0ca7b0251ccd893f93d7c24a96abea38e332bf6/aiohttp-3.11.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:620598717fce1b3bd14dd09947ea53e1ad510317c85dda2c9c65b622edc96b12", size = 1715312 }, - { url = "https://files.pythonhosted.org/packages/79/c1/756a7e65aa087c7fac724d6c4c038f2faaa2a42fe56dbc1dd62a33ca7213/aiohttp-3.11.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bf8d9bfee991d8acc72d060d53860f356e07a50f0e0d09a8dfedea1c554dd0d5", size = 1672783 }, - { url = "https://files.pythonhosted.org/packages/73/ba/a6190ebb02176c7f75e6308da31f5d49f6477b651a3dcfaaaca865a298e2/aiohttp-3.11.11-cp313-cp313-win32.whl", hash = "sha256:9d73ee3725b7a737ad86c2eac5c57a4a97793d9f442599bea5ec67ac9f4bdc3d", size = 410229 }, - { url = "https://files.pythonhosted.org/packages/b8/62/c9fa5bafe03186a0e4699150a7fed9b1e73240996d0d2f0e5f70f3fdf471/aiohttp-3.11.11-cp313-cp313-win_amd64.whl", hash = "sha256:c7a06301c2fb096bdb0bd25fe2011531c1453b9f2c163c8031600ec73af1cc99", size = 436081 }, +sdist = { url = "https://files.pythonhosted.org/packages/37/4b/952d49c73084fb790cb5c6ead50848c8e96b4980ad806cf4d2ad341eaa03/aiohttp-3.11.12.tar.gz", hash = "sha256:7603ca26d75b1b86160ce1bbe2787a0b706e592af5b2504e12caa88a217767b0", size = 7673175 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/65/42/3880e133590820aa7bc6d068eb7d8e0ad9fdce9b4663f92b821d3f6b5601/aiohttp-3.11.12-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:aa8a8caca81c0a3e765f19c6953416c58e2f4cc1b84829af01dd1c771bb2f91f", size = 708721 }, + { url = "https://files.pythonhosted.org/packages/d8/8c/04869803bed108b25afad75f94c651b287851843caacbec6677d8f2d572b/aiohttp-3.11.12-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:84ede78acde96ca57f6cf8ccb8a13fbaf569f6011b9a52f870c662d4dc8cd854", size = 468596 }, + { url = "https://files.pythonhosted.org/packages/4f/f4/9074011f0d1335b161c953fb32545b6667cf24465e1932b9767874995c7e/aiohttp-3.11.12-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:584096938a001378484aa4ee54e05dc79c7b9dd933e271c744a97b3b6f644957", size = 455758 }, + { url = "https://files.pythonhosted.org/packages/fd/68/06298c57ef8f534065930b805e6dbd83613f0534447922782fb9920fce28/aiohttp-3.11.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:392432a2dde22b86f70dd4a0e9671a349446c93965f261dbaecfaf28813e5c42", size = 1584797 }, + { url = "https://files.pythonhosted.org/packages/bd/1e/cee6b51fcb3b1c4185a7dc62b3113bc136fae07f39386c88c90b7f79f199/aiohttp-3.11.12-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:88d385b8e7f3a870146bf5ea31786ef7463e99eb59e31db56e2315535d811f55", size = 1632535 }, + { url = "https://files.pythonhosted.org/packages/71/1f/42424462b7a09da362e1711090db9f8d68a37a33f0aab51307335517c599/aiohttp-3.11.12-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b10a47e5390c4b30a0d58ee12581003be52eedd506862ab7f97da7a66805befb", size = 1668484 }, + { url = "https://files.pythonhosted.org/packages/f6/79/0e25542bbe3c2bfd7a12c7a49c7bce73b09a836f65079e4b77bc2bafc89e/aiohttp-3.11.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b5263dcede17b6b0c41ef0c3ccce847d82a7da98709e75cf7efde3e9e3b5cae", size = 1589708 }, + { url = "https://files.pythonhosted.org/packages/d1/13/93ae26b75e23f7d3a613872e472fae836ca100dc5bde5936ebc93ada8890/aiohttp-3.11.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50c5c7b8aa5443304c55c262c5693b108c35a3b61ef961f1e782dd52a2f559c7", size = 1544752 }, + { url = "https://files.pythonhosted.org/packages/cf/5e/48847fad1b014ef92ef18ea1339a3b58eb81d3bc717b94c3627f5d2a42c5/aiohttp-3.11.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d1c031a7572f62f66f1257db37ddab4cb98bfaf9b9434a3b4840bf3560f5e788", size = 1529417 }, + { url = "https://files.pythonhosted.org/packages/ae/56/fbd4ea019303f4877f0e0b8c9de92e9db24338e7545570d3f275f3c74c53/aiohttp-3.11.12-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:7e44eba534381dd2687be50cbd5f2daded21575242ecfdaf86bbeecbc38dae8e", size = 1557808 }, + { url = "https://files.pythonhosted.org/packages/f1/43/112189cf6b3c482ecdd6819b420eaa0c2033426f28d741bb7f19db5dd2bb/aiohttp-3.11.12-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:145a73850926018ec1681e734cedcf2716d6a8697d90da11284043b745c286d5", size = 1536765 }, + { url = "https://files.pythonhosted.org/packages/30/12/59986547de8306e06c7b30e547ccda02d29636e152366caba2dd8627bfe1/aiohttp-3.11.12-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:2c311e2f63e42c1bf86361d11e2c4a59f25d9e7aabdbdf53dc38b885c5435cdb", size = 1607621 }, + { url = "https://files.pythonhosted.org/packages/aa/9b/af3b323b20df3318ed20d701d8242e523d59c842ca93f23134b05c9d5054/aiohttp-3.11.12-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ea756b5a7bac046d202a9a3889b9a92219f885481d78cd318db85b15cc0b7bcf", size = 1628977 }, + { url = "https://files.pythonhosted.org/packages/36/62/adf5a331a7bda475cc326dde393fa2bc5849060b1b37ac3d1bee1953f2cd/aiohttp-3.11.12-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:526c900397f3bbc2db9cb360ce9c35134c908961cdd0ac25b1ae6ffcaa2507ff", size = 1564455 }, + { url = "https://files.pythonhosted.org/packages/90/c4/4a24291f22f111a854dfdb54dc94d4e0a5229ccbb7bc7f0bed972aa50410/aiohttp-3.11.12-cp310-cp310-win32.whl", hash = "sha256:b8d3bb96c147b39c02d3db086899679f31958c5d81c494ef0fc9ef5bb1359b3d", size = 416768 }, + { url = "https://files.pythonhosted.org/packages/51/69/5221c8006acb7bb10d9e8e2238fb216571bddc2e00a8d95bcfbe2f579c57/aiohttp-3.11.12-cp310-cp310-win_amd64.whl", hash = "sha256:7fe3d65279bfbee8de0fb4f8c17fc4e893eed2dba21b2f680e930cc2b09075c5", size = 442170 }, + { url = "https://files.pythonhosted.org/packages/9c/38/35311e70196b6a63cfa033a7f741f800aa8a93f57442991cbe51da2394e7/aiohttp-3.11.12-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:87a2e00bf17da098d90d4145375f1d985a81605267e7f9377ff94e55c5d769eb", size = 708797 }, + { url = "https://files.pythonhosted.org/packages/44/3e/46c656e68cbfc4f3fc7cb5d2ba4da6e91607fe83428208028156688f6201/aiohttp-3.11.12-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b34508f1cd928ce915ed09682d11307ba4b37d0708d1f28e5774c07a7674cac9", size = 468669 }, + { url = "https://files.pythonhosted.org/packages/a0/d6/2088fb4fd1e3ac2bfb24bc172223babaa7cdbb2784d33c75ec09e66f62f8/aiohttp-3.11.12-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:936d8a4f0f7081327014742cd51d320296b56aa6d324461a13724ab05f4b2933", size = 455739 }, + { url = "https://files.pythonhosted.org/packages/e7/dc/c443a6954a56f4a58b5efbfdf23cc6f3f0235e3424faf5a0c56264d5c7bb/aiohttp-3.11.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2de1378f72def7dfb5dbd73d86c19eda0ea7b0a6873910cc37d57e80f10d64e1", size = 1685858 }, + { url = "https://files.pythonhosted.org/packages/25/67/2d5b3aaade1d5d01c3b109aa76e3aa9630531252cda10aa02fb99b0b11a1/aiohttp-3.11.12-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b9d45dbb3aaec05cf01525ee1a7ac72de46a8c425cb75c003acd29f76b1ffe94", size = 1743829 }, + { url = "https://files.pythonhosted.org/packages/90/9b/9728fe9a3e1b8521198455d027b0b4035522be18f504b24c5d38d59e7278/aiohttp-3.11.12-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:930ffa1925393381e1e0a9b82137fa7b34c92a019b521cf9f41263976666a0d6", size = 1785587 }, + { url = "https://files.pythonhosted.org/packages/ce/cf/28fbb43d4ebc1b4458374a3c7b6db3b556a90e358e9bbcfe6d9339c1e2b6/aiohttp-3.11.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8340def6737118f5429a5df4e88f440746b791f8f1c4ce4ad8a595f42c980bd5", size = 1675319 }, + { url = "https://files.pythonhosted.org/packages/e5/d2/006c459c11218cabaa7bca401f965c9cc828efbdea7e1615d4644eaf23f7/aiohttp-3.11.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4016e383f91f2814e48ed61e6bda7d24c4d7f2402c75dd28f7e1027ae44ea204", size = 1619982 }, + { url = "https://files.pythonhosted.org/packages/9d/83/ca425891ebd37bee5d837110f7fddc4d808a7c6c126a7d1b5c3ad72fc6ba/aiohttp-3.11.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3c0600bcc1adfaaac321422d615939ef300df81e165f6522ad096b73439c0f58", size = 1654176 }, + { url = "https://files.pythonhosted.org/packages/25/df/047b1ce88514a1b4915d252513640184b63624e7914e41d846668b8edbda/aiohttp-3.11.12-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:0450ada317a65383b7cce9576096150fdb97396dcfe559109b403c7242faffef", size = 1660198 }, + { url = "https://files.pythonhosted.org/packages/d3/cc/6ecb8e343f0902528620b9dbd567028a936d5489bebd7dbb0dd0914f4fdb/aiohttp-3.11.12-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:850ff6155371fd802a280f8d369d4e15d69434651b844bde566ce97ee2277420", size = 1650186 }, + { url = "https://files.pythonhosted.org/packages/f8/f8/453df6dd69256ca8c06c53fc8803c9056e2b0b16509b070f9a3b4bdefd6c/aiohttp-3.11.12-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:8fd12d0f989c6099e7b0f30dc6e0d1e05499f3337461f0b2b0dadea6c64b89df", size = 1733063 }, + { url = "https://files.pythonhosted.org/packages/55/f8/540160787ff3000391de0e5d0d1d33be4c7972f933c21991e2ea105b2d5e/aiohttp-3.11.12-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:76719dd521c20a58a6c256d058547b3a9595d1d885b830013366e27011ffe804", size = 1755306 }, + { url = "https://files.pythonhosted.org/packages/30/7d/49f3bfdfefd741576157f8f91caa9ff61a6f3d620ca6339268327518221b/aiohttp-3.11.12-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:97fe431f2ed646a3b56142fc81d238abcbaff08548d6912acb0b19a0cadc146b", size = 1692909 }, + { url = "https://files.pythonhosted.org/packages/40/9c/8ce00afd6f6112ce9a2309dc490fea376ae824708b94b7b5ea9cba979d1d/aiohttp-3.11.12-cp311-cp311-win32.whl", hash = "sha256:e10c440d142fa8b32cfdb194caf60ceeceb3e49807072e0dc3a8887ea80e8c16", size = 416584 }, + { url = "https://files.pythonhosted.org/packages/35/97/4d3c5f562f15830de472eb10a7a222655d750839943e0e6d915ef7e26114/aiohttp-3.11.12-cp311-cp311-win_amd64.whl", hash = "sha256:246067ba0cf5560cf42e775069c5d80a8989d14a7ded21af529a4e10e3e0f0e6", size = 442674 }, + { url = "https://files.pythonhosted.org/packages/4d/d0/94346961acb476569fca9a644cc6f9a02f97ef75961a6b8d2b35279b8d1f/aiohttp-3.11.12-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e392804a38353900c3fd8b7cacbea5132888f7129f8e241915e90b85f00e3250", size = 704837 }, + { url = "https://files.pythonhosted.org/packages/a9/af/05c503f1cc8f97621f199ef4b8db65fb88b8bc74a26ab2adb74789507ad3/aiohttp-3.11.12-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8fa1510b96c08aaad49303ab11f8803787c99222288f310a62f493faf883ede1", size = 464218 }, + { url = "https://files.pythonhosted.org/packages/f2/48/b9949eb645b9bd699153a2ec48751b985e352ab3fed9d98c8115de305508/aiohttp-3.11.12-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dc065a4285307607df3f3686363e7f8bdd0d8ab35f12226362a847731516e42c", size = 456166 }, + { url = "https://files.pythonhosted.org/packages/14/fb/980981807baecb6f54bdd38beb1bd271d9a3a786e19a978871584d026dcf/aiohttp-3.11.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cddb31f8474695cd61fc9455c644fc1606c164b93bff2490390d90464b4655df", size = 1682528 }, + { url = "https://files.pythonhosted.org/packages/90/cb/77b1445e0a716914e6197b0698b7a3640590da6c692437920c586764d05b/aiohttp-3.11.12-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9dec0000d2d8621d8015c293e24589d46fa218637d820894cb7356c77eca3259", size = 1737154 }, + { url = "https://files.pythonhosted.org/packages/ff/24/d6fb1f4cede9ccbe98e4def6f3ed1e1efcb658871bbf29f4863ec646bf38/aiohttp-3.11.12-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3552fe98e90fdf5918c04769f338a87fa4f00f3b28830ea9b78b1bdc6140e0d", size = 1793435 }, + { url = "https://files.pythonhosted.org/packages/17/e2/9f744cee0861af673dc271a3351f59ebd5415928e20080ab85be25641471/aiohttp-3.11.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dfe7f984f28a8ae94ff3a7953cd9678550dbd2a1f9bda5dd9c5ae627744c78e", size = 1692010 }, + { url = "https://files.pythonhosted.org/packages/90/c4/4a1235c1df544223eb57ba553ce03bc706bdd065e53918767f7fa1ff99e0/aiohttp-3.11.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a481a574af914b6e84624412666cbfbe531a05667ca197804ecc19c97b8ab1b0", size = 1619481 }, + { url = "https://files.pythonhosted.org/packages/60/70/cf12d402a94a33abda86dd136eb749b14c8eb9fec1e16adc310e25b20033/aiohttp-3.11.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1987770fb4887560363b0e1a9b75aa303e447433c41284d3af2840a2f226d6e0", size = 1641578 }, + { url = "https://files.pythonhosted.org/packages/1b/25/7211973fda1f5e833fcfd98ccb7f9ce4fbfc0074e3e70c0157a751d00db8/aiohttp-3.11.12-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:a4ac6a0f0f6402854adca4e3259a623f5c82ec3f0c049374133bcb243132baf9", size = 1684463 }, + { url = "https://files.pythonhosted.org/packages/93/60/b5905b4d0693f6018b26afa9f2221fefc0dcbd3773fe2dff1a20fb5727f1/aiohttp-3.11.12-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c96a43822f1f9f69cc5c3706af33239489a6294be486a0447fb71380070d4d5f", size = 1646691 }, + { url = "https://files.pythonhosted.org/packages/b4/fc/ba1b14d6fdcd38df0b7c04640794b3683e949ea10937c8a58c14d697e93f/aiohttp-3.11.12-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a5e69046f83c0d3cb8f0d5bd9b8838271b1bc898e01562a04398e160953e8eb9", size = 1702269 }, + { url = "https://files.pythonhosted.org/packages/5e/39/18c13c6f658b2ba9cc1e0c6fb2d02f98fd653ad2addcdf938193d51a9c53/aiohttp-3.11.12-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:68d54234c8d76d8ef74744f9f9fc6324f1508129e23da8883771cdbb5818cbef", size = 1734782 }, + { url = "https://files.pythonhosted.org/packages/9f/d2/ccc190023020e342419b265861877cd8ffb75bec37b7ddd8521dd2c6deb8/aiohttp-3.11.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c9fd9dcf9c91affe71654ef77426f5cf8489305e1c66ed4816f5a21874b094b9", size = 1694740 }, + { url = "https://files.pythonhosted.org/packages/3f/54/186805bcada64ea90ea909311ffedcd74369bfc6e880d39d2473314daa36/aiohttp-3.11.12-cp312-cp312-win32.whl", hash = "sha256:0ed49efcd0dc1611378beadbd97beb5d9ca8fe48579fc04a6ed0844072261b6a", size = 411530 }, + { url = "https://files.pythonhosted.org/packages/3d/63/5eca549d34d141bcd9de50d4e59b913f3641559460c739d5e215693cb54a/aiohttp-3.11.12-cp312-cp312-win_amd64.whl", hash = "sha256:54775858c7f2f214476773ce785a19ee81d1294a6bedc5cc17225355aab74802", size = 437860 }, + { url = "https://files.pythonhosted.org/packages/c3/9b/cea185d4b543ae08ee478373e16653722c19fcda10d2d0646f300ce10791/aiohttp-3.11.12-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:413ad794dccb19453e2b97c2375f2ca3cdf34dc50d18cc2693bd5aed7d16f4b9", size = 698148 }, + { url = "https://files.pythonhosted.org/packages/91/5c/80d47fe7749fde584d1404a68ade29bcd7e58db8fa11fa38e8d90d77e447/aiohttp-3.11.12-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4a93d28ed4b4b39e6f46fd240896c29b686b75e39cc6992692e3922ff6982b4c", size = 460831 }, + { url = "https://files.pythonhosted.org/packages/8e/f9/de568f8a8ca6b061d157c50272620c53168d6e3eeddae78dbb0f7db981eb/aiohttp-3.11.12-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d589264dbba3b16e8951b6f145d1e6b883094075283dafcab4cdd564a9e353a0", size = 453122 }, + { url = "https://files.pythonhosted.org/packages/8b/fd/b775970a047543bbc1d0f66725ba72acef788028fce215dc959fd15a8200/aiohttp-3.11.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5148ca8955affdfeb864aca158ecae11030e952b25b3ae15d4e2b5ba299bad2", size = 1665336 }, + { url = "https://files.pythonhosted.org/packages/82/9b/aff01d4f9716245a1b2965f02044e4474fadd2bcfe63cf249ca788541886/aiohttp-3.11.12-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:525410e0790aab036492eeea913858989c4cb070ff373ec3bc322d700bdf47c1", size = 1718111 }, + { url = "https://files.pythonhosted.org/packages/e0/a9/166fd2d8b2cc64f08104aa614fad30eee506b563154081bf88ce729bc665/aiohttp-3.11.12-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bd8695be2c80b665ae3f05cb584093a1e59c35ecb7d794d1edd96e8cc9201d7", size = 1775293 }, + { url = "https://files.pythonhosted.org/packages/13/c5/0d3c89bd9e36288f10dc246f42518ce8e1c333f27636ac78df091c86bb4a/aiohttp-3.11.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0203433121484b32646a5f5ea93ae86f3d9559d7243f07e8c0eab5ff8e3f70e", size = 1677338 }, + { url = "https://files.pythonhosted.org/packages/72/b2/017db2833ef537be284f64ead78725984db8a39276c1a9a07c5c7526e238/aiohttp-3.11.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40cd36749a1035c34ba8d8aaf221b91ca3d111532e5ccb5fa8c3703ab1b967ed", size = 1603365 }, + { url = "https://files.pythonhosted.org/packages/fc/72/b66c96a106ec7e791e29988c222141dd1219d7793ffb01e72245399e08d2/aiohttp-3.11.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a7442662afebbf7b4c6d28cb7aab9e9ce3a5df055fc4116cc7228192ad6cb484", size = 1618464 }, + { url = "https://files.pythonhosted.org/packages/3f/50/e68a40f267b46a603bab569d48d57f23508801614e05b3369898c5b2910a/aiohttp-3.11.12-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:8a2fb742ef378284a50766e985804bd6adb5adb5aa781100b09befdbfa757b65", size = 1657827 }, + { url = "https://files.pythonhosted.org/packages/c5/1d/aafbcdb1773d0ba7c20793ebeedfaba1f3f7462f6fc251f24983ed738aa7/aiohttp-3.11.12-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2cee3b117a8d13ab98b38d5b6bdcd040cfb4181068d05ce0c474ec9db5f3c5bb", size = 1616700 }, + { url = "https://files.pythonhosted.org/packages/b0/5e/6cd9724a2932f36e2a6b742436a36d64784322cfb3406ca773f903bb9a70/aiohttp-3.11.12-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f6a19bcab7fbd8f8649d6595624856635159a6527861b9cdc3447af288a00c00", size = 1685643 }, + { url = "https://files.pythonhosted.org/packages/8b/38/ea6c91d5c767fd45a18151675a07c710ca018b30aa876a9f35b32fa59761/aiohttp-3.11.12-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e4cecdb52aaa9994fbed6b81d4568427b6002f0a91c322697a4bfcc2b2363f5a", size = 1715487 }, + { url = "https://files.pythonhosted.org/packages/8e/24/e9edbcb7d1d93c02e055490348df6f955d675e85a028c33babdcaeda0853/aiohttp-3.11.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:30f546358dfa0953db92ba620101fefc81574f87b2346556b90b5f3ef16e55ce", size = 1672948 }, + { url = "https://files.pythonhosted.org/packages/25/be/0b1fb737268e003198f25c3a68c2135e76e4754bf399a879b27bd508a003/aiohttp-3.11.12-cp313-cp313-win32.whl", hash = "sha256:ce1bb21fc7d753b5f8a5d5a4bae99566386b15e716ebdb410154c16c91494d7f", size = 410396 }, + { url = "https://files.pythonhosted.org/packages/68/fd/677def96a75057b0a26446b62f8fbb084435b20a7d270c99539c26573bfd/aiohttp-3.11.12-cp313-cp313-win_amd64.whl", hash = "sha256:f7914ab70d2ee8ab91c13e5402122edbc77821c66d2758abb53aabe87f013287", size = 436234 }, ] [[package]] @@ -376,14 +380,15 @@ wheels = [ [[package]] name = "beautifulsoup4" -version = "4.12.3" +version = "4.13.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "soupsieve", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b3/ca/824b1195773ce6166d388573fc106ce56d4a805bd7427b624e063596ec58/beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", size = 581181 } +sdist = { url = "https://files.pythonhosted.org/packages/f0/3c/adaf39ce1fb4afdd21b611e3d530b183bb7759c9b673d60db0e347fd4439/beautifulsoup4-4.13.3.tar.gz", hash = "sha256:1bd32405dacc920b42b83ba01644747ed77456a65760e285fbc47633ceddaf8b", size = 619516 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", size = 147925 }, + { url = "https://files.pythonhosted.org/packages/f9/49/6abb616eb3cbab6a7cca303dc02fdf3836de2e0b834bf966a7f5271a34d8/beautifulsoup4-4.13.3-py3-none-any.whl", hash = "sha256:99045d7d3f08f91f0d656bc9b7efbae189426cd913d830294a15eefa0ea4df16", size = 186015 }, ] [[package]] @@ -414,30 +419,30 @@ wheels = [ [[package]] name = "boto3" -version = "1.36.10" +version = "1.36.16" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "jmespath", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "s3transfer", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/16/af/e41306c8fe705f19436b5339b23edcc6c4388b548c79fdd21cc120f61899/boto3-1.36.10.tar.gz", hash = "sha256:d2f1010db699326b26fbd465d91c4b49177c9d995d7e72c0f31335f139efa0d2", size = 111006 } +sdist = { url = "https://files.pythonhosted.org/packages/8c/bd/46dea249b6fab89f30a341683844d7b176ce0c439b90c59818bd6407b505/boto3-1.36.16.tar.gz", hash = "sha256:0cf92ca0538ab115447e1c58050d43e1273e88c58ddfea2b6f133fdc508b400a", size = 110986 } wheels = [ - { url = "https://files.pythonhosted.org/packages/34/3b/7a169cf550531dd89aa702a38313185af30aef685f058cf6f56e840d2eb4/boto3-1.36.10-py3-none-any.whl", hash = "sha256:5f8d5c2024a2d1411d3d67abb7357ec7d4c6162e3f1c396dc9b79d042cfd0a80", size = 139177 }, + { url = "https://files.pythonhosted.org/packages/af/29/7018c7a7106f3dbb6a43d21db68f854259c117551876702ffeac9e8a01c9/boto3-1.36.16-py3-none-any.whl", hash = "sha256:b10583bf8bd35be1b4027ee7e26b7cdf2078c79eab18357fd602cecb6d39400b", size = 139178 }, ] [[package]] name = "botocore" -version = "1.36.10" +version = "1.36.16" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "python-dateutil", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "urllib3", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/05/da/8d21e15a1366a076c54529059c45c66943c217f1eadea5eb36791274d8d0/botocore-1.36.10.tar.gz", hash = "sha256:d27bb73f0ea81395527a6298ac0a7ea5b2958094169f7cf7d48e3f4e4bc21b65", size = 13495786 } +sdist = { url = "https://files.pythonhosted.org/packages/d2/98/a32b62a6dabc91611343e8fcf6634c97d3711c5d4be090f4388efff35e2a/botocore-1.36.16.tar.gz", hash = "sha256:10c6aa386ba1a9a0faef6bb5dbfc58fc2563a3c6b95352e86a583cd5f14b11f3", size = 13511801 } wheels = [ - { url = "https://files.pythonhosted.org/packages/f6/84/b038ec69154135a46267d96eb6ddbebe8e6775f18e1e827700b3e30f4170/botocore-1.36.10-py3-none-any.whl", hash = "sha256:45c8a6e01dc18d44a13ba688f1d60ad562db8154b08c46b412387ea040a741c2", size = 13325134 }, + { url = "https://files.pythonhosted.org/packages/31/17/1776cdd6dbeaa9910f005cc8bda6c436518ba83be94a438f7b9848d49d6b/botocore-1.36.16-py3-none-any.whl", hash = "sha256:aca0348ccd730332082489b6817fdf89e1526049adcf6e9c8c11c96dd9f42c03", size = 13340384 }, ] [[package]] @@ -467,11 +472,11 @@ wheels = [ [[package]] name = "certifi" -version = "2024.12.14" +version = "2025.1.31" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0f/bd/1d41ee578ce09523c81a15426705dd20969f5abf006d1afe8aeff0dd776a/certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db", size = 166010 } +sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", size = 164927 }, + { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393 }, ] [[package]] @@ -742,61 +747,58 @@ wheels = [ [[package]] name = "coverage" -version = "7.6.10" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/84/ba/ac14d281f80aab516275012e8875991bb06203957aa1e19950139238d658/coverage-7.6.10.tar.gz", hash = "sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23", size = 803868 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c5/12/2a2a923edf4ddabdffed7ad6da50d96a5c126dae7b80a33df7310e329a1e/coverage-7.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78", size = 207982 }, - { url = "https://files.pythonhosted.org/packages/ca/49/6985dbca9c7be3f3cb62a2e6e492a0c88b65bf40579e16c71ae9c33c6b23/coverage-7.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c", size = 208414 }, - { url = "https://files.pythonhosted.org/packages/35/93/287e8f1d1ed2646f4e0b2605d14616c9a8a2697d0d1b453815eb5c6cebdb/coverage-7.6.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a", size = 236860 }, - { url = "https://files.pythonhosted.org/packages/de/e1/cfdb5627a03567a10031acc629b75d45a4ca1616e54f7133ca1fa366050a/coverage-7.6.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165", size = 234758 }, - { url = "https://files.pythonhosted.org/packages/6d/85/fc0de2bcda3f97c2ee9fe8568f7d48f7279e91068958e5b2cc19e0e5f600/coverage-7.6.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988", size = 235920 }, - { url = "https://files.pythonhosted.org/packages/79/73/ef4ea0105531506a6f4cf4ba571a214b14a884630b567ed65b3d9c1975e1/coverage-7.6.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5", size = 234986 }, - { url = "https://files.pythonhosted.org/packages/c6/4d/75afcfe4432e2ad0405c6f27adeb109ff8976c5e636af8604f94f29fa3fc/coverage-7.6.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3", size = 233446 }, - { url = "https://files.pythonhosted.org/packages/86/5b/efee56a89c16171288cafff022e8af44f8f94075c2d8da563c3935212871/coverage-7.6.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5", size = 234566 }, - { url = "https://files.pythonhosted.org/packages/f2/db/67770cceb4a64d3198bf2aa49946f411b85ec6b0a9b489e61c8467a4253b/coverage-7.6.10-cp310-cp310-win32.whl", hash = "sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244", size = 210675 }, - { url = "https://files.pythonhosted.org/packages/8d/27/e8bfc43f5345ec2c27bc8a1fa77cdc5ce9dcf954445e11f14bb70b889d14/coverage-7.6.10-cp310-cp310-win_amd64.whl", hash = "sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e", size = 211518 }, - { url = "https://files.pythonhosted.org/packages/85/d2/5e175fcf6766cf7501a8541d81778fd2f52f4870100e791f5327fd23270b/coverage-7.6.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3", size = 208088 }, - { url = "https://files.pythonhosted.org/packages/4b/6f/06db4dc8fca33c13b673986e20e466fd936235a6ec1f0045c3853ac1b593/coverage-7.6.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43", size = 208536 }, - { url = "https://files.pythonhosted.org/packages/0d/62/c6a0cf80318c1c1af376d52df444da3608eafc913b82c84a4600d8349472/coverage-7.6.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132", size = 240474 }, - { url = "https://files.pythonhosted.org/packages/a3/59/750adafc2e57786d2e8739a46b680d4fb0fbc2d57fbcb161290a9f1ecf23/coverage-7.6.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f", size = 237880 }, - { url = "https://files.pythonhosted.org/packages/2c/f8/ef009b3b98e9f7033c19deb40d629354aab1d8b2d7f9cfec284dbedf5096/coverage-7.6.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994", size = 239750 }, - { url = "https://files.pythonhosted.org/packages/a6/e2/6622f3b70f5f5b59f705e680dae6db64421af05a5d1e389afd24dae62e5b/coverage-7.6.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99", size = 238642 }, - { url = "https://files.pythonhosted.org/packages/2d/10/57ac3f191a3c95c67844099514ff44e6e19b2915cd1c22269fb27f9b17b6/coverage-7.6.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd", size = 237266 }, - { url = "https://files.pythonhosted.org/packages/ee/2d/7016f4ad9d553cabcb7333ed78ff9d27248ec4eba8dd21fa488254dff894/coverage-7.6.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377", size = 238045 }, - { url = "https://files.pythonhosted.org/packages/a7/fe/45af5c82389a71e0cae4546413266d2195c3744849669b0bab4b5f2c75da/coverage-7.6.10-cp311-cp311-win32.whl", hash = "sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8", size = 210647 }, - { url = "https://files.pythonhosted.org/packages/db/11/3f8e803a43b79bc534c6a506674da9d614e990e37118b4506faf70d46ed6/coverage-7.6.10-cp311-cp311-win_amd64.whl", hash = "sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609", size = 211508 }, - { url = "https://files.pythonhosted.org/packages/86/77/19d09ea06f92fdf0487499283b1b7af06bc422ea94534c8fe3a4cd023641/coverage-7.6.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853", size = 208281 }, - { url = "https://files.pythonhosted.org/packages/b6/67/5479b9f2f99fcfb49c0d5cf61912a5255ef80b6e80a3cddba39c38146cf4/coverage-7.6.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078", size = 208514 }, - { url = "https://files.pythonhosted.org/packages/15/d1/febf59030ce1c83b7331c3546d7317e5120c5966471727aa7ac157729c4b/coverage-7.6.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0", size = 241537 }, - { url = "https://files.pythonhosted.org/packages/4b/7e/5ac4c90192130e7cf8b63153fe620c8bfd9068f89a6d9b5f26f1550f7a26/coverage-7.6.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50", size = 238572 }, - { url = "https://files.pythonhosted.org/packages/dc/03/0334a79b26ecf59958f2fe9dd1f5ab3e2f88db876f5071933de39af09647/coverage-7.6.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022", size = 240639 }, - { url = "https://files.pythonhosted.org/packages/d7/45/8a707f23c202208d7b286d78ad6233f50dcf929319b664b6cc18a03c1aae/coverage-7.6.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b", size = 240072 }, - { url = "https://files.pythonhosted.org/packages/66/02/603ce0ac2d02bc7b393279ef618940b4a0535b0868ee791140bda9ecfa40/coverage-7.6.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0", size = 238386 }, - { url = "https://files.pythonhosted.org/packages/04/62/4e6887e9be060f5d18f1dd58c2838b2d9646faf353232dec4e2d4b1c8644/coverage-7.6.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852", size = 240054 }, - { url = "https://files.pythonhosted.org/packages/5c/74/83ae4151c170d8bd071924f212add22a0e62a7fe2b149edf016aeecad17c/coverage-7.6.10-cp312-cp312-win32.whl", hash = "sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359", size = 210904 }, - { url = "https://files.pythonhosted.org/packages/c3/54/de0893186a221478f5880283119fc40483bc460b27c4c71d1b8bba3474b9/coverage-7.6.10-cp312-cp312-win_amd64.whl", hash = "sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247", size = 211692 }, - { url = "https://files.pythonhosted.org/packages/25/6d/31883d78865529257bf847df5789e2ae80e99de8a460c3453dbfbe0db069/coverage-7.6.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9", size = 208308 }, - { url = "https://files.pythonhosted.org/packages/70/22/3f2b129cc08de00c83b0ad6252e034320946abfc3e4235c009e57cfeee05/coverage-7.6.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b", size = 208565 }, - { url = "https://files.pythonhosted.org/packages/97/0a/d89bc2d1cc61d3a8dfe9e9d75217b2be85f6c73ebf1b9e3c2f4e797f4531/coverage-7.6.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690", size = 241083 }, - { url = "https://files.pythonhosted.org/packages/4c/81/6d64b88a00c7a7aaed3a657b8eaa0931f37a6395fcef61e53ff742b49c97/coverage-7.6.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18", size = 238235 }, - { url = "https://files.pythonhosted.org/packages/9a/0b/7797d4193f5adb4b837207ed87fecf5fc38f7cc612b369a8e8e12d9fa114/coverage-7.6.10-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c", size = 240220 }, - { url = "https://files.pythonhosted.org/packages/65/4d/6f83ca1bddcf8e51bf8ff71572f39a1c73c34cf50e752a952c34f24d0a60/coverage-7.6.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd", size = 239847 }, - { url = "https://files.pythonhosted.org/packages/30/9d/2470df6aa146aff4c65fee0f87f58d2164a67533c771c9cc12ffcdb865d5/coverage-7.6.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e", size = 237922 }, - { url = "https://files.pythonhosted.org/packages/08/dd/723fef5d901e6a89f2507094db66c091449c8ba03272861eaefa773ad95c/coverage-7.6.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694", size = 239783 }, - { url = "https://files.pythonhosted.org/packages/3d/f7/64d3298b2baf261cb35466000628706ce20a82d42faf9b771af447cd2b76/coverage-7.6.10-cp313-cp313-win32.whl", hash = "sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6", size = 210965 }, - { url = "https://files.pythonhosted.org/packages/d5/58/ec43499a7fc681212fe7742fe90b2bc361cdb72e3181ace1604247a5b24d/coverage-7.6.10-cp313-cp313-win_amd64.whl", hash = "sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e", size = 211719 }, - { url = "https://files.pythonhosted.org/packages/ab/c9/f2857a135bcff4330c1e90e7d03446b036b2363d4ad37eb5e3a47bbac8a6/coverage-7.6.10-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe", size = 209050 }, - { url = "https://files.pythonhosted.org/packages/aa/b3/f840e5bd777d8433caa9e4a1eb20503495709f697341ac1a8ee6a3c906ad/coverage-7.6.10-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273", size = 209321 }, - { url = "https://files.pythonhosted.org/packages/85/7d/125a5362180fcc1c03d91850fc020f3831d5cda09319522bcfa6b2b70be7/coverage-7.6.10-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8", size = 252039 }, - { url = "https://files.pythonhosted.org/packages/a9/9c/4358bf3c74baf1f9bddd2baf3756b54c07f2cfd2535f0a47f1e7757e54b3/coverage-7.6.10-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098", size = 247758 }, - { url = "https://files.pythonhosted.org/packages/cf/c7/de3eb6fc5263b26fab5cda3de7a0f80e317597a4bad4781859f72885f300/coverage-7.6.10-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb", size = 250119 }, - { url = "https://files.pythonhosted.org/packages/3e/e6/43de91f8ba2ec9140c6a4af1102141712949903dc732cf739167cfa7a3bc/coverage-7.6.10-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0", size = 249597 }, - { url = "https://files.pythonhosted.org/packages/08/40/61158b5499aa2adf9e37bc6d0117e8f6788625b283d51e7e0c53cf340530/coverage-7.6.10-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf", size = 247473 }, - { url = "https://files.pythonhosted.org/packages/50/69/b3f2416725621e9f112e74e8470793d5b5995f146f596f133678a633b77e/coverage-7.6.10-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2", size = 248737 }, - { url = "https://files.pythonhosted.org/packages/3c/6e/fe899fb937657db6df31cc3e61c6968cb56d36d7326361847440a430152e/coverage-7.6.10-cp313-cp313t-win32.whl", hash = "sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312", size = 211611 }, - { url = "https://files.pythonhosted.org/packages/1c/55/52f5e66142a9d7bc93a15192eba7a78513d2abf6b3558d77b4ca32f5f424/coverage-7.6.10-cp313-cp313t-win_amd64.whl", hash = "sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d", size = 212781 }, - { url = "https://files.pythonhosted.org/packages/a1/70/de81bfec9ed38a64fc44a77c7665e20ca507fc3265597c28b0d989e4082e/coverage-7.6.10-pp39.pp310-none-any.whl", hash = "sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f", size = 200223 }, +version = "7.6.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/89/4e/38141d42af7452f4b7c5d3d7442a8018de34754ef52eb9a400768bc8d59e/coverage-7.6.11.tar.gz", hash = "sha256:e642e6a46a04e992ebfdabed79e46f478ec60e2c528e1e1a074d63800eda4286", size = 805460 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/15/e92184931a6773cf1f690575a443a502af213ec8e6d5c48b77a768f3e237/coverage-7.6.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eafea49da254a8289bed3fab960f808b322eda5577cb17a3733014928bbfbebd", size = 208240 }, + { url = "https://files.pythonhosted.org/packages/38/35/f22234dfc289aac8c890e9fa5031bfcf3a83f626c39a4f2442c2c3e7a552/coverage-7.6.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5a3f7cbbcb4ad95067a6525f83a6fc78d9cbc1e70f8abaeeaeaa72ef34f48fc3", size = 208674 }, + { url = "https://files.pythonhosted.org/packages/11/f1/d91d847e79dfb2985b14090427c7df0c13d81f4e263a2ecb5f84ee667f0b/coverage-7.6.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de6b079b39246a7da9a40cfa62d5766bd52b4b7a88cf5a82ec4c45bf6e152306", size = 237826 }, + { url = "https://files.pythonhosted.org/packages/c7/13/72f363b7a9171c97756db9a3e9a659d7ad24190a01aa75b033460a7e7c13/coverage-7.6.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:60d4ad09dfc8c36c4910685faafcb8044c84e4dae302e86c585b3e2e7778726c", size = 235734 }, + { url = "https://files.pythonhosted.org/packages/7f/61/fe984f4a955f5fdc95f5ae9c5b35b7464589e3beb791e493d3d88def1769/coverage-7.6.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e433b6e3a834a43dae2889adc125f3fa4c66668df420d8e49bc4ee817dd7a70", size = 236866 }, + { url = "https://files.pythonhosted.org/packages/7e/b8/67c1e79118b9b2632cdea6b5e78b6d9bcef0528f620e1e8947637d49b560/coverage-7.6.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ac5d92e2cc121a13270697e4cb37e1eb4511ac01d23fe1b6c097facc3b46489e", size = 235983 }, + { url = "https://files.pythonhosted.org/packages/06/07/bb575758c887ac328ac67dc786bf81e10bfa0b4ac98eef3518f726dff098/coverage-7.6.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5128f3ba694c0a1bde55fc480090392c336236c3e1a10dad40dc1ab17c7675ff", size = 234292 }, + { url = "https://files.pythonhosted.org/packages/76/92/a52f3de97812f31652fda25c2fe3b6f1b832833f116b293101f9fe3d28f1/coverage-7.6.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:397489c611b76302dfa1d9ea079e138dddc4af80fc6819d5f5119ec8ca6c0e47", size = 235433 }, + { url = "https://files.pythonhosted.org/packages/1d/5e/de487d979ae47a52d7007b7a58d7ccb1d64c68027cf6953488a8f7b5fb16/coverage-7.6.11-cp310-cp310-win32.whl", hash = "sha256:c7719a5e1dc93883a6b319bc0374ecd46fb6091ed659f3fbe281ab991634b9b0", size = 210963 }, + { url = "https://files.pythonhosted.org/packages/8b/3f/2f61ee4261bb3b9d92377bcf627ca5bd6725dd5433e6f1e51d6467b827a0/coverage-7.6.11-cp310-cp310-win_amd64.whl", hash = "sha256:c27df03730059118b8a923cfc8b84b7e9976742560af528242f201880879c1da", size = 211853 }, + { url = "https://files.pythonhosted.org/packages/28/c9/dc238d47920531f7a7fa39f4e2110d9c964c284ffa8b9bacb3db94eafe36/coverage-7.6.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:532fe139691af134aa8b54ed60dd3c806aa81312d93693bd2883c7b61592c840", size = 208358 }, + { url = "https://files.pythonhosted.org/packages/11/a0/8b4d0c21deac57253348ea35c86cbbe5077241d418540bfe58b561826649/coverage-7.6.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0b0f272901a5172090c0802053fbc503cdc3fa2612720d2669a98a7384a7bec", size = 208788 }, + { url = "https://files.pythonhosted.org/packages/0b/4b/670ad3c404802d45211a5cf0605a70a109ad0bc1210dabb463642a143949/coverage-7.6.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4bda710139ea646890d1c000feb533caff86904a0e0638f85e967c28cb8eec50", size = 239129 }, + { url = "https://files.pythonhosted.org/packages/7a/d8/a241aa17ca90478b98da23dfe08ae871d8cfa949e34a61d667802b7f6f2d/coverage-7.6.11-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a165b09e7d5f685bf659063334a9a7b1a2d57b531753d3e04bd442b3cfe5845b", size = 240912 }, + { url = "https://files.pythonhosted.org/packages/b5/9b/e9af16145352fc5889f9c3df343235796e170c04295e615180fa194f8d41/coverage-7.6.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ff136607689c1c87f43d24203b6d2055b42030f352d5176f9c8b204d4235ef27", size = 238361 }, + { url = "https://files.pythonhosted.org/packages/59/7b/ab1c1ff66efbbd978b27e9789ce430cbbce53195fb18f7fe3ba14fc73b9b/coverage-7.6.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:050172741de03525290e67f0161ae5f7f387c88fca50d47fceb4724ceaa591d2", size = 239204 }, + { url = "https://files.pythonhosted.org/packages/dc/6f/08db69a0c0257257e9b942efdb31d317093b8c038be2ff61e114a72ee32e/coverage-7.6.11-cp311-cp311-win32.whl", hash = "sha256:27700d859be68e4fb2e7bf774cf49933dcac6f81a9bc4c13bd41735b8d26a53b", size = 211014 }, + { url = "https://files.pythonhosted.org/packages/1b/0d/d287ef28d7525642101b1a3891d35b966560c116aa20f0bbd22c5a136ef5/coverage-7.6.11-cp311-cp311-win_amd64.whl", hash = "sha256:cd4839813b09ab1dd1be1bbc74f9a7787615f931f83952b6a9af1b2d3f708bf7", size = 211913 }, + { url = "https://files.pythonhosted.org/packages/65/83/cf3d6ac06bd02e1fb7fc6609d7a3be799328a94938dd2a64cf091989b8ce/coverage-7.6.11-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:dbb1a822fd858d9853333a7c95d4e70dde9a79e65893138ce32c2ec6457d7a36", size = 208543 }, + { url = "https://files.pythonhosted.org/packages/e7/e1/b1448995072ab033898758179e208afa924f4625ea4524ec868fafbae77d/coverage-7.6.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:61c834cbb80946d6ebfddd9b393a4c46bec92fcc0fa069321fcb8049117f76ea", size = 208805 }, + { url = "https://files.pythonhosted.org/packages/80/22/11ae7726086bf16ad35ecd1ebf31c0c709647b2618977bc088003bd38808/coverage-7.6.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a46d56e99a31d858d6912d31ffa4ede6a325c86af13139539beefca10a1234ce", size = 239768 }, + { url = "https://files.pythonhosted.org/packages/7d/68/717286bda6530f39f3ac16899dac1855a71921aca5ee565484269326c979/coverage-7.6.11-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b48db06f53d1864fea6dbd855e6d51d41c0f06c212c3004511c0bdc6847b297", size = 242023 }, + { url = "https://files.pythonhosted.org/packages/93/57/4b028c7c882411d9ca3f12cd4223ceeb5cb39f84bb91c4fb21a06440cbd9/coverage-7.6.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b6ff5be3b1853e0862da9d349fe87f869f68e63a25f7c37ce1130b321140f963", size = 239610 }, + { url = "https://files.pythonhosted.org/packages/44/88/720c9eba316406f243670237306bcdb8e269e4d0e12b191a697f66369404/coverage-7.6.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be05bde21d5e6eefbc3a6de6b9bee2b47894b8945342e8663192809c4d1f08ce", size = 241212 }, + { url = "https://files.pythonhosted.org/packages/1d/ae/a09edf77bd535d597de13679262845f5cb6ff1fab37a3065640fb3d5e6e8/coverage-7.6.11-cp312-cp312-win32.whl", hash = "sha256:e3b746fa0ffc5b6b8856529de487da8b9aeb4fb394bb58de6502ef45f3434f12", size = 211186 }, + { url = "https://files.pythonhosted.org/packages/80/5d/63ad5e3f1421504194da0228d259a3913884830999d1297b5e16b59bcb0f/coverage-7.6.11-cp312-cp312-win_amd64.whl", hash = "sha256:ac476e6d0128fb7919b3fae726de72b28b5c9644cb4b579e4a523d693187c551", size = 211974 }, + { url = "https://files.pythonhosted.org/packages/8b/83/096a4954b686212b4e8d3ef14e01370e111b44972370fcc26169e3b32757/coverage-7.6.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c86f4c7a6d1a54a24d804d9684d96e36a62d3ef7c0d7745ae2ea39e3e0293251", size = 208568 }, + { url = "https://files.pythonhosted.org/packages/bc/78/74f5f1545b06524a3c9c36be339fa1ebbc17eef182c961fbed91cd0805e1/coverage-7.6.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7eb0504bb307401fd08bc5163a351df301438b3beb88a4fa044681295bbefc67", size = 208839 }, + { url = "https://files.pythonhosted.org/packages/6a/4b/df3433cbb9a91cb3f5ea8301bef312a8e77587881e2dea93f2d58683908e/coverage-7.6.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca95d40900cf614e07f00cee8c2fad0371df03ca4d7a80161d84be2ec132b7a4", size = 242383 }, + { url = "https://files.pythonhosted.org/packages/40/22/681a1b724866f12b96bf46d178e0d5df557bb9c3da43aa2a8be67a4be65e/coverage-7.6.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db4b1a69976b1b02acda15937538a1d3fe10b185f9d99920b17a740a0a102e06", size = 239424 }, + { url = "https://files.pythonhosted.org/packages/29/08/978e14dca15fec135b13246cd5cbbedc6506d8102854f4bdde73038efaa3/coverage-7.6.11-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf96beb05d004e4c51cd846fcdf9eee9eb2681518524b66b2e7610507944c2f", size = 241440 }, + { url = "https://files.pythonhosted.org/packages/a6/34/39fc8ad65d6381d1e8278f9042ff4e201a2cb52092d705d7a02ffc8ccc1b/coverage-7.6.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:08e5fb93576a6b054d3d326242af5ef93daaac9bb52bc25f12ccbc3fa94227cd", size = 241076 }, + { url = "https://files.pythonhosted.org/packages/13/6b/392fa652391bf6751766921a7b29f576a3de1db78b8d48e1f438ce0121b4/coverage-7.6.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:25575cd5a7d2acc46b42711e8aff826027c0e4f80fb38028a74f31ac22aae69d", size = 239186 }, + { url = "https://files.pythonhosted.org/packages/3d/ad/6c0edcd7ee9b7ceddcfda45aeea2b84ef017d19bde27fe3de51deab6468a/coverage-7.6.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8fa4fffd90ee92f62ff7404b4801b59e8ea8502e19c9bf2d3241ce745b52926c", size = 240928 }, + { url = "https://files.pythonhosted.org/packages/e7/7c/f4f38aa65aad6d2f0ec3ba2a1d50a06f4c8c2d3516761d4eaff332ec14d7/coverage-7.6.11-cp313-cp313-win32.whl", hash = "sha256:0d03c9452d9d1ccfe5d3a5df0427705022a49b356ac212d529762eaea5ef97b4", size = 211211 }, + { url = "https://files.pythonhosted.org/packages/c1/c1/2003bf96e799e5414be7aac2dae14bcc463067f7d8d40d69e33a82c352e6/coverage-7.6.11-cp313-cp313-win_amd64.whl", hash = "sha256:fd2fffc8ce8692ce540103dff26279d2af22d424516ddebe2d7e4d6dbb3816b2", size = 211995 }, + { url = "https://files.pythonhosted.org/packages/e3/7c/8c71cf43a68d09772408182177394d1f3aafe8ec45c88bd0702efc9e5640/coverage-7.6.11-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:5e7ac966ab110bd94ee844f2643f196d78fde1cd2450399116d3efdd706e19f5", size = 209408 }, + { url = "https://files.pythonhosted.org/packages/17/74/25a3f0e9745cab1120a641240074eb9e77d3278e9b2e6b53d4ba5b6ae1f0/coverage-7.6.11-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:6ba27a0375c5ef4d2a7712f829265102decd5ff78b96d342ac2fa555742c4f4f", size = 209629 }, + { url = "https://files.pythonhosted.org/packages/f6/e4/22d61ef97964ec28246a8487fa117568b7ef225913de43621b86ad6d2446/coverage-7.6.11-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2778be4f574b39ec9dcd9e5e13644f770351ee0990a0ecd27e364aba95af89b", size = 253884 }, + { url = "https://files.pythonhosted.org/packages/44/3b/c272005a36f28374c76d4cef63e4ff1824b33eb6970ce2cea2c5293a8119/coverage-7.6.11-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5edc16712187139ab635a2e644cc41fc239bc6d245b16124045743130455c652", size = 249592 }, + { url = "https://files.pythonhosted.org/packages/cf/4f/d9daa13ebad04a22e9f48a8619aa27380961fefc20e15e5bf3f7d6325fd1/coverage-7.6.11-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df6ff122a0a10a30121d9f0cb3fbd03a6fe05861e4ec47adb9f25e9245aabc19", size = 251928 }, + { url = "https://files.pythonhosted.org/packages/a7/52/42b5b3bde8b0fbc268fc8809b775caffb1ebc51555d04ad979e824b84f9a/coverage-7.6.11-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ff562952f15eff27247a4c4b03e45ce8a82e3fb197de6a7c54080f9d4ba07845", size = 251431 }, + { url = "https://files.pythonhosted.org/packages/ef/0e/efb47cd1a2279acc1c05966a441f1658564ec81fa331a9420aef54997bfc/coverage-7.6.11-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4f21e3617f48d683f30cf2a6c8b739c838e600cb1454fe6b2eb486ac2bce8fbd", size = 249089 }, + { url = "https://files.pythonhosted.org/packages/ea/65/bd348b3d0da43ad6a2e70c3bd9bffde2ef680c2987a2ea8b19f189a83cae/coverage-7.6.11-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6d60577673ba48d8ae8e362e61fd4ad1a640293ffe8991d11c86f195479100b7", size = 250526 }, + { url = "https://files.pythonhosted.org/packages/f8/b8/b2ba25ebda1f3e149d679b0468eda846cfba5d48f8c2f9e0b565c0cdbb91/coverage-7.6.11-cp313-cp313t-win32.whl", hash = "sha256:13100f98497086b359bf56fc035a762c674de8ef526daa389ac8932cb9bff1e0", size = 211929 }, + { url = "https://files.pythonhosted.org/packages/0a/97/ad0cc489eddd0ffdb1b873a39182834d6119d8e1f6ee5ce760345a573971/coverage-7.6.11-cp313-cp313t-win_amd64.whl", hash = "sha256:2c81e53782043b323bd34c7de711ed9b4673414eb517eaf35af92185b873839c", size = 213138 }, + { url = "https://files.pythonhosted.org/packages/ba/2a/a072ae54fa666397960b5a84702f62e13360e6040998cf6ac2114f44153c/coverage-7.6.11-pp39.pp310-none-any.whl", hash = "sha256:adc2d941c0381edfcf3897f94b9f41b1e504902fab78a04b1677f2f72afead4b", size = 200452 }, + { url = "https://files.pythonhosted.org/packages/24/f3/63cd48409a519d4f6cf79abc6c89103a8eabc5c93e496f40779269dba0c0/coverage-7.6.11-py3-none-any.whl", hash = "sha256:f0f334ae844675420164175bf32b04e18a81fe57ad8eb7e0cfd4689d681ffed7", size = 200446 }, ] [package.optional-dependencies] @@ -984,6 +986,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4c/a3/ac312faeceffd2d8f86bc6dcb5c401188ba5a01bc88e69bed97578a0dfcd/durationpy-0.9-py3-none-any.whl", hash = "sha256:e65359a7af5cedad07fb77a2dd3f390f8eb0b74cb845589fa6c057086834dd38", size = 3461 }, ] +[[package]] +name = "environs" +version = "9.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "marshmallow", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "python-dotenv", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d4/e3/c3c6c76f3dbe3e019e9a451b35bf9f44690026a5bb1232f7b77097b72ff5/environs-9.5.0.tar.gz", hash = "sha256:a76307b36fbe856bdca7ee9161e6c466fd7fcffc297109a118c59b54e27e30c9", size = 20795 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/5e/f0f217dc393372681bfe05c50f06a212e78d0a3fee907a74ab451ec1dcdb/environs-9.5.0-py2.py3-none-any.whl", hash = "sha256:1e549569a3de49c05f856f40bce86979e7d5ffbbc4398e7f338574c220189124", size = 12548 }, +] + [[package]] name = "eval-type-backport" version = "0.2.2" @@ -1161,11 +1176,11 @@ wheels = [ [[package]] name = "fsspec" -version = "2024.12.0" +version = "2025.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/11/de70dee31455c546fbc88301971ec03c328f3d1138cfba14263f651e9551/fsspec-2024.12.0.tar.gz", hash = "sha256:670700c977ed2fb51e0d9f9253177ed20cbde4a3e5c0283cc5385b5870c8533f", size = 291600 } +sdist = { url = "https://files.pythonhosted.org/packages/b5/79/68612ed99700e6413de42895aa725463e821a6b3be75c87fcce1b4af4c70/fsspec-2025.2.0.tar.gz", hash = "sha256:1c24b16eaa0a1798afa0337aa0db9b256718ab2a89c425371f5628d22c3b6afd", size = 292283 } wheels = [ - { url = "https://files.pythonhosted.org/packages/de/86/5486b0188d08aa643e127774a99bac51ffa6cf343e3deb0583956dca5b22/fsspec-2024.12.0-py3-none-any.whl", hash = "sha256:b520aed47ad9804237ff878b504267a3b0b441e97508bd6d2d8774e3db85cee2", size = 183862 }, + { url = "https://files.pythonhosted.org/packages/e2/94/758680531a00d06e471ef649e4ec2ed6bf185356a7f9fbfbb7368a40bd49/fsspec-2025.2.0-py3-none-any.whl", hash = "sha256:9de2ad9ce1f85e1931858535bc882543171d197001a0a5eb2ddc04f1781ab95b", size = 184484 }, ] [[package]] @@ -1250,7 +1265,7 @@ wheels = [ [[package]] name = "google-cloud-aiplatform" -version = "1.60.0" +version = "1.79.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "docstring-parser", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, @@ -1264,10 +1279,11 @@ dependencies = [ { name = "protobuf", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "pydantic", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "shapely", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/db/57/41a6e447bb486c2da67629b5399be78952711d21a400b70a9208109c02a9/google-cloud-aiplatform-1.60.0.tar.gz", hash = "sha256:782c7f1ec0e77a7c7daabef3b65bfd506ed2b4b1dc2186753c43cd6faf8dd04e", size = 6129755 } +sdist = { url = "https://files.pythonhosted.org/packages/a5/8e/93e9f5a7059883c21a82adf8687248c6615d4b833b3bf665631a768b8ebd/google_cloud_aiplatform-1.79.0.tar.gz", hash = "sha256:362bfd16716dcfb6c131736f25246790002b29c99a246fcf4c08a7c71bd2301f", size = 8455732 } wheels = [ - { url = "https://files.pythonhosted.org/packages/9c/75/b055676eb1bff2fe276566d5f8b593a61a82feb6d2a3a8dcd370768e254c/google_cloud_aiplatform-1.60.0-py2.py3-none-any.whl", hash = "sha256:5f14159c9575f4b46335027e3ceb8fa57bd5eaa76a07f858105b8c6c034ec0d6", size = 5129635 }, + { url = "https://files.pythonhosted.org/packages/d9/df/a7629fc1c405ead82249a70903068992932cc5a8c494c396e22995b4429d/google_cloud_aiplatform-1.79.0-py2.py3-none-any.whl", hash = "sha256:e52d518c386ce2b4ce57f1b73b46c57531d9a6ccd70c21a37b349f428bfc1c3f", size = 7086167 }, ] [[package]] @@ -1423,46 +1439,46 @@ wheels = [ [[package]] name = "grpcio" -version = "1.67.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/20/53/d9282a66a5db45981499190b77790570617a604a38f3d103d0400974aeb5/grpcio-1.67.1.tar.gz", hash = "sha256:3dc2ed4cabea4dc14d5e708c2b426205956077cc5de419b4d4079315017e9732", size = 12580022 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4e/cd/f6ca5c49aa0ae7bc6d0757f7dae6f789569e9490a635eaabe02bc02de7dc/grpcio-1.67.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:8b0341d66a57f8a3119b77ab32207072be60c9bf79760fa609c5609f2deb1f3f", size = 5112450 }, - { url = "https://files.pythonhosted.org/packages/d4/f0/d9bbb4a83cbee22f738ee7a74aa41e09ccfb2dcea2cc30ebe8dab5b21771/grpcio-1.67.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:f5a27dddefe0e2357d3e617b9079b4bfdc91341a91565111a21ed6ebbc51b22d", size = 10937518 }, - { url = "https://files.pythonhosted.org/packages/5b/17/0c5dbae3af548eb76669887642b5f24b232b021afe77eb42e22bc8951d9c/grpcio-1.67.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:43112046864317498a33bdc4797ae6a268c36345a910de9b9c17159d8346602f", size = 5633610 }, - { url = "https://files.pythonhosted.org/packages/17/48/e000614e00153d7b2760dcd9526b95d72f5cfe473b988e78f0ff3b472f6c/grpcio-1.67.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9b929f13677b10f63124c1a410994a401cdd85214ad83ab67cc077fc7e480f0", size = 6240678 }, - { url = "https://files.pythonhosted.org/packages/64/19/a16762a70eeb8ddfe43283ce434d1499c1c409ceec0c646f783883084478/grpcio-1.67.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7d1797a8a3845437d327145959a2c0c47c05947c9eef5ff1a4c80e499dcc6fa", size = 5884528 }, - { url = "https://files.pythonhosted.org/packages/6b/dc/bd016aa3684914acd2c0c7fa4953b2a11583c2b844f3d7bae91fa9b98fbb/grpcio-1.67.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0489063974d1452436139501bf6b180f63d4977223ee87488fe36858c5725292", size = 6583680 }, - { url = "https://files.pythonhosted.org/packages/1a/93/1441cb14c874f11aa798a816d582f9da82194b6677f0f134ea53d2d5dbeb/grpcio-1.67.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9fd042de4a82e3e7aca44008ee2fb5da01b3e5adb316348c21980f7f58adc311", size = 6162967 }, - { url = "https://files.pythonhosted.org/packages/29/e9/9295090380fb4339b7e935b9d005fa9936dd573a22d147c9e5bb2df1b8d4/grpcio-1.67.1-cp310-cp310-win32.whl", hash = "sha256:638354e698fd0c6c76b04540a850bf1db27b4d2515a19fcd5cf645c48d3eb1ed", size = 3616336 }, - { url = "https://files.pythonhosted.org/packages/ce/de/7c783b8cb8f02c667ca075c49680c4aeb8b054bc69784bcb3e7c1bbf4985/grpcio-1.67.1-cp310-cp310-win_amd64.whl", hash = "sha256:608d87d1bdabf9e2868b12338cd38a79969eaf920c89d698ead08f48de9c0f9e", size = 4352071 }, - { url = "https://files.pythonhosted.org/packages/59/2c/b60d6ea1f63a20a8d09c6db95c4f9a16497913fb3048ce0990ed81aeeca0/grpcio-1.67.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:7818c0454027ae3384235a65210bbf5464bd715450e30a3d40385453a85a70cb", size = 5119075 }, - { url = "https://files.pythonhosted.org/packages/b3/9a/e1956f7ca582a22dd1f17b9e26fcb8229051b0ce6d33b47227824772feec/grpcio-1.67.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ea33986b70f83844cd00814cee4451055cd8cab36f00ac64a31f5bb09b31919e", size = 11009159 }, - { url = "https://files.pythonhosted.org/packages/43/a8/35fbbba580c4adb1d40d12e244cf9f7c74a379073c0a0ca9d1b5338675a1/grpcio-1.67.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:c7a01337407dd89005527623a4a72c5c8e2894d22bead0895306b23c6695698f", size = 5629476 }, - { url = "https://files.pythonhosted.org/packages/77/c9/864d336e167263d14dfccb4dbfa7fce634d45775609895287189a03f1fc3/grpcio-1.67.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80b866f73224b0634f4312a4674c1be21b2b4afa73cb20953cbbb73a6b36c3cc", size = 6239901 }, - { url = "https://files.pythonhosted.org/packages/f7/1e/0011408ebabf9bd69f4f87cc1515cbfe2094e5a32316f8714a75fd8ddfcb/grpcio-1.67.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9fff78ba10d4250bfc07a01bd6254a6d87dc67f9627adece85c0b2ed754fa96", size = 5881010 }, - { url = "https://files.pythonhosted.org/packages/b4/7d/fbca85ee9123fb296d4eff8df566f458d738186d0067dec6f0aa2fd79d71/grpcio-1.67.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8a23cbcc5bb11ea7dc6163078be36c065db68d915c24f5faa4f872c573bb400f", size = 6580706 }, - { url = "https://files.pythonhosted.org/packages/75/7a/766149dcfa2dfa81835bf7df623944c1f636a15fcb9b6138ebe29baf0bc6/grpcio-1.67.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1a65b503d008f066e994f34f456e0647e5ceb34cfcec5ad180b1b44020ad4970", size = 6161799 }, - { url = "https://files.pythonhosted.org/packages/09/13/5b75ae88810aaea19e846f5380611837de411181df51fd7a7d10cb178dcb/grpcio-1.67.1-cp311-cp311-win32.whl", hash = "sha256:e29ca27bec8e163dca0c98084040edec3bc49afd10f18b412f483cc68c712744", size = 3616330 }, - { url = "https://files.pythonhosted.org/packages/aa/39/38117259613f68f072778c9638a61579c0cfa5678c2558706b10dd1d11d3/grpcio-1.67.1-cp311-cp311-win_amd64.whl", hash = "sha256:786a5b18544622bfb1e25cc08402bd44ea83edfb04b93798d85dca4d1a0b5be5", size = 4354535 }, - { url = "https://files.pythonhosted.org/packages/6e/25/6f95bd18d5f506364379eabc0d5874873cc7dbdaf0757df8d1e82bc07a88/grpcio-1.67.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:267d1745894200e4c604958da5f856da6293f063327cb049a51fe67348e4f953", size = 5089809 }, - { url = "https://files.pythonhosted.org/packages/10/3f/d79e32e5d0354be33a12db2267c66d3cfeff700dd5ccdd09fd44a3ff4fb6/grpcio-1.67.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:85f69fdc1d28ce7cff8de3f9c67db2b0ca9ba4449644488c1e0303c146135ddb", size = 10981985 }, - { url = "https://files.pythonhosted.org/packages/21/f2/36fbc14b3542e3a1c20fb98bd60c4732c55a44e374a4eb68f91f28f14aab/grpcio-1.67.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:f26b0b547eb8d00e195274cdfc63ce64c8fc2d3e2d00b12bf468ece41a0423a0", size = 5588770 }, - { url = "https://files.pythonhosted.org/packages/0d/af/bbc1305df60c4e65de8c12820a942b5e37f9cf684ef5e49a63fbb1476a73/grpcio-1.67.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4422581cdc628f77302270ff839a44f4c24fdc57887dc2a45b7e53d8fc2376af", size = 6214476 }, - { url = "https://files.pythonhosted.org/packages/92/cf/1d4c3e93efa93223e06a5c83ac27e32935f998bc368e276ef858b8883154/grpcio-1.67.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d7616d2ded471231c701489190379e0c311ee0a6c756f3c03e6a62b95a7146e", size = 5850129 }, - { url = "https://files.pythonhosted.org/packages/ae/ca/26195b66cb253ac4d5ef59846e354d335c9581dba891624011da0e95d67b/grpcio-1.67.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8a00efecde9d6fcc3ab00c13f816313c040a28450e5e25739c24f432fc6d3c75", size = 6568489 }, - { url = "https://files.pythonhosted.org/packages/d1/94/16550ad6b3f13b96f0856ee5dfc2554efac28539ee84a51d7b14526da985/grpcio-1.67.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:699e964923b70f3101393710793289e42845791ea07565654ada0969522d0a38", size = 6149369 }, - { url = "https://files.pythonhosted.org/packages/33/0d/4c3b2587e8ad7f121b597329e6c2620374fccbc2e4e1aa3c73ccc670fde4/grpcio-1.67.1-cp312-cp312-win32.whl", hash = "sha256:4e7b904484a634a0fff132958dabdb10d63e0927398273917da3ee103e8d1f78", size = 3599176 }, - { url = "https://files.pythonhosted.org/packages/7d/36/0c03e2d80db69e2472cf81c6123aa7d14741de7cf790117291a703ae6ae1/grpcio-1.67.1-cp312-cp312-win_amd64.whl", hash = "sha256:5721e66a594a6c4204458004852719b38f3d5522082be9061d6510b455c90afc", size = 4346574 }, - { url = "https://files.pythonhosted.org/packages/12/d2/2f032b7a153c7723ea3dea08bffa4bcaca9e0e5bdf643ce565b76da87461/grpcio-1.67.1-cp313-cp313-linux_armv7l.whl", hash = "sha256:aa0162e56fd10a5547fac8774c4899fc3e18c1aa4a4759d0ce2cd00d3696ea6b", size = 5091487 }, - { url = "https://files.pythonhosted.org/packages/d0/ae/ea2ff6bd2475a082eb97db1104a903cf5fc57c88c87c10b3c3f41a184fc0/grpcio-1.67.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:beee96c8c0b1a75d556fe57b92b58b4347c77a65781ee2ac749d550f2a365dc1", size = 10943530 }, - { url = "https://files.pythonhosted.org/packages/07/62/646be83d1a78edf8d69b56647327c9afc223e3140a744c59b25fbb279c3b/grpcio-1.67.1-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:a93deda571a1bf94ec1f6fcda2872dad3ae538700d94dc283c672a3b508ba3af", size = 5589079 }, - { url = "https://files.pythonhosted.org/packages/d0/25/71513d0a1b2072ce80d7f5909a93596b7ed10348b2ea4fdcbad23f6017bf/grpcio-1.67.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e6f255980afef598a9e64a24efce87b625e3e3c80a45162d111a461a9f92955", size = 6213542 }, - { url = "https://files.pythonhosted.org/packages/76/9a/d21236297111052dcb5dc85cd77dc7bf25ba67a0f55ae028b2af19a704bc/grpcio-1.67.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e838cad2176ebd5d4a8bb03955138d6589ce9e2ce5d51c3ada34396dbd2dba8", size = 5850211 }, - { url = "https://files.pythonhosted.org/packages/2d/fe/70b1da9037f5055be14f359026c238821b9bcf6ca38a8d760f59a589aacd/grpcio-1.67.1-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:a6703916c43b1d468d0756c8077b12017a9fcb6a1ef13faf49e67d20d7ebda62", size = 6572129 }, - { url = "https://files.pythonhosted.org/packages/74/0d/7df509a2cd2a54814598caf2fb759f3e0b93764431ff410f2175a6efb9e4/grpcio-1.67.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:917e8d8994eed1d86b907ba2a61b9f0aef27a2155bca6cbb322430fc7135b7bb", size = 6149819 }, - { url = "https://files.pythonhosted.org/packages/0a/08/bc3b0155600898fd10f16b79054e1cca6cb644fa3c250c0fe59385df5e6f/grpcio-1.67.1-cp313-cp313-win32.whl", hash = "sha256:e279330bef1744040db8fc432becc8a727b84f456ab62b744d3fdb83f327e121", size = 3596561 }, - { url = "https://files.pythonhosted.org/packages/5a/96/44759eca966720d0f3e1b105c43f8ad4590c97bf8eb3cd489656e9590baa/grpcio-1.67.1-cp313-cp313-win_amd64.whl", hash = "sha256:fa0c739ad8b1996bd24823950e3cb5152ae91fca1c09cc791190bf1627ffefba", size = 4346042 }, +version = "1.70.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/69/e1/4b21b5017c33f3600dcc32b802bb48fe44a4d36d6c066f52650c7c2690fa/grpcio-1.70.0.tar.gz", hash = "sha256:8d1584a68d5922330025881e63a6c1b54cc8117291d382e4fa69339b6d914c56", size = 12788932 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/e9/f72408bac1f7b05b25e4df569b02d6b200c8e7857193aa9f1df7a3744add/grpcio-1.70.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:95469d1977429f45fe7df441f586521361e235982a0b39e33841549143ae2851", size = 5229736 }, + { url = "https://files.pythonhosted.org/packages/b3/17/e65139ea76dac7bcd8a3f17cbd37e3d1a070c44db3098d0be5e14c5bd6a1/grpcio-1.70.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:ed9718f17fbdb472e33b869c77a16d0b55e166b100ec57b016dc7de9c8d236bf", size = 11432751 }, + { url = "https://files.pythonhosted.org/packages/a0/12/42de6082b4ab14a59d30b2fc7786882fdaa75813a4a4f3d4a8c4acd6ed59/grpcio-1.70.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:374d014f29f9dfdb40510b041792e0e2828a1389281eb590df066e1cc2b404e5", size = 5711439 }, + { url = "https://files.pythonhosted.org/packages/34/f8/b5a19524d273cbd119274a387bb72d6fbb74578e13927a473bc34369f079/grpcio-1.70.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2af68a6f5c8f78d56c145161544ad0febbd7479524a59c16b3e25053f39c87f", size = 6330777 }, + { url = "https://files.pythonhosted.org/packages/1a/67/3d6c0ad786238aac7fa93b79246fc452978fbfe9e5f86f70da8e8a2797d0/grpcio-1.70.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce7df14b2dcd1102a2ec32f621cc9fab6695effef516efbc6b063ad749867295", size = 5944639 }, + { url = "https://files.pythonhosted.org/packages/76/0d/d9f7cbc41c2743cf18236a29b6a582f41bd65572a7144d92b80bc1e68479/grpcio-1.70.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c78b339869f4dbf89881e0b6fbf376313e4f845a42840a7bdf42ee6caed4b11f", size = 6643543 }, + { url = "https://files.pythonhosted.org/packages/fc/24/bdd7e606b3400c14330e33a4698fa3a49e38a28c9e0a831441adbd3380d2/grpcio-1.70.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:58ad9ba575b39edef71f4798fdb5c7b6d02ad36d47949cd381d4392a5c9cbcd3", size = 6199897 }, + { url = "https://files.pythonhosted.org/packages/d1/33/8132eb370087960c82d01b89faeb28f3e58f5619ffe19889f57c58a19c18/grpcio-1.70.0-cp310-cp310-win32.whl", hash = "sha256:2b0d02e4b25a5c1f9b6c7745d4fa06efc9fd6a611af0fb38d3ba956786b95199", size = 3617513 }, + { url = "https://files.pythonhosted.org/packages/99/bc/0fce5cfc0ca969df66f5dca6cf8d2258abb88146bf9ab89d8cf48e970137/grpcio-1.70.0-cp310-cp310-win_amd64.whl", hash = "sha256:0de706c0a5bb9d841e353f6343a9defc9fc35ec61d6eb6111802f3aa9fef29e1", size = 4303342 }, + { url = "https://files.pythonhosted.org/packages/65/c4/1f67d23d6bcadd2fd61fb460e5969c52b3390b4a4e254b5e04a6d1009e5e/grpcio-1.70.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:17325b0be0c068f35770f944124e8839ea3185d6d54862800fc28cc2ffad205a", size = 5229017 }, + { url = "https://files.pythonhosted.org/packages/e4/bd/cc36811c582d663a740fb45edf9f99ddbd99a10b6ba38267dc925e1e193a/grpcio-1.70.0-cp311-cp311-macosx_10_14_universal2.whl", hash = "sha256:dbe41ad140df911e796d4463168e33ef80a24f5d21ef4d1e310553fcd2c4a386", size = 11472027 }, + { url = "https://files.pythonhosted.org/packages/7e/32/8538bb2ace5cd72da7126d1c9804bf80b4fe3be70e53e2d55675c24961a8/grpcio-1.70.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:5ea67c72101d687d44d9c56068328da39c9ccba634cabb336075fae2eab0d04b", size = 5707785 }, + { url = "https://files.pythonhosted.org/packages/ce/5c/a45f85f2a0dfe4a6429dee98717e0e8bd7bd3f604315493c39d9679ca065/grpcio-1.70.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb5277db254ab7586769e490b7b22f4ddab3876c490da0a1a9d7c695ccf0bf77", size = 6331599 }, + { url = "https://files.pythonhosted.org/packages/9f/e5/5316b239380b8b2ad30373eb5bb25d9fd36c0375e94a98a0a60ea357d254/grpcio-1.70.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7831a0fc1beeeb7759f737f5acd9fdcda520e955049512d68fda03d91186eea", size = 5940834 }, + { url = "https://files.pythonhosted.org/packages/05/33/dbf035bc6d167068b4a9f2929dfe0b03fb763f0f861ecb3bb1709a14cb65/grpcio-1.70.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:27cc75e22c5dba1fbaf5a66c778e36ca9b8ce850bf58a9db887754593080d839", size = 6641191 }, + { url = "https://files.pythonhosted.org/packages/4c/c4/684d877517e5bfd6232d79107e5a1151b835e9f99051faef51fed3359ec4/grpcio-1.70.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d63764963412e22f0491d0d32833d71087288f4e24cbcddbae82476bfa1d81fd", size = 6198744 }, + { url = "https://files.pythonhosted.org/packages/e9/43/92fe5eeaf340650a7020cfb037402c7b9209e7a0f3011ea1626402219034/grpcio-1.70.0-cp311-cp311-win32.whl", hash = "sha256:bb491125103c800ec209d84c9b51f1c60ea456038e4734688004f377cfacc113", size = 3617111 }, + { url = "https://files.pythonhosted.org/packages/55/15/b6cf2c9515c028aff9da6984761a3ab484a472b0dc6435fcd07ced42127d/grpcio-1.70.0-cp311-cp311-win_amd64.whl", hash = "sha256:d24035d49e026353eb042bf7b058fb831db3e06d52bee75c5f2f3ab453e71aca", size = 4304604 }, + { url = "https://files.pythonhosted.org/packages/4c/a4/ddbda79dd176211b518f0f3795af78b38727a31ad32bc149d6a7b910a731/grpcio-1.70.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:ef4c14508299b1406c32bdbb9fb7b47612ab979b04cf2b27686ea31882387cff", size = 5198135 }, + { url = "https://files.pythonhosted.org/packages/30/5c/60eb8a063ea4cb8d7670af8fac3f2033230fc4b75f62669d67c66ac4e4b0/grpcio-1.70.0-cp312-cp312-macosx_10_14_universal2.whl", hash = "sha256:aa47688a65643afd8b166928a1da6247d3f46a2784d301e48ca1cc394d2ffb40", size = 11447529 }, + { url = "https://files.pythonhosted.org/packages/fb/b9/1bf8ab66729f13b44e8f42c9de56417d3ee6ab2929591cfee78dce749b57/grpcio-1.70.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:880bfb43b1bb8905701b926274eafce5c70a105bc6b99e25f62e98ad59cb278e", size = 5664484 }, + { url = "https://files.pythonhosted.org/packages/d1/06/2f377d6906289bee066d96e9bdb91e5e96d605d173df9bb9856095cccb57/grpcio-1.70.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e654c4b17d07eab259d392e12b149c3a134ec52b11ecdc6a515b39aceeec898", size = 6303739 }, + { url = "https://files.pythonhosted.org/packages/ae/50/64c94cfc4db8d9ed07da71427a936b5a2bd2b27c66269b42fbda82c7c7a4/grpcio-1.70.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2394e3381071045a706ee2eeb6e08962dd87e8999b90ac15c55f56fa5a8c9597", size = 5910417 }, + { url = "https://files.pythonhosted.org/packages/53/89/8795dfc3db4389c15554eb1765e14cba8b4c88cc80ff828d02f5572965af/grpcio-1.70.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b3c76701428d2df01964bc6479422f20e62fcbc0a37d82ebd58050b86926ef8c", size = 6626797 }, + { url = "https://files.pythonhosted.org/packages/9c/b2/6a97ac91042a2c59d18244c479ee3894e7fb6f8c3a90619bb5a7757fa30c/grpcio-1.70.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ac073fe1c4cd856ebcf49e9ed6240f4f84d7a4e6ee95baa5d66ea05d3dd0df7f", size = 6190055 }, + { url = "https://files.pythonhosted.org/packages/86/2b/28db55c8c4d156053a8c6f4683e559cd0a6636f55a860f87afba1ac49a51/grpcio-1.70.0-cp312-cp312-win32.whl", hash = "sha256:cd24d2d9d380fbbee7a5ac86afe9787813f285e684b0271599f95a51bce33528", size = 3600214 }, + { url = "https://files.pythonhosted.org/packages/17/c3/a7a225645a965029ed432e5b5e9ed959a574e62100afab553eef58be0e37/grpcio-1.70.0-cp312-cp312-win_amd64.whl", hash = "sha256:0495c86a55a04a874c7627fd33e5beaee771917d92c0e6d9d797628ac40e7655", size = 4292538 }, + { url = "https://files.pythonhosted.org/packages/68/38/66d0f32f88feaf7d83f8559cd87d899c970f91b1b8a8819b58226de0a496/grpcio-1.70.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:aa573896aeb7d7ce10b1fa425ba263e8dddd83d71530d1322fd3a16f31257b4a", size = 5199218 }, + { url = "https://files.pythonhosted.org/packages/c1/96/947df763a0b18efb5cc6c2ae348e56d97ca520dc5300c01617b234410173/grpcio-1.70.0-cp313-cp313-macosx_10_14_universal2.whl", hash = "sha256:d405b005018fd516c9ac529f4b4122342f60ec1cee181788249372524e6db429", size = 11445983 }, + { url = "https://files.pythonhosted.org/packages/fd/5b/f3d4b063e51b2454bedb828e41f3485800889a3609c49e60f2296cc8b8e5/grpcio-1.70.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:f32090238b720eb585248654db8e3afc87b48d26ac423c8dde8334a232ff53c9", size = 5663954 }, + { url = "https://files.pythonhosted.org/packages/bd/0b/dab54365fcedf63e9f358c1431885478e77d6f190d65668936b12dd38057/grpcio-1.70.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfa089a734f24ee5f6880c83d043e4f46bf812fcea5181dcb3a572db1e79e01c", size = 6304323 }, + { url = "https://files.pythonhosted.org/packages/76/a8/8f965a7171ddd336ce32946e22954aa1bbc6f23f095e15dadaa70604ba20/grpcio-1.70.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f19375f0300b96c0117aca118d400e76fede6db6e91f3c34b7b035822e06c35f", size = 5910939 }, + { url = "https://files.pythonhosted.org/packages/1b/05/0bbf68be8b17d1ed6f178435a3c0c12e665a1e6054470a64ce3cb7896596/grpcio-1.70.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:7c73c42102e4a5ec76608d9b60227d917cea46dff4d11d372f64cbeb56d259d0", size = 6631405 }, + { url = "https://files.pythonhosted.org/packages/79/6a/5df64b6df405a1ed1482cb6c10044b06ec47fd28e87c2232dbcf435ecb33/grpcio-1.70.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:0a5c78d5198a1f0aa60006cd6eb1c912b4a1520b6a3968e677dbcba215fabb40", size = 6190982 }, + { url = "https://files.pythonhosted.org/packages/42/aa/aeaac87737e6d25d1048c53b8ec408c056d3ed0c922e7c5efad65384250c/grpcio-1.70.0-cp313-cp313-win32.whl", hash = "sha256:fe9dbd916df3b60e865258a8c72ac98f3ac9e2a9542dcb72b7a34d236242a5ce", size = 3598359 }, + { url = "https://files.pythonhosted.org/packages/1f/79/8edd2442d2de1431b4a3de84ef91c37002f12de0f9b577fb07b452989dbc/grpcio-1.70.0-cp313-cp313-win_amd64.whl", hash = "sha256:4119fed8abb7ff6c32e3d2255301e59c316c22d31ab812b3fbcbaf3d0d87cc68", size = 4293938 }, ] [[package]] @@ -1540,15 +1556,15 @@ wheels = [ [[package]] name = "h2" -version = "4.1.0" +version = "4.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "hpack", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "hyperframe", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2a/32/fec683ddd10629ea4ea46d206752a95a2d8a48c22521edd70b142488efe1/h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb", size = 2145593 } +sdist = { url = "https://files.pythonhosted.org/packages/1b/38/d7f80fd13e6582fb8e0df8c9a653dcc02b03ca34f4d72f34869298c5baf8/h2-4.2.0.tar.gz", hash = "sha256:c8a52129695e88b1a0578d8d2cc6842bbd79128ac685463b887ee278126ad01f", size = 2150682 } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/e5/db6d438da759efbb488c4f3fbdab7764492ff3c3f953132efa6b9f0e9e53/h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d", size = 57488 }, + { url = "https://files.pythonhosted.org/packages/d0/9e/984486f2d0a0bd2b024bf4bc1c62688fcafa9e61991f041fb0e2def4a982/h2-4.2.0-py3-none-any.whl", hash = "sha256:479a53ad425bb29af087f3458a61d30780bc818e4ebcf01f0b536ba916462ed0", size = 60957 }, ] [[package]] @@ -1757,11 +1773,11 @@ wheels = [ [[package]] name = "identify" -version = "2.6.6" +version = "2.6.7" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/bf/c68c46601bacd4c6fb4dd751a42b6e7087240eaabc6487f2ef7a48e0e8fc/identify-2.6.6.tar.gz", hash = "sha256:7bec12768ed44ea4761efb47806f0a41f86e7c0a5fdf5950d4648c90eca7e251", size = 99217 } +sdist = { url = "https://files.pythonhosted.org/packages/83/d1/524aa3350f78bcd714d148ade6133d67d6b7de2cdbae7d99039c024c9a25/identify-2.6.7.tar.gz", hash = "sha256:3fa266b42eba321ee0b2bb0936a6a6b9e36a1351cbb69055b3082f4193035684", size = 99260 } wheels = [ - { url = "https://files.pythonhosted.org/packages/74/a1/68a395c17eeefb04917034bd0a1bfa765e7654fa150cca473d669aa3afb5/identify-2.6.6-py2.py3-none-any.whl", hash = "sha256:cbd1810bce79f8b671ecb20f53ee0ae8e86ae84b557de31d89709dc2a48ba881", size = 99083 }, + { url = "https://files.pythonhosted.org/packages/03/00/1fd4a117c6c93f2dcc5b7edaeaf53ea45332ef966429be566ca16c2beb94/identify-2.6.7-py2.py3-none-any.whl", hash = "sha256:155931cb617a401807b09ecec6635d6c692d180090a1cedca8ef7d58ba5b6aa0", size = 99097 }, ] [[package]] @@ -1829,7 +1845,7 @@ wheels = [ [[package]] name = "ipython" -version = "8.31.0" +version = "8.32.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -1844,9 +1860,9 @@ dependencies = [ { name = "traitlets", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "typing-extensions", marker = "(python_full_version < '3.12' and sys_platform == 'darwin') or (python_full_version < '3.12' and sys_platform == 'linux') or (python_full_version < '3.12' and sys_platform == 'win32')" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/01/35/6f90fdddff7a08b7b715fccbd2427b5212c9525cd043d26fdc45bee0708d/ipython-8.31.0.tar.gz", hash = "sha256:b6a2274606bec6166405ff05e54932ed6e5cfecaca1fc05f2cacde7bb074d70b", size = 5501011 } +sdist = { url = "https://files.pythonhosted.org/packages/36/80/4d2a072e0db7d250f134bc11676517299264ebe16d62a8619d49a78ced73/ipython-8.32.0.tar.gz", hash = "sha256:be2c91895b0b9ea7ba49d33b23e2040c352b33eb6a519cca7ce6e0c743444251", size = 5507441 } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/60/d0feb6b6d9fe4ab89fe8fe5b47cbf6cd936bfd9f1e7ffa9d0015425aeed6/ipython-8.31.0-py3-none-any.whl", hash = "sha256:46ec58f8d3d076a61d128fe517a51eb730e3aaf0c184ea8c17d16e366660c6a6", size = 821583 }, + { url = "https://files.pythonhosted.org/packages/e7/e1/f4474a7ecdb7745a820f6f6039dc43c66add40f1bcc66485607d93571af6/ipython-8.32.0-py3-none-any.whl", hash = "sha256:cae85b0c61eff1fc48b0a8002de5958b6528fa9c8defb1894da63f42613708aa", size = 825524 }, ] [[package]] @@ -2180,6 +2196,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 }, ] +[[package]] +name = "marshmallow" +version = "3.26.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ab/5e/5e53d26b42ab75491cda89b871dab9e97c840bf12c63ec58a1919710cd06/marshmallow-3.26.1.tar.gz", hash = "sha256:e6d8affb6cb61d39d26402096dc0aee12d5a26d490a121f118d2e81dc0719dc6", size = 221825 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/75/51952c7b2d3873b44a0028b1bd26a25078c18f92f256608e8d1dc61b39fd/marshmallow-3.26.1-py3-none-any.whl", hash = "sha256:3350409f20a70a7e4e11a27661187b77cdcaeb20abca41c1454fe33636bea09c", size = 50878 }, +] + [[package]] name = "matplotlib-inline" version = "0.1.7" @@ -2489,40 +2517,40 @@ wheels = [ [[package]] name = "mypy" -version = "1.14.1" +version = "1.15.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mypy-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "tomli", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, { name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b9/eb/2c92d8ea1e684440f54fa49ac5d9a5f19967b7b472a281f419e69a8d228e/mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6", size = 3216051 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9b/7a/87ae2adb31d68402da6da1e5f30c07ea6063e9f09b5e7cfc9dfa44075e74/mypy-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb", size = 11211002 }, - { url = "https://files.pythonhosted.org/packages/e1/23/eada4c38608b444618a132be0d199b280049ded278b24cbb9d3fc59658e4/mypy-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0", size = 10358400 }, - { url = "https://files.pythonhosted.org/packages/43/c9/d6785c6f66241c62fd2992b05057f404237deaad1566545e9f144ced07f5/mypy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d", size = 12095172 }, - { url = "https://files.pythonhosted.org/packages/c3/62/daa7e787770c83c52ce2aaf1a111eae5893de9e004743f51bfcad9e487ec/mypy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b", size = 12828732 }, - { url = "https://files.pythonhosted.org/packages/1b/a2/5fb18318a3637f29f16f4e41340b795da14f4751ef4f51c99ff39ab62e52/mypy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427", size = 13012197 }, - { url = "https://files.pythonhosted.org/packages/28/99/e153ce39105d164b5f02c06c35c7ba958aaff50a2babba7d080988b03fe7/mypy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f", size = 9780836 }, - { url = "https://files.pythonhosted.org/packages/da/11/a9422850fd506edbcdc7f6090682ecceaf1f87b9dd847f9df79942da8506/mypy-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c", size = 11120432 }, - { url = "https://files.pythonhosted.org/packages/b6/9e/47e450fd39078d9c02d620545b2cb37993a8a8bdf7db3652ace2f80521ca/mypy-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1", size = 10279515 }, - { url = "https://files.pythonhosted.org/packages/01/b5/6c8d33bd0f851a7692a8bfe4ee75eb82b6983a3cf39e5e32a5d2a723f0c1/mypy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8", size = 12025791 }, - { url = "https://files.pythonhosted.org/packages/f0/4c/e10e2c46ea37cab5c471d0ddaaa9a434dc1d28650078ac1b56c2d7b9b2e4/mypy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f", size = 12749203 }, - { url = "https://files.pythonhosted.org/packages/88/55/beacb0c69beab2153a0f57671ec07861d27d735a0faff135a494cd4f5020/mypy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1", size = 12885900 }, - { url = "https://files.pythonhosted.org/packages/a2/75/8c93ff7f315c4d086a2dfcde02f713004357d70a163eddb6c56a6a5eff40/mypy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae", size = 9777869 }, - { url = "https://files.pythonhosted.org/packages/43/1b/b38c079609bb4627905b74fc6a49849835acf68547ac33d8ceb707de5f52/mypy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14", size = 11266668 }, - { url = "https://files.pythonhosted.org/packages/6b/75/2ed0d2964c1ffc9971c729f7a544e9cd34b2cdabbe2d11afd148d7838aa2/mypy-1.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9", size = 10254060 }, - { url = "https://files.pythonhosted.org/packages/a1/5f/7b8051552d4da3c51bbe8fcafffd76a6823779101a2b198d80886cd8f08e/mypy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11", size = 11933167 }, - { url = "https://files.pythonhosted.org/packages/04/90/f53971d3ac39d8b68bbaab9a4c6c58c8caa4d5fd3d587d16f5927eeeabe1/mypy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e", size = 12864341 }, - { url = "https://files.pythonhosted.org/packages/03/d2/8bc0aeaaf2e88c977db41583559319f1821c069e943ada2701e86d0430b7/mypy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89", size = 12972991 }, - { url = "https://files.pythonhosted.org/packages/6f/17/07815114b903b49b0f2cf7499f1c130e5aa459411596668267535fe9243c/mypy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b", size = 9879016 }, - { url = "https://files.pythonhosted.org/packages/9e/15/bb6a686901f59222275ab228453de741185f9d54fecbaacec041679496c6/mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255", size = 11252097 }, - { url = "https://files.pythonhosted.org/packages/f8/b3/8b0f74dfd072c802b7fa368829defdf3ee1566ba74c32a2cb2403f68024c/mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34", size = 10239728 }, - { url = "https://files.pythonhosted.org/packages/c5/9b/4fd95ab20c52bb5b8c03cc49169be5905d931de17edfe4d9d2986800b52e/mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a", size = 11924965 }, - { url = "https://files.pythonhosted.org/packages/56/9d/4a236b9c57f5d8f08ed346914b3f091a62dd7e19336b2b2a0d85485f82ff/mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9", size = 12867660 }, - { url = "https://files.pythonhosted.org/packages/40/88/a61a5497e2f68d9027de2bb139c7bb9abaeb1be1584649fa9d807f80a338/mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd", size = 12969198 }, - { url = "https://files.pythonhosted.org/packages/54/da/3d6fc5d92d324701b0c23fb413c853892bfe0e1dbe06c9138037d459756b/mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107", size = 9885276 }, - { url = "https://files.pythonhosted.org/packages/a0/b5/32dd67b69a16d088e533962e5044e51004176a9952419de0370cdaead0f8/mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1", size = 2752905 }, +sdist = { url = "https://files.pythonhosted.org/packages/ce/43/d5e49a86afa64bd3839ea0d5b9c7103487007d728e1293f52525d6d5486a/mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43", size = 3239717 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/68/f8/65a7ce8d0e09b6329ad0c8d40330d100ea343bd4dd04c4f8ae26462d0a17/mypy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13", size = 10738433 }, + { url = "https://files.pythonhosted.org/packages/b4/95/9c0ecb8eacfe048583706249439ff52105b3f552ea9c4024166c03224270/mypy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559", size = 9861472 }, + { url = "https://files.pythonhosted.org/packages/84/09/9ec95e982e282e20c0d5407bc65031dfd0f0f8ecc66b69538296e06fcbee/mypy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b", size = 11611424 }, + { url = "https://files.pythonhosted.org/packages/78/13/f7d14e55865036a1e6a0a69580c240f43bc1f37407fe9235c0d4ef25ffb0/mypy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3", size = 12365450 }, + { url = "https://files.pythonhosted.org/packages/48/e1/301a73852d40c241e915ac6d7bcd7fedd47d519246db2d7b86b9d7e7a0cb/mypy-1.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b", size = 12551765 }, + { url = "https://files.pythonhosted.org/packages/77/ba/c37bc323ae5fe7f3f15a28e06ab012cd0b7552886118943e90b15af31195/mypy-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828", size = 9274701 }, + { url = "https://files.pythonhosted.org/packages/03/bc/f6339726c627bd7ca1ce0fa56c9ae2d0144604a319e0e339bdadafbbb599/mypy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f", size = 10662338 }, + { url = "https://files.pythonhosted.org/packages/e2/90/8dcf506ca1a09b0d17555cc00cd69aee402c203911410136cd716559efe7/mypy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5", size = 9787540 }, + { url = "https://files.pythonhosted.org/packages/05/05/a10f9479681e5da09ef2f9426f650d7b550d4bafbef683b69aad1ba87457/mypy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e", size = 11538051 }, + { url = "https://files.pythonhosted.org/packages/e9/9a/1f7d18b30edd57441a6411fcbc0c6869448d1a4bacbaee60656ac0fc29c8/mypy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c", size = 12286751 }, + { url = "https://files.pythonhosted.org/packages/72/af/19ff499b6f1dafcaf56f9881f7a965ac2f474f69f6f618b5175b044299f5/mypy-1.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f", size = 12421783 }, + { url = "https://files.pythonhosted.org/packages/96/39/11b57431a1f686c1aed54bf794870efe0f6aeca11aca281a0bd87a5ad42c/mypy-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f", size = 9265618 }, + { url = "https://files.pythonhosted.org/packages/98/3a/03c74331c5eb8bd025734e04c9840532226775c47a2c39b56a0c8d4f128d/mypy-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd", size = 10793981 }, + { url = "https://files.pythonhosted.org/packages/f0/1a/41759b18f2cfd568848a37c89030aeb03534411eef981df621d8fad08a1d/mypy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f", size = 9749175 }, + { url = "https://files.pythonhosted.org/packages/12/7e/873481abf1ef112c582db832740f4c11b2bfa510e829d6da29b0ab8c3f9c/mypy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464", size = 11455675 }, + { url = "https://files.pythonhosted.org/packages/b3/d0/92ae4cde706923a2d3f2d6c39629134063ff64b9dedca9c1388363da072d/mypy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee", size = 12410020 }, + { url = "https://files.pythonhosted.org/packages/46/8b/df49974b337cce35f828ba6fda228152d6db45fed4c86ba56ffe442434fd/mypy-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e", size = 12498582 }, + { url = "https://files.pythonhosted.org/packages/13/50/da5203fcf6c53044a0b699939f31075c45ae8a4cadf538a9069b165c1050/mypy-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22", size = 9366614 }, + { url = "https://files.pythonhosted.org/packages/6a/9b/fd2e05d6ffff24d912f150b87db9e364fa8282045c875654ce7e32fffa66/mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445", size = 10788592 }, + { url = "https://files.pythonhosted.org/packages/74/37/b246d711c28a03ead1fd906bbc7106659aed7c089d55fe40dd58db812628/mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d", size = 9753611 }, + { url = "https://files.pythonhosted.org/packages/a6/ac/395808a92e10cfdac8003c3de9a2ab6dc7cde6c0d2a4df3df1b815ffd067/mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5", size = 11438443 }, + { url = "https://files.pythonhosted.org/packages/d2/8b/801aa06445d2de3895f59e476f38f3f8d610ef5d6908245f07d002676cbf/mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036", size = 12402541 }, + { url = "https://files.pythonhosted.org/packages/c7/67/5a4268782eb77344cc613a4cf23540928e41f018a9a1ec4c6882baf20ab8/mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357", size = 12494348 }, + { url = "https://files.pythonhosted.org/packages/83/3e/57bb447f7bbbfaabf1712d96f9df142624a386d98fb026a761532526057e/mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf", size = 9373648 }, + { url = "https://files.pythonhosted.org/packages/09/4e/a7d65c7322c510de2c409ff3828b03354a7c43f5a8ed458a7a131b41c7b9/mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e", size = 2221777 }, ] [[package]] @@ -2683,6 +2711,7 @@ name = "nvidia-cublas-cu12" version = "12.4.5.8" source = { registry = "https://pypi.org/simple" } wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/7f/7fbae15a3982dc9595e49ce0f19332423b260045d0a6afe93cdbe2f1f624/nvidia_cublas_cu12-12.4.5.8-py3-none-manylinux2014_aarch64.whl", hash = "sha256:0f8aa1706812e00b9f19dfe0cdb3999b092ccb8ca168c0db5b8ea712456fd9b3", size = 363333771 }, { url = "https://files.pythonhosted.org/packages/ae/71/1c91302526c45ab494c23f61c7a84aa568b8c1f9d196efa5993957faf906/nvidia_cublas_cu12-12.4.5.8-py3-none-manylinux2014_x86_64.whl", hash = "sha256:2fc8da60df463fdefa81e323eef2e36489e1c94335b5358bcb38360adf75ac9b", size = 363438805 }, ] @@ -2691,6 +2720,7 @@ name = "nvidia-cuda-cupti-cu12" version = "12.4.127" source = { registry = "https://pypi.org/simple" } wheels = [ + { url = "https://files.pythonhosted.org/packages/93/b5/9fb3d00386d3361b03874246190dfec7b206fd74e6e287b26a8fcb359d95/nvidia_cuda_cupti_cu12-12.4.127-py3-none-manylinux2014_aarch64.whl", hash = "sha256:79279b35cf6f91da114182a5ce1864997fd52294a87a16179ce275773799458a", size = 12354556 }, { url = "https://files.pythonhosted.org/packages/67/42/f4f60238e8194a3106d06a058d494b18e006c10bb2b915655bd9f6ea4cb1/nvidia_cuda_cupti_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:9dec60f5ac126f7bb551c055072b69d85392b13311fcc1bcda2202d172df30fb", size = 13813957 }, ] @@ -2699,6 +2729,7 @@ name = "nvidia-cuda-nvrtc-cu12" version = "12.4.127" source = { registry = "https://pypi.org/simple" } wheels = [ + { url = "https://files.pythonhosted.org/packages/77/aa/083b01c427e963ad0b314040565ea396f914349914c298556484f799e61b/nvidia_cuda_nvrtc_cu12-12.4.127-py3-none-manylinux2014_aarch64.whl", hash = "sha256:0eedf14185e04b76aa05b1fea04133e59f465b6f960c0cbf4e37c3cb6b0ea198", size = 24133372 }, { url = "https://files.pythonhosted.org/packages/2c/14/91ae57cd4db3f9ef7aa99f4019cfa8d54cb4caa7e00975df6467e9725a9f/nvidia_cuda_nvrtc_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a178759ebb095827bd30ef56598ec182b85547f1508941a3d560eb7ea1fbf338", size = 24640306 }, ] @@ -2707,6 +2738,7 @@ name = "nvidia-cuda-runtime-cu12" version = "12.4.127" source = { registry = "https://pypi.org/simple" } wheels = [ + { url = "https://files.pythonhosted.org/packages/a1/aa/b656d755f474e2084971e9a297def515938d56b466ab39624012070cb773/nvidia_cuda_runtime_cu12-12.4.127-py3-none-manylinux2014_aarch64.whl", hash = "sha256:961fe0e2e716a2a1d967aab7caee97512f71767f852f67432d572e36cb3a11f3", size = 894177 }, { url = "https://files.pythonhosted.org/packages/ea/27/1795d86fe88ef397885f2e580ac37628ed058a92ed2c39dc8eac3adf0619/nvidia_cuda_runtime_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:64403288fa2136ee8e467cdc9c9427e0434110899d07c779f25b5c068934faa5", size = 883737 }, ] @@ -2729,6 +2761,7 @@ dependencies = [ { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, ] wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/8a/0e728f749baca3fbeffad762738276e5df60851958be7783af121a7221e7/nvidia_cufft_cu12-11.2.1.3-py3-none-manylinux2014_aarch64.whl", hash = "sha256:5dad8008fc7f92f5ddfa2101430917ce2ffacd86824914c82e28990ad7f00399", size = 211422548 }, { url = "https://files.pythonhosted.org/packages/27/94/3266821f65b92b3138631e9c8e7fe1fb513804ac934485a8d05776e1dd43/nvidia_cufft_cu12-11.2.1.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:f083fc24912aa410be21fa16d157fed2055dab1cc4b6934a0e03cba69eb242b9", size = 211459117 }, ] @@ -2737,6 +2770,7 @@ name = "nvidia-curand-cu12" version = "10.3.5.147" source = { registry = "https://pypi.org/simple" } wheels = [ + { url = "https://files.pythonhosted.org/packages/80/9c/a79180e4d70995fdf030c6946991d0171555c6edf95c265c6b2bf7011112/nvidia_curand_cu12-10.3.5.147-py3-none-manylinux2014_aarch64.whl", hash = "sha256:1f173f09e3e3c76ab084aba0de819c49e56614feae5c12f69883f4ae9bb5fad9", size = 56314811 }, { url = "https://files.pythonhosted.org/packages/8a/6d/44ad094874c6f1b9c654f8ed939590bdc408349f137f9b98a3a23ccec411/nvidia_curand_cu12-10.3.5.147-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a88f583d4e0bb643c49743469964103aa59f7f708d862c3ddb0fc07f851e3b8b", size = 56305206 }, ] @@ -2750,6 +2784,7 @@ dependencies = [ { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, ] wheels = [ + { url = "https://files.pythonhosted.org/packages/46/6b/a5c33cf16af09166845345275c34ad2190944bcc6026797a39f8e0a282e0/nvidia_cusolver_cu12-11.6.1.9-py3-none-manylinux2014_aarch64.whl", hash = "sha256:d338f155f174f90724bbde3758b7ac375a70ce8e706d70b018dd3375545fc84e", size = 127634111 }, { url = "https://files.pythonhosted.org/packages/3a/e1/5b9089a4b2a4790dfdea8b3a006052cfecff58139d5a4e34cb1a51df8d6f/nvidia_cusolver_cu12-11.6.1.9-py3-none-manylinux2014_x86_64.whl", hash = "sha256:19e33fa442bcfd085b3086c4ebf7e8debc07cfe01e11513cc6d332fd918ac260", size = 127936057 }, ] @@ -2761,9 +2796,19 @@ dependencies = [ { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, ] wheels = [ + { url = "https://files.pythonhosted.org/packages/96/a9/c0d2f83a53d40a4a41be14cea6a0bf9e668ffcf8b004bd65633f433050c0/nvidia_cusparse_cu12-12.3.1.170-py3-none-manylinux2014_aarch64.whl", hash = "sha256:9d32f62896231ebe0480efd8a7f702e143c98cfaa0e8a76df3386c1ba2b54df3", size = 207381987 }, { url = "https://files.pythonhosted.org/packages/db/f7/97a9ea26ed4bbbfc2d470994b8b4f338ef663be97b8f677519ac195e113d/nvidia_cusparse_cu12-12.3.1.170-py3-none-manylinux2014_x86_64.whl", hash = "sha256:ea4f11a2904e2a8dc4b1833cc1b5181cde564edd0d5cd33e3c168eff2d1863f1", size = 207454763 }, ] +[[package]] +name = "nvidia-cusparselt-cu12" +version = "0.6.2" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/8e/675498726c605c9441cf46653bd29cb1b8666da1fb1469ffa25f67f20c58/nvidia_cusparselt_cu12-0.6.2-py3-none-manylinux2014_aarch64.whl", hash = "sha256:067a7f6d03ea0d4841c85f0c6f1991c5dda98211f6302cb83a4ab234ee95bef8", size = 149422781 }, + { url = "https://files.pythonhosted.org/packages/78/a8/bcbb63b53a4b1234feeafb65544ee55495e1bb37ec31b999b963cbccfd1d/nvidia_cusparselt_cu12-0.6.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:df2c24502fd76ebafe7457dbc4716b2fec071aabaed4fb7691a201cde03704d9", size = 150057751 }, +] + [[package]] name = "nvidia-nccl-cu12" version = "2.21.5" @@ -2777,6 +2822,7 @@ name = "nvidia-nvjitlink-cu12" version = "12.4.127" source = { registry = "https://pypi.org/simple" } wheels = [ + { url = "https://files.pythonhosted.org/packages/02/45/239d52c05074898a80a900f49b1615d81c07fceadd5ad6c4f86a987c0bc4/nvidia_nvjitlink_cu12-12.4.127-py3-none-manylinux2014_aarch64.whl", hash = "sha256:4abe7fef64914ccfa909bc2ba39739670ecc9e820c83ccc7a6ed414122599b83", size = 20552510 }, { url = "https://files.pythonhosted.org/packages/ff/ff/847841bacfbefc97a00036e0fce5a0f086b640756dc38caea5e1bb002655/nvidia_nvjitlink_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:06b3b9b25bf3f8af351d664978ca26a16d2c5127dbd53c0497e28d1fb9611d57", size = 21066810 }, ] @@ -2785,6 +2831,7 @@ name = "nvidia-nvtx-cu12" version = "12.4.127" source = { registry = "https://pypi.org/simple" } wheels = [ + { url = "https://files.pythonhosted.org/packages/06/39/471f581edbb7804b39e8063d92fc8305bdc7a80ae5c07dbe6ea5c50d14a5/nvidia_nvtx_cu12-12.4.127-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7959ad635db13edf4fc65c06a6e9f9e55fc2f92596db928d169c0bb031e88ef3", size = 100417 }, { url = "https://files.pythonhosted.org/packages/87/20/199b8713428322a2f22b722c62b8cc278cc53dffa9705d744484b5035ee9/nvidia_nvtx_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:781e950d9b9f60d8241ccea575b32f5105a5baf4c2351cab5256a24869f12a1a", size = 99144 }, ] @@ -2873,7 +2920,7 @@ wheels = [ [[package]] name = "openai" -version = "1.60.2" +version = "1.61.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, @@ -2885,9 +2932,9 @@ dependencies = [ { name = "tqdm", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/08/ae/8d9706b8ff2363287b4a8807de2dd29cdbdad5424e9d05d345df724320f5/openai-1.60.2.tar.gz", hash = "sha256:a8f843e10f2855713007f491d96afb2694b11b5e02cb97c7d01a0be60bc5bb51", size = 348185 } +sdist = { url = "https://files.pythonhosted.org/packages/d9/cf/61e71ce64cf0a38f029da0f9a5f10c9fa0e69a7a977b537126dac50adfea/openai-1.61.1.tar.gz", hash = "sha256:ce1851507218209961f89f3520e06726c0aa7d0512386f0f977e3ac3e4f2472e", size = 350784 } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/5a/d5474ca67a547dde9b87b5bc8a8f90eadf29f523d410f2ba23d63c9b82ec/openai-1.60.2-py3-none-any.whl", hash = "sha256:993bd11b96900b9098179c728026f016b4982ded7ee30dfcf4555eab1171fff9", size = 456107 }, + { url = "https://files.pythonhosted.org/packages/9a/b6/2e2a011b2dc27a6711376808b4cd8c922c476ea0f1420b39892117fa8563/openai-1.61.1-py3-none-any.whl", hash = "sha256:72b0826240ce26026ac2cd17951691f046e5be82ad122d20a8e1b30ca18bd11e", size = 463126 }, ] [[package]] @@ -2940,15 +2987,15 @@ wheels = [ [[package]] name = "opentelemetry-api" -version = "1.29.0" +version = "1.30.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "deprecated", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "importlib-metadata", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bc/8e/b886a5e9861afa188d1fe671fb96ff9a1d90a23d57799331e137cc95d573/opentelemetry_api-1.29.0.tar.gz", hash = "sha256:d04a6cf78aad09614f52964ecb38021e248f5714dc32c2e0d8fd99517b4d69cf", size = 62900 } +sdist = { url = "https://files.pythonhosted.org/packages/2b/6d/bbbf879826b7f3c89a45252010b5796fb1f1a0d45d9dc4709db0ef9a06c8/opentelemetry_api-1.30.0.tar.gz", hash = "sha256:375893400c1435bf623f7dfb3bcd44825fe6b56c34d0667c542ea8257b1a1240", size = 63703 } wheels = [ - { url = "https://files.pythonhosted.org/packages/43/53/5249ea860d417a26a3a6f1bdedfc0748c4f081a3adaec3d398bc0f7c6a71/opentelemetry_api-1.29.0-py3-none-any.whl", hash = "sha256:5fcd94c4141cc49c736271f3e1efb777bebe9cc535759c54c936cca4f1b312b8", size = 64304 }, + { url = "https://files.pythonhosted.org/packages/36/0a/eea862fae6413d8181b23acf8e13489c90a45f17986ee9cf4eab8a0b9ad9/opentelemetry_api-1.30.0-py3-none-any.whl", hash = "sha256:d5f5284890d73fdf47f843dda3210edf37a38d66f44f2b5aedc1e89ed455dc09", size = 64955 }, ] [[package]] @@ -2970,7 +3017,7 @@ wheels = [ [[package]] name = "opentelemetry-instrumentation" -version = "0.50b0" +version = "0.51b0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-api", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, @@ -2978,14 +3025,14 @@ dependencies = [ { name = "packaging", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "wrapt", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/79/2e/2e59a7cb636dc394bd7cf1758ada5e8ed87590458ca6bb2f9c26e0243847/opentelemetry_instrumentation-0.50b0.tar.gz", hash = "sha256:7d98af72de8dec5323e5202e46122e5f908592b22c6d24733aad619f07d82979", size = 26539 } +sdist = { url = "https://files.pythonhosted.org/packages/ec/5a/4c7f02235ac1269b48f3855f6be1afc641f31d4888d28b90b732fbce7141/opentelemetry_instrumentation-0.51b0.tar.gz", hash = "sha256:4ca266875e02f3988536982467f7ef8c32a38b8895490ddce9ad9604649424fa", size = 27760 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ff/b1/55a77152a83ec8998e520a3a575f44af1020cfe4bdc000b7538583293b85/opentelemetry_instrumentation-0.50b0-py3-none-any.whl", hash = "sha256:b8f9fc8812de36e1c6dffa5bfc6224df258841fb387b6dfe5df15099daa10630", size = 30728 }, + { url = "https://files.pythonhosted.org/packages/40/2c/48fa93f1acca9f79a06da0df7bfe916632ecc7fce1971067b3e46bcae55b/opentelemetry_instrumentation-0.51b0-py3-none-any.whl", hash = "sha256:c6de8bd26b75ec8b0e54dff59e198946e29de6a10ec65488c357d4b34aa5bdcf", size = 30923 }, ] [[package]] name = "opentelemetry-instrumentation-asgi" -version = "0.50b0" +version = "0.51b0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "asgiref", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, @@ -2994,14 +3041,14 @@ dependencies = [ { name = "opentelemetry-semantic-conventions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "opentelemetry-util-http", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/49/cc/a7b2fd243c6d2621803092eba62e450071b6752dfe4f64f530bbfd91a328/opentelemetry_instrumentation_asgi-0.50b0.tar.gz", hash = "sha256:3ca4cb5616ae6a3e8ce86e7d5c360a8d8cc8ed722cf3dc8a5e44300774e87d49", size = 24105 } +sdist = { url = "https://files.pythonhosted.org/packages/9e/67/8aa6e1129f641f0f3f8786e6c5d18c1f2bbe490bd4b0e91a6879e85154d2/opentelemetry_instrumentation_asgi-0.51b0.tar.gz", hash = "sha256:b3fe97c00f0bfa934371a69674981d76591c68d937b6422a5716ca21081b4148", size = 24201 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/81/0899c6b56b1023835f266d909250d439174afa0c34ed5944c5021d3da263/opentelemetry_instrumentation_asgi-0.50b0-py3-none-any.whl", hash = "sha256:2ba1297f746e55dec5a17fe825689da0613662fb25c004c3965a6c54b1d5be22", size = 16304 }, + { url = "https://files.pythonhosted.org/packages/54/7e/0a95ab37302729543631a789ba8e71dea75c520495739dbbbdfdc580b401/opentelemetry_instrumentation_asgi-0.51b0-py3-none-any.whl", hash = "sha256:e8072993db47303b633c6ec1bc74726ba4d32bd0c46c28dfadf99f79521a324c", size = 16340 }, ] [[package]] name = "opentelemetry-instrumentation-fastapi" -version = "0.50b0" +version = "0.51b0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-api", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, @@ -3010,9 +3057,9 @@ dependencies = [ { name = "opentelemetry-semantic-conventions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "opentelemetry-util-http", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8d/f8/1917b0b3e414e23c7d71c9a33f0ce020f94bc47d22a30f54ace704e07588/opentelemetry_instrumentation_fastapi-0.50b0.tar.gz", hash = "sha256:16b9181682136da210295def2bb304a32fb9bdee9a935cdc9da43567f7c1149e", size = 19214 } +sdist = { url = "https://files.pythonhosted.org/packages/2d/dc/8db4422b5084177d1ef6c7855c69bf2e9e689f595a4a9b59e60588e0d427/opentelemetry_instrumentation_fastapi-0.51b0.tar.gz", hash = "sha256:1624e70f2f4d12ceb792d8a0c331244cd6723190ccee01336273b4559bc13abc", size = 19249 } wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/d6/37784bb30b213e2dd6838b9f96c2940907022c1b75ef1ff18a99afe42433/opentelemetry_instrumentation_fastapi-0.50b0-py3-none-any.whl", hash = "sha256:8f03b738495e4705fbae51a2826389c7369629dace89d0f291c06ffefdff5e52", size = 12079 }, + { url = "https://files.pythonhosted.org/packages/55/1c/ec2d816b78edf2404d7b3df6d09eefb690b70bfd191b7da06f76634f1bdc/opentelemetry_instrumentation_fastapi-0.51b0-py3-none-any.whl", hash = "sha256:10513bbc11a1188adb9c1d2c520695f7a8f2b5f4de14e8162098035901cd6493", size = 12117 }, ] [[package]] @@ -3029,38 +3076,38 @@ wheels = [ [[package]] name = "opentelemetry-sdk" -version = "1.29.0" +version = "1.30.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-api", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "opentelemetry-semantic-conventions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0c/5a/1ed4c3cf6c09f80565fc085f7e8efa0c222712fd2a9412d07424705dcf72/opentelemetry_sdk-1.29.0.tar.gz", hash = "sha256:b0787ce6aade6ab84315302e72bd7a7f2f014b0fb1b7c3295b88afe014ed0643", size = 157229 } +sdist = { url = "https://files.pythonhosted.org/packages/93/ee/d710062e8a862433d1be0b85920d0c653abe318878fef2d14dfe2c62ff7b/opentelemetry_sdk-1.30.0.tar.gz", hash = "sha256:c9287a9e4a7614b9946e933a67168450b9ab35f08797eb9bc77d998fa480fa18", size = 158633 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/1d/512b86af21795fb463726665e2f61db77d384e8779fdcf4cb0ceec47866d/opentelemetry_sdk-1.29.0-py3-none-any.whl", hash = "sha256:173be3b5d3f8f7d671f20ea37056710217959e774e2749d984355d1f9391a30a", size = 118078 }, + { url = "https://files.pythonhosted.org/packages/97/28/64d781d6adc6bda2260067ce2902bd030cf45aec657e02e28c5b4480b976/opentelemetry_sdk-1.30.0-py3-none-any.whl", hash = "sha256:14fe7afc090caad881addb6926cec967129bd9260c4d33ae6a217359f6b61091", size = 118717 }, ] [[package]] name = "opentelemetry-semantic-conventions" -version = "0.50b0" +version = "0.51b0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "deprecated", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "opentelemetry-api", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e7/4e/d7c7c91ff47cd96fe4095dd7231701aec7347426fd66872ff320d6cd1fcc/opentelemetry_semantic_conventions-0.50b0.tar.gz", hash = "sha256:02dc6dbcb62f082de9b877ff19a3f1ffaa3c306300fa53bfac761c4567c83d38", size = 100459 } +sdist = { url = "https://files.pythonhosted.org/packages/1e/c0/0f9ef4605fea7f2b83d55dd0b0d7aebe8feead247cd6facd232b30907b4f/opentelemetry_semantic_conventions-0.51b0.tar.gz", hash = "sha256:3fabf47f35d1fd9aebcdca7e6802d86bd5ebc3bc3408b7e3248dde6e87a18c47", size = 107191 } wheels = [ - { url = "https://files.pythonhosted.org/packages/da/fb/dc15fad105450a015e913cfa4f5c27b6a5f1bea8fb649f8cae11e699c8af/opentelemetry_semantic_conventions-0.50b0-py3-none-any.whl", hash = "sha256:e87efba8fdb67fb38113efea6a349531e75ed7ffc01562f65b802fcecb5e115e", size = 166602 }, + { url = "https://files.pythonhosted.org/packages/2e/75/d7bdbb6fd8630b4cafb883482b75c4fc276b6426619539d266e32ac53266/opentelemetry_semantic_conventions-0.51b0-py3-none-any.whl", hash = "sha256:fdc777359418e8d06c86012c3dc92c88a6453ba662e941593adb062e48c2eeae", size = 177416 }, ] [[package]] name = "opentelemetry-util-http" -version = "0.50b0" +version = "0.51b0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/69/10/ce3f0d1157cedbd819194f0b27a6bbb7c19a8bceb3941e4a4775014076cf/opentelemetry_util_http-0.50b0.tar.gz", hash = "sha256:dc4606027e1bc02aabb9533cc330dd43f874fca492e4175c31d7154f341754af", size = 7859 } +sdist = { url = "https://files.pythonhosted.org/packages/58/64/32510c0a803465eb6ef1f5bd514d0f5627f8abc9444ed94f7240faf6fcaa/opentelemetry_util_http-0.51b0.tar.gz", hash = "sha256:05edd19ca1cc3be3968b1e502fd94816901a365adbeaab6b6ddb974384d3a0b9", size = 8043 } wheels = [ - { url = "https://files.pythonhosted.org/packages/64/8a/9e1b54f50d1fddebbeac9a9b0632f8db6ece7add904fb593ee2e268ee4de/opentelemetry_util_http-0.50b0-py3-none-any.whl", hash = "sha256:21f8aedac861ffa3b850f8c0a6c373026189eb8630ac6e14a2bf8c55695cc090", size = 6942 }, + { url = "https://files.pythonhosted.org/packages/48/dd/c371eeb9cc78abbdad231a27ce1a196a37ef96328d876ccbb381dea4c8ee/opentelemetry_util_http-0.51b0-py3-none-any.whl", hash = "sha256:0561d7a6e9c422b9ef9ae6e77eafcfcd32a2ab689f5e801475cbb67f189efa20", size = 7304 }, ] [[package]] @@ -3862,20 +3909,20 @@ sdist = { url = "https://files.pythonhosted.org/packages/ce/af/409edba35fc597f1e [[package]] name = "pymilvus" -version = "2.5.4" +version = "2.4.9" source = { registry = "https://pypi.org/simple" } dependencies = [ + { name = "environs", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "grpcio", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "milvus-lite", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "pandas", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "protobuf", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "python-dotenv", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "setuptools", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "ujson", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f7/64/b00289d52e33a6ebc645cf0d60a7a0a3ce4db74648ceb1f55d776971e34d/pymilvus-2.5.4.tar.gz", hash = "sha256:611732428ff669d57ded3d1f823bdeb10febf233d0251cce8498b287e5a10ce8", size = 1250160 } +sdist = { url = "https://files.pythonhosted.org/packages/1c/e4/208ac8d384bdcfa1a2983a6394705edccfd15a99f6f0e478ea0400fc1c73/pymilvus-2.4.9.tar.gz", hash = "sha256:0937663700007c23a84cfc0656160b301f6ff9247aaec4c96d599a6b43572136", size = 1219775 } wheels = [ - { url = "https://files.pythonhosted.org/packages/26/e6/1ba3cae7c723ecf9ede7a30c78824953afc2fe4bab5fce8ec5d8e233f541/pymilvus-2.5.4-py3-none-any.whl", hash = "sha256:3f7ddaeae0c8f63554b8e316b73f265d022e05a457d47c366ce47293434a3aea", size = 222399 }, + { url = "https://files.pythonhosted.org/packages/0e/98/0d79ebcc04e8a469f796e644302edee4368927a268f11afc298b6bd76e1f/pymilvus-2.4.9-py3-none-any.whl", hash = "sha256:45313607d2c164064bdc44e0f933cb6d6afa92e9efcc7f357c5240c57db58fbe", size = 201144 }, ] [[package]] @@ -4053,11 +4100,11 @@ wheels = [ [[package]] name = "pytz" -version = "2024.2" +version = "2025.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3a/31/3c70bf7603cc2dca0f19bdc53b4537a797747a58875b552c8c413d963a3f/pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a", size = 319692 } +sdist = { url = "https://files.pythonhosted.org/packages/5f/57/df1c9157c8d5a05117e455d66fd7cf6dbc46974f832b1058ed4856785d8a/pytz-2025.1.tar.gz", hash = "sha256:c2db42be2a2518b28e65f9207c4d05e6ff547d1efa4086469ef855e4ab70178e", size = 319617 } wheels = [ - { url = "https://files.pythonhosted.org/packages/11/c3/005fcca25ce078d2cc29fd559379817424e94885510568bc1bc53d7d5846/pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725", size = 508002 }, + { url = "https://files.pythonhosted.org/packages/eb/38/ac33370d784287baa1c3d538978b5e2ea064d4c1b93ffbd12826c190dd10/pytz-2025.1-py2.py3-none-any.whl", hash = "sha256:89dd22dca55b46eac6eda23b2d72721bf1bdfef212645d81513ef5d03038de57", size = 507930 }, ] [[package]] @@ -4542,27 +4589,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.9.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c0/17/529e78f49fc6f8076f50d985edd9a2cf011d1dbadb1cdeacc1d12afc1d26/ruff-0.9.4.tar.gz", hash = "sha256:6907ee3529244bb0ed066683e075f09285b38dd5b4039370df6ff06041ca19e7", size = 3599458 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b6/f8/3fafb7804d82e0699a122101b5bee5f0d6e17c3a806dcbc527bb7d3f5b7a/ruff-0.9.4-py3-none-linux_armv6l.whl", hash = "sha256:64e73d25b954f71ff100bb70f39f1ee09e880728efb4250c632ceed4e4cdf706", size = 11668400 }, - { url = "https://files.pythonhosted.org/packages/2e/a6/2efa772d335da48a70ab2c6bb41a096c8517ca43c086ea672d51079e3d1f/ruff-0.9.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6ce6743ed64d9afab4fafeaea70d3631b4d4b28b592db21a5c2d1f0ef52934bf", size = 11628395 }, - { url = "https://files.pythonhosted.org/packages/dc/d7/cd822437561082f1c9d7225cc0d0fbb4bad117ad7ac3c41cd5d7f0fa948c/ruff-0.9.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:54499fb08408e32b57360f6f9de7157a5fec24ad79cb3f42ef2c3f3f728dfe2b", size = 11090052 }, - { url = "https://files.pythonhosted.org/packages/9e/67/3660d58e893d470abb9a13f679223368ff1684a4ef40f254a0157f51b448/ruff-0.9.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37c892540108314a6f01f105040b5106aeb829fa5fb0561d2dcaf71485021137", size = 11882221 }, - { url = "https://files.pythonhosted.org/packages/79/d1/757559995c8ba5f14dfec4459ef2dd3fcea82ac43bc4e7c7bf47484180c0/ruff-0.9.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:de9edf2ce4b9ddf43fd93e20ef635a900e25f622f87ed6e3047a664d0e8f810e", size = 11424862 }, - { url = "https://files.pythonhosted.org/packages/c0/96/7915a7c6877bb734caa6a2af424045baf6419f685632469643dbd8eb2958/ruff-0.9.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87c90c32357c74f11deb7fbb065126d91771b207bf9bfaaee01277ca59b574ec", size = 12626735 }, - { url = "https://files.pythonhosted.org/packages/0e/cc/dadb9b35473d7cb17c7ffe4737b4377aeec519a446ee8514123ff4a26091/ruff-0.9.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:56acd6c694da3695a7461cc55775f3a409c3815ac467279dfa126061d84b314b", size = 13255976 }, - { url = "https://files.pythonhosted.org/packages/5f/c3/ad2dd59d3cabbc12df308cced780f9c14367f0321e7800ca0fe52849da4c/ruff-0.9.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0c93e7d47ed951b9394cf352d6695b31498e68fd5782d6cbc282425655f687a", size = 12752262 }, - { url = "https://files.pythonhosted.org/packages/c7/17/5f1971e54bd71604da6788efd84d66d789362b1105e17e5ccc53bba0289b/ruff-0.9.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d4c8772670aecf037d1bf7a07c39106574d143b26cfe5ed1787d2f31e800214", size = 14401648 }, - { url = "https://files.pythonhosted.org/packages/30/24/6200b13ea611b83260501b6955b764bb320e23b2b75884c60ee7d3f0b68e/ruff-0.9.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfc5f1d7afeda8d5d37660eeca6d389b142d7f2b5a1ab659d9214ebd0e025231", size = 12414702 }, - { url = "https://files.pythonhosted.org/packages/34/cb/f5d50d0c4ecdcc7670e348bd0b11878154bc4617f3fdd1e8ad5297c0d0ba/ruff-0.9.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:faa935fc00ae854d8b638c16a5f1ce881bc3f67446957dd6f2af440a5fc8526b", size = 11859608 }, - { url = "https://files.pythonhosted.org/packages/d6/f4/9c8499ae8426da48363bbb78d081b817b0f64a9305f9b7f87eab2a8fb2c1/ruff-0.9.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a6c634fc6f5a0ceae1ab3e13c58183978185d131a29c425e4eaa9f40afe1e6d6", size = 11485702 }, - { url = "https://files.pythonhosted.org/packages/18/59/30490e483e804ccaa8147dd78c52e44ff96e1c30b5a95d69a63163cdb15b/ruff-0.9.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:433dedf6ddfdec7f1ac7575ec1eb9844fa60c4c8c2f8887a070672b8d353d34c", size = 12067782 }, - { url = "https://files.pythonhosted.org/packages/3d/8c/893fa9551760b2f8eb2a351b603e96f15af167ceaf27e27ad873570bc04c/ruff-0.9.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d612dbd0f3a919a8cc1d12037168bfa536862066808960e0cc901404b77968f0", size = 12483087 }, - { url = "https://files.pythonhosted.org/packages/23/15/f6751c07c21ca10e3f4a51ea495ca975ad936d780c347d9808bcedbd7182/ruff-0.9.4-py3-none-win32.whl", hash = "sha256:db1192ddda2200671f9ef61d9597fcef89d934f5d1705e571a93a67fb13a4402", size = 9852302 }, - { url = "https://files.pythonhosted.org/packages/12/41/2d2d2c6a72e62566f730e49254f602dfed23019c33b5b21ea8f8917315a1/ruff-0.9.4-py3-none-win_amd64.whl", hash = "sha256:05bebf4cdbe3ef75430d26c375773978950bbf4ee3c95ccb5448940dc092408e", size = 10850051 }, - { url = "https://files.pythonhosted.org/packages/c6/e6/3d6ec3bc3d254e7f005c543a661a41c3e788976d0e52a1ada195bd664344/ruff-0.9.4-py3-none-win_arm64.whl", hash = "sha256:585792f1e81509e38ac5123492f8875fbc36f3ede8185af0a26df348e5154f41", size = 10078251 }, +version = "0.9.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/e1/e265aba384343dd8ddd3083f5e33536cd17e1566c41453a5517b5dd443be/ruff-0.9.6.tar.gz", hash = "sha256:81761592f72b620ec8fa1068a6fd00e98a5ebee342a3642efd84454f3031dca9", size = 3639454 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/e3/3d2c022e687e18cf5d93d6bfa2722d46afc64eaa438c7fbbdd603b3597be/ruff-0.9.6-py3-none-linux_armv6l.whl", hash = "sha256:2f218f356dd2d995839f1941322ff021c72a492c470f0b26a34f844c29cdf5ba", size = 11714128 }, + { url = "https://files.pythonhosted.org/packages/e1/22/aff073b70f95c052e5c58153cba735748c9e70107a77d03420d7850710a0/ruff-0.9.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b908ff4df65dad7b251c9968a2e4560836d8f5487c2f0cc238321ed951ea0504", size = 11682539 }, + { url = "https://files.pythonhosted.org/packages/75/a7/f5b7390afd98a7918582a3d256cd3e78ba0a26165a467c1820084587cbf9/ruff-0.9.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b109c0ad2ececf42e75fa99dc4043ff72a357436bb171900714a9ea581ddef83", size = 11132512 }, + { url = "https://files.pythonhosted.org/packages/a6/e3/45de13ef65047fea2e33f7e573d848206e15c715e5cd56095589a7733d04/ruff-0.9.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1de4367cca3dac99bcbd15c161404e849bb0bfd543664db39232648dc00112dc", size = 11929275 }, + { url = "https://files.pythonhosted.org/packages/7d/f2/23d04cd6c43b2e641ab961ade8d0b5edb212ecebd112506188c91f2a6e6c/ruff-0.9.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac3ee4d7c2c92ddfdaedf0bf31b2b176fa7aa8950efc454628d477394d35638b", size = 11466502 }, + { url = "https://files.pythonhosted.org/packages/b5/6f/3a8cf166f2d7f1627dd2201e6cbc4cb81f8b7d58099348f0c1ff7b733792/ruff-0.9.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5dc1edd1775270e6aa2386119aea692039781429f0be1e0949ea5884e011aa8e", size = 12676364 }, + { url = "https://files.pythonhosted.org/packages/f5/c4/db52e2189983c70114ff2b7e3997e48c8318af44fe83e1ce9517570a50c6/ruff-0.9.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4a091729086dffa4bd070aa5dab7e39cc6b9d62eb2bef8f3d91172d30d599666", size = 13335518 }, + { url = "https://files.pythonhosted.org/packages/66/44/545f8a4d136830f08f4d24324e7db957c5374bf3a3f7a6c0bc7be4623a37/ruff-0.9.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1bbc6808bf7b15796cef0815e1dfb796fbd383e7dbd4334709642649625e7c5", size = 12823287 }, + { url = "https://files.pythonhosted.org/packages/c5/26/8208ef9ee7431032c143649a9967c3ae1aae4257d95e6f8519f07309aa66/ruff-0.9.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:589d1d9f25b5754ff230dce914a174a7c951a85a4e9270613a2b74231fdac2f5", size = 14592374 }, + { url = "https://files.pythonhosted.org/packages/31/70/e917781e55ff39c5b5208bda384fd397ffd76605e68544d71a7e40944945/ruff-0.9.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc61dd5131742e21103fbbdcad683a8813be0e3c204472d520d9a5021ca8b217", size = 12500173 }, + { url = "https://files.pythonhosted.org/packages/84/f5/e4ddee07660f5a9622a9c2b639afd8f3104988dc4f6ba0b73ffacffa9a8c/ruff-0.9.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5e2d9126161d0357e5c8f30b0bd6168d2c3872372f14481136d13de9937f79b6", size = 11906555 }, + { url = "https://files.pythonhosted.org/packages/f1/2b/6ff2fe383667075eef8656b9892e73dd9b119b5e3add51298628b87f6429/ruff-0.9.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:68660eab1a8e65babb5229a1f97b46e3120923757a68b5413d8561f8a85d4897", size = 11538958 }, + { url = "https://files.pythonhosted.org/packages/3c/db/98e59e90de45d1eb46649151c10a062d5707b5b7f76f64eb1e29edf6ebb1/ruff-0.9.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c4cae6c4cc7b9b4017c71114115db0445b00a16de3bcde0946273e8392856f08", size = 12117247 }, + { url = "https://files.pythonhosted.org/packages/ec/bc/54e38f6d219013a9204a5a2015c09e7a8c36cedcd50a4b01ac69a550b9d9/ruff-0.9.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:19f505b643228b417c1111a2a536424ddde0db4ef9023b9e04a46ed8a1cb4656", size = 12554647 }, + { url = "https://files.pythonhosted.org/packages/a5/7d/7b461ab0e2404293c0627125bb70ac642c2e8d55bf590f6fce85f508f1b2/ruff-0.9.6-py3-none-win32.whl", hash = "sha256:194d8402bceef1b31164909540a597e0d913c0e4952015a5b40e28c146121b5d", size = 9949214 }, + { url = "https://files.pythonhosted.org/packages/ee/30/c3cee10f915ed75a5c29c1e57311282d1a15855551a64795c1b2bbe5cf37/ruff-0.9.6-py3-none-win_amd64.whl", hash = "sha256:03482d5c09d90d4ee3f40d97578423698ad895c87314c4de39ed2af945633caa", size = 10999914 }, + { url = "https://files.pythonhosted.org/packages/e8/a8/d71f44b93e3aa86ae232af1f2126ca7b95c0f515ec135462b3e1f351441c/ruff-0.9.6-py3-none-win_arm64.whl", hash = "sha256:0e2bb706a2be7ddfea4a4af918562fdc1bcb16df255e5fa595bbd800ce322a5a", size = 10177499 }, ] [[package]] @@ -4689,6 +4736,7 @@ wheels = [ [[package]] name = "semantic-kernel" +version = "1.20.0" source = { editable = "." } dependencies = [ { name = "aiohttp", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, @@ -4817,7 +4865,7 @@ requires-dist = [ { name = "dapr-ext-fastapi", marker = "extra == 'dapr'", specifier = ">=1.14.0" }, { name = "defusedxml", specifier = "~=0.7" }, { name = "flask-dapr", marker = "extra == 'dapr'", specifier = ">=1.14.0" }, - { name = "google-cloud-aiplatform", marker = "extra == 'google'", specifier = "==1.60" }, + { name = "google-cloud-aiplatform", marker = "extra == 'google'", specifier = "==1.79.0" }, { name = "google-generativeai", marker = "extra == 'google'", specifier = "==0.7" }, { name = "ipykernel", marker = "extra == 'notebooks'", specifier = "~=6.29" }, { name = "jinja2", specifier = "~=3.1" }, @@ -4842,12 +4890,12 @@ requires-dist = [ { name = "pydantic", specifier = ">=2.0,!=2.10.0,!=2.10.1,!=2.10.2,!=2.10.3,<2.11" }, { name = "pydantic-settings", specifier = "~=2.0" }, { name = "pymilvus", marker = "extra == 'milvus'", specifier = ">=2.3,<2.6" }, - { name = "pymongo", marker = "extra == 'mongo'", specifier = ">=4.8.0,<4.11" }, + { name = "pymongo", marker = "extra == 'mongo'", specifier = ">=4.8.0,<4.12" }, { name = "qdrant-client", marker = "extra == 'qdrant'", specifier = "~=1.9" }, { name = "redis", extras = ["hiredis"], marker = "extra == 'redis'", specifier = "~=5.0" }, { name = "redisvl", marker = "extra == 'redis'", specifier = ">=0.3.6" }, { name = "sentence-transformers", marker = "extra == 'hugging-face'", specifier = ">=2.2,<4.0" }, - { name = "torch", marker = "extra == 'hugging-face'", specifier = "==2.5.1" }, + { name = "torch", marker = "extra == 'hugging-face'", specifier = "==2.6.0" }, { name = "transformers", extras = ["torch"], marker = "extra == 'hugging-face'", specifier = "~=4.28" }, { name = "types-redis", marker = "extra == 'redis'", specifier = "~=4.6.0.20240425" }, { name = "usearch", marker = "extra == 'usearch'", specifier = "~=2.9" }, @@ -4899,37 +4947,37 @@ wheels = [ [[package]] name = "shapely" -version = "2.0.6" +version = "2.0.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4a/89/0d20bac88016be35ff7d3c0c2ae64b477908f1b1dfa540c5d69ac7af07fe/shapely-2.0.6.tar.gz", hash = "sha256:997f6159b1484059ec239cacaa53467fd8b5564dabe186cd84ac2944663b0bf6", size = 282361 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/17/d4/f84bbbdb7771f5b9ade94db2398b256cf1471f1eb0ca8afbe0f6ca725d5a/shapely-2.0.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29a34e068da2d321e926b5073539fd2a1d4429a2c656bd63f0bd4c8f5b236d0b", size = 1449635 }, - { url = "https://files.pythonhosted.org/packages/03/10/bd6edb66ed0a845f0809f7ce653596f6fd9c6be675b3653872f47bf49f82/shapely-2.0.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c84c3f53144febf6af909d6b581bc05e8785d57e27f35ebaa5c1ab9baba13b", size = 1296756 }, - { url = "https://files.pythonhosted.org/packages/af/09/6374c11cb493a9970e8c04d7be25f578a37f6494a2fecfbed3a447b16b2c/shapely-2.0.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ad2fae12dca8d2b727fa12b007e46fbc522148a584f5d6546c539f3464dccde", size = 2381960 }, - { url = "https://files.pythonhosted.org/packages/2b/a6/302e0d9c210ccf4d1ffadf7ab941797d3255dcd5f93daa73aaf116a4db39/shapely-2.0.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3304883bd82d44be1b27a9d17f1167fda8c7f5a02a897958d86c59ec69b705e", size = 2468133 }, - { url = "https://files.pythonhosted.org/packages/8c/be/e448681dc485f2931d4adee93d531fce93608a3ee59433303cc1a46e21a5/shapely-2.0.6-cp310-cp310-win32.whl", hash = "sha256:3ec3a0eab496b5e04633a39fa3d5eb5454628228201fb24903d38174ee34565e", size = 1294982 }, - { url = "https://files.pythonhosted.org/packages/cd/4c/6f4a6fc085e3be01c4c9de0117a2d373bf9fec5f0426cf4d5c94090a5a4d/shapely-2.0.6-cp310-cp310-win_amd64.whl", hash = "sha256:28f87cdf5308a514763a5c38de295544cb27429cfa655d50ed8431a4796090c4", size = 1441141 }, - { url = "https://files.pythonhosted.org/packages/37/15/269d8e1f7f658a37e61f7028683c546f520e4e7cedba1e32c77ff9d3a3c7/shapely-2.0.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5aeb0f51a9db176da9a30cb2f4329b6fbd1e26d359012bb0ac3d3c7781667a9e", size = 1449578 }, - { url = "https://files.pythonhosted.org/packages/37/63/e182e43081fffa0a2d970c480f2ef91647a6ab94098f61748c23c2a485f2/shapely-2.0.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9a7a78b0d51257a367ee115f4d41ca4d46edbd0dd280f697a8092dd3989867b2", size = 1296792 }, - { url = "https://files.pythonhosted.org/packages/6e/5a/d019f69449329dcd517355444fdb9ddd58bec5e080b8bdba007e8e4c546d/shapely-2.0.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f32c23d2f43d54029f986479f7c1f6e09c6b3a19353a3833c2ffb226fb63a855", size = 2443997 }, - { url = "https://files.pythonhosted.org/packages/25/aa/53f145e5a610a49af9ac49f2f1be1ec8659ebd5c393d66ac94e57c83b00e/shapely-2.0.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3dc9fb0eb56498912025f5eb352b5126f04801ed0e8bdbd867d21bdbfd7cbd0", size = 2528334 }, - { url = "https://files.pythonhosted.org/packages/64/64/0c7b0a22b416d36f6296b92bb4219d82b53d0a7c47e16fd0a4c85f2f117c/shapely-2.0.6-cp311-cp311-win32.whl", hash = "sha256:d93b7e0e71c9f095e09454bf18dad5ea716fb6ced5df3cb044564a00723f339d", size = 1294669 }, - { url = "https://files.pythonhosted.org/packages/b1/5a/6a67d929c467a1973b6bb9f0b00159cc343b02bf9a8d26db1abd2f87aa23/shapely-2.0.6-cp311-cp311-win_amd64.whl", hash = "sha256:c02eb6bf4cfb9fe6568502e85bb2647921ee49171bcd2d4116c7b3109724ef9b", size = 1442032 }, - { url = "https://files.pythonhosted.org/packages/46/77/efd9f9d4b6a762f976f8b082f54c9be16f63050389500fb52e4f6cc07c1a/shapely-2.0.6-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cec9193519940e9d1b86a3b4f5af9eb6910197d24af02f247afbfb47bcb3fab0", size = 1450326 }, - { url = "https://files.pythonhosted.org/packages/68/53/5efa6e7a4036a94fe6276cf7bbb298afded51ca3396b03981ad680c8cc7d/shapely-2.0.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83b94a44ab04a90e88be69e7ddcc6f332da7c0a0ebb1156e1c4f568bbec983c3", size = 1298480 }, - { url = "https://files.pythonhosted.org/packages/88/a2/1be1db4fc262e536465a52d4f19d85834724fedf2299a1b9836bc82fe8fa/shapely-2.0.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:537c4b2716d22c92036d00b34aac9d3775e3691f80c7aa517c2c290351f42cd8", size = 2439311 }, - { url = "https://files.pythonhosted.org/packages/d5/7d/9a57e187cbf2fbbbdfd4044a4f9ce141c8d221f9963750d3b001f0ec080d/shapely-2.0.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98fea108334be345c283ce74bf064fa00cfdd718048a8af7343c59eb40f59726", size = 2524835 }, - { url = "https://files.pythonhosted.org/packages/6d/0a/f407509ab56825f39bf8cfce1fb410238da96cf096809c3e404e5bc71ea1/shapely-2.0.6-cp312-cp312-win32.whl", hash = "sha256:42fd4cd4834747e4990227e4cbafb02242c0cffe9ce7ef9971f53ac52d80d55f", size = 1295613 }, - { url = "https://files.pythonhosted.org/packages/7b/b3/857afd9dfbfc554f10d683ac412eac6fa260d1f4cd2967ecb655c57e831a/shapely-2.0.6-cp312-cp312-win_amd64.whl", hash = "sha256:665990c84aece05efb68a21b3523a6b2057e84a1afbef426ad287f0796ef8a48", size = 1442539 }, - { url = "https://files.pythonhosted.org/packages/34/e8/d164ef5b0eab86088cde06dee8415519ffd5bb0dd1bd9d021e640e64237c/shapely-2.0.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:42805ef90783ce689a4dde2b6b2f261e2c52609226a0438d882e3ced40bb3013", size = 1445344 }, - { url = "https://files.pythonhosted.org/packages/ce/e2/9fba7ac142f7831757a10852bfa465683724eadbc93d2d46f74a16f9af04/shapely-2.0.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6d2cb146191a47bd0cee8ff5f90b47547b82b6345c0d02dd8b25b88b68af62d7", size = 1296182 }, - { url = "https://files.pythonhosted.org/packages/cf/dc/790d4bda27d196cd56ec66975eaae3351c65614cafd0e16ddde39ec9fb92/shapely-2.0.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3fdef0a1794a8fe70dc1f514440aa34426cc0ae98d9a1027fb299d45741c381", size = 2423426 }, - { url = "https://files.pythonhosted.org/packages/af/b0/f8169f77eac7392d41e231911e0095eb1148b4d40c50ea9e34d999c89a7e/shapely-2.0.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c665a0301c645615a107ff7f52adafa2153beab51daf34587170d85e8ba6805", size = 2513249 }, - { url = "https://files.pythonhosted.org/packages/f6/1d/a8c0e9ab49ff2f8e4dedd71b0122eafb22a18ad7e9d256025e1f10c84704/shapely-2.0.6-cp313-cp313-win32.whl", hash = "sha256:0334bd51828f68cd54b87d80b3e7cee93f249d82ae55a0faf3ea21c9be7b323a", size = 1294848 }, - { url = "https://files.pythonhosted.org/packages/23/38/2bc32dd1e7e67a471d4c60971e66df0bdace88656c47a9a728ace0091075/shapely-2.0.6-cp313-cp313-win_amd64.whl", hash = "sha256:d37d070da9e0e0f0a530a621e17c0b8c3c9d04105655132a87cfff8bd77cc4c2", size = 1441371 }, +sdist = { url = "https://files.pythonhosted.org/packages/21/c0/a911d1fd765d07a2b6769ce155219a281bfbe311584ebe97340d75c5bdb1/shapely-2.0.7.tar.gz", hash = "sha256:28fe2997aab9a9dc026dc6a355d04e85841546b2a5d232ed953e3321ab958ee5", size = 283413 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/15/2e/02c694d6ddacd4f13b625722d313d2838f23c5b988cbc680132983f73ce3/shapely-2.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:33fb10e50b16113714ae40adccf7670379e9ccf5b7a41d0002046ba2b8f0f691", size = 1478310 }, + { url = "https://files.pythonhosted.org/packages/87/69/b54a08bcd25e561bdd5183c008ace4424c25e80506e80674032504800efd/shapely-2.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f44eda8bd7a4bccb0f281264b34bf3518d8c4c9a8ffe69a1a05dabf6e8461147", size = 1336082 }, + { url = "https://files.pythonhosted.org/packages/b3/f9/40473fcb5b66ff849e563ca523d2a26dafd6957d52dd876ffd0eded39f1c/shapely-2.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf6c50cd879831955ac47af9c907ce0310245f9d162e298703f82e1785e38c98", size = 2371047 }, + { url = "https://files.pythonhosted.org/packages/d6/f3/c9cc07a7a03b5f5e83bd059f9adf3e21cf086b0e41d7f95e6464b151e798/shapely-2.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:04a65d882456e13c8b417562c36324c0cd1e5915f3c18ad516bb32ee3f5fc895", size = 2469112 }, + { url = "https://files.pythonhosted.org/packages/5d/b9/fc63d6b0b25063a3ff806857a5dc88851d54d1c278288f18cef1b322b449/shapely-2.0.7-cp310-cp310-win32.whl", hash = "sha256:7e97104d28e60b69f9b6a957c4d3a2a893b27525bc1fc96b47b3ccef46726bf2", size = 1296057 }, + { url = "https://files.pythonhosted.org/packages/fe/d1/8df43f94cf4cda0edbab4545f7cdd67d3f1d02910eaff152f9f45c6d00d8/shapely-2.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:35524cc8d40ee4752520819f9894b9f28ba339a42d4922e92c99b148bed3be39", size = 1441787 }, + { url = "https://files.pythonhosted.org/packages/1d/ad/21798c2fec013e289f8ab91d42d4d3299c315b8c4460c08c75fef0901713/shapely-2.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5cf23400cb25deccf48c56a7cdda8197ae66c0e9097fcdd122ac2007e320bc34", size = 1473091 }, + { url = "https://files.pythonhosted.org/packages/15/63/eef4f180f1b5859c70e7f91d2f2570643e5c61e7d7c40743d15f8c6cbc42/shapely-2.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8f1da01c04527f7da59ee3755d8ee112cd8967c15fab9e43bba936b81e2a013", size = 1332921 }, + { url = "https://files.pythonhosted.org/packages/fe/67/77851dd17738bbe7762a0ef1acf7bc499d756f68600dd68a987d78229412/shapely-2.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f623b64bb219d62014781120f47499a7adc30cf7787e24b659e56651ceebcb0", size = 2427949 }, + { url = "https://files.pythonhosted.org/packages/0b/a5/2c8dbb0f383519771df19164e3bf3a8895d195d2edeab4b6040f176ee28e/shapely-2.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6d95703efaa64aaabf278ced641b888fc23d9c6dd71f8215091afd8a26a66e3", size = 2529282 }, + { url = "https://files.pythonhosted.org/packages/dc/4e/e1d608773c7fe4cde36d48903c0d6298e3233dc69412403783ac03fa5205/shapely-2.0.7-cp311-cp311-win32.whl", hash = "sha256:2f6e4759cf680a0f00a54234902415f2fa5fe02f6b05546c662654001f0793a2", size = 1295751 }, + { url = "https://files.pythonhosted.org/packages/27/57/8ec7c62012bed06731f7ee979da7f207bbc4b27feed5f36680b6a70df54f/shapely-2.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:b52f3ab845d32dfd20afba86675c91919a622f4627182daec64974db9b0b4608", size = 1442684 }, + { url = "https://files.pythonhosted.org/packages/4f/3e/ea100eec5811bafd0175eb21828a3be5b0960f65250f4474391868be7c0f/shapely-2.0.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4c2b9859424facbafa54f4a19b625a752ff958ab49e01bc695f254f7db1835fa", size = 1482451 }, + { url = "https://files.pythonhosted.org/packages/ce/53/c6a3487716fd32e1f813d2a9608ba7b72a8a52a6966e31c6443480a1d016/shapely-2.0.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5aed1c6764f51011d69a679fdf6b57e691371ae49ebe28c3edb5486537ffbd51", size = 1345765 }, + { url = "https://files.pythonhosted.org/packages/fd/dd/b35d7891d25cc11066a70fb8d8169a6a7fca0735dd9b4d563a84684969a3/shapely-2.0.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:73c9ae8cf443187d784d57202199bf9fd2d4bb7d5521fe8926ba40db1bc33e8e", size = 2421540 }, + { url = "https://files.pythonhosted.org/packages/62/de/8dbd7df60eb23cb983bb698aac982944b3d602ef0ce877a940c269eae34e/shapely-2.0.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9469f49ff873ef566864cb3516091881f217b5d231c8164f7883990eec88b73", size = 2525741 }, + { url = "https://files.pythonhosted.org/packages/96/64/faf0413ebc7a84fe7a0790bf39ec0b02b40132b68e57aba985c0b6e4e7b6/shapely-2.0.7-cp312-cp312-win32.whl", hash = "sha256:6bca5095e86be9d4ef3cb52d56bdd66df63ff111d580855cb8546f06c3c907cd", size = 1296552 }, + { url = "https://files.pythonhosted.org/packages/63/05/8a1c279c226d6ad7604d9e237713dd21788eab96db97bf4ce0ea565e5596/shapely-2.0.7-cp312-cp312-win_amd64.whl", hash = "sha256:f86e2c0259fe598c4532acfcf638c1f520fa77c1275912bbc958faecbf00b108", size = 1443464 }, + { url = "https://files.pythonhosted.org/packages/c6/21/abea43effbfe11f792e44409ee9ad7635aa93ef1c8ada0ef59b3c1c3abad/shapely-2.0.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a0c09e3e02f948631c7763b4fd3dd175bc45303a0ae04b000856dedebefe13cb", size = 1481618 }, + { url = "https://files.pythonhosted.org/packages/d9/71/af688798da36fe355a6e6ffe1d4628449cb5fa131d57fc169bcb614aeee7/shapely-2.0.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:06ff6020949b44baa8fc2e5e57e0f3d09486cd5c33b47d669f847c54136e7027", size = 1345159 }, + { url = "https://files.pythonhosted.org/packages/67/47/f934fe2b70d31bb9774ad4376e34f81666deed6b811306ff574faa3d115e/shapely-2.0.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d6dbf096f961ca6bec5640e22e65ccdec11e676344e8157fe7d636e7904fd36", size = 2410267 }, + { url = "https://files.pythonhosted.org/packages/f5/8a/2545cc2a30afc63fc6176c1da3b76af28ef9c7358ed4f68f7c6a9d86cf5b/shapely-2.0.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:adeddfb1e22c20548e840403e5e0b3d9dc3daf66f05fa59f1fcf5b5f664f0e98", size = 2514128 }, + { url = "https://files.pythonhosted.org/packages/87/54/2344ce7da39676adec94e84fbaba92a8f1664e4ae2d33bd404dafcbe607f/shapely-2.0.7-cp313-cp313-win32.whl", hash = "sha256:a7f04691ce1c7ed974c2f8b34a1fe4c3c5dfe33128eae886aa32d730f1ec1913", size = 1295783 }, + { url = "https://files.pythonhosted.org/packages/d7/1e/6461e5cfc8e73ae165b8cff6eb26a4d65274fad0e1435137c5ba34fe4e88/shapely-2.0.7-cp313-cp313-win_amd64.whl", hash = "sha256:aaaf5f7e6cc234c1793f2a2760da464b604584fb58c6b6d7d94144fd2692d67e", size = 1442300 }, ] [[package]] @@ -5202,7 +5250,7 @@ wheels = [ [[package]] name = "torch" -version = "2.5.1" +version = "2.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filelock", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, @@ -5218,28 +5266,32 @@ dependencies = [ { name = "nvidia-curand-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-cusolver-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-cusparse-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusparselt-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "setuptools", marker = "(python_full_version >= '3.12' and sys_platform == 'darwin') or (python_full_version >= '3.12' and sys_platform == 'linux') or (python_full_version >= '3.12' and sys_platform == 'win32')" }, { name = "sympy", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "triton", marker = "python_full_version < '3.13' and platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "triton", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/ef/834af4a885b31a0b32fff2d80e1e40f771e1566ea8ded55347502440786a/torch-2.5.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:71328e1bbe39d213b8721678f9dcac30dfc452a46d586f1d514a6aa0a99d4744", size = 906446312 }, - { url = "https://files.pythonhosted.org/packages/69/f0/46e74e0d145f43fa506cb336eaefb2d240547e4ce1f496e442711093ab25/torch-2.5.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:34bfa1a852e5714cbfa17f27c49d8ce35e1b7af5608c4bc6e81392c352dbc601", size = 91919522 }, - { url = "https://files.pythonhosted.org/packages/a5/13/1eb674c8efbd04d71e4a157ceba991904f633e009a584dd65dccbafbb648/torch-2.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:32a037bd98a241df6c93e4c789b683335da76a2ac142c0973675b715102dc5fa", size = 203088048 }, - { url = "https://files.pythonhosted.org/packages/a9/9d/e0860474ee0ff8f6ef2c50ec8f71a250f38d78a9b9df9fd241ad3397a65b/torch-2.5.1-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:23d062bf70776a3d04dbe74db950db2a5245e1ba4f27208a87f0d743b0d06e86", size = 63877046 }, - { url = "https://files.pythonhosted.org/packages/d1/35/e8b2daf02ce933e4518e6f5682c72fd0ed66c15910ea1fb4168f442b71c4/torch-2.5.1-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:de5b7d6740c4b636ef4db92be922f0edc425b65ed78c5076c43c42d362a45457", size = 906474467 }, - { url = "https://files.pythonhosted.org/packages/40/04/bd91593a4ca178ece93ca55f27e2783aa524aaccbfda66831d59a054c31e/torch-2.5.1-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:340ce0432cad0d37f5a31be666896e16788f1adf8ad7be481196b503dad675b9", size = 91919450 }, - { url = "https://files.pythonhosted.org/packages/0d/4a/e51420d46cfc90562e85af2fee912237c662ab31140ab179e49bd69401d6/torch-2.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:603c52d2fe06433c18b747d25f5c333f9c1d58615620578c326d66f258686f9a", size = 203098237 }, - { url = "https://files.pythonhosted.org/packages/d0/db/5d9cbfbc7968d79c5c09a0bc0bc3735da079f2fd07cc10498a62b320a480/torch-2.5.1-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:31f8c39660962f9ae4eeec995e3049b5492eb7360dd4f07377658ef4d728fa4c", size = 63884466 }, - { url = "https://files.pythonhosted.org/packages/8b/5c/36c114d120bfe10f9323ed35061bc5878cc74f3f594003854b0ea298942f/torch-2.5.1-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:ed231a4b3a5952177fafb661213d690a72caaad97d5824dd4fc17ab9e15cec03", size = 906389343 }, - { url = "https://files.pythonhosted.org/packages/6d/69/d8ada8b6e0a4257556d5b4ddeb4345ea8eeaaef3c98b60d1cca197c7ad8e/torch-2.5.1-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:3f4b7f10a247e0dcd7ea97dc2d3bfbfc90302ed36d7f3952b0008d0df264e697", size = 91811673 }, - { url = "https://files.pythonhosted.org/packages/5f/ba/607d013b55b9fd805db2a5c2662ec7551f1910b4eef39653eeaba182c5b2/torch-2.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:73e58e78f7d220917c5dbfad1a40e09df9929d3b95d25e57d9f8558f84c9a11c", size = 203046841 }, - { url = "https://files.pythonhosted.org/packages/57/6c/bf52ff061da33deb9f94f4121fde7ff3058812cb7d2036c97bc167793bd1/torch-2.5.1-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:8c712df61101964eb11910a846514011f0b6f5920c55dbf567bff8a34163d5b1", size = 63858109 }, - { url = "https://files.pythonhosted.org/packages/69/72/20cb30f3b39a9face296491a86adb6ff8f1a47a897e4d14667e6cf89d5c3/torch-2.5.1-cp313-cp313-manylinux1_x86_64.whl", hash = "sha256:9b61edf3b4f6e3b0e0adda8b3960266b9009d02b37555971f4d1c8f7a05afed7", size = 906393265 }, + { url = "https://files.pythonhosted.org/packages/37/81/aa9ab58ec10264c1abe62c8b73f5086c3c558885d6beecebf699f0dbeaeb/torch-2.6.0-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:6860df13d9911ac158f4c44031609700e1eba07916fff62e21e6ffa0a9e01961", size = 766685561 }, + { url = "https://files.pythonhosted.org/packages/86/86/e661e229df2f5bfc6eab4c97deb1286d598bbeff31ab0cdb99b3c0d53c6f/torch-2.6.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:c4f103a49830ce4c7561ef4434cc7926e5a5fe4e5eb100c19ab36ea1e2b634ab", size = 95751887 }, + { url = "https://files.pythonhosted.org/packages/20/e0/5cb2f8493571f0a5a7273cd7078f191ac252a402b5fb9cb6091f14879109/torch-2.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:56eeaf2ecac90da5d9e35f7f35eb286da82673ec3c582e310a8d1631a1c02341", size = 204165139 }, + { url = "https://files.pythonhosted.org/packages/e5/16/ea1b7842413a7b8a5aaa5e99e8eaf3da3183cc3ab345ad025a07ff636301/torch-2.6.0-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:09e06f9949e1a0518c5b09fe95295bc9661f219d9ecb6f9893e5123e10696628", size = 66520221 }, + { url = "https://files.pythonhosted.org/packages/78/a9/97cbbc97002fff0de394a2da2cdfa859481fdca36996d7bd845d50aa9d8d/torch-2.6.0-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:7979834102cd5b7a43cc64e87f2f3b14bd0e1458f06e9f88ffa386d07c7446e1", size = 766715424 }, + { url = "https://files.pythonhosted.org/packages/6d/fa/134ce8f8a7ea07f09588c9cc2cea0d69249efab977707cf67669431dcf5c/torch-2.6.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:ccbd0320411fe1a3b3fec7b4d3185aa7d0c52adac94480ab024b5c8f74a0bf1d", size = 95759416 }, + { url = "https://files.pythonhosted.org/packages/11/c5/2370d96b31eb1841c3a0883a492c15278a6718ccad61bb6a649c80d1d9eb/torch-2.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:46763dcb051180ce1ed23d1891d9b1598e07d051ce4c9d14307029809c4d64f7", size = 204164970 }, + { url = "https://files.pythonhosted.org/packages/0b/fa/f33a4148c6fb46ca2a3f8de39c24d473822d5774d652b66ed9b1214da5f7/torch-2.6.0-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:94fc63b3b4bedd327af588696559f68c264440e2503cc9e6954019473d74ae21", size = 66530713 }, + { url = "https://files.pythonhosted.org/packages/e5/35/0c52d708144c2deb595cd22819a609f78fdd699b95ff6f0ebcd456e3c7c1/torch-2.6.0-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:2bb8987f3bb1ef2675897034402373ddfc8f5ef0e156e2d8cfc47cacafdda4a9", size = 766624563 }, + { url = "https://files.pythonhosted.org/packages/01/d6/455ab3fbb2c61c71c8842753b566012e1ed111e7a4c82e0e1c20d0c76b62/torch-2.6.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:b789069020c5588c70d5c2158ac0aa23fd24a028f34a8b4fcb8fcb4d7efcf5fb", size = 95607867 }, + { url = "https://files.pythonhosted.org/packages/18/cf/ae99bd066571656185be0d88ee70abc58467b76f2f7c8bfeb48735a71fe6/torch-2.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:7e1448426d0ba3620408218b50aa6ada88aeae34f7a239ba5431f6c8774b1239", size = 204120469 }, + { url = "https://files.pythonhosted.org/packages/81/b4/605ae4173aa37fb5aa14605d100ff31f4f5d49f617928c9f486bb3aaec08/torch-2.6.0-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:9a610afe216a85a8b9bc9f8365ed561535c93e804c2a317ef7fabcc5deda0989", size = 66532538 }, + { url = "https://files.pythonhosted.org/packages/24/85/ead1349fc30fe5a32cadd947c91bda4a62fbfd7f8c34ee61f6398d38fb48/torch-2.6.0-cp313-cp313-manylinux1_x86_64.whl", hash = "sha256:4874a73507a300a5d089ceaff616a569e7bb7c613c56f37f63ec3ffac65259cf", size = 766626191 }, + { url = "https://files.pythonhosted.org/packages/dd/b0/26f06f9428b250d856f6d512413e9e800b78625f63801cbba13957432036/torch-2.6.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:a0d5e1b9874c1a6c25556840ab8920569a7a4137afa8a63a32cee0bc7d89bd4b", size = 95611439 }, + { url = "https://files.pythonhosted.org/packages/c2/9c/fc5224e9770c83faed3a087112d73147cd7c7bfb7557dcf9ad87e1dda163/torch-2.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:510c73251bee9ba02ae1cb6c9d4ee0907b3ce6020e62784e2d7598e0cfa4d6cc", size = 204126475 }, + { url = "https://files.pythonhosted.org/packages/88/8b/d60c0491ab63634763be1537ad488694d316ddc4a20eaadd639cedc53971/torch-2.6.0-cp313-none-macosx_11_0_arm64.whl", hash = "sha256:ff96f4038f8af9f7ec4231710ed4549da1bdebad95923953a25045dcf6fd87e2", size = 66536783 }, ] [[package]] @@ -5283,7 +5335,7 @@ wheels = [ [[package]] name = "transformers" -version = "4.48.2" +version = "4.48.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filelock", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, @@ -5297,9 +5349,9 @@ dependencies = [ { name = "tokenizers", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "tqdm", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c5/cf/1093586e09c8d889d2f6b8ffe6a1369e1e179eb7b8e732fc0f348a8fe58f/transformers-4.48.2.tar.gz", hash = "sha256:dcfb73473e61f22fb3366fe2471ed2e42779ecdd49527a1bdf1937574855d516", size = 8370945 } +sdist = { url = "https://files.pythonhosted.org/packages/e3/82/cebeb7af5e64440f1638f18c4ed0f89156d0eeaa6290d98da8ca93ac3872/transformers-4.48.3.tar.gz", hash = "sha256:a5e8f1e9a6430aa78215836be70cecd3f872d99eeda300f41ad6cc841724afdb", size = 8373458 } wheels = [ - { url = "https://files.pythonhosted.org/packages/bd/40/902c95a2a6f5d2d120c940ac4bd1f937c01035af529803c13d65ca33c2d1/transformers-4.48.2-py3-none-any.whl", hash = "sha256:493bc5b0268b116eff305edf6656367fc89cf570e7a9d5891369e04751db698a", size = 9667774 }, + { url = "https://files.pythonhosted.org/packages/b6/1a/efeecb8d83705f2f4beac98d46f2148c95ecd7babfb31b5c0f1e7017e83d/transformers-4.48.3-py3-none-any.whl", hash = "sha256:78697f990f5ef350c23b46bf86d5081ce96b49479ab180b2de7687267de8fd36", size = 9669412 }, ] [package.optional-dependencies] @@ -5310,15 +5362,13 @@ torch = [ [[package]] name = "triton" -version = "3.1.0" +version = "3.2.0" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "filelock", marker = "python_full_version < '3.13' and sys_platform == 'linux'" }, -] wheels = [ - { url = "https://files.pythonhosted.org/packages/98/29/69aa56dc0b2eb2602b553881e34243475ea2afd9699be042316842788ff5/triton-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b0dd10a925263abbe9fa37dcde67a5e9b2383fc269fdf59f5657cac38c5d1d8", size = 209460013 }, - { url = "https://files.pythonhosted.org/packages/86/17/d9a5cf4fcf46291856d1e90762e36cbabd2a56c7265da0d1d9508c8e3943/triton-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f34f6e7885d1bf0eaaf7ba875a5f0ce6f3c13ba98f9503651c1e6dc6757ed5c", size = 209506424 }, - { url = "https://files.pythonhosted.org/packages/78/eb/65f5ba83c2a123f6498a3097746607e5b2f16add29e36765305e4ac7fdd8/triton-3.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8182f42fd8080a7d39d666814fa36c5e30cc00ea7eeeb1a2983dbb4c99a0fdc", size = 209551444 }, + { url = "https://files.pythonhosted.org/packages/01/65/3ffa90e158a2c82f0716eee8d26a725d241549b7d7aaf7e4f44ac03ebd89/triton-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3e54983cd51875855da7c68ec05c05cf8bb08df361b1d5b69e05e40b0c9bd62", size = 253090354 }, + { url = "https://files.pythonhosted.org/packages/a7/2e/757d2280d4fefe7d33af7615124e7e298ae7b8e3bc4446cdb8e88b0f9bab/triton-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8009a1fb093ee8546495e96731336a33fb8856a38e45bb4ab6affd6dbc3ba220", size = 253157636 }, + { url = "https://files.pythonhosted.org/packages/06/00/59500052cb1cf8cf5316be93598946bc451f14072c6ff256904428eaf03c/triton-3.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d9b215efc1c26fa7eefb9a157915c92d52e000d2bf83e5f69704047e63f125c", size = 253159365 }, + { url = "https://files.pythonhosted.org/packages/c7/30/37a3384d1e2e9320331baca41e835e90a3767303642c7a80d4510152cbcf/triton-3.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5dfa23ba84541d7c0a531dfce76d8bcd19159d50a4a8b14ad01e91734a5c1b0", size = 253154278 }, ] [[package]] @@ -5385,11 +5435,11 @@ wheels = [ [[package]] name = "types-setuptools" -version = "75.8.0.20250110" +version = "75.8.0.20250210" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f7/42/5713e90d4f9683f2301d900f33e4fc2405ad8ac224dda30f6cb7f4cd215b/types_setuptools-75.8.0.20250110.tar.gz", hash = "sha256:96f7ec8bbd6e0a54ea180d66ad68ad7a1d7954e7281a710ea2de75e355545271", size = 48185 } +sdist = { url = "https://files.pythonhosted.org/packages/c3/20/794589df23b1e7d3c1a1f86285e749f2a83ef845d90f2461bc2912b8f989/types_setuptools-75.8.0.20250210.tar.gz", hash = "sha256:c1547361b2441f07c94e25dce8a068e18c611593ad4b6fdd727b1a8f5d1fda33", size = 48240 } wheels = [ - { url = "https://files.pythonhosted.org/packages/cf/a3/dbfd106751b11c728cec21cc62cbfe7ff7391b935c4b6e8f0bdc2e6fd541/types_setuptools-75.8.0.20250110-py3-none-any.whl", hash = "sha256:a9f12980bbf9bcdc23ecd80755789085bad6bfce4060c2275bc2b4ca9f2bc480", size = 71521 }, + { url = "https://files.pythonhosted.org/packages/2d/b4/5978a63dac80d9a653fdb73f58e08b208486d303f9a3ee481f0c807630de/types_setuptools-75.8.0.20250210-py3-none-any.whl", hash = "sha256:a217d7b4d59be04c29e23d142c959a0f85e71292fd3fc4313f016ca11f0b56dc", size = 71535 }, ] [[package]] From 0c85ce4bb5f91d7d34259c085a1f106cf5477fae Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Tue, 11 Feb 2025 07:51:51 -0800 Subject: [PATCH 05/16] Update python/samples/concepts/plugins/crew_ai_plugin.py Co-authored-by: Eduard van Valkenburg --- python/samples/concepts/plugins/crew_ai_plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samples/concepts/plugins/crew_ai_plugin.py b/python/samples/concepts/plugins/crew_ai_plugin.py index b373a3c4cee9..5f47805a1d1b 100644 --- a/python/samples/concepts/plugins/crew_ai_plugin.py +++ b/python/samples/concepts/plugins/crew_ai_plugin.py @@ -3,7 +3,7 @@ import asyncio import logging -from semantic_kernel.core_plugins.crew_ai.crew_ai_enterprise import CrewAIEnterprise, InputMetadata +from semantic_kernel.core_plugins.crew_ai import CrewAIEnterprise, InputMetadata from semantic_kernel.core_plugins.crew_ai.crew_ai_settings import CrewAISettings from semantic_kernel.functions.kernel_arguments import KernelArguments from semantic_kernel.functions.kernel_function import KernelFunction From 0c4c6f9f2b02436d42164ca291cfd5ff94b309b2 Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Tue, 11 Feb 2025 07:52:06 -0800 Subject: [PATCH 06/16] Update python/samples/concepts/plugins/crew_ai_plugin.py Co-authored-by: Eduard van Valkenburg --- python/samples/concepts/plugins/crew_ai_plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samples/concepts/plugins/crew_ai_plugin.py b/python/samples/concepts/plugins/crew_ai_plugin.py index 5f47805a1d1b..5489890b165c 100644 --- a/python/samples/concepts/plugins/crew_ai_plugin.py +++ b/python/samples/concepts/plugins/crew_ai_plugin.py @@ -5,7 +5,7 @@ from semantic_kernel.core_plugins.crew_ai import CrewAIEnterprise, InputMetadata from semantic_kernel.core_plugins.crew_ai.crew_ai_settings import CrewAISettings -from semantic_kernel.functions.kernel_arguments import KernelArguments +from semantic_kernel.functions import KernelArguments from semantic_kernel.functions.kernel_function import KernelFunction from semantic_kernel.kernel import Kernel From ba6c47145c2e077fd7cfd6e4ab5e4fecf1d65e0f Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Tue, 11 Feb 2025 07:52:15 -0800 Subject: [PATCH 07/16] Update python/samples/concepts/plugins/crew_ai_plugin.py Co-authored-by: Eduard van Valkenburg --- python/samples/concepts/plugins/crew_ai_plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samples/concepts/plugins/crew_ai_plugin.py b/python/samples/concepts/plugins/crew_ai_plugin.py index 5489890b165c..6ac6f02a2b90 100644 --- a/python/samples/concepts/plugins/crew_ai_plugin.py +++ b/python/samples/concepts/plugins/crew_ai_plugin.py @@ -6,7 +6,7 @@ from semantic_kernel.core_plugins.crew_ai import CrewAIEnterprise, InputMetadata from semantic_kernel.core_plugins.crew_ai.crew_ai_settings import CrewAISettings from semantic_kernel.functions import KernelArguments -from semantic_kernel.functions.kernel_function import KernelFunction +from semantic_kernel.functions import KernelFunction from semantic_kernel.kernel import Kernel logging.basicConfig(level=logging.INFO) From b0f34eacdba34e80c2952e72b9d7aa0b6eec5df6 Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Tue, 11 Feb 2025 07:52:23 -0800 Subject: [PATCH 08/16] Update python/samples/concepts/plugins/crew_ai_plugin.py Co-authored-by: Eduard van Valkenburg --- python/samples/concepts/plugins/crew_ai_plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samples/concepts/plugins/crew_ai_plugin.py b/python/samples/concepts/plugins/crew_ai_plugin.py index 6ac6f02a2b90..7314389dd9ee 100644 --- a/python/samples/concepts/plugins/crew_ai_plugin.py +++ b/python/samples/concepts/plugins/crew_ai_plugin.py @@ -7,7 +7,7 @@ from semantic_kernel.core_plugins.crew_ai.crew_ai_settings import CrewAISettings from semantic_kernel.functions import KernelArguments from semantic_kernel.functions import KernelFunction -from semantic_kernel.kernel import Kernel +from semantic_kernel import Kernel logging.basicConfig(level=logging.INFO) From fb3842fc726717b20b794071e83034220d0e1d2f Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Tue, 11 Feb 2025 07:53:37 -0800 Subject: [PATCH 09/16] Update python/semantic_kernel/core_plugins/crew_ai/crew_ai_client.py Co-authored-by: Eduard van Valkenburg --- python/semantic_kernel/core_plugins/crew_ai/crew_ai_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_client.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_client.py index 3303ff679625..82f1be4e5f2e 100644 --- a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_client.py +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_client.py @@ -29,7 +29,7 @@ async def get_inputs(self) -> CrewAIRequiredInputs: """ async with await self._create_http_client() as client, client.get(f"{self.endpoint}/inputs") as response: response.raise_for_status() - body = await response.text() + return CrewAIRequiredInputs.model_validate_json(await response.text()) return CrewAIRequiredInputs(**json.loads(body)) async def kickoff( From 23fce9eb430578735174692d7f9d6dbe940123fb Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Tue, 11 Feb 2025 10:07:43 -0800 Subject: [PATCH 10/16] Updates per pr feedback. --- .../concepts/plugins/crew_ai_plugin.py | 25 +++--- .../crew_ai/crew_ai_enterprise.py | 84 ++++++++++++------- ...client.py => crew_ai_enterprise_client.py} | 62 ++++++++------ .../core_plugins/crew_ai/crew_ai_settings.py | 15 +--- 4 files changed, 105 insertions(+), 81 deletions(-) rename python/semantic_kernel/core_plugins/crew_ai/{crew_ai_client.py => crew_ai_enterprise_client.py} (64%) diff --git a/python/samples/concepts/plugins/crew_ai_plugin.py b/python/samples/concepts/plugins/crew_ai_plugin.py index 7314389dd9ee..3153ad39d765 100644 --- a/python/samples/concepts/plugins/crew_ai_plugin.py +++ b/python/samples/concepts/plugins/crew_ai_plugin.py @@ -3,18 +3,21 @@ import asyncio import logging -from semantic_kernel.core_plugins.crew_ai import CrewAIEnterprise, InputMetadata -from semantic_kernel.core_plugins.crew_ai.crew_ai_settings import CrewAISettings -from semantic_kernel.functions import KernelArguments -from semantic_kernel.functions import KernelFunction from semantic_kernel import Kernel +from semantic_kernel.core_plugins.crew_ai import CrewAIEnterprise +from semantic_kernel.core_plugins.crew_ai.crew_ai_models import InputMetadata +from semantic_kernel.functions import KernelArguments, KernelFunction logging.basicConfig(level=logging.INFO) async def using_crew_ai_enterprise(): - settings = CrewAISettings.create() - crew = CrewAIEnterprise(settings=settings) + # Create an instance of the CrewAI Enterprise Crew + crew = CrewAIEnterprise() + + ##################################################################### + # Using the CrewAI Enterprise Crew directly # + ##################################################################### # The required inputs for the Crew must be known in advance. This example is modeled after the # Enterprise Content Marketing Crew Template and requires the following inputs: @@ -29,10 +32,9 @@ async def using_crew_ai_enterprise(): print("CrewAI Enterprise Crew completed with the following result:") print(result) - -async def using_crew_ai_enterprise_as_plugin(): - settings = CrewAISettings.create() - crew = CrewAIEnterprise(settings=settings) + ##################################################################### + # Using the CrewAI Enterprise as a Plugin # + ##################################################################### # Define the description of the Crew. This will used as the semantic description of the plugin. crew_description = ( @@ -71,5 +73,4 @@ async def using_crew_ai_enterprise_as_plugin(): if __name__ == "__main__": - # asyncio.run(using_crew_ai_enterprise()) - asyncio.run(using_crew_ai_enterprise_as_plugin()) + asyncio.run(using_crew_ai_enterprise()) diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py index 326958b01aa0..554cda61459f 100644 --- a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py @@ -2,12 +2,12 @@ import asyncio import logging -from collections.abc import Awaitable, Callable from typing import Any -from pydantic import Field +import aiohttp +from pydantic import Field, ValidationError -from semantic_kernel.core_plugins.crew_ai.crew_ai_client import CrewAIEnterpriseClient +from semantic_kernel.core_plugins.crew_ai.crew_ai_enterprise_client import CrewAIEnterpriseClient from semantic_kernel.core_plugins.crew_ai.crew_ai_models import ( CrewAIEnterpriseKickoffState, CrewAIStatusResponse, @@ -24,36 +24,57 @@ from semantic_kernel.functions.kernel_parameter_metadata import KernelParameterMetadata from semantic_kernel.functions.kernel_plugin import KernelPlugin from semantic_kernel.kernel_pydantic import KernelBaseModel +from semantic_kernel.utils.experimental_decorator import experimental_class logger: logging.Logger = logging.getLogger(__name__) +@experimental_class class CrewAIEnterprise(KernelBaseModel): - """Class to interface with Crew.AI Crews from Semantic Kernel.""" + """Class to interface with Crew.AI Crews from Semantic Kernel. + + This object can be used directly or as a plugin in the Kernel. + """ client: CrewAIEnterpriseClient polling_interval: float = Field(default=1.0) + polling_timeout: float = Field(default=30.0) - def __init__(self, settings: CrewAISettings, auth_token_provider: Callable[..., Awaitable[str]] | None = None): - """Initialize a new instance of the class. + def __init__( + self, + endpoint: str | None = None, + auth_token: str | None = None, + polling_interval: float | None = 1.0, + polling_timeout: float | None = 30.0, + session: aiohttp.ClientSession | None = None, + ): + """Initialize a new instance of the class. This object can be used directly or as a plugin in the Kernel. Args: - settings (CrewAISettings): The API endpoint. - auth_token_provider (Optional[callable], optional): A callable to provide the authentication token. + endpoint (str | None, optional): The API endpoint. + auth_token (str | None, optional): The authentication token. + polling_interval (float, optional): The polling interval in seconds. Defaults to 1.0. + polling_timeout (float, optional): The polling timeout in seconds. Defaults to 30.0. + session (aiohttp.ClientSession | None, optional): The HTTP client session. Defaults to None. """ - if not auth_token_provider: - if not settings.auth_token: - raise PluginInitializationError("An auth token provider or auth token must be provided.") - - async def auth_token_provider() -> Awaitable[str]: - await asyncio.sleep(0) # Yield control to the event loop - return settings.auth_token.get_secret_value() + try: + settings = CrewAISettings.create( + endpoint=endpoint, + auth_token=auth_token, + polling_interval=polling_interval, + polling_timeout=polling_timeout, + ) + except ValidationError as ex: + raise PluginInitializationError("Failed to initialize CrewAI settings.") from ex - client = CrewAIEnterpriseClient(endpoint=settings.endpoint, auth_token_provider=auth_token_provider) + client = CrewAIEnterpriseClient( + endpoint=settings.endpoint, auth_token=settings.auth_token.get_secret_value(), session=session + ) super().__init__( client=client, polling_interval=settings.polling_interval, + polling_timeout=settings.polling_timeout, ) async def kickoff( @@ -116,19 +137,24 @@ async def wait_for_crew_completion(self, kickoff_id: str) -> str: try: status_response = None status = CrewAIEnterpriseKickoffState.Pending - while status not in [ - CrewAIEnterpriseKickoffState.Failed, - CrewAIEnterpriseKickoffState.Failure, - CrewAIEnterpriseKickoffState.Success, - CrewAIEnterpriseKickoffState.Not_Found, - ]: - logger.info( - f"Waiting for CrewAI Crew with kickoff Id: {kickoff_id} to complete. Current state: {status}" - ) - - await asyncio.sleep(self.polling_interval) - status_response = await self.client.get_status(kickoff_id) - status = status_response.state + + async def poll_status(): + nonlocal status, status_response + while status not in [ + CrewAIEnterpriseKickoffState.Failed, + CrewAIEnterpriseKickoffState.Failure, + CrewAIEnterpriseKickoffState.Success, + CrewAIEnterpriseKickoffState.Not_Found, + ]: + logger.debug( + f"Waiting for CrewAI Crew with kickoff Id: {kickoff_id} to complete. Current state: {status}" + ) + + await asyncio.sleep(self.polling_interval) + status_response = await self.client.get_status(kickoff_id) + status = status_response.state + + await asyncio.wait_for(poll_status(), timeout=self.polling_timeout) logger.info(f"CrewAI Crew with kickoff Id: {kickoff_id} completed with status: {status_response.state}") if status in ["Failed", "Failure"]: diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_client.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise_client.py similarity index 64% rename from python/semantic_kernel/core_plugins/crew_ai/crew_ai_client.py rename to python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise_client.py index 82f1be4e5f2e..1fe7a17ff229 100644 --- a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_client.py +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise_client.py @@ -1,11 +1,10 @@ # Copyright (c) Microsoft. All rights reserved. -import json -from collections.abc import Awaitable, Callable from typing import Any import aiohttp +from semantic_kernel.connectors.memory.astradb.utils import AsyncSession from semantic_kernel.core_plugins.crew_ai.crew_ai_models import ( CrewAIKickoffResponse, CrewAIRequiredInputs, @@ -19,7 +18,31 @@ class CrewAIEnterpriseClient(KernelBaseModel): """Client to interact with the Crew AI Enterprise API.""" endpoint: str - auth_token_provider: Callable[..., Awaitable[str]] + auth_token: str + request_header: dict[str, str] + session: aiohttp.ClientSession | None + + def __init__( + self, + endpoint: str, + auth_token: str, + session: aiohttp.ClientSession | None = None, + ): + """Initializes a new instance of the CrewAIEnterpriseClient class. + + Args: + endpoint (str): The API endpoint. + auth_token (str): The authentication token. + session (Optional[aiohttp.ClientSession], optional): The HTTP client session. Defaults to None. + """ + request_header = { + "Authorization": f"Bearer {auth_token}", + "Content-Type": "application/json", + "user_agent": SEMANTIC_KERNEL_USER_AGENT, + } + + session = session + super().__init__(endpoint=endpoint, auth_token=auth_token, request_header=request_header, session=session) async def get_inputs(self) -> CrewAIRequiredInputs: """Get the required inputs for Crew AI. @@ -27,10 +50,12 @@ async def get_inputs(self) -> CrewAIRequiredInputs: Returns: CrewAIRequiredInputs: The required inputs for Crew AI. """ - async with await self._create_http_client() as client, client.get(f"{self.endpoint}/inputs") as response: + async with ( + AsyncSession(self.session) as session, + session.get(f"{self.endpoint}/inputs", headers=self.request_header) as response, + ): response.raise_for_status() return CrewAIRequiredInputs.model_validate_json(await response.text()) - return CrewAIRequiredInputs(**json.loads(body)) async def kickoff( self, @@ -57,12 +82,12 @@ async def kickoff( "crewWebhookUrl": crew_webhook_url, } async with ( - await self._create_http_client() as client, - client.post(f"{self.endpoint}/kickoff", json=content) as response, + AsyncSession(self.session) as session, + session.post(f"{self.endpoint}/kickoff", json=content, headers=self.request_header) as response, ): response.raise_for_status() body = await response.text() - return CrewAIKickoffResponse(**json.loads(body)) + return CrewAIKickoffResponse.model_validate_json(body) async def get_status(self, task_id: str) -> CrewAIStatusResponse: """Get the status of a Crew AI task. @@ -74,24 +99,9 @@ async def get_status(self, task_id: str) -> CrewAIStatusResponse: CrewAIStatusResponse: The status response of the task. """ async with ( - await self._create_http_client() as client, - client.get(f"{self.endpoint}/status/{task_id}") as response, + AsyncSession(self.session) as session, + session.get(f"{self.endpoint}/status/{task_id}", headers=self.request_header) as response, ): response.raise_for_status() body = await response.text() - return CrewAIStatusResponse(**json.loads(body)) - - async def _create_http_client(self) -> aiohttp.ClientSession: - """Create an HTTP client session with the necessary headers. - - Returns: - aiohttp.ClientSession: The HTTP client session. - """ - auth_token = await self.auth_token_provider() - headers = { - "Authorization": f"Bearer {auth_token}", - "Content-Type": "application/json", - "user_agent": SEMANTIC_KERNEL_USER_AGENT, - } - - return aiohttp.ClientSession(headers=headers) + return CrewAIStatusResponse.model_validate_json(body) diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_settings.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_settings.py index 69f13799f25a..57bbe319a2b3 100644 --- a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_settings.py +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_settings.py @@ -19,17 +19,4 @@ class CrewAISettings(KernelBaseSettings): endpoint: str auth_token: SecretStr | None = None polling_interval: float = 1.0 - - -class CrewAIClientSettings(KernelBaseSettings): - """The Crew.AI client settings. - - Required: - - endpoint: str - The API endpoint. - """ - - env_prefix: ClassVar[str] = "CREW_AI_CLIENT_" - - endpoint: str - auth_token: SecretStr | None = None - polling_interval: float = 1.0 + polling_timeout: float = 30.0 From 4fdd301d1b495afdf2c9f1d5c60ccbf950a67ec2 Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Tue, 11 Feb 2025 12:41:13 -0800 Subject: [PATCH 11/16] Updates per pr feedback. --- .../connectors/memory/astradb/astra_client.py | 2 +- .../connectors/memory/astradb/utils.py | 17 ------------ .../crew_ai/crew_ai_enterprise.py | 26 +++++++++++-------- .../crew_ai/crew_ai_enterprise_client.py | 24 +++++++---------- .../core_plugins/crew_ai/crew_ai_settings.py | 2 +- python/semantic_kernel/utils/http/__init__.py | 0 python/semantic_kernel/utils/http/utils.py | 18 +++++++++++++ 7 files changed, 44 insertions(+), 45 deletions(-) create mode 100644 python/semantic_kernel/utils/http/__init__.py create mode 100644 python/semantic_kernel/utils/http/utils.py diff --git a/python/semantic_kernel/connectors/memory/astradb/astra_client.py b/python/semantic_kernel/connectors/memory/astradb/astra_client.py index 83dcd3b3ce9d..ee0b0e6c0bed 100644 --- a/python/semantic_kernel/connectors/memory/astradb/astra_client.py +++ b/python/semantic_kernel/connectors/memory/astradb/astra_client.py @@ -4,9 +4,9 @@ import aiohttp -from semantic_kernel.connectors.memory.astradb.utils import AsyncSession from semantic_kernel.exceptions import ServiceResponseException from semantic_kernel.utils.experimental_decorator import experimental_class +from semantic_kernel.utils.http.utils import AsyncSession from semantic_kernel.utils.telemetry.user_agent import APP_INFO ASTRA_CALLER_IDENTITY: str diff --git a/python/semantic_kernel/connectors/memory/astradb/utils.py b/python/semantic_kernel/connectors/memory/astradb/utils.py index b327db0688ba..e4e29ea557db 100644 --- a/python/semantic_kernel/connectors/memory/astradb/utils.py +++ b/python/semantic_kernel/connectors/memory/astradb/utils.py @@ -1,28 +1,11 @@ # Copyright (c) Microsoft. All rights reserved. from typing import Any -import aiohttp import numpy from semantic_kernel.memory.memory_record import MemoryRecord -class AsyncSession: - """A wrapper around aiohttp.ClientSession that can be used as an async context manager.""" - - def __init__(self, session: aiohttp.ClientSession = None): - """Initializes a new instance of the AsyncSession class.""" - self._session = session if session else aiohttp.ClientSession() - - async def __aenter__(self): - """Enter the session.""" - return await self._session.__aenter__() - - async def __aexit__(self, *args, **kwargs): - """Close the session.""" - await self._session.close() - - def build_payload(record: MemoryRecord) -> dict[str, Any]: """Builds a metadata payload to be sent to AstraDb from a MemoryRecord.""" payload: dict[str, Any] = {} diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py index 554cda61459f..dd4178e0721c 100644 --- a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py @@ -135,31 +135,35 @@ async def wait_for_crew_completion(self, kickoff_id: str) -> str: FunctionExecutionException: If the task fails or an error occurs while waiting for completion. """ try: - status_response = None - status = CrewAIEnterpriseKickoffState.Pending + status_response: CrewAIStatusResponse | None = None + state: str = CrewAIEnterpriseKickoffState.Pending async def poll_status(): - nonlocal status, status_response - while status not in [ + nonlocal state, status_response + while state not in [ CrewAIEnterpriseKickoffState.Failed, CrewAIEnterpriseKickoffState.Failure, CrewAIEnterpriseKickoffState.Success, CrewAIEnterpriseKickoffState.Not_Found, ]: logger.debug( - f"Waiting for CrewAI Crew with kickoff Id: {kickoff_id} to complete. Current state: {status}" + f"Waiting for CrewAI Crew with kickoff Id: {kickoff_id} to complete. Current state: {state}" ) await asyncio.sleep(self.polling_interval) status_response = await self.client.get_status(kickoff_id) - status = status_response.state + state = status_response.state await asyncio.wait_for(poll_status(), timeout=self.polling_timeout) - logger.info(f"CrewAI Crew with kickoff Id: {kickoff_id} completed with status: {status_response.state}") - if status in ["Failed", "Failure"]: - raise FunctionResultError(f"CrewAI Crew failed with error: {status_response.result}") - return status_response.result or "" + logger.info(f"CrewAI Crew with kickoff Id: {kickoff_id} completed with status: {state}") + result = ( + status_response.result if status_response is not None and status_response.result is not None else "" + ) + + if state in ["Failed", "Failure"]: + raise FunctionResultError(f"CrewAI Crew failed with error: {result}") + return result except Exception as ex: raise FunctionExecutionException( f"Failed to wait for completion of CrewAI Crew with kickoff Id: {kickoff_id}." @@ -173,7 +177,7 @@ def create_kernel_plugin( task_webhook_url: str | None = None, step_webhook_url: str | None = None, crew_webhook_url: str | None = None, - ) -> dict[str, Any]: + ) -> KernelPlugin: """Creates a kernel plugin that can be used to invoke the CrewAI Crew. Args: diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise_client.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise_client.py index 1fe7a17ff229..033a9f5f3dd8 100644 --- a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise_client.py +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise_client.py @@ -4,24 +4,18 @@ import aiohttp -from semantic_kernel.connectors.memory.astradb.utils import AsyncSession from semantic_kernel.core_plugins.crew_ai.crew_ai_models import ( CrewAIKickoffResponse, CrewAIRequiredInputs, CrewAIStatusResponse, ) -from semantic_kernel.kernel_pydantic import KernelBaseModel +from semantic_kernel.utils.http.utils import AsyncSession from semantic_kernel.utils.telemetry.user_agent import SEMANTIC_KERNEL_USER_AGENT -class CrewAIEnterpriseClient(KernelBaseModel): +class CrewAIEnterpriseClient: """Client to interact with the Crew AI Enterprise API.""" - endpoint: str - auth_token: str - request_header: dict[str, str] - session: aiohttp.ClientSession | None - def __init__( self, endpoint: str, @@ -35,15 +29,15 @@ def __init__( auth_token (str): The authentication token. session (Optional[aiohttp.ClientSession], optional): The HTTP client session. Defaults to None. """ - request_header = { + self.endpoint = endpoint + self.auth_token = auth_token + self._session = session + self.request_header = { "Authorization": f"Bearer {auth_token}", "Content-Type": "application/json", "user_agent": SEMANTIC_KERNEL_USER_AGENT, } - session = session - super().__init__(endpoint=endpoint, auth_token=auth_token, request_header=request_header, session=session) - async def get_inputs(self) -> CrewAIRequiredInputs: """Get the required inputs for Crew AI. @@ -51,7 +45,7 @@ async def get_inputs(self) -> CrewAIRequiredInputs: CrewAIRequiredInputs: The required inputs for Crew AI. """ async with ( - AsyncSession(self.session) as session, + AsyncSession(self._session) as session, session.get(f"{self.endpoint}/inputs", headers=self.request_header) as response, ): response.raise_for_status() @@ -82,7 +76,7 @@ async def kickoff( "crewWebhookUrl": crew_webhook_url, } async with ( - AsyncSession(self.session) as session, + AsyncSession(self._session) as session, session.post(f"{self.endpoint}/kickoff", json=content, headers=self.request_header) as response, ): response.raise_for_status() @@ -99,7 +93,7 @@ async def get_status(self, task_id: str) -> CrewAIStatusResponse: CrewAIStatusResponse: The status response of the task. """ async with ( - AsyncSession(self.session) as session, + AsyncSession(self._session) as session, session.get(f"{self.endpoint}/status/{task_id}", headers=self.request_header) as response, ): response.raise_for_status() diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_settings.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_settings.py index 57bbe319a2b3..7b54b6b9a90e 100644 --- a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_settings.py +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_settings.py @@ -17,6 +17,6 @@ class CrewAISettings(KernelBaseSettings): env_prefix: ClassVar[str] = "CREW_AI_" endpoint: str - auth_token: SecretStr | None = None + auth_token: SecretStr polling_interval: float = 1.0 polling_timeout: float = 30.0 diff --git a/python/semantic_kernel/utils/http/__init__.py b/python/semantic_kernel/utils/http/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/semantic_kernel/utils/http/utils.py b/python/semantic_kernel/utils/http/utils.py new file mode 100644 index 000000000000..a785ccbc9c3d --- /dev/null +++ b/python/semantic_kernel/utils/http/utils.py @@ -0,0 +1,18 @@ +# Copyright (c) Microsoft. All rights reserved. +import aiohttp + + +class AsyncSession: + """A wrapper around aiohttp.ClientSession that can be used as an async context manager.""" + + def __init__(self, session: aiohttp.ClientSession = None): + """Initializes a new instance of the AsyncSession class.""" + self._session = session if session else aiohttp.ClientSession() + + async def __aenter__(self): + """Enter the session.""" + return await self._session.__aenter__() + + async def __aexit__(self, *args, **kwargs): + """Close the session.""" + await self._session.close() From cc5a6e5b5656eb186c27260e92056e7ea366bb22 Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Tue, 11 Feb 2025 17:01:39 -0800 Subject: [PATCH 12/16] Improved client session handling. --- .../concepts/plugins/crew_ai_plugin.py | 115 +++++++++--------- .../connectors/memory/astradb/astra_client.py | 2 +- .../connectors/memory/astradb/utils.py | 17 +++ .../crew_ai/crew_ai_enterprise.py | 9 ++ .../crew_ai/crew_ai_enterprise_client.py | 23 ++-- python/semantic_kernel/utils/http/__init__.py | 0 python/semantic_kernel/utils/http/utils.py | 18 --- 7 files changed, 99 insertions(+), 85 deletions(-) delete mode 100644 python/semantic_kernel/utils/http/__init__.py delete mode 100644 python/semantic_kernel/utils/http/utils.py diff --git a/python/samples/concepts/plugins/crew_ai_plugin.py b/python/samples/concepts/plugins/crew_ai_plugin.py index 3153ad39d765..51d911dbca9b 100644 --- a/python/samples/concepts/plugins/crew_ai_plugin.py +++ b/python/samples/concepts/plugins/crew_ai_plugin.py @@ -13,63 +13,64 @@ async def using_crew_ai_enterprise(): # Create an instance of the CrewAI Enterprise Crew - crew = CrewAIEnterprise() - - ##################################################################### - # Using the CrewAI Enterprise Crew directly # - ##################################################################### - - # The required inputs for the Crew must be known in advance. This example is modeled after the - # Enterprise Content Marketing Crew Template and requires the following inputs: - inputs = {"company": "CrewAI", "topic": "Agentic products for consumers"} - - # Invoke directly with our inputs - kickoff_id = await crew.kickoff(inputs) - print(f"CrewAI Enterprise Crew kicked off with ID: {kickoff_id}") - - # Wait for completion - result = await crew.wait_for_crew_completion(kickoff_id) - print("CrewAI Enterprise Crew completed with the following result:") - print(result) - - ##################################################################### - # Using the CrewAI Enterprise as a Plugin # - ##################################################################### - - # Define the description of the Crew. This will used as the semantic description of the plugin. - crew_description = ( - "Conducts thorough research on the specified company and topic to identify emerging trends," - "analyze competitor strategies, and gather data-driven insights." - ) - - # The required inputs for the Crew must be known in advance. This example is modeled after the - # Enterprise Content Marketing Crew Template and requires string inputs for the company and topic. - # We need to describe the type and purpose of each input to allow the LLM to invoke the crew as expected. - crew_plugin_definitions = [ - InputMetadata(name="company", type="string", description="The name of the company that should be researched"), - InputMetadata(name="topic", type="string", description="The topic that should be researched"), - ] - - # Create the CrewAI Plugin. This builds a plugin that can be added to the Kernel and invoked like any other plugin. - # The plugin will contain the following functions: - # - kickoff: Starts the Crew with the specified inputs and returns the Id of the scheduled kickoff. - # - kickoff_and_wait: Starts the Crew with the specified inputs and waits for the Crew to complete before returning - # the result. - # - wait_for_completion: Waits for the specified Crew kickoff to complete and returns the result. - # - get_status: Gets the status of the specified Crew kickoff. - crew_plugin = crew.create_kernel_plugin( - name="EnterpriseContentMarketingCrew", - description=crew_description, - input_metadata=crew_plugin_definitions, - ) - - # Example of invoking the plugin directly - kickoff_and_wait_function: KernelFunction = crew_plugin["kickoff_and_wait"] - result = await kickoff_and_wait_function.invoke( - kernel=Kernel(), arguments=KernelArguments(company="CrewAI", topic="Consumer AI Products") - ) - - print(result) + async with CrewAIEnterprise() as crew: + ##################################################################### + # Using the CrewAI Enterprise Crew directly # + ##################################################################### + + # The required inputs for the Crew must be known in advance. This example is modeled after the + # Enterprise Content Marketing Crew Template and requires the following inputs: + inputs = {"company": "CrewAI", "topic": "Agentic products for consumers"} + + # Invoke directly with our inputs + kickoff_id = await crew.kickoff(inputs) + print(f"CrewAI Enterprise Crew kicked off with ID: {kickoff_id}") + + # Wait for completion + result = await crew.wait_for_crew_completion(kickoff_id) + print("CrewAI Enterprise Crew completed with the following result:") + print(result) + + ##################################################################### + # Using the CrewAI Enterprise as a Plugin # + ##################################################################### + + # Define the description of the Crew. This will used as the semantic description of the plugin. + crew_description = ( + "Conducts thorough research on the specified company and topic to identify emerging trends," + "analyze competitor strategies, and gather data-driven insights." + ) + + # The required inputs for the Crew must be known in advance. This example is modeled after the + # Enterprise Content Marketing Crew Template and requires string inputs for the company and topic. + # We need to describe the type and purpose of each input to allow the LLM to invoke the crew as expected. + crew_plugin_definitions = [ + InputMetadata( + name="company", type="string", description="The name of the company that should be researched" + ), + InputMetadata(name="topic", type="string", description="The topic that should be researched"), + ] + + # Create the CrewAI Plugin. This builds a plugin that can be added to the Kernel and invoked like any other + # plugin. The plugin will contain the following functions: + # - kickoff: Starts the Crew with the specified inputs and returns the Id of the scheduled kickoff. + # - kickoff_and_wait: Starts the Crew with the specified inputs and waits for the Crew to complete before + # returning the result. + # - wait_for_completion: Waits for the specified Crew kickoff to complete and returns the result. + # - get_status: Gets the status of the specified Crew kickoff. + crew_plugin = crew.create_kernel_plugin( + name="EnterpriseContentMarketingCrew", + description=crew_description, + input_metadata=crew_plugin_definitions, + ) + + # Example of invoking the plugin directly + kickoff_and_wait_function: KernelFunction = crew_plugin["kickoff_and_wait"] + result = await kickoff_and_wait_function.invoke( + kernel=Kernel(), arguments=KernelArguments(company="CrewAI", topic="Consumer AI Products") + ) + + print(result) if __name__ == "__main__": diff --git a/python/semantic_kernel/connectors/memory/astradb/astra_client.py b/python/semantic_kernel/connectors/memory/astradb/astra_client.py index ee0b0e6c0bed..83dcd3b3ce9d 100644 --- a/python/semantic_kernel/connectors/memory/astradb/astra_client.py +++ b/python/semantic_kernel/connectors/memory/astradb/astra_client.py @@ -4,9 +4,9 @@ import aiohttp +from semantic_kernel.connectors.memory.astradb.utils import AsyncSession from semantic_kernel.exceptions import ServiceResponseException from semantic_kernel.utils.experimental_decorator import experimental_class -from semantic_kernel.utils.http.utils import AsyncSession from semantic_kernel.utils.telemetry.user_agent import APP_INFO ASTRA_CALLER_IDENTITY: str diff --git a/python/semantic_kernel/connectors/memory/astradb/utils.py b/python/semantic_kernel/connectors/memory/astradb/utils.py index e4e29ea557db..b327db0688ba 100644 --- a/python/semantic_kernel/connectors/memory/astradb/utils.py +++ b/python/semantic_kernel/connectors/memory/astradb/utils.py @@ -1,11 +1,28 @@ # Copyright (c) Microsoft. All rights reserved. from typing import Any +import aiohttp import numpy from semantic_kernel.memory.memory_record import MemoryRecord +class AsyncSession: + """A wrapper around aiohttp.ClientSession that can be used as an async context manager.""" + + def __init__(self, session: aiohttp.ClientSession = None): + """Initializes a new instance of the AsyncSession class.""" + self._session = session if session else aiohttp.ClientSession() + + async def __aenter__(self): + """Enter the session.""" + return await self._session.__aenter__() + + async def __aexit__(self, *args, **kwargs): + """Close the session.""" + await self._session.close() + + def build_payload(record: MemoryRecord) -> dict[str, Any]: """Builds a metadata payload to be sent to AstraDb from a MemoryRecord.""" payload: dict[str, Any] = {} diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py index dd4178e0721c..89edd83dab4c 100644 --- a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py @@ -256,3 +256,12 @@ def _build_arguments(self, input_metadata: list[InputMetadata] | None, arguments raise PluginInitializationError(f"Missing required input '{name}' for CrewAI.") args[name] = arguments[name] return args + + async def __aenter__(self): + """Enter the session.""" + await self.client.__aenter__() + return self + + async def __aexit__(self, *args, **kwargs): + """Close the session.""" + await self.client.__aexit__() diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise_client.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise_client.py index 033a9f5f3dd8..d492102ccc61 100644 --- a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise_client.py +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise_client.py @@ -9,7 +9,6 @@ CrewAIRequiredInputs, CrewAIStatusResponse, ) -from semantic_kernel.utils.http.utils import AsyncSession from semantic_kernel.utils.telemetry.user_agent import SEMANTIC_KERNEL_USER_AGENT @@ -27,11 +26,11 @@ def __init__( Args: endpoint (str): The API endpoint. auth_token (str): The authentication token. - session (Optional[aiohttp.ClientSession], optional): The HTTP client session. Defaults to None. + session (aiohttp.ClientSession | None, optional): The HTTP client session. Defaults to None. """ self.endpoint = endpoint self.auth_token = auth_token - self._session = session + self.session = session if session else aiohttp.ClientSession() self.request_header = { "Authorization": f"Bearer {auth_token}", "Content-Type": "application/json", @@ -45,8 +44,7 @@ async def get_inputs(self) -> CrewAIRequiredInputs: CrewAIRequiredInputs: The required inputs for Crew AI. """ async with ( - AsyncSession(self._session) as session, - session.get(f"{self.endpoint}/inputs", headers=self.request_header) as response, + self.session.get(f"{self.endpoint}/inputs", headers=self.request_header) as response, ): response.raise_for_status() return CrewAIRequiredInputs.model_validate_json(await response.text()) @@ -76,8 +74,7 @@ async def kickoff( "crewWebhookUrl": crew_webhook_url, } async with ( - AsyncSession(self._session) as session, - session.post(f"{self.endpoint}/kickoff", json=content, headers=self.request_header) as response, + self.session.post(f"{self.endpoint}/kickoff", json=content, headers=self.request_header) as response, ): response.raise_for_status() body = await response.text() @@ -93,9 +90,17 @@ async def get_status(self, task_id: str) -> CrewAIStatusResponse: CrewAIStatusResponse: The status response of the task. """ async with ( - AsyncSession(self._session) as session, - session.get(f"{self.endpoint}/status/{task_id}", headers=self.request_header) as response, + self.session.get(f"{self.endpoint}/status/{task_id}", headers=self.request_header) as response, ): response.raise_for_status() body = await response.text() return CrewAIStatusResponse.model_validate_json(body) + + async def __aenter__(self): + """Enter the session.""" + await self.session.__aenter__() + return self + + async def __aexit__(self, *args, **kwargs): + """Close the session.""" + await self.session.close() diff --git a/python/semantic_kernel/utils/http/__init__.py b/python/semantic_kernel/utils/http/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/python/semantic_kernel/utils/http/utils.py b/python/semantic_kernel/utils/http/utils.py deleted file mode 100644 index a785ccbc9c3d..000000000000 --- a/python/semantic_kernel/utils/http/utils.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) Microsoft. All rights reserved. -import aiohttp - - -class AsyncSession: - """A wrapper around aiohttp.ClientSession that can be used as an async context manager.""" - - def __init__(self, session: aiohttp.ClientSession = None): - """Initializes a new instance of the AsyncSession class.""" - self._session = session if session else aiohttp.ClientSession() - - async def __aenter__(self): - """Enter the session.""" - return await self._session.__aenter__() - - async def __aexit__(self, *args, **kwargs): - """Close the session.""" - await self._session.close() From f8b8faa89057a726407cca5c983d8de6cae7fa51 Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Wed, 12 Feb 2025 10:25:15 -0800 Subject: [PATCH 13/16] Improvements per PR feedback. --- .../concepts/plugins/crew_ai/README.md | 47 ++++++ .../plugins/crew_ai/crew_ai_plugin.py | 140 ++++++++++++++++++ .../concepts/plugins/crew_ai_plugin.py | 77 ---------- .../crew_ai/crew_ai_enterprise.py | 34 ++--- .../core_plugins/crew_ai/crew_ai_models.py | 8 - 5 files changed, 201 insertions(+), 105 deletions(-) create mode 100644 python/samples/concepts/plugins/crew_ai/README.md create mode 100644 python/samples/concepts/plugins/crew_ai/crew_ai_plugin.py delete mode 100644 python/samples/concepts/plugins/crew_ai_plugin.py diff --git a/python/samples/concepts/plugins/crew_ai/README.md b/python/samples/concepts/plugins/crew_ai/README.md new file mode 100644 index 000000000000..faa9a4b9c72f --- /dev/null +++ b/python/samples/concepts/plugins/crew_ai/README.md @@ -0,0 +1,47 @@ +# Crew AI Plugin for Semantic Kernel + +This sample demonstrates how to integrate with [Crew AI Enterprise](https://app.crewai.com/) crews in Semantic Kernel. + +## Requirements + +Before running this sample you need to have a Crew deployed to the Crew AI Enterprise cloud. Many pre-built Crew templates can be found [here](https://app.crewai.com/crewai_plus/templates). You will need the following information from your deployed Crew: + +- endpoint: The base URL for your Crew. +- authentication token: The authentication token for your Crew +- required inputs: Most Crews have a set of required inputs that need to provided when kicking off the Crew and those input names, types, and values need to be known. + +- ## Using the Crew Plugin + +Once configured, the `CrewAIEnterprise` class can be used directly by calling methods on it, or can be used to generate a Semantic Kernel plugin with inputs that match those of your Crew. Generating a plugin is useful for scenarios when you want an LLM to be able to invoke your Crew as a tool. + +## Running the sample + +1. Deploy your Crew to the Crew Enterprise cloud. +1. Gather the required information listed above. +1. Create environment variables or use your .env file to define your Crew's endpoint and token as: + +```md +CREW_AI_ENDPOINT="{Your Crew's endpoint}" +CREW_AI_TOKEN="{Your Crew's authentication token}" +``` + +1. In [crew_ai_plugin.py](./crew_ai_plugin.py) find the section that defines the Crew's required inputs and modify it to match your Crew's inputs. The input descriptions and types are critical to help LLMs understand the inputs semantic meaning so that it can accurately call the plugin. The sample is based on the `Enterprise Content Marketing Crew` template which has two required inputs, `company` and `topic`. + +```python + # The required inputs for the Crew must be known in advance. This example is modeled after the + # Enterprise Content Marketing Crew Template and requires string inputs for the company and topic. + # We need to describe the type and purpose of each input to allow the LLM to invoke the crew as expected. + crew_plugin_definitions = [ + KernelParameterMetadata( + name="company", + type="string", + description="The name of the company that should be researched", + is_required=True, + ), + KernelParameterMetadata( + name="topic", type="string", description="The topic that should be researched", is_required=True + ), + ] +``` + +1. Run the sample. Notice that the sample invokes (kicks-off) the Crew twice, once directly by calling the `kickoff` method and once by creating a plugin and invoking it. diff --git a/python/samples/concepts/plugins/crew_ai/crew_ai_plugin.py b/python/samples/concepts/plugins/crew_ai/crew_ai_plugin.py new file mode 100644 index 000000000000..0f9fbfdc426c --- /dev/null +++ b/python/samples/concepts/plugins/crew_ai/crew_ai_plugin.py @@ -0,0 +1,140 @@ +# Copyright (c) Microsoft. All rights reserved. + +import asyncio +import logging + +from samples.concepts.setup.chat_completion_services import Services, get_chat_completion_service_and_request_settings +from semantic_kernel import Kernel +from semantic_kernel.connectors.ai.chat_completion_client_base import ChatCompletionClientBase +from semantic_kernel.connectors.ai.function_choice_behavior import FunctionChoiceBehavior +from semantic_kernel.connectors.ai.prompt_execution_settings import PromptExecutionSettings +from semantic_kernel.contents.chat_history import ChatHistory +from semantic_kernel.core_plugins.crew_ai import CrewAIEnterprise +from semantic_kernel.functions.kernel_parameter_metadata import KernelParameterMetadata + +logging.basicConfig(level=logging.INFO) + + +async def using_crew_ai_enterprise(): + # Create an instance of the CrewAI Enterprise Crew + async with CrewAIEnterprise() as crew: + ##################################################################### + # Using the CrewAI Enterprise Crew directly # + ##################################################################### + + # The required inputs for the Crew must be known in advance. This example is modeled after the + # Enterprise Content Marketing Crew Template and requires the following inputs: + inputs = {"company": "CrewAI", "topic": "Agentic products for consumers"} + + # Invoke directly with our inputs + kickoff_id = await crew.kickoff(inputs) + print(f"CrewAI Enterprise Crew kicked off with ID: {kickoff_id}") + + # Wait for completion + result = await crew.wait_for_crew_completion(kickoff_id) + print("CrewAI Enterprise Crew completed with the following result:") + print(result) + + ##################################################################### + # Using the CrewAI Enterprise as a Plugin # + ##################################################################### + + # Define the description of the Crew. This will used as the semantic description of the plugin. + crew_description = ( + "Conducts thorough research on the specified company and topic to identify emerging trends," + "analyze competitor strategies, and gather data-driven insights." + ) + + # The required inputs for the Crew must be known in advance. This example is modeled after the + # Enterprise Content Marketing Crew Template and requires string inputs for the company and topic. + # We need to describe the type and purpose of each input to allow the LLM to invoke the crew as expected. + crew_plugin_definitions = [ + KernelParameterMetadata( + name="company", + type="string", + type_object=str, + description="The name of the company that should be researched", + is_required=True, + ), + KernelParameterMetadata( + name="topic", + type="string", + type_object=str, + description="The topic that should be researched", + is_required=True, + ), + ] + + # Create the CrewAI Plugin. This builds a plugin that can be added to the Kernel and invoked like any other + # plugin. The plugin will contain the following functions: + # - kickoff: Starts the Crew with the specified inputs and returns the Id of the scheduled kickoff. + # - kickoff_and_wait: Starts the Crew with the specified inputs and waits for the Crew to complete before + # returning the result. + # - wait_for_completion: Waits for the specified Crew kickoff to complete and returns the result. + # - get_status: Gets the status of the specified Crew kickoff. + crew_plugin = crew.create_kernel_plugin( + name="EnterpriseContentMarketingCrew", + description=crew_description, + input_metadata=crew_plugin_definitions, + ) + + # Configure the kernel for chat completion and add the CrewAI plugin. + kernel, chat_completion, settings = configure_kernel_for_chat() + kernel.add_plugin(crew_plugin) + + # Create a chat history to store the system message, initial messages, and the conversation. + history = ChatHistory() + history.add_system_message("You are an AI assistant that can help me with research.") + history.add_user_message( + "I'm looking for emerging marketplace trends about Crew AI and their concumer AI products." + ) + + # Invoke the chat completion service with enough information for the CrewAI plugin to be invoked. + response = await chat_completion.get_chat_message_content(history, settings, kernel=kernel) + print(response) + + # expected output: + # INFO:semantic_kernel.connectors.ai.open_ai.services.open_ai_handler:OpenAI usage: ... + # INFO:semantic_kernel.connectors.ai.chat_completion_client_base:processing 1 tool calls in parallel. + # INFO:semantic_kernel.kernel:Calling EnterpriseContentMarketingCrew-kickoff_and_wait function with args: + # {"company":"Crew AI","topic":"emerging marketplace trends in consumer AI products"} + # INFO:semantic_kernel.functions.kernel_function:Function EnterpriseContentMarketingCrew-kickoff_and_wait + # invoking. + # INFO:semantic_kernel.core_plugins.crew_ai.crew_ai_enterprise:CrewAI Crew kicked off with Id: ***** + # INFO:semantic_kernel.core_plugins.crew_ai.crew_ai_enterprise:CrewAI Crew with kickoff Id: ***** completed with + # status: SUCCESS + # INFO:semantic_kernel.functions.kernel_function:Function EnterpriseContentMarketingCrew-kickoff_and_wait + # succeeded. + # Here are some emerging marketplace trends related to Crew AI and their consumer AI products, along with + # suggested content pieces to explore these trends: ... + + +def configure_kernel_for_chat() -> tuple[Kernel, ChatCompletionClientBase, PromptExecutionSettings]: + kernel = Kernel() + + # You can select from the following chat completion services that support function calling: + # - Services.OPENAI + # - Services.AZURE_OPENAI + # - Services.AZURE_AI_INFERENCE + # - Services.ANTHROPIC + # - Services.BEDROCK + # - Services.GOOGLE_AI + # - Services.MISTRAL_AI + # - Services.OLLAMA + # - Services.ONNX + # - Services.VERTEX_AI + # - Services.DEEPSEEK + # Please make sure you have configured your environment correctly for the selected chat completion service. + chat_completion_service, request_settings = get_chat_completion_service_and_request_settings(Services.OPENAI) + + # Configure the function choice behavior. Here, we set it to Auto, where auto_invoke=True by default. + # With `auto_invoke=True`, the model will automatically choose and call functions as needed. + request_settings.function_choice_behavior = FunctionChoiceBehavior.Auto() + + # Pass the request settings to the kernel arguments. + kernel.add_service(chat_completion_service) + return kernel, chat_completion_service, request_settings + + +if __name__ == "__main__": + asyncio.run(using_crew_ai_enterprise()) diff --git a/python/samples/concepts/plugins/crew_ai_plugin.py b/python/samples/concepts/plugins/crew_ai_plugin.py deleted file mode 100644 index 51d911dbca9b..000000000000 --- a/python/samples/concepts/plugins/crew_ai_plugin.py +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright (c) Microsoft. All rights reserved. - -import asyncio -import logging - -from semantic_kernel import Kernel -from semantic_kernel.core_plugins.crew_ai import CrewAIEnterprise -from semantic_kernel.core_plugins.crew_ai.crew_ai_models import InputMetadata -from semantic_kernel.functions import KernelArguments, KernelFunction - -logging.basicConfig(level=logging.INFO) - - -async def using_crew_ai_enterprise(): - # Create an instance of the CrewAI Enterprise Crew - async with CrewAIEnterprise() as crew: - ##################################################################### - # Using the CrewAI Enterprise Crew directly # - ##################################################################### - - # The required inputs for the Crew must be known in advance. This example is modeled after the - # Enterprise Content Marketing Crew Template and requires the following inputs: - inputs = {"company": "CrewAI", "topic": "Agentic products for consumers"} - - # Invoke directly with our inputs - kickoff_id = await crew.kickoff(inputs) - print(f"CrewAI Enterprise Crew kicked off with ID: {kickoff_id}") - - # Wait for completion - result = await crew.wait_for_crew_completion(kickoff_id) - print("CrewAI Enterprise Crew completed with the following result:") - print(result) - - ##################################################################### - # Using the CrewAI Enterprise as a Plugin # - ##################################################################### - - # Define the description of the Crew. This will used as the semantic description of the plugin. - crew_description = ( - "Conducts thorough research on the specified company and topic to identify emerging trends," - "analyze competitor strategies, and gather data-driven insights." - ) - - # The required inputs for the Crew must be known in advance. This example is modeled after the - # Enterprise Content Marketing Crew Template and requires string inputs for the company and topic. - # We need to describe the type and purpose of each input to allow the LLM to invoke the crew as expected. - crew_plugin_definitions = [ - InputMetadata( - name="company", type="string", description="The name of the company that should be researched" - ), - InputMetadata(name="topic", type="string", description="The topic that should be researched"), - ] - - # Create the CrewAI Plugin. This builds a plugin that can be added to the Kernel and invoked like any other - # plugin. The plugin will contain the following functions: - # - kickoff: Starts the Crew with the specified inputs and returns the Id of the scheduled kickoff. - # - kickoff_and_wait: Starts the Crew with the specified inputs and waits for the Crew to complete before - # returning the result. - # - wait_for_completion: Waits for the specified Crew kickoff to complete and returns the result. - # - get_status: Gets the status of the specified Crew kickoff. - crew_plugin = crew.create_kernel_plugin( - name="EnterpriseContentMarketingCrew", - description=crew_description, - input_metadata=crew_plugin_definitions, - ) - - # Example of invoking the plugin directly - kickoff_and_wait_function: KernelFunction = crew_plugin["kickoff_and_wait"] - result = await kickoff_and_wait_function.invoke( - kernel=Kernel(), arguments=KernelArguments(company="CrewAI", topic="Consumer AI Products") - ) - - print(result) - - -if __name__ == "__main__": - asyncio.run(using_crew_ai_enterprise()) diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py index 89edd83dab4c..54b2e74a050c 100644 --- a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py @@ -8,11 +8,7 @@ from pydantic import Field, ValidationError from semantic_kernel.core_plugins.crew_ai.crew_ai_enterprise_client import CrewAIEnterpriseClient -from semantic_kernel.core_plugins.crew_ai.crew_ai_models import ( - CrewAIEnterpriseKickoffState, - CrewAIStatusResponse, - InputMetadata, -) +from semantic_kernel.core_plugins.crew_ai.crew_ai_models import CrewAIEnterpriseKickoffState, CrewAIStatusResponse from semantic_kernel.core_plugins.crew_ai.crew_ai_settings import CrewAISettings from semantic_kernel.exceptions.function_exceptions import ( FunctionExecutionException, @@ -47,6 +43,8 @@ def __init__( polling_interval: float | None = 1.0, polling_timeout: float | None = 30.0, session: aiohttp.ClientSession | None = None, + env_file_path: str | None = None, + env_file_encoding: str | None = None, ): """Initialize a new instance of the class. This object can be used directly or as a plugin in the Kernel. @@ -56,6 +54,9 @@ def __init__( polling_interval (float, optional): The polling interval in seconds. Defaults to 1.0. polling_timeout (float, optional): The polling timeout in seconds. Defaults to 30.0. session (aiohttp.ClientSession | None, optional): The HTTP client session. Defaults to None. + env_file_path (str | None): Use the environment settings file as a + fallback to environment variables. (Optional) + env_file_encoding (str | None): The encoding of the environment settings file. (Optional) """ try: settings = CrewAISettings.create( @@ -63,6 +64,8 @@ def __init__( auth_token=auth_token, polling_interval=polling_interval, polling_timeout=polling_timeout, + env_file_path=env_file_path, + env_file_encoding=env_file_encoding, ) except ValidationError as ex: raise PluginInitializationError("Failed to initialize CrewAI settings.") from ex @@ -173,7 +176,7 @@ def create_kernel_plugin( self, name: str, description: str, - input_metadata: list[InputMetadata] | None = None, + input_metadata: list[KernelParameterMetadata] | None = None, task_webhook_url: str | None = None, step_webhook_url: str | None = None, crew_webhook_url: str | None = None, @@ -193,17 +196,6 @@ def create_kernel_plugin( dict[str, Any]: A dictionary representing the kernel plugin. """ - def build_metadata(input_metadata: InputMetadata) -> KernelParameterMetadata: - return KernelParameterMetadata( - name=input_metadata.name, - description=input_metadata.description, - default_value=None, - type=input_metadata.type, - is_required=True, - ) - - parameters = [build_metadata(input) for input in input_metadata or []] - @kernel_function(description="Kickoff the CrewAI task.") async def kickoff(**kwargs: Any) -> str: args = self._build_arguments(input_metadata, kwargs) @@ -229,16 +221,18 @@ async def kickoff_and_wait(**kwargs: Any) -> str: name, description, { - "kickoff": KernelFunctionFromMethod(kickoff, stream_method=None, parameters=parameters), + "kickoff": KernelFunctionFromMethod(kickoff, stream_method=None, parameters=input_metadata), "kickoff_and_wait": KernelFunctionFromMethod( - kickoff_and_wait, stream_method=None, parameters=parameters + kickoff_and_wait, stream_method=None, parameters=input_metadata ), "get_status": self.get_crew_kickoff_status, "wait_for_completion": self.wait_for_crew_completion, }, ) - def _build_arguments(self, input_metadata: list[InputMetadata] | None, arguments: dict[str, Any]) -> dict[str, Any]: + def _build_arguments( + self, input_metadata: list[KernelParameterMetadata] | None, arguments: dict[str, Any] + ) -> dict[str, Any]: """Builds the arguments for the CrewAI task from the provided metadata and arguments. Args: diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_models.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_models.py index 52bde361b2f8..31ed068ad2f8 100644 --- a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_models.py +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_models.py @@ -36,11 +36,3 @@ class CrewAIRequiredInputs(KernelBaseModel): """Represents the required inputs for Crew AI.""" inputs: dict[str, str] - - -class InputMetadata(KernelBaseModel): - """Represents the metadata for an input required by Crew AI.""" - - name: str - type: str - description: str | None From 26a054b8c6816d123217f6167b69f6c0e6472628 Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Wed, 12 Feb 2025 13:45:20 -0800 Subject: [PATCH 14/16] Improvements per PR feedback. --- .../plugins/crew_ai/crew_ai_plugin.py | 4 +- .../crew_ai/crew_ai_enterprise.py | 80 +++++++++---------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/python/samples/concepts/plugins/crew_ai/crew_ai_plugin.py b/python/samples/concepts/plugins/crew_ai/crew_ai_plugin.py index 0f9fbfdc426c..c817f6d8cda1 100644 --- a/python/samples/concepts/plugins/crew_ai/crew_ai_plugin.py +++ b/python/samples/concepts/plugins/crew_ai/crew_ai_plugin.py @@ -48,7 +48,7 @@ async def using_crew_ai_enterprise(): # The required inputs for the Crew must be known in advance. This example is modeled after the # Enterprise Content Marketing Crew Template and requires string inputs for the company and topic. # We need to describe the type and purpose of each input to allow the LLM to invoke the crew as expected. - crew_plugin_definitions = [ + crew_input_parameters = [ KernelParameterMetadata( name="company", type="string", @@ -75,7 +75,7 @@ async def using_crew_ai_enterprise(): crew_plugin = crew.create_kernel_plugin( name="EnterpriseContentMarketingCrew", description=crew_description, - input_metadata=crew_plugin_definitions, + parameters=crew_input_parameters, ) # Configure the kernel for chat completion and add the CrewAI plugin. diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py index 54b2e74a050c..db4e610c56af 100644 --- a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise.py @@ -137,46 +137,46 @@ async def wait_for_crew_completion(self, kickoff_id: str) -> str: Raises: FunctionExecutionException: If the task fails or an error occurs while waiting for completion. """ - try: - status_response: CrewAIStatusResponse | None = None - state: str = CrewAIEnterpriseKickoffState.Pending - - async def poll_status(): - nonlocal state, status_response - while state not in [ - CrewAIEnterpriseKickoffState.Failed, - CrewAIEnterpriseKickoffState.Failure, - CrewAIEnterpriseKickoffState.Success, - CrewAIEnterpriseKickoffState.Not_Found, - ]: - logger.debug( - f"Waiting for CrewAI Crew with kickoff Id: {kickoff_id} to complete. Current state: {state}" - ) - - await asyncio.sleep(self.polling_interval) + status_response: CrewAIStatusResponse | None = None + state: str = CrewAIEnterpriseKickoffState.Pending + + async def poll_status(): + nonlocal state, status_response + while state not in [ + CrewAIEnterpriseKickoffState.Failed, + CrewAIEnterpriseKickoffState.Failure, + CrewAIEnterpriseKickoffState.Success, + CrewAIEnterpriseKickoffState.Not_Found, + ]: + logger.debug( + f"Waiting for CrewAI Crew with kickoff Id: {kickoff_id} to complete. Current state: {state}" + ) + + await asyncio.sleep(self.polling_interval) + + try: status_response = await self.client.get_status(kickoff_id) state = status_response.state + except Exception as ex: + raise FunctionExecutionException( + f"Failed to wait for completion of CrewAI Crew with kickoff Id: {kickoff_id}." + ) from ex - await asyncio.wait_for(poll_status(), timeout=self.polling_timeout) + await asyncio.wait_for(poll_status(), timeout=self.polling_timeout) - logger.info(f"CrewAI Crew with kickoff Id: {kickoff_id} completed with status: {state}") - result = ( - status_response.result if status_response is not None and status_response.result is not None else "" - ) + logger.info(f"CrewAI Crew with kickoff Id: {kickoff_id} completed with status: {state}") + result = status_response.result if status_response is not None and status_response.result is not None else "" - if state in ["Failed", "Failure"]: - raise FunctionResultError(f"CrewAI Crew failed with error: {result}") - return result - except Exception as ex: - raise FunctionExecutionException( - f"Failed to wait for completion of CrewAI Crew with kickoff Id: {kickoff_id}." - ) from ex + if state in ["Failed", "Failure"]: + raise FunctionResultError(f"CrewAI Crew failed with error: {result}") + + return result def create_kernel_plugin( self, name: str, description: str, - input_metadata: list[KernelParameterMetadata] | None = None, + parameters: list[KernelParameterMetadata] | None = None, task_webhook_url: str | None = None, step_webhook_url: str | None = None, crew_webhook_url: str | None = None, @@ -186,7 +186,7 @@ def create_kernel_plugin( Args: name (str): The name of the kernel plugin. description (str): The description of the kernel plugin. - input_metadata (Optional[List[InputMetadata]], optional): The definitions of the Crew's + parameters (List[KernelParameterMetadata] | None, optional): The definitions of the Crew's required inputs. Defaults to None. task_webhook_url (Optional[str], optional): The task level webhook URL. Defaults to None. step_webhook_url (Optional[str], optional): The step level webhook URL. Defaults to None. @@ -198,7 +198,7 @@ def create_kernel_plugin( @kernel_function(description="Kickoff the CrewAI task.") async def kickoff(**kwargs: Any) -> str: - args = self._build_arguments(input_metadata, kwargs) + args = self._build_arguments(parameters, kwargs) return await self.kickoff( inputs=args, task_webhook_url=task_webhook_url, @@ -208,7 +208,7 @@ async def kickoff(**kwargs: Any) -> str: @kernel_function(description="Kickoff the CrewAI task and wait for completion.") async def kickoff_and_wait(**kwargs: Any) -> str: - args = self._build_arguments(input_metadata, kwargs) + args = self._build_arguments(parameters, kwargs) kickoff_id = await self.kickoff( inputs=args, task_webhook_url=task_webhook_url, @@ -221,9 +221,9 @@ async def kickoff_and_wait(**kwargs: Any) -> str: name, description, { - "kickoff": KernelFunctionFromMethod(kickoff, stream_method=None, parameters=input_metadata), + "kickoff": KernelFunctionFromMethod(kickoff, stream_method=None, parameters=parameters), "kickoff_and_wait": KernelFunctionFromMethod( - kickoff_and_wait, stream_method=None, parameters=input_metadata + kickoff_and_wait, stream_method=None, parameters=parameters ), "get_status": self.get_crew_kickoff_status, "wait_for_completion": self.wait_for_crew_completion, @@ -231,20 +231,20 @@ async def kickoff_and_wait(**kwargs: Any) -> str: ) def _build_arguments( - self, input_metadata: list[KernelParameterMetadata] | None, arguments: dict[str, Any] + self, parameters: list[KernelParameterMetadata] | None, arguments: dict[str, Any] ) -> dict[str, Any]: - """Builds the arguments for the CrewAI task from the provided metadata and arguments. + """Builds the arguments for the CrewAI task from the provided parameters and arguments. Args: - input_metadata (Optional[List[InputMetadata]]): The metadata for the inputs. + parameters (List[KernelParameterMetadata] | None): The metadata for the inputs. arguments (dict[str, Any]): The provided arguments. Returns: dict[str, Any]: The built arguments. """ args = {} - if input_metadata: - for input in input_metadata: + if parameters: + for input in parameters: name = input.name if name not in arguments: raise PluginInitializationError(f"Missing required input '{name}' for CrewAI.") From d81e7c00d78bea42c1d53b9c0e8165d55d8958ad Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Wed, 12 Feb 2025 15:01:24 -0800 Subject: [PATCH 15/16] Improvements per PR feedback. --- .../crew_ai/crew_ai_enterprise_client.py | 2 +- .../core_plugins/crew_ai/crew_ai_models.py | 4 +- .../core_plugins/test_crew_ai_enterprise.py | 95 +++++++++++++++++++ 3 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 python/tests/unit/core_plugins/test_crew_ai_enterprise.py diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise_client.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise_client.py index d492102ccc61..82a717997d10 100644 --- a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise_client.py +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise_client.py @@ -30,7 +30,7 @@ def __init__( """ self.endpoint = endpoint self.auth_token = auth_token - self.session = session if session else aiohttp.ClientSession() + self.session = session if session is None else aiohttp.ClientSession() self.request_header = { "Authorization": f"Bearer {auth_token}", "Content-Type": "application/json", diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_models.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_models.py index 31ed068ad2f8..540b3e5293af 100644 --- a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_models.py +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_models.py @@ -22,8 +22,8 @@ class CrewAIStatusResponse(KernelBaseModel): """Represents the status response from Crew AI.""" state: CrewAIEnterpriseKickoffState - result: str | None - last_step: dict[str, Any] | None + result: str | None = None + last_step: dict[str, Any] | None = None class CrewAIKickoffResponse(KernelBaseModel): diff --git a/python/tests/unit/core_plugins/test_crew_ai_enterprise.py b/python/tests/unit/core_plugins/test_crew_ai_enterprise.py new file mode 100644 index 000000000000..1dbf8ee40679 --- /dev/null +++ b/python/tests/unit/core_plugins/test_crew_ai_enterprise.py @@ -0,0 +1,95 @@ +# Copyright (c) Microsoft. All rights reserved. + +from unittest.mock import patch + +import pytest + +from semantic_kernel.core_plugins.crew_ai.crew_ai_enterprise import CrewAIEnterprise +from semantic_kernel.core_plugins.crew_ai.crew_ai_models import CrewAIEnterpriseKickoffState, CrewAIStatusResponse +from semantic_kernel.exceptions.function_exceptions import PluginInitializationError +from semantic_kernel.functions.kernel_parameter_metadata import KernelParameterMetadata +from semantic_kernel.functions.kernel_plugin import KernelPlugin + + +@pytest.fixture +def crew_ai_enterprise(): + return CrewAIEnterprise(endpoint="https://test.com", auth_token="FakeToken") + + +def test_it_can_be_instantiated(crew_ai_enterprise): + assert crew_ai_enterprise is not None + + +def test_create_kernel_plugin(crew_ai_enterprise): + plugin = crew_ai_enterprise.create_kernel_plugin( + name="test_plugin", + description="Test plugin", + parameters=[KernelParameterMetadata(name="param1")], + ) + assert isinstance(plugin, KernelPlugin) + assert "kickoff" in plugin.functions + assert "kickoff_and_wait" in plugin.functions + assert "get_status" in plugin.functions + assert "wait_for_completion" in plugin.functions + + +@patch("semantic_kernel.core_plugins.crew_ai.crew_ai_enterprise.CrewAIEnterpriseClient.kickoff") +async def test_kickoff(mock_kickoff, crew_ai_enterprise): + mock_kickoff.return_value.kickoff_id = "123" + kickoff_id = await crew_ai_enterprise.kickoff(inputs={"param1": "value"}) + assert kickoff_id == "123" + + +@pytest.mark.parametrize( + "state", + [ + CrewAIEnterpriseKickoffState.Pending, + CrewAIEnterpriseKickoffState.Started, + CrewAIEnterpriseKickoffState.Running, + CrewAIEnterpriseKickoffState.Success, + CrewAIEnterpriseKickoffState.Failed, + CrewAIEnterpriseKickoffState.Failure, + CrewAIEnterpriseKickoffState.Not_Found, + ], +) +@patch("semantic_kernel.core_plugins.crew_ai.crew_ai_enterprise.CrewAIEnterpriseClient.get_status") +async def test_get_crew_kickoff_status(mock_get_status, crew_ai_enterprise, state): + mock_get_status.return_value = CrewAIStatusResponse(state=state.value) + status_response = await crew_ai_enterprise.get_crew_kickoff_status(kickoff_id="123") + assert status_response.state == state + + +@patch("semantic_kernel.core_plugins.crew_ai.crew_ai_enterprise.CrewAIEnterpriseClient.get_status") +async def test_wait_for_crew_completion(mock_get_status, crew_ai_enterprise): + mock_get_status.side_effect = [ + CrewAIStatusResponse(state=CrewAIEnterpriseKickoffState.Pending), + CrewAIStatusResponse(state=CrewAIEnterpriseKickoffState.Success, result="result"), + ] + result = await crew_ai_enterprise.wait_for_crew_completion(kickoff_id="123") + assert result == "result" + + +def test_build_arguments(crew_ai_enterprise): + parameters = [KernelParameterMetadata(name="param1")] + arguments = {"param1": "value"} + args = crew_ai_enterprise._build_arguments(parameters, arguments) + assert args["param1"] == "value" + + +def test_build_arguments_missing_param(crew_ai_enterprise): + parameters = [KernelParameterMetadata(name="param1")] + arguments = {} + with pytest.raises(PluginInitializationError): + crew_ai_enterprise._build_arguments(parameters, arguments) + + +@patch("semantic_kernel.core_plugins.crew_ai.crew_ai_enterprise.CrewAIEnterpriseClient.__aenter__") +async def test_aenter(mock_aenter, crew_ai_enterprise): + await crew_ai_enterprise.__aenter__() + mock_aenter.assert_called_once() + + +@patch("semantic_kernel.core_plugins.crew_ai.crew_ai_enterprise.CrewAIEnterpriseClient.__aexit__") +async def test_aexit(mock_aexit, crew_ai_enterprise): + await crew_ai_enterprise.__aexit__() + mock_aexit.assert_called_once() From f2d2c63862dc6599ed59b3ea52cfd4871a0c64b3 Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Wed, 12 Feb 2025 15:23:26 -0800 Subject: [PATCH 16/16] Fixing mypi issues, --- .../core_plugins/crew_ai/crew_ai_enterprise_client.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise_client.py b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise_client.py index 82a717997d10..f52efa77e17d 100644 --- a/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise_client.py +++ b/python/semantic_kernel/core_plugins/crew_ai/crew_ai_enterprise_client.py @@ -44,7 +44,7 @@ async def get_inputs(self) -> CrewAIRequiredInputs: CrewAIRequiredInputs: The required inputs for Crew AI. """ async with ( - self.session.get(f"{self.endpoint}/inputs", headers=self.request_header) as response, + self.session.get(f"{self.endpoint}/inputs", headers=self.request_header) as response, # type: ignore ): response.raise_for_status() return CrewAIRequiredInputs.model_validate_json(await response.text()) @@ -74,7 +74,7 @@ async def kickoff( "crewWebhookUrl": crew_webhook_url, } async with ( - self.session.post(f"{self.endpoint}/kickoff", json=content, headers=self.request_header) as response, + self.session.post(f"{self.endpoint}/kickoff", json=content, headers=self.request_header) as response, # type: ignore ): response.raise_for_status() body = await response.text() @@ -90,7 +90,7 @@ async def get_status(self, task_id: str) -> CrewAIStatusResponse: CrewAIStatusResponse: The status response of the task. """ async with ( - self.session.get(f"{self.endpoint}/status/{task_id}", headers=self.request_header) as response, + self.session.get(f"{self.endpoint}/status/{task_id}", headers=self.request_header) as response, # type: ignore ): response.raise_for_status() body = await response.text() @@ -98,9 +98,9 @@ async def get_status(self, task_id: str) -> CrewAIStatusResponse: async def __aenter__(self): """Enter the session.""" - await self.session.__aenter__() + await self.session.__aenter__() # type: ignore return self async def __aexit__(self, *args, **kwargs): """Close the session.""" - await self.session.close() + await self.session.close() # type: ignore