Compare commits

..

3 Commits

Author SHA1 Message Date
Devin AI
f36d48d57e feat: Enhance Bedrock authentication with improved docs, validation, and tests
- Add clearer authentication method comments in documentation examples
- Include security best practices for API key usage
- Add CLI validation hints for AWS Bedrock API key format
- Implement comprehensive error handling tests (timeout, rate limit, invalid key)
- Add connection error and retry scenario test cases
- Maintain consistency between English and Portuguese documentation

Addresses AI code review feedback on PR #3126

Co-Authored-By: Jo\u00E3o <joao@crewai.com>
2025-07-09 12:24:56 +00:00
Devin AI
3eea890409 fix: Remove unused pytest import to resolve lint check
- Remove unused pytest import from test_bedrock_authentication.py
- Fixes F401 lint error that was causing CI failure

Co-Authored-By: Jo\u00E3o <joao@crewai.com>
2025-07-09 12:18:33 +00:00
Devin AI
a670b2b35e feat: Add AWS Bedrock API key authentication support
- Add AWS_BEARER_TOKEN_BEDROCK environment variable to CLI constants
- Update English and Portuguese documentation with both IAM and API key auth methods
- Document boto3 v1.393+ requirement for API key authentication
- Add comprehensive tests for both authentication methods
- Include links to AWS console for API key generation

Addresses issue #3125

Co-Authored-By: Jo\u00E3o <joao@crewai.com>
2025-07-09 12:15:57 +00:00
13 changed files with 255 additions and 75 deletions

View File

@@ -311,20 +311,47 @@ In this section, you'll find detailed examples that help you select, configure,
</Accordion>
<Accordion title="AWS Bedrock">
Amazon Bedrock supports two authentication methods:
**Method 1: IAM Role Authentication (Recommended for Production)**
```toml Code
AWS_ACCESS_KEY_ID=<your-access-key>
AWS_SECRET_ACCESS_KEY=<your-secret-key>
AWS_DEFAULT_REGION=<your-region>
```
**Method 2: API Key Authentication (Recommended for Development)**
```toml Code
AWS_BEARER_TOKEN_BEDROCK=<your-api-key>
AWS_DEFAULT_REGION=<your-region>
```
Example usage in your CrewAI project:
```python Code
# Method 1: IAM Role Authentication (uses AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY)
# Set environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION
llm = LLM(
model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0"
)
# Method 2: API Key Authentication (uses AWS_BEARER_TOKEN_BEDROCK)
# Set environment variables: AWS_BEARER_TOKEN_BEDROCK, AWS_DEFAULT_REGION
llm = LLM(
model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0"
)
```
Before using Amazon Bedrock, make sure you have boto3 installed in your environment
**Requirements:**
- Before using Amazon Bedrock, make sure you have boto3 v1.393+ installed in your environment
- For API key authentication, you can generate a 30-day API key from the [Amazon Bedrock console](https://console.aws.amazon.com/bedrock/)
- For production applications, use IAM roles or temporary credentials instead of long-term API keys
**Security Best Practices:**
- API keys expire after 30 days and should be rotated regularly
- Use IAM roles for production environments for better security
- Store API keys securely and never commit them to version control
- Monitor API usage and set up alerts for unusual activity
- Consider using temporary credentials for enhanced security
[Amazon Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/models-regions.html) is a managed service that provides access to multiple foundation models from top AI companies through a unified API, enabling secure and responsible AI application development.

View File

@@ -40,7 +40,7 @@ This installs the tool and adds it to `pyproject.toml`.
To create a new tool project:
```bash
crewai create tool <tool-name>
crewai tool create <tool-name>
```
This generates a scaffolded tool project locally.
@@ -95,7 +95,7 @@ Deletion is permanent. Deleted tools cannot be restored or re-installed.
## Security Checks
Every published version undergoes automated security checks, and are only available to install after they pass.
Every published version undergoes automated security checks, and are only available to install after they pass.
You can check the security check status of a tool at:

View File

@@ -309,20 +309,47 @@ Nesta seção, você encontrará exemplos detalhados que ajudam a selecionar, co
</Accordion>
<Accordion title="AWS Bedrock">
O Amazon Bedrock suporta dois métodos de autenticação:
**Método 1: Autenticação por Função IAM (Recomendado para Produção)**
```toml Code
AWS_ACCESS_KEY_ID=<your-access-key>
AWS_SECRET_ACCESS_KEY=<your-secret-key>
AWS_DEFAULT_REGION=<your-region>
```
**Método 2: Autenticação por Chave de API (Recomendado para Desenvolvimento)**
```toml Code
AWS_BEARER_TOKEN_BEDROCK=<your-api-key>
AWS_DEFAULT_REGION=<your-region>
```
Exemplo de uso em seu projeto CrewAI:
```python Code
# Método 1: Autenticação por Função IAM (usa AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY)
# Configure as variáveis de ambiente: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION
llm = LLM(
model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0"
)
# Método 2: Autenticação por Chave de API (usa AWS_BEARER_TOKEN_BEDROCK)
# Configure as variáveis de ambiente: AWS_BEARER_TOKEN_BEDROCK, AWS_DEFAULT_REGION
llm = LLM(
model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0"
)
```
Antes de usar o Amazon Bedrock, certifique-se de ter o boto3 instalado em seu ambiente
**Requisitos:**
- Antes de usar o Amazon Bedrock, certifique-se de ter o boto3 v1.393+ instalado em seu ambiente
- Para autenticação por chave de API, você pode gerar uma chave de 30 dias no [console do Amazon Bedrock](https://console.aws.amazon.com/bedrock/)
- Para aplicações de produção, use funções IAM ou credenciais temporárias em vez de chaves de API de longo prazo
**Melhores Práticas de Segurança:**
- Chaves de API expiram após 30 dias e devem ser rotacionadas regularmente
- Use funções IAM para ambientes de produção para melhor segurança
- Armazene chaves de API com segurança e nunca as confirme no controle de versão
- Monitore o uso da API e configure alertas para atividades incomuns
- Considere usar credenciais temporárias para segurança aprimorada
[Amazon Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/models-regions.html) é um serviço gerenciado que fornece acesso a múltiplos modelos fundamentais dos principais provedores de IA através de uma API unificada, permitindo o desenvolvimento seguro e responsável de aplicações de IA.
@@ -881,4 +908,4 @@ Saiba como obter o máximo da configuração do seu LLM:
llm = LLM(model="openai/gpt-4o") # 128K tokens
```
</Tab>
</Tabs>
</Tabs>

View File

@@ -40,7 +40,7 @@ Isso instala a ferramenta e a adiciona ao `pyproject.toml`.
Para criar um novo projeto de ferramenta:
```bash
crewai create tool <nome-da-ferramenta>
crewai tool create <nome-da-ferramenta>
```
Isso gera um projeto de ferramenta estruturado localmente.
@@ -104,4 +104,4 @@ Você pode verificar o status das verificações de segurança de uma ferramenta
<Card title="Precisa de ajuda?" icon="headset" href="mailto:support@crewai.com">
Entre em contato com nossa equipe de suporte para assistência com integração de API ou resolução de problemas.
</Card>
</Card>

View File

@@ -47,7 +47,7 @@ Documentation = "https://docs.crewai.com"
Repository = "https://github.com/crewAIInc/crewAI"
[project.optional-dependencies]
tools = ["crewai-tools~=0.51.0"]
tools = ["crewai-tools~=0.49.0"]
embeddings = [
"tiktoken~=0.8.0"
]

View File

@@ -54,7 +54,7 @@ def _track_install_async():
_track_install_async()
__version__ = "0.141.0"
__version__ = "0.140.0"
__all__ = [
"Agent",
"Crew",

View File

@@ -33,21 +33,18 @@ def crewai():
@crewai.command()
@click.argument("type", type=click.Choice(["crew", "flow", "tool"]))
@click.argument("type", type=click.Choice(["crew", "flow"]))
@click.argument("name")
@click.option("--provider", type=str, help="The provider to use for the crew")
@click.option("--skip_provider", is_flag=True, help="Skip provider validation")
def create(type, name, provider, skip_provider=False):
"""Create a new crew, flow, or tool."""
"""Create a new crew, or flow."""
if type == "crew":
create_crew(name, provider, skip_provider)
elif type == "flow":
create_flow(name)
elif type == "tool":
tool_cmd = ToolCommand()
tool_cmd.create(name)
else:
click.secho("Error: Invalid type. Must be 'crew', 'flow', or 'tool'.", fg="red")
click.secho("Error: Invalid type. Must be 'crew' or 'flow'.", fg="red")
@crewai.command()
@@ -360,7 +357,7 @@ def chat():
and using the Chat LLM to generate responses.
"""
click.secho(
"\nStarting a conversation with the Crew\nType 'exit' or Ctrl+C to quit.\n",
"\nStarting a conversation with the Crew\n" "Type 'exit' or Ctrl+C to quit.\n",
)
run_chat()

View File

@@ -62,6 +62,10 @@ ENV_VARS = {
"prompt": "Enter your AWS Region Name (press Enter to skip)",
"key_name": "AWS_REGION_NAME",
},
{
"prompt": "Enter your AWS Bedrock API Key (30-day key from AWS console, press Enter to skip)",
"key_name": "AWS_BEARER_TOKEN_BEDROCK",
},
],
"azure": [
{

View File

@@ -5,7 +5,7 @@ description = "{{name}} using crewAI"
authors = [{ name = "Your Name", email = "you@example.com" }]
requires-python = ">=3.10,<3.14"
dependencies = [
"crewai[tools]>=0.141.0,<1.0.0"
"crewai[tools]>=0.140.0,<1.0.0"
]
[project.scripts]

View File

@@ -5,7 +5,7 @@ description = "{{name}} using crewAI"
authors = [{ name = "Your Name", email = "you@example.com" }]
requires-python = ">=3.10,<3.14"
dependencies = [
"crewai[tools]>=0.141.0,<1.0.0",
"crewai[tools]>=0.140.0,<1.0.0",
]
[project.scripts]

View File

@@ -5,7 +5,7 @@ description = "Power up your crews with {{folder_name}}"
readme = "README.md"
requires-python = ">=3.10,<3.14"
dependencies = [
"crewai[tools]>=0.141.0"
"crewai[tools]>=0.140.0"
]
[tool.crewai]

View File

@@ -0,0 +1,177 @@
import os
import pytest
from unittest.mock import patch, MagicMock
from crewai import LLM
class TestBedrockAuthentication:
"""Test AWS Bedrock authentication methods."""
@patch.dict(os.environ, {
'AWS_ACCESS_KEY_ID': 'test-key-id',
'AWS_SECRET_ACCESS_KEY': 'test-secret-key',
'AWS_DEFAULT_REGION': 'us-east-1'
})
@patch('litellm.completion')
def test_bedrock_iam_authentication(self, mock_completion):
"""Test Bedrock with IAM role authentication."""
mock_completion.return_value = MagicMock()
mock_completion.return_value.choices = [MagicMock()]
mock_completion.return_value.choices[0].message.content = "Test response"
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
result = llm.call("test message")
mock_completion.assert_called_once()
assert result == "Test response"
@patch.dict(os.environ, {
'AWS_BEARER_TOKEN_BEDROCK': 'test-api-key',
'AWS_DEFAULT_REGION': 'us-east-1'
})
@patch('litellm.completion')
def test_bedrock_api_key_authentication(self, mock_completion):
"""Test Bedrock with API key authentication."""
mock_completion.return_value = MagicMock()
mock_completion.return_value.choices = [MagicMock()]
mock_completion.return_value.choices[0].message.content = "Test response"
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
result = llm.call("test message")
mock_completion.assert_called_once()
assert result == "Test response"
def test_bedrock_missing_credentials(self):
"""Test Bedrock fails gracefully with missing credentials."""
with patch.dict(os.environ, {}, clear=True):
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
assert llm.model == "bedrock/anthropic.claude-3-sonnet-20240229-v1:0"
@patch.dict(os.environ, {
'AWS_BEARER_TOKEN_BEDROCK': 'test-api-key',
'AWS_DEFAULT_REGION': 'us-east-1'
})
@patch('litellm.completion')
def test_bedrock_api_key_with_streaming(self, mock_completion):
"""Test Bedrock API key authentication with streaming."""
mock_completion.return_value = iter([
MagicMock(choices=[MagicMock(delta=MagicMock(content="Test"))]),
MagicMock(choices=[MagicMock(delta=MagicMock(content=" response"))])
])
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
result = list(llm.stream("test message"))
mock_completion.assert_called_once()
assert len(result) == 2
@patch.dict(os.environ, {
'AWS_ACCESS_KEY_ID': 'test-key-id',
'AWS_SECRET_ACCESS_KEY': 'test-secret-key',
'AWS_DEFAULT_REGION': 'us-east-1'
})
@patch('litellm.completion')
def test_bedrock_iam_with_custom_parameters(self, mock_completion):
"""Test Bedrock IAM authentication with custom parameters."""
mock_completion.return_value = MagicMock()
mock_completion.return_value.choices = [MagicMock()]
mock_completion.return_value.choices[0].message.content = "Test response"
llm = LLM(
model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0",
temperature=0.7,
max_tokens=100
)
result = llm.call("test message")
mock_completion.assert_called_once()
call_args = mock_completion.call_args
assert call_args[1]['temperature'] == 0.7
assert call_args[1]['max_tokens'] == 100
assert result == "Test response"
@patch.dict(os.environ, {
'AWS_BEARER_TOKEN_BEDROCK': 'test-api-key',
'AWS_DEFAULT_REGION': 'us-west-2'
})
@patch('litellm.completion')
def test_bedrock_api_key_different_region(self, mock_completion):
"""Test Bedrock API key authentication with different region."""
mock_completion.return_value = MagicMock()
mock_completion.return_value.choices = [MagicMock()]
mock_completion.return_value.choices[0].message.content = "Test response"
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
result = llm.call("test message")
mock_completion.assert_called_once()
assert result == "Test response"
@patch.dict(os.environ, {
'AWS_BEARER_TOKEN_BEDROCK': 'test-api-key',
'AWS_DEFAULT_REGION': 'us-east-1'
})
@patch('litellm.completion')
def test_bedrock_timeout_handling(self, mock_completion):
"""Test Bedrock API timeout handling."""
mock_completion.side_effect = TimeoutError("Request timed out")
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
with pytest.raises(TimeoutError, match="Request timed out"):
llm.call("test message")
@patch.dict(os.environ, {
'AWS_BEARER_TOKEN_BEDROCK': 'test-api-key',
'AWS_DEFAULT_REGION': 'us-east-1'
})
@patch('litellm.completion')
def test_bedrock_rate_limit_handling(self, mock_completion):
"""Test Bedrock API rate limit handling."""
mock_completion.side_effect = Exception("Rate limit exceeded")
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
with pytest.raises(Exception, match="Rate limit exceeded"):
llm.call("test message")
@patch.dict(os.environ, {
'AWS_BEARER_TOKEN_BEDROCK': 'invalid-key',
'AWS_DEFAULT_REGION': 'us-east-1'
})
@patch('litellm.completion')
def test_bedrock_invalid_api_key(self, mock_completion):
"""Test Bedrock with invalid API key."""
mock_completion.side_effect = Exception("Invalid API key")
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
with pytest.raises(Exception, match="Invalid API key"):
llm.call("test message")
@patch.dict(os.environ, {
'AWS_ACCESS_KEY_ID': 'test-key-id',
'AWS_SECRET_ACCESS_KEY': 'test-secret-key',
'AWS_DEFAULT_REGION': 'us-east-1'
})
@patch('litellm.completion')
def test_bedrock_connection_error(self, mock_completion):
"""Test Bedrock with connection error."""
mock_completion.side_effect = ConnectionError("Connection failed")
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
with pytest.raises(ConnectionError, match="Connection failed"):
llm.call("test message")
@patch.dict(os.environ, {
'AWS_BEARER_TOKEN_BEDROCK': 'test-api-key',
'AWS_DEFAULT_REGION': 'us-east-1'
})
@patch('litellm.completion')
def test_bedrock_api_key_with_retry_scenario(self, mock_completion):
"""Test Bedrock API key authentication with retry scenario."""
mock_completion.side_effect = [
Exception("Temporary error"),
MagicMock(choices=[MagicMock(message=MagicMock(content="Success after retry"))])
]
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
with pytest.raises(Exception, match="Temporary error"):
llm.call("test message")

60
uv.lock generated
View File

@@ -746,10 +746,8 @@ dev = [
{ name = "pytest-asyncio" },
{ name = "pytest-randomly" },
{ name = "pytest-recording" },
{ name = "pytest-split" },
{ name = "pytest-subprocess" },
{ name = "pytest-timeout" },
{ name = "pytest-xdist" },
{ name = "python-dotenv" },
{ name = "ruff" },
]
@@ -762,7 +760,7 @@ requires-dist = [
{ name = "blinker", specifier = ">=1.9.0" },
{ name = "chromadb", specifier = ">=0.5.23" },
{ name = "click", specifier = ">=8.1.7" },
{ name = "crewai-tools", marker = "extra == 'tools'", specifier = "~=0.51.0" },
{ name = "crewai-tools", marker = "extra == 'tools'", specifier = "~=0.49.0" },
{ name = "docling", marker = "extra == 'docling'", specifier = ">=2.12.0" },
{ name = "instructor", specifier = ">=1.3.3" },
{ name = "json-repair", specifier = "==0.25.2" },
@@ -803,17 +801,15 @@ dev = [
{ name = "pytest-asyncio", specifier = ">=0.23.7" },
{ name = "pytest-randomly", specifier = ">=3.16.0" },
{ name = "pytest-recording", specifier = ">=0.13.2" },
{ name = "pytest-split", specifier = ">=0.9.0" },
{ name = "pytest-subprocess", specifier = ">=1.5.2" },
{ name = "pytest-timeout", specifier = ">=2.3.1" },
{ name = "pytest-xdist", specifier = ">=3.6.1" },
{ name = "python-dotenv", specifier = ">=1.0.0" },
{ name = "ruff", specifier = ">=0.8.2" },
]
[[package]]
name = "crewai-tools"
version = "0.51.0"
version = "0.49.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "chromadb" },
@@ -829,9 +825,9 @@ dependencies = [
{ name = "requests" },
{ name = "tiktoken" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a1/ef/3426aebf495a887898466d38d6b78b09317d4c102a89493699d6af5aa823/crewai_tools-0.51.0.tar.gz", hash = "sha256:a5d73f344b740b13ffef8d189d6d210da143227982edf619e4de77896e2fd017", size = 1011735, upload-time = "2025-07-09T16:39:24.179Z" }
sdist = { url = "https://files.pythonhosted.org/packages/4b/49/9bfe6c6ef9b951289e872ea3897eaa27812fc62d711a60e1e67ffb732585/crewai_tools-0.49.0.tar.gz", hash = "sha256:fa2e3a0effb62cfc02cdad01a26eee6e9afef464b36f20f74168fed8c11c2c95", size = 938528, upload-time = "2025-07-02T20:27:46.393Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/61/ea/9931f130dae5910a1b2e9d1fc6347d991100538e1faf3ece37ec8380ec96/crewai_tools-0.51.0-py3-none-any.whl", hash = "sha256:ba67e6bed6134e374c96fe9038bce6045600ff3b5358f6a6d75ff8f316defd06", size = 633012, upload-time = "2025-07-09T16:39:22.239Z" },
{ url = "https://files.pythonhosted.org/packages/20/3d/363fedbb6aa2534eae13e551fcdb5d54ef0ac21c76264d46c37f2ef83f92/crewai_tools-0.49.0-py3-none-any.whl", hash = "sha256:f771d8fd677cd4420409964ab8bb700af616341836051a25d534896e46e8b3c4", size = 622043, upload-time = "2025-07-02T20:27:44.869Z" },
]
[[package]]
@@ -1196,15 +1192,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674, upload-time = "2025-05-10T17:42:49.33Z" },
]
[[package]]
name = "execnet"
version = "2.1.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/bb/ff/b4c0dc78fbe20c3e59c0c7334de0c27eb4001a2b2017999af398bf730817/execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3", size = 166524, upload-time = "2024-04-08T09:04:19.245Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/43/09/2aea36ff60d16dd8879bdb2f5b3ee0ba8d08cbbdcdfe870e695ce3784385/execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc", size = 40612, upload-time = "2024-04-08T09:04:17.414Z" },
]
[[package]]
name = "executing"
version = "2.2.0"
@@ -3705,8 +3692,6 @@ sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/d0d6dea55cd152ce3
wheels = [
{ url = "https://files.pythonhosted.org/packages/4c/5d/45a3553a253ac8763f3561371432a90bdbe6000fbdcf1397ffe502aa206c/pillow-11.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1b9c17fd4ace828b3003dfd1e30bff24863e0eb59b535e8f80194d9cc7ecf860", size = 5316554, upload-time = "2025-07-01T09:13:39.342Z" },
{ url = "https://files.pythonhosted.org/packages/7c/c8/67c12ab069ef586a25a4a79ced553586748fad100c77c0ce59bb4983ac98/pillow-11.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:65dc69160114cdd0ca0f35cb434633c75e8e7fad4cf855177a05bf38678f73ad", size = 4686548, upload-time = "2025-07-01T09:13:41.835Z" },
{ url = "https://files.pythonhosted.org/packages/2f/bd/6741ebd56263390b382ae4c5de02979af7f8bd9807346d068700dd6d5cf9/pillow-11.3.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7107195ddc914f656c7fc8e4a5e1c25f32e9236ea3ea860f257b0436011fddd0", size = 5859742, upload-time = "2025-07-03T13:09:47.439Z" },
{ url = "https://files.pythonhosted.org/packages/ca/0b/c412a9e27e1e6a829e6ab6c2dca52dd563efbedf4c9c6aa453d9a9b77359/pillow-11.3.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc3e831b563b3114baac7ec2ee86819eb03caa1a2cef0b481a5675b59c4fe23b", size = 7633087, upload-time = "2025-07-03T13:09:51.796Z" },
{ url = "https://files.pythonhosted.org/packages/59/9d/9b7076aaf30f5dd17e5e5589b2d2f5a5d7e30ff67a171eb686e4eecc2adf/pillow-11.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f1f182ebd2303acf8c380a54f615ec883322593320a9b00438eb842c1f37ae50", size = 5963350, upload-time = "2025-07-01T09:13:43.865Z" },
{ url = "https://files.pythonhosted.org/packages/f0/16/1a6bf01fb622fb9cf5c91683823f073f053005c849b1f52ed613afcf8dae/pillow-11.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4445fa62e15936a028672fd48c4c11a66d641d2c05726c7ec1f8ba6a572036ae", size = 6631840, upload-time = "2025-07-01T09:13:46.161Z" },
{ url = "https://files.pythonhosted.org/packages/7b/e6/6ff7077077eb47fde78739e7d570bdcd7c10495666b6afcd23ab56b19a43/pillow-11.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:71f511f6b3b91dd543282477be45a033e4845a40278fa8dcdbfdb07109bf18f9", size = 6074005, upload-time = "2025-07-01T09:13:47.829Z" },
@@ -3716,8 +3701,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/9f/28/4f4a0203165eefb3763939c6789ba31013a2e90adffb456610f30f613850/pillow-11.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:819931d25e57b513242859ce1876c58c59dc31587847bf74cfe06b2e0cb22d2f", size = 2422899, upload-time = "2025-07-01T09:13:57.497Z" },
{ url = "https://files.pythonhosted.org/packages/db/26/77f8ed17ca4ffd60e1dcd220a6ec6d71210ba398cfa33a13a1cd614c5613/pillow-11.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722", size = 5316531, upload-time = "2025-07-01T09:13:59.203Z" },
{ url = "https://files.pythonhosted.org/packages/cb/39/ee475903197ce709322a17a866892efb560f57900d9af2e55f86db51b0a5/pillow-11.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288", size = 4686560, upload-time = "2025-07-01T09:14:01.101Z" },
{ url = "https://files.pythonhosted.org/packages/d5/90/442068a160fd179938ba55ec8c97050a612426fae5ec0a764e345839f76d/pillow-11.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d", size = 5870978, upload-time = "2025-07-03T13:09:55.638Z" },
{ url = "https://files.pythonhosted.org/packages/13/92/dcdd147ab02daf405387f0218dcf792dc6dd5b14d2573d40b4caeef01059/pillow-11.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494", size = 7641168, upload-time = "2025-07-03T13:10:00.37Z" },
{ url = "https://files.pythonhosted.org/packages/6e/db/839d6ba7fd38b51af641aa904e2960e7a5644d60ec754c046b7d2aee00e5/pillow-11.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58", size = 5973053, upload-time = "2025-07-01T09:14:04.491Z" },
{ url = "https://files.pythonhosted.org/packages/f2/2f/d7675ecae6c43e9f12aa8d58b6012683b20b6edfbdac7abcb4e6af7a3784/pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f", size = 6640273, upload-time = "2025-07-01T09:14:06.235Z" },
{ url = "https://files.pythonhosted.org/packages/45/ad/931694675ede172e15b2ff03c8144a0ddaea1d87adb72bb07655eaffb654/pillow-11.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e", size = 6082043, upload-time = "2025-07-01T09:14:07.978Z" },
@@ -3727,8 +3710,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/c6/df/90bd886fabd544c25addd63e5ca6932c86f2b701d5da6c7839387a076b4a/pillow-11.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd", size = 2423079, upload-time = "2025-07-01T09:14:15.268Z" },
{ url = "https://files.pythonhosted.org/packages/40/fe/1bc9b3ee13f68487a99ac9529968035cca2f0a51ec36892060edcc51d06a/pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4", size = 5278800, upload-time = "2025-07-01T09:14:17.648Z" },
{ url = "https://files.pythonhosted.org/packages/2c/32/7e2ac19b5713657384cec55f89065fb306b06af008cfd87e572035b27119/pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69", size = 4686296, upload-time = "2025-07-01T09:14:19.828Z" },
{ url = "https://files.pythonhosted.org/packages/8e/1e/b9e12bbe6e4c2220effebc09ea0923a07a6da1e1f1bfbc8d7d29a01ce32b/pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d", size = 5871726, upload-time = "2025-07-03T13:10:04.448Z" },
{ url = "https://files.pythonhosted.org/packages/8d/33/e9200d2bd7ba00dc3ddb78df1198a6e80d7669cce6c2bdbeb2530a74ec58/pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6", size = 7644652, upload-time = "2025-07-03T13:10:10.391Z" },
{ url = "https://files.pythonhosted.org/packages/41/f1/6f2427a26fc683e00d985bc391bdd76d8dd4e92fac33d841127eb8fb2313/pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7", size = 5977787, upload-time = "2025-07-01T09:14:21.63Z" },
{ url = "https://files.pythonhosted.org/packages/e4/c9/06dd4a38974e24f932ff5f98ea3c546ce3f8c995d3f0985f8e5ba48bba19/pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024", size = 6645236, upload-time = "2025-07-01T09:14:23.321Z" },
{ url = "https://files.pythonhosted.org/packages/40/e7/848f69fb79843b3d91241bad658e9c14f39a32f71a301bcd1d139416d1be/pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809", size = 6086950, upload-time = "2025-07-01T09:14:25.237Z" },
@@ -3741,8 +3722,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/aa/86/3f758a28a6e381758545f7cdb4942e1cb79abd271bea932998fc0db93cb6/pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f", size = 2227443, upload-time = "2025-07-01T09:14:39.344Z" },
{ url = "https://files.pythonhosted.org/packages/01/f4/91d5b3ffa718df2f53b0dc109877993e511f4fd055d7e9508682e8aba092/pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c", size = 5278474, upload-time = "2025-07-01T09:14:41.843Z" },
{ url = "https://files.pythonhosted.org/packages/f9/0e/37d7d3eca6c879fbd9dba21268427dffda1ab00d4eb05b32923d4fbe3b12/pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd", size = 4686038, upload-time = "2025-07-01T09:14:44.008Z" },
{ url = "https://files.pythonhosted.org/packages/ff/b0/3426e5c7f6565e752d81221af9d3676fdbb4f352317ceafd42899aaf5d8a/pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e", size = 5864407, upload-time = "2025-07-03T13:10:15.628Z" },
{ url = "https://files.pythonhosted.org/packages/fc/c1/c6c423134229f2a221ee53f838d4be9d82bab86f7e2f8e75e47b6bf6cd77/pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1", size = 7639094, upload-time = "2025-07-03T13:10:21.857Z" },
{ url = "https://files.pythonhosted.org/packages/ba/c9/09e6746630fe6372c67c648ff9deae52a2bc20897d51fa293571977ceb5d/pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805", size = 5973503, upload-time = "2025-07-01T09:14:45.698Z" },
{ url = "https://files.pythonhosted.org/packages/d5/1c/a2a29649c0b1983d3ef57ee87a66487fdeb45132df66ab30dd37f7dbe162/pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8", size = 6642574, upload-time = "2025-07-01T09:14:47.415Z" },
{ url = "https://files.pythonhosted.org/packages/36/de/d5cc31cc4b055b6c6fd990e3e7f0f8aaf36229a2698501bcb0cdf67c7146/pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2", size = 6084060, upload-time = "2025-07-01T09:14:49.636Z" },
@@ -3752,8 +3731,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/17/d2/622f4547f69cd173955194b78e4d19ca4935a1b0f03a302d655c9f6aae65/pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580", size = 2423055, upload-time = "2025-07-01T09:14:58.072Z" },
{ url = "https://files.pythonhosted.org/packages/dd/80/a8a2ac21dda2e82480852978416cfacd439a4b490a501a288ecf4fe2532d/pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e", size = 5281110, upload-time = "2025-07-01T09:14:59.79Z" },
{ url = "https://files.pythonhosted.org/packages/44/d6/b79754ca790f315918732e18f82a8146d33bcd7f4494380457ea89eb883d/pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d", size = 4689547, upload-time = "2025-07-01T09:15:01.648Z" },
{ url = "https://files.pythonhosted.org/packages/49/20/716b8717d331150cb00f7fdd78169c01e8e0c219732a78b0e59b6bdb2fd6/pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced", size = 5901554, upload-time = "2025-07-03T13:10:27.018Z" },
{ url = "https://files.pythonhosted.org/packages/74/cf/a9f3a2514a65bb071075063a96f0a5cf949c2f2fce683c15ccc83b1c1cab/pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c", size = 7669132, upload-time = "2025-07-03T13:10:33.01Z" },
{ url = "https://files.pythonhosted.org/packages/98/3c/da78805cbdbee9cb43efe8261dd7cc0b4b93f2ac79b676c03159e9db2187/pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8", size = 6005001, upload-time = "2025-07-01T09:15:03.365Z" },
{ url = "https://files.pythonhosted.org/packages/6c/fa/ce044b91faecf30e635321351bba32bab5a7e034c60187fe9698191aef4f/pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59", size = 6668814, upload-time = "2025-07-01T09:15:05.655Z" },
{ url = "https://files.pythonhosted.org/packages/7b/51/90f9291406d09bf93686434f9183aba27b831c10c87746ff49f127ee80cb/pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe", size = 6113124, upload-time = "2025-07-01T09:15:07.358Z" },
@@ -3763,15 +3740,11 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/f3/7e/b623008460c09a0cb38263c93b828c666493caee2eb34ff67f778b87e58c/pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e", size = 2424803, upload-time = "2025-07-01T09:15:15.695Z" },
{ url = "https://files.pythonhosted.org/packages/6f/8b/209bd6b62ce8367f47e68a218bffac88888fdf2c9fcf1ecadc6c3ec1ebc7/pillow-11.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3cee80663f29e3843b68199b9d6f4f54bd1d4a6b59bdd91bceefc51238bcb967", size = 5270556, upload-time = "2025-07-01T09:16:09.961Z" },
{ url = "https://files.pythonhosted.org/packages/2e/e6/231a0b76070c2cfd9e260a7a5b504fb72da0a95279410fa7afd99d9751d6/pillow-11.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b5f56c3f344f2ccaf0dd875d3e180f631dc60a51b314295a3e681fe8cf851fbe", size = 4654625, upload-time = "2025-07-01T09:16:11.913Z" },
{ url = "https://files.pythonhosted.org/packages/13/f4/10cf94fda33cb12765f2397fc285fa6d8eb9c29de7f3185165b702fc7386/pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e67d793d180c9df62f1f40aee3accca4829d3794c95098887edc18af4b8b780c", size = 4874207, upload-time = "2025-07-03T13:11:10.201Z" },
{ url = "https://files.pythonhosted.org/packages/72/c9/583821097dc691880c92892e8e2d41fe0a5a3d6021f4963371d2f6d57250/pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d000f46e2917c705e9fb93a3606ee4a819d1e3aa7a9b442f6444f07e77cf5e25", size = 6583939, upload-time = "2025-07-03T13:11:15.68Z" },
{ url = "https://files.pythonhosted.org/packages/3b/8e/5c9d410f9217b12320efc7c413e72693f48468979a013ad17fd690397b9a/pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:527b37216b6ac3a12d7838dc3bd75208ec57c1c6d11ef01902266a5a0c14fc27", size = 4957166, upload-time = "2025-07-01T09:16:13.74Z" },
{ url = "https://files.pythonhosted.org/packages/62/bb/78347dbe13219991877ffb3a91bf09da8317fbfcd4b5f9140aeae020ad71/pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be5463ac478b623b9dd3937afd7fb7ab3d79dd290a28e2b6df292dc75063eb8a", size = 5581482, upload-time = "2025-07-01T09:16:16.107Z" },
{ url = "https://files.pythonhosted.org/packages/d9/28/1000353d5e61498aaeaaf7f1e4b49ddb05f2c6575f9d4f9f914a3538b6e1/pillow-11.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:8dc70ca24c110503e16918a658b869019126ecfe03109b754c402daff12b3d9f", size = 6984596, upload-time = "2025-07-01T09:16:18.07Z" },
{ url = "https://files.pythonhosted.org/packages/9e/e3/6fa84033758276fb31da12e5fb66ad747ae83b93c67af17f8c6ff4cc8f34/pillow-11.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6", size = 5270566, upload-time = "2025-07-01T09:16:19.801Z" },
{ url = "https://files.pythonhosted.org/packages/5b/ee/e8d2e1ab4892970b561e1ba96cbd59c0d28cf66737fc44abb2aec3795a4e/pillow-11.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438", size = 4654618, upload-time = "2025-07-01T09:16:21.818Z" },
{ url = "https://files.pythonhosted.org/packages/f2/6d/17f80f4e1f0761f02160fc433abd4109fa1548dcfdca46cfdadaf9efa565/pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3", size = 4874248, upload-time = "2025-07-03T13:11:20.738Z" },
{ url = "https://files.pythonhosted.org/packages/de/5f/c22340acd61cef960130585bbe2120e2fd8434c214802f07e8c03596b17e/pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c", size = 6583963, upload-time = "2025-07-03T13:11:26.283Z" },
{ url = "https://files.pythonhosted.org/packages/31/5e/03966aedfbfcbb4d5f8aa042452d3361f325b963ebbadddac05b122e47dd/pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361", size = 4957170, upload-time = "2025-07-01T09:16:23.762Z" },
{ url = "https://files.pythonhosted.org/packages/cc/2d/e082982aacc927fc2cab48e1e731bdb1643a1406acace8bed0900a61464e/pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7", size = 5581505, upload-time = "2025-07-01T09:16:25.593Z" },
{ url = "https://files.pythonhosted.org/packages/34/e7/ae39f538fd6844e982063c3a5e4598b8ced43b9633baa3a85ef33af8c05c/pillow-11.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8", size = 6984598, upload-time = "2025-07-01T09:16:27.732Z" },
@@ -4388,18 +4361,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/42/c2/ce34735972cc42d912173e79f200fe66530225190c06655c5632a9d88f1e/pytest_recording-0.13.4-py3-none-any.whl", hash = "sha256:ad49a434b51b1c4f78e85b1e6b74fdcc2a0a581ca16e52c798c6ace971f7f439", size = 13723, upload-time = "2025-05-08T10:41:09.684Z" },
]
[[package]]
name = "pytest-split"
version = "0.10.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pytest" },
]
sdist = { url = "https://files.pythonhosted.org/packages/46/d7/e30ba44adf83f15aee3f636daea54efadf735769edc0f0a7d98163f61038/pytest_split-0.10.0.tar.gz", hash = "sha256:adf80ba9fef7be89500d571e705b4f963dfa05038edf35e4925817e6b34ea66f", size = 13903, upload-time = "2024-10-16T15:45:19.783Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d6/a7/cad88e9c1109a5c2a320d608daa32e5ee008ccbc766310f54b1cd6b3d69c/pytest_split-0.10.0-py3-none-any.whl", hash = "sha256:466096b086a7147bcd423c6e6c2e57fc62af1c5ea2e256b4ed50fc030fc3dddc", size = 11961, upload-time = "2024-10-16T15:45:18.289Z" },
]
[[package]]
name = "pytest-subprocess"
version = "1.5.3"
@@ -4424,19 +4385,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/fa/b6/3127540ecdf1464a00e5a01ee60a1b09175f6913f0644ac748494d9c4b21/pytest_timeout-2.4.0-py3-none-any.whl", hash = "sha256:c42667e5cdadb151aeb5b26d114aff6bdf5a907f176a007a30b940d3d865b5c2", size = 14382, upload-time = "2025-05-05T19:44:33.502Z" },
]
[[package]]
name = "pytest-xdist"
version = "3.8.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "execnet" },
{ name = "pytest" },
]
sdist = { url = "https://files.pythonhosted.org/packages/78/b4/439b179d1ff526791eb921115fca8e44e596a13efeda518b9d845a619450/pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1", size = 88069, upload-time = "2025-07-01T13:30:59.346Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88", size = 46396, upload-time = "2025-07-01T13:30:56.632Z" },
]
[[package]]
name = "python-bidi"
version = "0.6.6"