diff --git a/pyproject.toml b/pyproject.toml index b24e9149..3471c608 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,8 +26,8 @@ classifiers = [ "Topic :: Software Development :: Libraries :: Python Modules", ] dependencies = [ - "boto3>=1.43.115", - "botocore>=1.43.115", + "boto3>=1.43.127", + "botocore>=1.43.127", "pydantic>=2.0.0,<2.41.3", "urllib3>=1.26.0", "starlette>=0.46.2", diff --git a/src/bedrock_agentcore/tools/__init__.py b/src/bedrock_agentcore/tools/__init__.py index a548b52b..0d56a51d 100644 --- a/src/bedrock_agentcore/tools/__init__.py +++ b/src/bedrock_agentcore/tools/__init__.py @@ -28,6 +28,7 @@ ) from .web_search_client import ( GatewayMcpBackend, + WebSearchApiBackend, WebSearchBackend, WebSearchClient, WebSearchError, @@ -62,6 +63,7 @@ "SessionConfiguration", "ViewportConfiguration", "VpcConfig", + "WebSearchApiBackend", "WebSearchBackend", "WebSearchClient", "WebSearchError", diff --git a/src/bedrock_agentcore/tools/web_search_client.py b/src/bedrock_agentcore/tools/web_search_client.py index 97da54f4..27942959 100644 --- a/src/bedrock_agentcore/tools/web_search_client.py +++ b/src/bedrock_agentcore/tools/web_search_client.py @@ -1,32 +1,40 @@ """Client for AgentCore Web Search. -Web Search is reachable today as an AgentCore Gateway connector target, which the -agent calls as an MCP tool. This module wraps that so callers get a plain -``search()`` method and a normalized result type instead of MCP content blocks: +Web Search is reachable two ways: directly, through the ``InvokeWebSearch`` operation on the +AgentCore data plane, and as an AgentCore Gateway connector target that agents call as an MCP +tool. This module wraps both, so callers get a plain ``search()`` method and a normalized +result type instead of API shapes or MCP content blocks: >>> from bedrock_agentcore.tools import WebSearchClient >>> - >>> client = WebSearchClient(region="us-east-1", gateway_id="my-gateway-abc123") + >>> client = WebSearchClient(region="us-east-1") # the Web Search API >>> response = client.search("what shipped in python 3.13", max_results=5) >>> for result in response.results: - ... print(result.title, result.url) + ... print(result.title, result.url, result.published_at) -The transport lives behind :class:`WebSearchBackend` so the same ``search()`` -signature and the same :class:`WebSearchResult` can be served by a different -backend later without changing callers. +Pass ``gateway_id`` (or ``gateway_arn`` or ``gateway_endpoint``) to search through a gateway +target instead. The transport lives behind :class:`WebSearchBackend`, so the same +``search()`` signature and the same :class:`WebSearchResult` are served by either one. """ import json import logging +import re import threading from dataclasses import dataclass, field +from datetime import datetime, timedelta, timezone from typing import Any, Dict, Iterator, List, Optional, Sequence, Tuple import urllib3 from botocore.auth import SigV4Auth from botocore.awsrequest import AWSRequest -from bedrock_agentcore._utils.endpoints import _validate_endpoint_url, get_gateway_mcp_endpoint +from bedrock_agentcore._utils.endpoints import ( + DP_ENDPOINT_OVERRIDE, + _validate_endpoint_url, + get_gateway_mcp_endpoint, + validate_region, +) from bedrock_agentcore._utils.sse import iter_sse_data from bedrock_agentcore._utils.user_agent import SDK_VERSION, build_user_agent_suffix @@ -47,10 +55,67 @@ MAX_MAX_RESULTS = 25 MAX_DOMAIN_FILTER_ENTRIES = 100 +#: Identifier of the AWS-managed web search tool that the Web Search API invokes. +DEFAULT_WEB_SEARCH_ID = "web-search.v1" + #: Regions where the web search connector is offered. Used for a warning only, never #: to block a call, so that a newly added region does not require an SDK release. KNOWN_REGIONS = ("us-east-1", "eu-west-1", "ap-northeast-1") +#: Regions where the Web Search API is offered. Also used for a warning only. +KNOWN_API_REGIONS = ("us-east-1", "us-east-2", "us-west-2", "eu-west-1", "ap-northeast-1", "ap-southeast-2") + +#: UTC offsets, in hours, for the zone names the gateway connector writes into its dates. +_ZONE_OFFSETS = { + "UTC": 0, + "GMT": 0, + "PDT": -7, + "PST": -8, + "MDT": -6, + "MST": -7, + "CDT": -5, + "CST": -6, + "EDT": -4, + "EST": -5, + "BST": 1, + "CET": 1, + "CEST": 2, + "JST": 9, + "KST": 9, + "AEST": 10, + "AEDT": 11, +} + +#: English names in the gateway connector's dates, parsed without the process locale. +_MONTHS = { + name: number + for number, name in enumerate( + ( + "january", + "february", + "march", + "april", + "may", + "june", + "july", + "august", + "september", + "october", + "november", + "december", + ), + start=1, + ) +} +_WEEKDAYS = ("monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday") +_GATEWAY_DATE = re.compile( + r"(?P\d{1,2}):(?P\d{2})\s*(?PAM|PM),\s*(?P[A-Za-z]+),\s*" + r"(?P[A-Za-z]+)\s+(?P\d{1,2})\s+(?P\d{4})", + re.IGNORECASE, +) +_DATE_ONLY = re.compile(r"\d{4}-\d{2}-\d{2}") +_FRACTION = re.compile(r"(T\d{2}:\d{2}:\d{2})\.(\d+)") + _MCP_PROTOCOL_VERSION = "2025-06-18" _DEFAULT_TIMEOUT = 30 @@ -67,25 +132,90 @@ class WebSearchResult: text: The extracted snippet relevant to the query. Always present. url: URL of the source page. title: Title of the source page. - published_date: Publication date of the page, as reported by the index. + published_date: Publication date of the page, as the service reported it. The Web + Search API reports ISO 8601. The gateway connector reports a readable form such + as ``"05:00PM, Tuesday, October 06 2026, PDT"``. + published_at: ``published_date`` parsed into a timezone-aware UTC datetime, the same + for both transports. ``None`` when the service reported no date or one that + can't be parsed. + acquired_at: When the index acquired the page, as a timezone-aware UTC datetime, if + the service reports it. """ text: str url: Optional[str] = None title: Optional[str] = None published_date: Optional[str] = None + published_at: Optional[datetime] = None + acquired_at: Optional[datetime] = None @classmethod def from_payload(cls, payload: Dict[str, Any]) -> "WebSearchResult": - """Build a result from one entry of a search response.""" + """Build a result from one entry of a search response, from either transport.""" + published = payload.get("publishedDate", payload.get("publishedAt")) + acquired = payload.get("acquiredDate", payload.get("acquiredAt")) return cls( text=payload.get("text") or "", url=payload.get("url"), title=payload.get("title"), - published_date=payload.get("publishedDate"), + published_date=_format_timestamp(published) if isinstance(published, datetime) else published, + published_at=_parse_timestamp(published), + acquired_at=_parse_timestamp(acquired), ) +def _as_aware_utc(value: datetime) -> datetime: + """Convert to UTC, taking a naive datetime as already UTC.""" + return value.astimezone(timezone.utc) if value.tzinfo else value.replace(tzinfo=timezone.utc) + + +def _parse_iso(text: str) -> Optional[datetime]: + """Parse ISO 8601, including a ``Z`` suffix and any number of fractional digits.""" + text = _FRACTION.sub(lambda m: f"{m.group(1)}.{(m.group(2) + '000000')[:6]}", text) + try: + return datetime.fromisoformat(text[:-1] + "+00:00" if text.endswith("Z") else text) + except ValueError: + return None + + +def _parse_gateway_date(text: str) -> Optional[datetime]: + """Parse the connector's form, "05:00PM, Tuesday, October 06 2026, PDT", in any locale.""" + stamp, _, zone = text.rpartition(", ") + match = _GATEWAY_DATE.fullmatch(stamp.strip()) + month = _MONTHS.get(match.group("month").lower()) if match else None + if not match or month is None or zone.upper() not in _ZONE_OFFSETS: + return None + if match.group("weekday").lower() not in _WEEKDAYS: + return None + hour = int(match.group("hour")) + if not 1 <= hour <= 12: + return None + hour = hour % 12 + (12 if match.group("half").upper() == "PM" else 0) + try: + local = datetime(int(match.group("year")), month, int(match.group("day")), hour, int(match.group("minute"))) + except ValueError: + return None + return (local - timedelta(hours=_ZONE_OFFSETS[zone.upper()])).replace(tzinfo=timezone.utc) + + +def _parse_timestamp(value: Any) -> Optional[datetime]: + """Parse a date from either transport into an aware UTC datetime, or ``None``.""" + if isinstance(value, datetime): + return _as_aware_utc(value) + if not isinstance(value, str) or not value.strip(): + return None + text = value.strip() + parsed = _parse_iso(text) + if parsed is not None: + return _as_aware_utc(parsed) + return _parse_gateway_date(text) + + +def _format_timestamp(value: datetime) -> str: + """Format a datetime as ISO 8601 UTC with a ``Z`` suffix, keeping fractional seconds.""" + return _as_aware_utc(value).isoformat().replace("+00:00", "Z") + + @dataclass(frozen=True) class WebSearchResponse: """The results of one web search. @@ -477,6 +607,124 @@ def close(self) -> None: self._reset_session() +class WebSearchApiBackend(WebSearchBackend): + """Reaches web search through the ``InvokeWebSearch`` operation on the AgentCore data plane. + + Calls are signed with the caller's AWS credentials by boto3. The calling identity needs + ``bedrock-agentcore:InvokeWebSearch`` on + ``arn::bedrock-agentcore::aws:tool/web-search.v1``. There is no + resource to create first. boto3 clients are thread-safe, so unlike the gateway backend + this one holds no session state and one instance can serve concurrent searches. + """ + + def __init__( + self, + region: str, + *, + boto3_session: Optional[Any] = None, + client: Optional[Any] = None, + web_search_id: str = DEFAULT_WEB_SEARCH_ID, + integration_source: Optional[str] = None, + timeout: float = _DEFAULT_TIMEOUT, + ): + """Initialize the backend. + + Args: + region: Region to call. + boto3_session: Session to build the ``bedrock-agentcore`` client from. Defaults + to a new session. + client: A ``bedrock-agentcore`` boto3 client to use as is, instead of building one. + web_search_id: Identifier of the web search tool to invoke. + integration_source: Optional framework identifier for the User-Agent. + timeout: Connect and read timeout in seconds for the client this backend builds. + """ + self._web_search_id = web_search_id + if client is None: + import boto3 + from botocore.config import Config + + # Same data plane client, endpoint override and User-Agent as the browser and + # code interpreter clients. + kwargs: Dict[str, Any] = { + "region_name": validate_region(region), + "config": Config( + user_agent_extra=build_user_agent_suffix(integration_source), + connect_timeout=timeout, + read_timeout=timeout, + ), + } + if DP_ENDPOINT_OVERRIDE: + kwargs["endpoint_url"] = DP_ENDPOINT_OVERRIDE + client = (boto3_session or boto3.Session()).client("bedrock-agentcore", **kwargs) + self._client = client + + def search(self, arguments: Dict[str, Any]) -> Dict[str, Any]: + """Run one search and return the decoded payload. + + Raises: + botocore.exceptions.ClientError: If the service rejects the call, for example + with ``ThrottlingException`` or ``AccessDeniedException``. It is not wrapped, + matching the browser and code interpreter clients. + """ + request: Dict[str, Any] = {"webSearchId": self._web_search_id, "searchQuery": arguments["query"]} + if "maxResults" in arguments: + request["maxResults"] = arguments["maxResults"] + + given = arguments.get("filters") or {} + filters: Dict[str, Any] = {} + if given.get("domainFilter"): + filters["domainFilter"] = dict(given["domainFilter"]) + # The argument object names the date bounds "from" and "to", as the gateway tool does. + dates = given.get("publishedDateFilter") or {} + published: Dict[str, Any] = {} + # The API accepts only UTC date-times, so a bound given with an offset is converted. + if "from" in dates: + published["publishedAfter"] = _as_utc(dates["from"]) + if "to" in dates: + published["publishedBefore"] = _inclusive_upper_bound(dates["to"]) + if published: + filters["publishedDateFilter"] = published + if filters: + request["filters"] = filters + + response = self._client.invoke_web_search(**request) + + results = [] + for item in response.get("results") or []: + entry = {key: item[key] for key in ("title", "url", "text") if key in item} + for key in ("publishedAt", "acquiredAt"): + value = item.get(key) + if value is not None: + entry[key] = _format_timestamp(value) if isinstance(value, datetime) else value + results.append(entry) + return {"results": results} + + +def _as_utc(value: Any) -> Any: + """Return a date bound as an ISO 8601 UTC string when it can be parsed, else unchanged.""" + parsed = _parse_timestamp(value) + return _format_timestamp(parsed) if parsed is not None else value + + +def _end_of_day(value: Any) -> Optional[datetime]: + """For a date-only string, the last instant of that day in UTC, else ``None``.""" + if isinstance(value, str) and _DATE_ONLY.fullmatch(value.strip()): + day = datetime.fromisoformat(value.strip()).replace(tzinfo=timezone.utc) + return day + timedelta(days=1) - timedelta(microseconds=1) + return None + + +def _inclusive_upper_bound(value: Any) -> Any: + """Return ``published_before`` for the API, where both bounds are inclusive. + + A date-only bound means "through that day", as the gateway connector reads it, so it + becomes the last instant of that day in UTC. boto3 would otherwise send midnight at + the start of the day and drop the rest of it. + """ + end = _end_of_day(value) + return _format_timestamp(end) if end is not None else _as_utc(value) + + def _decode_jsonrpc(content_type: str, data: bytes, expected_id: Optional[int] = None) -> Optional[Dict[str, Any]]: """Decode the JSON-RPC reply to ``expected_id`` from a JSON body or an SSE stream. @@ -535,11 +783,11 @@ class WebSearchClient: """Client for AgentCore Web Search. Calls are authenticated with SigV4 using ordinary AWS credentials. There is no - web search API key: the credentials this client resolves need - ``bedrock-agentcore:InvokeGateway`` on the gateway ARN, and the gateway's own - service role needs ``bedrock-agentcore:InvokeWebSearch`` on the connector. - An ``AccessDeniedException`` from a search is almost always the first of those - two missing. + web search API key. With no gateway argument, the client calls the Web Search API, and + the credentials it resolves need ``bedrock-agentcore:InvokeWebSearch`` on + ``arn::bedrock-agentcore::aws:tool/web-search.v1``. Through a gateway, + those credentials need ``bedrock-agentcore:InvokeGateway`` on the gateway ARN, and the + gateway's own service role needs ``bedrock-agentcore:InvokeWebSearch`` on the connector. Attributes: region (str): The region being used. @@ -548,10 +796,19 @@ class WebSearchClient: Basic Usage: >>> from bedrock_agentcore.tools import WebSearchClient >>> - >>> client = WebSearchClient(region="us-east-1", gateway_id="my-gateway-abc123") + >>> client = WebSearchClient(region="us-east-1") >>> response = client.search("latest boto3 release notes") >>> response.results[0].url + Filters every search must carry: + >>> client = WebSearchClient(region="us-east-1", exclude_domains=["example.com"], + ... published_after="2026-11-01T00:00:00Z") + >>> client.search("openssl advisory", published_after="2026-01-01T00:00:00Z") + ... # still searches from 2026-11-01: a call can narrow these, never widen them + + Through a gateway: + >>> client = WebSearchClient(region="us-east-1", gateway_id="my-gateway-abc123") + Context Manager: >>> with WebSearchClient(region="us-east-1", gateway_id="my-gateway-abc123") as client: ... response = client.search("who maintains urllib3") @@ -570,13 +827,23 @@ def __init__( boto3_session: Optional[Any] = None, timeout: float = _DEFAULT_TIMEOUT, integration_source: Optional[str] = None, + web_search_id: str = DEFAULT_WEB_SEARCH_ID, + include_domains: Optional[Sequence[str]] = None, + exclude_domains: Optional[Sequence[str]] = None, + published_after: Optional[str] = None, + published_before: Optional[str] = None, ): """Initialize the client. - Exactly one of ``gateway_id``, ``gateway_arn``, ``gateway_endpoint`` or - ``backend`` identifies where the search goes. The gateway arguments are - keyword only and optional so that a future transport needing none of them - is an addition rather than a breaking change. + At most one of ``gateway_id``, ``gateway_arn``, ``gateway_endpoint`` or + ``backend`` says where the search goes. With none of them, the client calls the + Web Search API directly. + + The filter arguments set rules that every search through this client carries. A + call to :meth:`search` can narrow them but never widen them: its exclude list is + added to this one, its include list is intersected with this one, and its date + bounds only take effect when they are stricter. Use them for rules your + application enforces, so that a model choosing search arguments can't lift them. Args: region: Region to call. Defaults to the session's region. @@ -592,15 +859,28 @@ def __init__( boto3_session: Session to take credentials and region from. timeout: Per-request timeout in seconds. integration_source: Optional framework identifier for the User-Agent. + web_search_id: Identifier of the web search tool the Web Search API invokes. + Ignored when searching through a gateway or a supplied backend. + include_domains: Every search returns only these domains. Up to 100. + exclude_domains: Every search drops these domains. Up to 100. + published_after: Every search returns only pages published at or after this + time, ISO 8601 UTC. + published_before: Every search returns only pages published before this time, + ISO 8601 UTC. Raises: - ValueError: If no gateway is identified, or more than one is. + ValueError: If more than one gateway is identified, a filter list is longer + than the documented maximum, or a date bound can't be parsed. InvalidGatewayIdentifierError: If ``gateway_id`` is not a gateway ID. InvalidRegionError: If the region is malformed, or a supplied ``gateway_endpoint`` does not point at an AWS host. """ self._session = boto3_session self._owns_backend = backend is None + self._fixed_include = _checked_domains("include_domains", include_domains) if include_domains else None + self._fixed_exclude = _checked_domains("exclude_domains", exclude_domains) if exclude_domains else None + self._fixed_after = _checked_bound("published_after", published_after) + self._fixed_before = _checked_bound("published_before", published_before) if backend is not None: if any(value is not None for value in (gateway_id, gateway_arn, gateway_endpoint)): @@ -630,6 +910,23 @@ def __init__( self.region = region or self._resolve_session().region_name if not self.region: raise ValueError("region could not be determined. Pass region= or configure a default region.") + + if not given: + if self.region not in KNOWN_API_REGIONS: + logger.warning( + "The Web Search API is offered in %s. Calling %s may fail.", + ", ".join(KNOWN_API_REGIONS), + self.region, + ) + self.backend = WebSearchApiBackend( + self.region, + boto3_session=self._resolve_session(), + web_search_id=web_search_id, + integration_source=integration_source, + timeout=timeout, + ) + return + if self.region not in KNOWN_REGIONS: logger.warning( "Web search is offered in %s. Calling %s may fail if the connector is not available there.", @@ -690,30 +987,50 @@ def search( Args: query: What to search for. 200 characters or fewer. - max_results: How many results to return, 1 to 25. Service default is 10. + max_results: How many results to return, 1 to 25. If unset, the Web Search API + returns up to 25 and the gateway tool up to 10. include_domains: Restrict results to these domains. Up to 100. A root domain matches its subdomains. exclude_domains: Drop results from these domains. Up to 100. published_after: Earliest publication date, ISO-8601 UTC, inclusive. Applies to web results only. - published_before: Latest publication date, ISO-8601 UTC, inclusive. - Applies to web results only. + published_before: Latest publication date, ISO-8601 UTC. Applies to web + results only. Inclusive. A date-only value such as ``2026-11-01`` covers + that whole day. Returns: The search results. Raises: ValueError: If the query, max_results or either domain list is outside the - documented limits. - WebSearchError: If the call fails or the response cannot be decoded. + documented limits, including an exclude list that goes over 100 once + combined with the client's own. + WebSearchError: If a gateway call fails or its response cannot be decoded. + botocore.exceptions.ClientError: If the Web Search API rejects the call. """ + # Validate the caller's own arguments first, so bad input raises even when the + # fixed filters would leave nothing to search. + _build_arguments( + query=query, max_results=max_results, include_domains=include_domains, exclude_domains=exclude_domains + ) + nothing_allowed = False + if self._fixed_include and include_domains: + include_domains = [domain for domain in include_domains if _covered(domain, self._fixed_include)] + nothing_allowed = not include_domains + else: + include_domains = include_domains or self._fixed_include + if self._fixed_exclude: + exclude_domains = _combined_excludes(self._fixed_exclude, exclude_domains or []) + if nothing_allowed: + # None of the requested domains is inside the client's include list. + return WebSearchResponse() arguments = _build_arguments( query=query, max_results=max_results, include_domains=include_domains, exclude_domains=exclude_domains, - published_after=published_after, - published_before=published_before, + published_after=_stricter(self._fixed_after, published_after, later=True), + published_before=_stricter(self._fixed_before, published_before, later=False), ) return WebSearchResponse.from_payload(self.backend.search(arguments)) @@ -731,6 +1048,59 @@ def __exit__(self, *exc_info: Any) -> None: self.close() +def _checked_bound(argument: str, value: Optional[str]) -> Optional[str]: + """Return a fixed date bound, rejecting one that can't be parsed.""" + if value is not None and _parse_timestamp(value) is None: + raise ValueError(f"{argument} must be an ISO 8601 date or date-time, got {value!r}") + return value + + +def _covered(domain: str, allowed: Sequence[str]) -> bool: + """Whether a domain equals or is a subdomain of one in ``allowed``, ignoring case. + + This matches the service, where a root domain also covers its subdomains. + """ + name = domain.strip().lower().rstrip(".") + for root in allowed: + root = root.strip().lower().rstrip(".") + if name == root or name.endswith("." + root): + return True + return False + + +def _combined_excludes(fixed: Sequence[str], requested: Sequence[str]) -> List[str]: + """Combine the client's and the call's exclude lists, within the API's limit.""" + combined: List[str] = [] + seen = set() + for domain in [*fixed, *requested]: + if domain.lower() not in seen: + seen.add(domain.lower()) + combined.append(domain) + if len(combined) > MAX_DOMAIN_FILTER_ENTRIES: + raise ValueError( + f"exclude_domains accepts at most {MAX_DOMAIN_FILTER_ENTRIES} domains including the client's own: " + f"{len(fixed)} set on the client plus {len(combined) - len(fixed)} from this call is {len(combined)}" + ) + return combined + + +def _stricter(fixed: Optional[str], requested: Optional[str], *, later: bool) -> Optional[str]: + """Return whichever date bound is stricter, keeping ``fixed`` when they can't be compared.""" + if not fixed or not requested: + return fixed or requested + if later: + fixed_at, requested_at = _parse_timestamp(fixed), _parse_timestamp(requested) + else: + # A date-only upper bound covers that whole day, so compare it at the day's end. + fixed_at = _end_of_day(fixed) or _parse_timestamp(fixed) + requested_at = _end_of_day(requested) or _parse_timestamp(requested) + if fixed_at is None or requested_at is None: + return fixed + if later: + return requested if requested_at > fixed_at else fixed + return requested if requested_at < fixed_at else fixed + + def _parse_gateway_arn(arn: str) -> Tuple[str, str]: """Pull the gateway ID and region out of a gateway ARN. diff --git a/tests/bedrock_agentcore/tools/test_web_search_client.py b/tests/bedrock_agentcore/tools/test_web_search_client.py index f76953d3..a597a981 100644 --- a/tests/bedrock_agentcore/tools/test_web_search_client.py +++ b/tests/bedrock_agentcore/tools/test_web_search_client.py @@ -1,14 +1,18 @@ """Tests for WebSearchClient.""" import json +from datetime import datetime, timezone from unittest.mock import MagicMock, patch import pytest import urllib3 +from botocore.exceptions import ClientError from bedrock_agentcore._utils.endpoints import InvalidGatewayIdentifierError, InvalidRegionError from bedrock_agentcore.tools.web_search_client import ( + DEFAULT_WEB_SEARCH_ID, GatewayMcpBackend, + WebSearchApiBackend, WebSearchBackend, WebSearchClient, WebSearchError, @@ -16,7 +20,9 @@ WebSearchResult, _build_arguments, _decode_jsonrpc, + _format_timestamp, _parse_gateway_arn, + _parse_timestamp, ) ENDPOINT = "https://gw-abc123.gateway.bedrock-agentcore.us-east-1.amazonaws.com/mcp" @@ -764,9 +770,32 @@ def test_unknown_region_warns_but_proceeds(self, caplog): assert client.region == "us-west-2" assert "us-east-1, eu-west-1, ap-northeast-1" in caplog.text - def test_no_gateway_raises(self): - with pytest.raises(ValueError, match="is required"): - WebSearchClient(region="us-east-1", boto3_session=MagicMock()) + def test_no_gateway_uses_the_web_search_api(self): + client = WebSearchClient(region="us-east-1", boto3_session=MagicMock()) + + assert isinstance(client.backend, WebSearchApiBackend) + assert client.backend._web_search_id == DEFAULT_WEB_SEARCH_ID + + def test_web_search_id_is_passed_to_the_api_backend(self): + client = WebSearchClient(region="us-east-1", boto3_session=MagicMock(), web_search_id="web-search.v2") + + assert client.backend._web_search_id == "web-search.v2" + + def test_api_region_outside_the_known_list_warns(self, caplog): + with caplog.at_level("WARNING"): + WebSearchClient(region="sa-east-1", boto3_session=MagicMock()) + + assert "The Web Search API is offered in" in caplog.text + + def test_malformed_region_raises_for_the_api(self): + with pytest.raises(InvalidRegionError): + WebSearchClient(region="not a region", boto3_session=MagicMock()) + + def test_api_launch_region_does_not_warn(self, caplog): + with caplog.at_level("WARNING"): + WebSearchClient(region="us-west-2", boto3_session=MagicMock()) + + assert caplog.text == "" def test_two_gateways_raise(self): with pytest.raises(ValueError, match="only one of"): @@ -859,3 +888,381 @@ def test_exported_from_the_tools_package(): from bedrock_agentcore.tools import WebSearchClient as exported assert exported is WebSearchClient + + +class TestParseTimestamp: + """Tests for date parsing across both transports.""" + + def test_iso_with_z(self): + assert _parse_timestamp("2026-10-30T19:24:00Z") == datetime(2026, 10, 30, 19, 24, tzinfo=timezone.utc) + + def test_iso_with_offset_is_converted_to_utc(self): + assert _parse_timestamp("2026-10-30T12:24:00-07:00") == datetime(2026, 10, 30, 19, 24, tzinfo=timezone.utc) + + def test_gateway_format(self): + assert _parse_timestamp("05:00PM, Wednesday, October 28 2026, PDT") == datetime( + 2026, 10, 29, 0, 0, tzinfo=timezone.utc + ) + + def test_naive_datetime_is_taken_as_utc(self): + assert _parse_timestamp(datetime(2026, 1, 1)) == datetime(2026, 1, 1, tzinfo=timezone.utc) + + def test_any_number_of_fractional_digits(self): + assert _parse_timestamp("2026-11-01T00:00:00.5Z") == datetime(2026, 11, 1, 0, 0, 0, 500000, tzinfo=timezone.utc) + + def test_gateway_format_with_a_non_us_zone(self): + assert _parse_timestamp("12:30AM, Monday, January 05 2026, JST") == datetime( + 2026, 1, 4, 15, 30, tzinfo=timezone.utc + ) + + def test_gateway_format_ignores_the_process_locale(self): + import locale + + previous = locale.setlocale(locale.LC_TIME) + try: + locale.setlocale(locale.LC_TIME, "de_DE.UTF-8") + except locale.Error: + pytest.skip("de_DE.UTF-8 locale not installed") + try: + assert _parse_timestamp("05:00PM, Wednesday, October 28 2026, PDT") == datetime( + 2026, 10, 29, 0, 0, tzinfo=timezone.utc + ) + finally: + locale.setlocale(locale.LC_TIME, previous) + + def test_format_keeps_fractional_seconds(self): + assert _format_timestamp(datetime(2026, 11, 1, 12, 0, 0, 900000, tzinfo=timezone.utc)) == ( + "2026-11-01T12:00:00.900000Z" + ) + + @pytest.mark.parametrize( + "value", + [ + None, + "", + "unknown", + "05:00PM, Wednesday, October 28 2026, XYZ", + "not a date, PDT", + "13:00PM, Wednesday, October 28 2026, PDT", + "05:00PM, Someday, October 28 2026, PDT", + 42, + ], + ) + def test_unparseable_values_become_none(self, value): + assert _parse_timestamp(value) is None + + +class TestResultDates: + """Tests for the parsed date fields on results.""" + + def test_gateway_payload(self): + result = WebSearchResult.from_payload( + {"text": "t", "publishedDate": "05:00PM, Wednesday, October 28 2026, PDT"} + ) + + assert result.published_date == "05:00PM, Wednesday, October 28 2026, PDT" + assert result.published_at == datetime(2026, 10, 29, 0, 0, tzinfo=timezone.utc) + assert result.acquired_at is None + + def test_api_payload(self): + result = WebSearchResult.from_payload( + {"text": "t", "publishedAt": "2026-10-30T19:24:00Z", "acquiredAt": "2026-10-31T08:00:00Z"} + ) + + assert result.published_date == "2026-10-30T19:24:00Z" + assert result.published_at == datetime(2026, 10, 30, 19, 24, tzinfo=timezone.utc) + assert result.acquired_at == datetime(2026, 10, 31, 8, 0, tzinfo=timezone.utc) + + def test_unknown_date_keeps_the_string_and_parses_to_none(self): + result = WebSearchResult.from_payload({"text": "t", "publishedDate": "unknown"}) + + assert result.published_date == "unknown" + assert result.published_at is None + + +def _api_client(response=None): + client = MagicMock() + client.invoke_web_search.return_value = response if response is not None else {"results": []} + return client + + +class TestWebSearchApiBackend: + """Tests for the Web Search API transport.""" + + def test_minimal_request(self): + boto_client = _api_client() + WebSearchApiBackend("us-east-1", client=boto_client).search({"query": "q"}) + + boto_client.invoke_web_search.assert_called_once_with(webSearchId=DEFAULT_WEB_SEARCH_ID, searchQuery="q") + + def test_arguments_are_translated(self): + boto_client = _api_client() + WebSearchApiBackend("us-east-1", client=boto_client, web_search_id="web-search.v2").search( + { + "query": "q", + "maxResults": 5, + "filters": { + "domainFilter": {"include": ["a.example"], "exclude": ["b.example"]}, + "publishedDateFilter": {"from": "2026-01-01T00:00:00Z", "to": "2026-02-01T00:00:00Z"}, + }, + } + ) + + boto_client.invoke_web_search.assert_called_once_with( + webSearchId="web-search.v2", + searchQuery="q", + maxResults=5, + filters={ + "domainFilter": {"include": ["a.example"], "exclude": ["b.example"]}, + "publishedDateFilter": { + "publishedAfter": "2026-01-01T00:00:00Z", + "publishedBefore": "2026-02-01T00:00:00Z", + }, + }, + ) + + def test_response_datetimes_become_iso_strings(self): + published = datetime(2026, 10, 30, 19, 24, tzinfo=timezone.utc) + boto_client = _api_client( + { + "results": [ + {"title": "T", "url": "https://x.example/", "text": "t", "publishedAt": published}, + {"text": "only text"}, + ] + } + ) + + payload = WebSearchApiBackend("us-east-1", client=boto_client).search({"query": "q"}) + + assert payload == { + "results": [ + {"title": "T", "url": "https://x.example/", "text": "t", "publishedAt": "2026-10-30T19:24:00Z"}, + {"text": "only text"}, + ] + } + + def test_date_bounds_with_an_offset_are_sent_as_utc(self): + boto_client = _api_client() + WebSearchApiBackend("us-east-1", client=boto_client).search( + {"query": "q", "filters": {"publishedDateFilter": {"from": "2026-01-01T01:00:00+01:00"}}} + ) + + assert boto_client.invoke_web_search.call_args.kwargs["filters"] == { + "publishedDateFilter": {"publishedAfter": "2026-01-01T00:00:00Z"} + } + + def test_client_error_is_not_wrapped(self): + boto_client = _api_client() + error = ClientError({"Error": {"Code": "ThrottlingException", "Message": "slow down"}}, "InvokeWebSearch") + boto_client.invoke_web_search.side_effect = error + + with pytest.raises(ClientError) as raised: + WebSearchApiBackend("us-east-1", client=boto_client).search({"query": "q"}) + assert raised.value is error + + def test_date_only_upper_bound_covers_that_whole_day(self): + boto_client = _api_client() + WebSearchApiBackend("us-east-1", client=boto_client).search( + {"query": "q", "filters": {"publishedDateFilter": {"from": "2026-11-01", "to": "2026-11-01"}}} + ) + + assert boto_client.invoke_web_search.call_args.kwargs["filters"] == { + "publishedDateFilter": { + "publishedAfter": "2026-11-01T00:00:00Z", + "publishedBefore": "2026-11-01T23:59:59.999999Z", + } + } + + def test_fractional_seconds_are_kept(self): + boto_client = _api_client() + WebSearchApiBackend("us-east-1", client=boto_client).search( + {"query": "q", "filters": {"publishedDateFilter": {"from": "2026-11-01T12:00:00.900Z"}}} + ) + + assert boto_client.invoke_web_search.call_args.kwargs["filters"] == { + "publishedDateFilter": {"publishedAfter": "2026-11-01T12:00:00.900000Z"} + } + + def test_timeout_reaches_the_boto3_client(self): + session = MagicMock() + WebSearchApiBackend("us-east-1", boto3_session=session, timeout=5) + + config = session.client.call_args.kwargs["config"] + assert (config.connect_timeout, config.read_timeout) == (5, 5) + + def test_client_timeout_is_passed_to_the_api_backend(self): + session = MagicMock() + WebSearchClient(region="us-east-1", boto3_session=session, timeout=7) + + assert session.client.call_args.kwargs["config"].read_timeout == 7 + + def test_builds_a_client_with_the_sdk_user_agent(self): + session = MagicMock() + WebSearchApiBackend("us-west-2", boto3_session=session, integration_source="langchain") + + (service,) = session.client.call_args.args + kwargs = session.client.call_args.kwargs + assert service == "bedrock-agentcore" + assert kwargs["region_name"] == "us-west-2" + assert "integration_source=langchain" in kwargs["config"].user_agent_extra + + def test_end_to_end_through_the_client(self): + boto_client = _api_client( + {"results": [{"text": "t", "publishedAt": datetime(2026, 1, 2, tzinfo=timezone.utc)}]} + ) + client = WebSearchClient(region="us-east-1", backend=WebSearchApiBackend("us-east-1", client=boto_client)) + + response = client.search("q", published_after="2026-01-01T00:00:00Z") + + assert response.results[0].published_at == datetime(2026, 1, 2, tzinfo=timezone.utc) + assert boto_client.invoke_web_search.call_args.kwargs["filters"] == { + "publishedDateFilter": {"publishedAfter": "2026-01-01T00:00:00Z"} + } + + +class TestFixedFilters: + """Tests for filters set on the client, which every search carries.""" + + def test_fixed_filters_apply_when_the_call_gives_none(self): + backend = _RecordingBackend() + client = WebSearchClient( + region="us-east-1", + backend=backend, + include_domains=["a.example"], + exclude_domains=["b.example"], + published_after="2026-01-01T00:00:00Z", + published_before="2026-12-01T00:00:00Z", + ) + + client.search("q") + + assert backend.arguments["filters"] == { + "domainFilter": {"include": ["a.example"], "exclude": ["b.example"]}, + "publishedDateFilter": {"from": "2026-01-01T00:00:00Z", "to": "2026-12-01T00:00:00Z"}, + } + + def test_excludes_are_combined(self): + backend = _RecordingBackend() + client = WebSearchClient(region="us-east-1", backend=backend, exclude_domains=["b.example"]) + + client.search("q", exclude_domains=["c.example", "b.example"]) + + assert backend.arguments["filters"]["domainFilter"]["exclude"] == ["b.example", "c.example"] + + def test_includes_are_intersected(self): + backend = _RecordingBackend() + client = WebSearchClient(region="us-east-1", backend=backend, include_domains=["a.example", "b.example"]) + + client.search("q", include_domains=["b.example", "z.example"]) + + assert backend.arguments["filters"]["domainFilter"]["include"] == ["b.example"] + + def test_disjoint_includes_return_nothing_without_a_call(self): + backend = _RecordingBackend() + client = WebSearchClient(region="us-east-1", backend=backend, include_domains=["a.example"]) + + response = client.search("q", include_domains=["z.example"]) + + assert len(response) == 0 + assert backend.arguments is None + + def test_a_call_can_narrow_the_date_window(self): + backend = _RecordingBackend() + client = WebSearchClient( + region="us-east-1", + backend=backend, + published_after="2026-01-01T00:00:00Z", + published_before="2026-12-01T00:00:00Z", + ) + + client.search("q", published_after="2026-06-01T00:00:00Z", published_before="2026-07-01T00:00:00Z") + + assert backend.arguments["filters"]["publishedDateFilter"] == { + "from": "2026-06-01T00:00:00Z", + "to": "2026-07-01T00:00:00Z", + } + + def test_a_call_cannot_widen_the_date_window(self): + backend = _RecordingBackend() + client = WebSearchClient( + region="us-east-1", + backend=backend, + published_after="2026-06-01T00:00:00Z", + published_before="2026-07-01T00:00:00Z", + ) + + client.search("q", published_after="2026-01-01T00:00:00Z", published_before="2026-12-01T00:00:00Z") + + assert backend.arguments["filters"]["publishedDateFilter"] == { + "from": "2026-06-01T00:00:00Z", + "to": "2026-07-01T00:00:00Z", + } + + def test_an_unparseable_requested_date_keeps_the_fixed_one(self): + backend = _RecordingBackend() + client = WebSearchClient(region="us-east-1", backend=backend, published_after="2026-06-01T00:00:00Z") + + client.search("q", published_after="last week") + + assert backend.arguments["filters"]["publishedDateFilter"] == {"from": "2026-06-01T00:00:00Z"} + + def test_fixed_list_over_the_maximum_is_rejected(self): + with pytest.raises(ValueError, match="at most 100"): + WebSearchClient( + region="us-east-1", backend=_RecordingBackend(), exclude_domains=[f"d{i}.example" for i in range(101)] + ) + + def test_a_subdomain_of_a_fixed_include_is_kept(self): + backend = _RecordingBackend() + client = WebSearchClient(region="us-east-1", backend=backend, include_domains=["example.com"]) + + client.search("q", include_domains=["docs.example.com", "Example.com", "notexample.com"]) + + assert backend.arguments["filters"]["domainFilter"]["include"] == ["docs.example.com", "Example.com"] + + def test_bad_input_raises_even_when_nothing_is_allowed(self): + client = WebSearchClient(region="us-east-1", backend=_RecordingBackend(), include_domains=["a.example"]) + + with pytest.raises(ValueError, match="non-empty"): + client.search("", include_domains=["other.com"]) + with pytest.raises(ValueError, match="max_results"): + client.search("q", include_domains=["other.com"], max_results=0) + + def test_combined_exclude_limit_names_the_client_list(self): + client = WebSearchClient( + region="us-east-1", backend=_RecordingBackend(), exclude_domains=[f"f{i}.example" for i in range(90)] + ) + + with pytest.raises(ValueError, match="90 set on the client plus 20 from this call is 110"): + client.search("q", exclude_domains=[f"c{i}.example" for i in range(20)]) + + def test_excludes_are_deduplicated_ignoring_case(self): + backend = _RecordingBackend() + client = WebSearchClient(region="us-east-1", backend=backend, exclude_domains=["b.example"]) + + client.search("q", exclude_domains=["B.example", "c.example"]) + + assert backend.arguments["filters"]["domainFilter"]["exclude"] == ["b.example", "c.example"] + + @pytest.mark.parametrize("argument", ["published_after", "published_before"]) + def test_unparseable_fixed_bound_is_rejected(self, argument): + with pytest.raises(ValueError, match=argument): + WebSearchClient(region="us-east-1", backend=_RecordingBackend(), **{argument: "yesterday"}) + + def test_fixed_bound_with_short_fraction_still_narrows(self): + backend = _RecordingBackend() + client = WebSearchClient(region="us-east-1", backend=backend, published_after="2026-11-01T00:00:00.5Z") + + client.search("q", published_after="2026-11-02T00:00:00Z") + + assert backend.arguments["filters"]["publishedDateFilter"] == {"from": "2026-11-02T00:00:00Z"} + + def test_date_only_upper_bounds_compare_at_the_end_of_the_day(self): + backend = _RecordingBackend() + client = WebSearchClient(region="us-east-1", backend=backend, published_before="2026-11-01") + + client.search("q", published_before="2026-11-01T12:00:00Z") + assert backend.arguments["filters"]["publishedDateFilter"] == {"to": "2026-11-01T12:00:00Z"} + + client.search("q", published_before="2026-11-02") + assert backend.arguments["filters"]["publishedDateFilter"] == {"to": "2026-11-01"} diff --git a/tests_integ/tools/test_web_search_api_client.py b/tests_integ/tools/test_web_search_api_client.py new file mode 100644 index 00000000..68f77b29 --- /dev/null +++ b/tests_integ/tools/test_web_search_api_client.py @@ -0,0 +1,67 @@ +"""Integration tests for WebSearchClient over the Web Search API (InvokeWebSearch). + +These tests call the real API with the default backend, so they need credentials allowed to +call bedrock-agentcore:InvokeWebSearch. + +Run with: + uv run pytest tests_integ/tools/test_web_search_api_client.py -xvs + +Requires environment variables: + BEDROCK_TEST_REGION: AWS region (default: us-east-1). The API is offered in us-east-1, + us-east-2, us-west-2, eu-west-1, ap-northeast-1 and ap-southeast-2. +""" + +import os +from datetime import datetime, timedelta, timezone +from urllib.parse import urlparse + +import pytest + +from bedrock_agentcore.tools.web_search_client import WebSearchApiBackend, WebSearchClient + + +@pytest.mark.integration +class TestWebSearchApiClient: + """Integration tests for WebSearchClient over the Web Search API.""" + + @classmethod + def setup_class(cls): + cls.region = os.environ.get("BEDROCK_TEST_REGION", "us-east-1") + + def test_default_backend_is_the_api(self): + with WebSearchClient(region=self.region) as client: + assert isinstance(client.backend, WebSearchApiBackend) + + def test_search_returns_results(self): + with WebSearchClient(region=self.region) as client: + response = client.search("what is amazon bedrock agentcore", max_results=3) + + assert 0 < len(response) <= 3 + assert all(result.text for result in response) + + def test_published_dates_are_parsed(self): + with WebSearchClient(region=self.region) as client: + response = client.search("aws news this week", max_results=10) + + dated = [result for result in response if result.published_date] + assert dated, "expected at least one dated result" + assert all(result.published_at is not None and result.published_at.tzinfo for result in dated) + + def test_excluded_domain_is_not_returned(self): + with WebSearchClient(region=self.region) as client: + response = client.search("kubernetes release notes", max_results=10, exclude_domains=["kubernetes.io"]) + + hosts = [urlparse(result.url).hostname or "" for result in response if result.url] + assert not any(host == "kubernetes.io" or host.endswith(".kubernetes.io") for host in hosts) + + def test_fixed_date_floor_is_not_widened_by_a_call(self): + floor = datetime.now(timezone.utc) - timedelta(days=7) + with WebSearchClient(region=self.region, published_after=floor.strftime("%Y-%m-%dT%H:%M:%SZ")) as client: + response = client.search("security advisory", max_results=10, published_after="2020-01-01T00:00:00Z") + + assert all(result.published_at is None or result.published_at >= floor for result in response) + + def test_oversized_query_is_rejected_locally(self): + with WebSearchClient(region=self.region) as client: + with pytest.raises(ValueError): + client.search("x" * 201) diff --git a/uv.lock b/uv.lock index 2af3e035..81c716ad 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 5 +revision = 3 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'win32'", @@ -171,7 +171,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, { name = "aiosignal" }, - { name = "async-timeout", marker = "python_full_version < '3.11'" }, + { name = "async-timeout", marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "attrs" }, { name = "frozenlist" }, { name = "multidict" }, @@ -304,7 +304,7 @@ version = "1.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "frozenlist" }, - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "typing-extensions", marker = "python_full_version < '3.13' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } wheels = [ @@ -334,10 +334,10 @@ name = "anyio" version = "4.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "idna" }, { name = "sniffio" }, - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "typing-extensions", marker = "python_full_version < '3.13' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949, upload-time = "2025-03-17T00:02:54.77Z" } wheels = [ @@ -413,41 +413,41 @@ wheels = [ [[package]] name = "awscrt" -version = "0.36.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6a/7d/fd87588cffbef8fbdb8436f14fa673ee3735cf8600a1a2a36ef78718cfd6/awscrt-0.36.0.tar.gz", hash = "sha256:ad2198461f3b2a2851f37891d75dcb9173bfe2474d8550ad6260bf9970b4064a", size = 37058473, upload-time = "2026-07-16T19:36:20.843Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/f4/f1fc56f0a48154e14428ed4dada897fbea8d1d5c94127575af3041cbdf2e/awscrt-0.36.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:698c0af9c376d8103c03b8b45ef80bdd100c6a91d26538fa8baa1f22c0a848be", size = 5148286, upload-time = "2026-07-16T19:35:07.156Z" }, - { url = "https://files.pythonhosted.org/packages/d2/aa/94174564e1b1e54307e7564c4c97bd4563f77c41b1b35e79b1d4475b050a/awscrt-0.36.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d901f73c9cf722d76f5947c87dfb10de3cea324646c29ecc053fef63b79ef466", size = 4012383, upload-time = "2026-07-16T19:35:08.815Z" }, - { url = "https://files.pythonhosted.org/packages/7d/9d/65cb2e5b6b96acfb3d98a21414293584d4457e28827bf754a377aed39585/awscrt-0.36.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bf326cf5248835df4828ddd2ee74ad9e7fa2a294de0d8301e04af2bcd7af3e2a", size = 4303769, upload-time = "2026-07-16T19:35:10.172Z" }, - { url = "https://files.pythonhosted.org/packages/b4/c1/a7addb874a662fff63586e2857c54b1ce72775f02fd8a6b2113370d49e35/awscrt-0.36.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9950a556b5a2d6b3dc5d5aab1755639cc357c0b7fde6f5a4d8bafc3c333f433b", size = 3945220, upload-time = "2026-07-16T19:35:11.693Z" }, - { url = "https://files.pythonhosted.org/packages/13/ad/ddeaba1a318d1448a7fa522d0acc2ce919f397d75fa63ed0b4f97ad4b7f1/awscrt-0.36.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:48b2622ecf02dcb7092a3b7b7ec92f71b9d7cd234e0bdb72cc9a2faecb4d058a", size = 4186776, upload-time = "2026-07-16T19:35:13.008Z" }, - { url = "https://files.pythonhosted.org/packages/60/77/adeed08e1cbb207685199ade997f4b523236343914bb7b34af0e276654aa/awscrt-0.36.0-cp310-cp310-win32.whl", hash = "sha256:642ed998d7c794ad3844c23281a68f67adc57c9756eb0c65b0b4f76649d59239", size = 4166268, upload-time = "2026-07-16T19:35:14.541Z" }, - { url = "https://files.pythonhosted.org/packages/cb/91/b66dd9f28e5d1a38888a3839b4f29eea3e49d05af9bd7fc7dd8ca7defa88/awscrt-0.36.0-cp310-cp310-win_amd64.whl", hash = "sha256:e40a43780a1ea080a8dc9d313be76694b6609bbced7193d182a51bf6662febba", size = 4336657, upload-time = "2026-07-16T19:35:16.022Z" }, - { url = "https://files.pythonhosted.org/packages/b7/37/1dd6a63dc5325bdb36f082490fd770aec1fd6565d1aaacb3ff9fd9c2bad7/awscrt-0.36.0-cp311-abi3-macosx_10_15_universal2.whl", hash = "sha256:1f6dbe7fd755d981c6492f6ad08775060e86e9ccb7d84f6725e4444cee14bf5c", size = 5148128, upload-time = "2026-07-16T19:35:17.537Z" }, - { url = "https://files.pythonhosted.org/packages/78/e6/3ecfa5ad2023bc7e897ccd9f09e6d30d34448c9fddbdb2f7549f7964784e/awscrt-0.36.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:900eb2cf518a3f1c7e9c4ebc320f5a3fac891208992b9428da76e3f0fb0300a5", size = 3972156, upload-time = "2026-07-16T19:35:19.025Z" }, - { url = "https://files.pythonhosted.org/packages/0a/94/a5fc3f83e4178f20f4e75fbecfaefc1c8d5a1d848eeba100c46226bf966e/awscrt-0.36.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bf8bafef584f9d5fead3a88f3b86e0aea957c85ecab5243d0c47858ea3d9b39a", size = 4264588, upload-time = "2026-07-16T19:35:20.437Z" }, - { url = "https://files.pythonhosted.org/packages/42/8d/0c3d1ea026a20be02a0586dd31c41018a98ec7e52701b1ff68c408e79d09/awscrt-0.36.0-cp311-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:1608b45260678aeb4aabdf5f0c69799cb801304b50d065891f96a474e053f908", size = 3880158, upload-time = "2026-07-16T19:35:21.971Z" }, - { url = "https://files.pythonhosted.org/packages/cb/58/870c1a5adc6d0675e8a4cbb39ea7070ec2860a82b4fa71416bc18cc2f805/awscrt-0.36.0-cp311-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:a950c3b4082a687f7e76accc01f937113c6febe13a790856381314323e6a8d03", size = 4121252, upload-time = "2026-07-16T19:35:23.442Z" }, - { url = "https://files.pythonhosted.org/packages/2a/85/a06708ee6caf8d0281a9a7c5f73ec36d5471dda37ccd0b630933c869fa4e/awscrt-0.36.0-cp311-abi3-win32.whl", hash = "sha256:b195103c3b87f02a2c2f278281a64e35dfe57d03d92017097adeb31332731459", size = 4167298, upload-time = "2026-07-16T19:35:24.86Z" }, - { url = "https://files.pythonhosted.org/packages/d6/0a/3fa90ed5283aba9c41f3ea657a4bc71addf6eda0fe85d05aff338f159a53/awscrt-0.36.0-cp311-abi3-win_amd64.whl", hash = "sha256:d4b391736d15f44d452bef0372997c418af44c83d0a11953d0e18a5fd937ba0f", size = 4337077, upload-time = "2026-07-16T19:35:26.236Z" }, - { url = "https://files.pythonhosted.org/packages/69/68/355a9c06805f14ac4e1ac1bdf81c8e50d1308dd8c1ea73ae8b3ff35a09ac/awscrt-0.36.0-cp313-abi3-macosx_10_15_universal2.whl", hash = "sha256:0ef852c7bd977402f2c82959d9b6c68e39c74bca885d4578cec86e6a3b60c864", size = 5146650, upload-time = "2026-07-16T19:35:27.565Z" }, - { url = "https://files.pythonhosted.org/packages/93/fb/982bb2798550c469e1fe8ff3b368dbc458f82187a82c38ce6b61456a7a94/awscrt-0.36.0-cp313-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:01a55a4de4d3d915714590bd50cd3cc430e8f5bce78a4c6b6308c6a7f513ca12", size = 3962528, upload-time = "2026-07-16T19:35:29.166Z" }, - { url = "https://files.pythonhosted.org/packages/4d/91/a607e1c70a56bc33008b4a2829334e1b319cf9056419784aaed24dbad9c9/awscrt-0.36.0-cp313-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6dba4e0ec0aeec18ecf534081c02357794b89d8a7e12d83f6c970f9d90b1ff0a", size = 4258010, upload-time = "2026-07-16T19:35:30.606Z" }, - { url = "https://files.pythonhosted.org/packages/3c/ed/57655a46f64a7a5d384248a16ad624d2aac076b8a0e759f3e820a30543d0/awscrt-0.36.0-cp313-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:63b726ee7165c5f13ffdd8c57402538a59d01dbc1eeec4eaef75790dbb4ce4d9", size = 3872506, upload-time = "2026-07-16T19:35:32.017Z" }, - { url = "https://files.pythonhosted.org/packages/06/c7/7963d182695a1a13597d8c1df36364595475eaba26af176a5d892e8199a6/awscrt-0.36.0-cp313-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:74e8419f3ab6770082a5a7af267508c72af10b7352bae17b284800ba8e6ec13b", size = 4116622, upload-time = "2026-07-16T19:35:33.477Z" }, - { url = "https://files.pythonhosted.org/packages/7a/2f/dbefbf49c797a4fc0698f9f5ef51ec6725cc46755e8ce8ecadad07efe64a/awscrt-0.36.0-cp313-abi3-win32.whl", hash = "sha256:ef8e655ffaf245a2d4a5c6ca9a1da12fe72cf43c70457dd07f6e0b162ffed164", size = 4163785, upload-time = "2026-07-16T19:35:35.006Z" }, - { url = "https://files.pythonhosted.org/packages/54/b4/710ec9200b10bb3a39eb3308723fb7ee86622e57a2a8b18532e37c191b7a/awscrt-0.36.0-cp313-abi3-win_amd64.whl", hash = "sha256:e1329d9e6b4e1051bf094130fc40d9790cd6986b529bbe8a8bf65ae4fb559d30", size = 4333718, upload-time = "2026-07-16T19:35:36.431Z" }, - { url = "https://files.pythonhosted.org/packages/f9/15/d4754f15a54206ea2fe4bb8b2343dc86cf1ae163a413aeb23280feffe129/awscrt-0.36.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:6f0044e3fdc3acb7287dc8285fb0710370b94ffd5d69ee1e01a0f161b5ea0376", size = 5155749, upload-time = "2026-07-16T19:35:37.904Z" }, - { url = "https://files.pythonhosted.org/packages/3c/b2/64590179bc367832edb16a56ff88d86a73f8bfe070311325851c404331c1/awscrt-0.36.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:93ece6a57527cb6124cda94345adc797bee99ae34bb013c7edcd4bbe09493778", size = 4013555, upload-time = "2026-07-16T19:35:39.569Z" }, - { url = "https://files.pythonhosted.org/packages/e4/5f/eba58de79c2e63758805de1d355cbe68a17053cd460f1040c98f7baa9211/awscrt-0.36.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:6231b3940c261ac3c6e2128d9ea3fcaabdeec6f5737c19e4310f98b1c5ea2b8d", size = 4254426, upload-time = "2026-07-16T19:35:41.103Z" }, - { url = "https://files.pythonhosted.org/packages/ad/a9/49839240e66c8373fe266c9d16218cbce06f31c6e706939e53976c197631/awscrt-0.36.0-cp313-cp313t-win32.whl", hash = "sha256:62d8938540dfa84e754621bcbf9dfdab19a39a4ae2d3a6f350f3d615b1ff4767", size = 4219945, upload-time = "2026-07-16T19:35:42.604Z" }, - { url = "https://files.pythonhosted.org/packages/71/c6/926f66a4f17d874d60fc60578fe6be58f5a91e64cd8836a94f87d1803bf7/awscrt-0.36.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3c822bb7c98c306484c70564d798400110928a0ea5c9c1b2091b74a5026b4561", size = 4380060, upload-time = "2026-07-16T19:35:44.211Z" }, - { url = "https://files.pythonhosted.org/packages/8f/43/98fa9bd741ce4e46e9701ee2247635aa5ccfb9fbcf0e5922ab14ff91306d/awscrt-0.36.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:4c1a10d5f33a6c3fb1e39474242c6761b9f607c048e688b344acf95354053d65", size = 5155758, upload-time = "2026-07-16T19:35:45.687Z" }, - { url = "https://files.pythonhosted.org/packages/df/da/b21fff2240b8185afcced69912db6231ff62545e428bc70248c196f73f48/awscrt-0.36.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b76cb47f2ed5c0bf989541ee80ab8f35d9a392d30b5de1e24b17d655e2f63da5", size = 4094173, upload-time = "2026-07-16T19:35:47.317Z" }, - { url = "https://files.pythonhosted.org/packages/4d/9c/b4ecc77494e5930f0bca50ba9b8c9f973ac477e0233c83126cfb81c85327/awscrt-0.36.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bfc4039bc8ee9924d9dfc1558d073305d5d1f0046e87d7773826901d0f0f0792", size = 4384153, upload-time = "2026-07-16T19:35:48.931Z" }, - { url = "https://files.pythonhosted.org/packages/bf/48/ed0f2b0cb2cb5b7fbb89f14574c7b4bb5f7584072054523c3d4424be693e/awscrt-0.36.0-cp314-cp314t-win32.whl", hash = "sha256:2c8ebe57a6d8a329b57b480357767da1ae3af49d243727e826c3317da09397a5", size = 4301556, upload-time = "2026-07-16T19:35:50.48Z" }, - { url = "https://files.pythonhosted.org/packages/85/a3/9f36da2b735b896c4eb5455d858c4bca80eeadcf6bbfdfafd189de46830f/awscrt-0.36.0-cp314-cp314t-win_amd64.whl", hash = "sha256:edc9814c5ddf4b49e9b4dc5f424b7172afc07a2f7b655338a25d6c87620d2b89", size = 4479687, upload-time = "2026-07-16T19:35:52.014Z" }, +version = "0.38.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0c/c4/1f7c4161aa665b06ddb9c34acbe6b5ea8fc8bf72b78de474d65e6f494ca4/awscrt-0.38.0.tar.gz", hash = "sha256:4a8423c4a76390c6e5c4f386e3e367dccdcf67d6d1a0bc1c59776bb14cdc2ad9", size = 37915957, upload-time = "2026-10-16T19:14:10.674Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/08/b9194c02f388aa0024b648c45d57e401357e35f87032f1c40ed3ad081492/awscrt-0.38.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:83ad2ef749959ff866f6379d12b0fcf05e3df222350777f8ed1027160e10fe3c", size = 5225251, upload-time = "2026-10-16T19:13:04.164Z" }, + { url = "https://files.pythonhosted.org/packages/9f/a4/062819675eb0c1746c39bd9783d6e3d149db319263d0a87cc2cb5e1b61d9/awscrt-0.38.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f714b850a57d24794b66fe82889ae01b3a4385cd273b33669ee15175a8a07287", size = 4148814, upload-time = "2026-10-16T19:13:06.366Z" }, + { url = "https://files.pythonhosted.org/packages/03/d1/89f116335777bda244c33674a4a926af397a4381677f2cf6d1306633787f/awscrt-0.38.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:98f7a784ecbe88103ca984dc6463a3f0878dce52742d456acf52dad7afc28130", size = 4423367, upload-time = "2026-10-16T19:13:07.734Z" }, + { url = "https://files.pythonhosted.org/packages/69/b5/9b82b5b61148f5814c8c4448ab56bd8e1d33fbff0daf83c5cbd20253bf22/awscrt-0.38.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a0c755a3c94ce36b43722d9b2cca3be207160ce125b39770058980f6af6c5955", size = 4075311, upload-time = "2026-10-16T19:13:09.049Z" }, + { url = "https://files.pythonhosted.org/packages/8c/6f/1b7dd84c7e339f3a4211e0326b51ca94109a394b05bc9e92b1cbf65a0ed4/awscrt-0.38.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2e5a7aef920a02ec3e8bd287f2486db95f8030279bc9ced15b6e08f38790ac2e", size = 4301252, upload-time = "2026-10-16T19:13:10.371Z" }, + { url = "https://files.pythonhosted.org/packages/6a/4e/5dbece021147a82011323c7a8a38e76ac84008c8262bbee0739531e4441d/awscrt-0.38.0-cp310-cp310-win32.whl", hash = "sha256:6f4d865feb1ccab497ac48641b7595235093e5b042524f955c48829e1e06553c", size = 4262621, upload-time = "2026-10-16T19:13:11.576Z" }, + { url = "https://files.pythonhosted.org/packages/54/a5/a4f48ac81b596e0585902202c3c0474127ae494bbc11159b07c099105ed8/awscrt-0.38.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6cb0d0139efe9dc8e0260b5b136c7aecad12a20efa2deb6d5a67115ecb43fd6", size = 4404116, upload-time = "2026-10-16T19:13:12.923Z" }, + { url = "https://files.pythonhosted.org/packages/ec/38/1bcbc5240d952b74a857ef4498714bb9107bdeb2786b3569caee6e11d03c/awscrt-0.38.0-cp311-abi3-macosx_10_15_universal2.whl", hash = "sha256:fa7b3bae4518c199ca35a442784237fce562121aa83f838fe23994ffddccb17b", size = 5225304, upload-time = "2026-10-16T19:13:14.688Z" }, + { url = "https://files.pythonhosted.org/packages/b2/32/1403fa8c73c723c8299b8162f46ce3d42940b8fcb10f0eccc87ae5d6aa8a/awscrt-0.38.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f54a804f321912f3d5e856721d5fbfb8129eda8120eec3e9cae8eb26bb9349af", size = 4108660, upload-time = "2026-10-16T19:13:16.466Z" }, + { url = "https://files.pythonhosted.org/packages/a9/ce/c1b84969cc9b830a96b0c42bbf0fec765ac338945dae5994d5d9124983c0/awscrt-0.38.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b91feaa8bafd264cd06484dc4efa5d95fbd25a9a46204eb71bf12a9dc8640a93", size = 4383864, upload-time = "2026-10-16T19:13:17.825Z" }, + { url = "https://files.pythonhosted.org/packages/8b/e2/1e36aaee1262231dca41dda6c25f1d718c976446e5ef6826bcc60f4da8fa/awscrt-0.38.0-cp311-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2a7c9aeaa9c64f33d5373b4d9e5d5a343a663b231e9c036269c3c9d5c8dd003c", size = 4009518, upload-time = "2026-10-16T19:13:18.984Z" }, + { url = "https://files.pythonhosted.org/packages/24/fa/1787950aae6429f23ae3216e83dbc78051888887da802268ba0fb1f34fa5/awscrt-0.38.0-cp311-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:d40b7a038ee37a378b320704cd76e59124f5009e98eeb19ca6daf9a5915220a9", size = 4239170, upload-time = "2026-10-16T19:13:20.567Z" }, + { url = "https://files.pythonhosted.org/packages/9f/6c/872f7cfbf629d1e0bc5471b616cf837a7a9183f5b76d33289fc318ceb2dc/awscrt-0.38.0-cp311-abi3-win32.whl", hash = "sha256:7012194d886576dc71eca7b2720a95c895bdde0cc875cce0646cab69009ca182", size = 4260927, upload-time = "2026-10-16T19:13:21.892Z" }, + { url = "https://files.pythonhosted.org/packages/42/b6/37bb001ebdfbcf1032eacd0db57fbfb25411bb34026b6f212bec47b45c2b/awscrt-0.38.0-cp311-abi3-win_amd64.whl", hash = "sha256:91ff2ff3af31428c5b835e91197b3b7d6a1526b78b8fcaf9ef31ed75e3d07e58", size = 4400851, upload-time = "2026-10-16T19:13:23.071Z" }, + { url = "https://files.pythonhosted.org/packages/97/bb/d54a0ae302a741ee0776184c93bb37b5dd221cab82681759c1ac36a17a30/awscrt-0.38.0-cp313-abi3-macosx_10_15_universal2.whl", hash = "sha256:a2b60b393d7eeb733604b8bd01709969a1833811e82cff574ccac5fc10de1f0e", size = 5223704, upload-time = "2026-10-16T19:13:24.635Z" }, + { url = "https://files.pythonhosted.org/packages/07/db/ba87b1e3a58c429866f5d472584746f3aee44b37932cb3cbc7ec33d5b84d/awscrt-0.38.0-cp313-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ef306404d069a8735bebc9415ba63b11251e7ad02b3e9a4dcc43dac685ebc838", size = 4098896, upload-time = "2026-10-16T19:13:26.013Z" }, + { url = "https://files.pythonhosted.org/packages/ff/84/d551f708df4ee610072c966dc8f72a79e47295c3e91c083c3e9ea7b6281e/awscrt-0.38.0-cp313-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:45bc3d46f6ee42fb106757dffd8536791dcace5c17e6b72639709282ac18b93f", size = 4377461, upload-time = "2026-10-16T19:13:27.603Z" }, + { url = "https://files.pythonhosted.org/packages/52/57/85e1aa6bee2eeede6c8a2c410f383a56e6fce34ff41f4e84e15cfa3119ce/awscrt-0.38.0-cp313-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:03a7ae10f93dbe54fe7af76507932538508dc3156e74576de826cfa80f40b862", size = 4001917, upload-time = "2026-10-16T19:13:28.795Z" }, + { url = "https://files.pythonhosted.org/packages/64/4c/4119fdcb47c4a441dbf0afc4a11910c37be61dae285c396d27bf608707e9/awscrt-0.38.0-cp313-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:30f15cc0bf4e7a9c6542ca11ba636e94b80571f332fc56c28652369aaece9627", size = 4233907, upload-time = "2026-10-16T19:13:30.308Z" }, + { url = "https://files.pythonhosted.org/packages/34/cf/2f77e2646628cd96d6cbb0d2c3f5e8663675a77e2b60f75adb1d595659c0/awscrt-0.38.0-cp313-abi3-win32.whl", hash = "sha256:b90229ac169bac976abf0029b5313504a53da87d393fd04b06888db444aebb12", size = 4258325, upload-time = "2026-10-16T19:13:31.533Z" }, + { url = "https://files.pythonhosted.org/packages/6c/ff/8792bb4288f5a034838074f592b00c6b2c10e137eb7811a5b386fc3fb10c/awscrt-0.38.0-cp313-abi3-win_amd64.whl", hash = "sha256:65d404ed5e22146154fc62626b1b8a8d8539cabd1b589337df6737361335ec0a", size = 4396443, upload-time = "2026-10-16T19:13:32.85Z" }, + { url = "https://files.pythonhosted.org/packages/85/fa/c096d6a4364c2da455cb6ad5eba07e9f8d7f754908a9e2acf7813ef7c36d/awscrt-0.38.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:f04d0710dde83bfa19dcfcb55524d632680b2edb2151afa7b9c986f364766b5d", size = 5235148, upload-time = "2026-10-16T19:13:34.121Z" }, + { url = "https://files.pythonhosted.org/packages/fa/50/1effa079885c4f36496477ece5434122e9c3fce48396236f250190d6807f/awscrt-0.38.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:2049d0480481f5ba1bd7dae290f2bfc2e2b757e95ec53b5247976f29673c0e60", size = 4143903, upload-time = "2026-10-16T19:13:35.272Z" }, + { url = "https://files.pythonhosted.org/packages/e4/3c/4f1ecb8db6cc413f3d9f16adb88b382baa1afd067a61eaf5f0d8f9f8f9ce/awscrt-0.38.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:e887bad4d11e1e30b6f3aef2b617f62825c9b591b3bc82effa3ffe2ac2ddf00d", size = 4368910, upload-time = "2026-10-16T19:13:36.576Z" }, + { url = "https://files.pythonhosted.org/packages/39/0c/01827948ed1cc0105fd96495ae83c08a22c582802becfec0068f9c8e5221/awscrt-0.38.0-cp313-cp313t-win32.whl", hash = "sha256:ab0a263c467f908496df52f4b6fec8f20b0576bfcc3360f3ebe4ea29d00c35ed", size = 4307287, upload-time = "2026-10-16T19:13:37.735Z" }, + { url = "https://files.pythonhosted.org/packages/7e/85/8b8e817167e10cf631e571209cf6c90d2299d10417a7d345b3cd4c4fe888/awscrt-0.38.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5a679e83a0d4eb69bc06677fa96117409f5707cdd2df8c7592673c5070b16bcf", size = 4448771, upload-time = "2026-10-16T19:13:38.889Z" }, + { url = "https://files.pythonhosted.org/packages/5e/1a/a826c05fae855deb3cb634e2f72125885eecbff7a6d0d0633af3a82ebedb/awscrt-0.38.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d6ca05bacb737e273feb1916a022da71d1aa84213a73b79b5a98ecd8eddc4905", size = 5235147, upload-time = "2026-10-16T19:13:40.139Z" }, + { url = "https://files.pythonhosted.org/packages/93/d8/ddeba7cc2d40c5d1ecc5349da113df73ab2c4bb87375bd1d29ebb6412be8/awscrt-0.38.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8757c70b0862f4195371ed69636c7a40f2f4519b02aa2c0ab07618a7b71d545c", size = 4229995, upload-time = "2026-10-16T19:13:41.815Z" }, + { url = "https://files.pythonhosted.org/packages/54/5e/69d6863ae78251ba75834f6f14ffde92e54e1ea0eda8d299d41150e3bf81/awscrt-0.38.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:522eea71c67192f9e3a6707d59b7165599f9b8292ae0513c41ac4cb3b53b0074", size = 4502995, upload-time = "2026-10-16T19:13:43.118Z" }, + { url = "https://files.pythonhosted.org/packages/dc/65/7ec3e696edc1963bf3e117277cfc5537509e696588def528414cf8730218/awscrt-0.38.0-cp314-cp314t-win32.whl", hash = "sha256:86163dbf8ff3e615bcae82d140c89a693b907e583c67141437676eb5042b8d45", size = 4392495, upload-time = "2026-10-16T19:13:44.814Z" }, + { url = "https://files.pythonhosted.org/packages/05/64/bcb865c82011255e15d66438157812b79fd50886b4a473851004540cac95/awscrt-0.38.0-cp314-cp314t-win_amd64.whl", hash = "sha256:cc70517731a6742706870d6c853bdec8eb29f3f085093b086792ed701270c24a", size = 4550440, upload-time = "2026-10-16T19:13:46.127Z" }, ] [[package]] @@ -560,7 +560,7 @@ strands-agents-evals = [ [package.dev-dependencies] dev = [ - { name = "a2a-sdk", version = "1.1.2", source = { registry = "https://pypi.org/simple" }, extra = ["http-server"], marker = "extra != 'extra-17-bedrock-agentcore-a2a' or extra == 'extra-17-bedrock-agentcore-a2a-v1' or extra == 'group-17-bedrock-agentcore-dev'" }, + { name = "a2a-sdk", version = "1.1.2", source = { registry = "https://pypi.org/simple" }, extra = ["http-server"], marker = "(extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra != 'extra-17-bedrock-agentcore-a2a-v1' and extra == 'group-17-bedrock-agentcore-dev') or (extra != 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "ag-ui-protocol" }, { name = "autoevals" }, { name = "deepeval" }, @@ -592,8 +592,8 @@ requires-dist = [ { name = "a2a-sdk", extras = ["http-server"], marker = "extra == 'a2a-v1'", specifier = ">=1.0.1,<2.0" }, { name = "ag-ui-protocol", marker = "extra == 'ag-ui'", specifier = ">=0.1.10" }, { name = "autoevals", marker = "extra == 'autoevals'", specifier = ">=0.3.0,<1.0.0" }, - { name = "boto3", specifier = ">=1.43.115" }, - { name = "botocore", specifier = ">=1.43.115" }, + { name = "boto3", specifier = ">=1.43.127" }, + { name = "botocore", specifier = ">=1.43.127" }, { name = "deepeval", marker = "extra == 'deepeval'", specifier = ">=3.5.0,<5.0.0" }, { name = "httpx", marker = "extra == 'langgraph'", specifier = ">=0.27.0" }, { name = "jinja2", marker = "extra == 'simulation'", specifier = ">=3.1.6" }, @@ -649,30 +649,30 @@ dev = [ [[package]] name = "boto3" -version = "1.43.115" +version = "1.43.127" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0e/4a/b0ce191492a1724be73d8aacaf70d508bc8cbb9674c046d2ff7181dc51fb/boto3-1.43.115.tar.gz", hash = "sha256:c0f35e5f9cdf0edb365195e306d5586d3970b224660a11a87a4ec361ec3d7168", size = 112677, upload-time = "2026-10-19T19:19:53.093Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/6b/2bc953d6f0b87505636d0a7c16e46a47ab6c49df4a278ac9c0b1c1732e65/boto3-1.43.127.tar.gz", hash = "sha256:b5417e81d439b35ccf3a1eb51fa06cf9c97167c9a6beaa1929175ee9840d505a", size = 112783, upload-time = "2026-11-09T20:52:17.411Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/be/bc/40dffae3238ef8d3415393132751fe2c88e8663ef84a31f0950e439ed2d5/boto3-1.43.115-py3-none-any.whl", hash = "sha256:6667a0c21d48dc125dbba88444bc8a601ce881a99341a0e6169f9333898e620d", size = 140044, upload-time = "2026-10-19T19:19:51.444Z" }, + { url = "https://files.pythonhosted.org/packages/40/48/f562f1240da499614a19bdf5d54dbdbfea5cffabbdd2703c3a413e0c13a1/boto3-1.43.127-py3-none-any.whl", hash = "sha256:47f87f89b10e62f5191bd98674beb0dd52ed368c19fcdfef2ef38ead31126f49", size = 140187, upload-time = "2026-11-09T20:52:15.845Z" }, ] [[package]] name = "botocore" -version = "1.43.115" +version = "1.43.127" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6f/10/ca525e88db50f5153ddad2a3d55908b5ace915d10f443d5e5135ba808d8d/botocore-1.43.115.tar.gz", hash = "sha256:aa4d9c4e7ef99988b7347e0cd276ba84e1eb1625510557b0e36cd57ecb19bbf2", size = 16383796, upload-time = "2026-10-19T19:19:45.382Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8f/45/b4e606b0f66c11c6bd44e91381aa562c6b4dacf478b97b461a429036a89a/botocore-1.43.127.tar.gz", hash = "sha256:93bae360fb3a6f1b8e36593faa8bbbfa05b19866f7a37e9606a98f13394156f8", size = 16559749, upload-time = "2026-11-09T20:52:12.475Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/2d/4b6b6f5704d1ec9b412c1dd9700bda0c315619dbac4a21418180a81a2780/botocore-1.43.115-py3-none-any.whl", hash = "sha256:9ceda640c868bc15f5399129e8cfdef8cbb4b350e8a99547c9b5f477cfb9619a", size = 16085101, upload-time = "2026-10-19T19:19:42.203Z" }, + { url = "https://files.pythonhosted.org/packages/4b/db/bee0401fd3f8cf1e2404044a4e3156dc7e064c2b1fc7162df2d795941cd8/botocore-1.43.127-py3-none-any.whl", hash = "sha256:aa0e3188679a2164a2098a14ea9b59520520cb573aaee9999d852480691e134a", size = 16257630, upload-time = "2026-11-09T20:52:09.488Z" }, ] [package.optional-dependencies] @@ -732,7 +732,7 @@ name = "cffi" version = "2.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pycparser", marker = "implementation_name != 'PyPy'" }, + { name = "pycparser", marker = "implementation_name != 'PyPy' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } wheels = [ @@ -893,7 +893,7 @@ name = "click" version = "8.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "colorama", marker = "sys_platform == 'win32' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" } wheels = [ @@ -983,8 +983,8 @@ name = "cryptography" version = "48.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "cffi", marker = "platform_python_implementation != 'PyPy' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "typing-extensions", marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/12/45/870e7f4bef50e5f53b9f51d4428aee5290eedf58ba443f16b1ebb7ab8e66/cryptography-48.0.1.tar.gz", hash = "sha256:266f4ee051abb2f725b74ef8072b521ce1feacf685a3364fa6a6b45548db791a", size = 832989, upload-time = "2026-06-09T22:32:31.8Z" } wheels = [ @@ -1092,12 +1092,12 @@ dependencies = [ { name = "httpx" }, { name = "huggingface-hub" }, { name = "multiprocess" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "packaging" }, - { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "pandas", version = "3.0.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "pandas", version = "3.0.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "pyarrow" }, { name = "pyyaml" }, { name = "requests" }, @@ -1221,7 +1221,7 @@ name = "exceptiongroup" version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11' or (python_full_version >= '3.11' and python_full_version < '3.13' and extra != 'extra-17-bedrock-agentcore-a2a') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "typing-extensions", marker = "python_full_version < '3.11' or (python_full_version < '3.13' and extra == 'group-17-bedrock-agentcore-dev') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [ @@ -1258,7 +1258,7 @@ name = "fastmcp" version = "3.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "fastmcp-slim", extra = ["client", "server"], marker = "extra != 'extra-17-bedrock-agentcore-a2a' or extra == 'extra-17-bedrock-agentcore-a2a-v1' or extra == 'group-17-bedrock-agentcore-dev'" }, + { name = "fastmcp-slim", extra = ["client", "server"], marker = "(extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra != 'extra-17-bedrock-agentcore-a2a-v1' and extra == 'group-17-bedrock-agentcore-dev') or (extra != 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/3b/a9/5c5a01b6abd5346bf60b97cfd29e4a86661940c27dd562bfcda07fd03519/fastmcp-3.3.1.tar.gz", hash = "sha256:979362ea557de42a5f40342563c7e4b236bcc8e7cd192715f50030695d1a71cd", size = 28681699, upload-time = "2026-05-15T15:50:39.673Z" } wheels = [ @@ -1271,7 +1271,7 @@ version = "3.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "platformdirs" }, - { name = "pydantic", extra = ["email"], marker = "extra != 'extra-17-bedrock-agentcore-a2a' or extra == 'extra-17-bedrock-agentcore-a2a-v1' or extra == 'group-17-bedrock-agentcore-dev'" }, + { name = "pydantic", extra = ["email"], marker = "(extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra != 'extra-17-bedrock-agentcore-a2a-v1' and extra == 'group-17-bedrock-agentcore-dev') or (extra != 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "pydantic-settings" }, { name = "python-dotenv" }, { name = "rich" }, @@ -1289,7 +1289,7 @@ client = [ { name = "httpx" }, { name = "mcp" }, { name = "opentelemetry-api" }, - { name = "py-key-value-aio", extra = ["filetree", "keyring", "memory"], marker = "extra != 'extra-17-bedrock-agentcore-a2a' or extra == 'extra-17-bedrock-agentcore-a2a-v1' or extra == 'group-17-bedrock-agentcore-dev'" }, + { name = "py-key-value-aio", extra = ["filetree", "keyring", "memory"], marker = "(extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra != 'extra-17-bedrock-agentcore-a2a-v1' and extra == 'group-17-bedrock-agentcore-dev') or (extra != 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] server = [ { name = "authlib" }, @@ -1303,7 +1303,7 @@ server = [ { name = "openapi-pydantic" }, { name = "opentelemetry-api" }, { name = "packaging" }, - { name = "py-key-value-aio", extra = ["filetree", "keyring", "memory"], marker = "extra != 'extra-17-bedrock-agentcore-a2a' or extra == 'extra-17-bedrock-agentcore-a2a-v1' or extra == 'group-17-bedrock-agentcore-dev'" }, + { name = "py-key-value-aio", extra = ["filetree", "keyring", "memory"], marker = "(extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra != 'extra-17-bedrock-agentcore-a2a-v1' and extra == 'group-17-bedrock-agentcore-dev') or (extra != 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "pyperclip" }, { name = "python-multipart" }, { name = "pyyaml" }, @@ -1507,14 +1507,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/07/67/07ecd6d85c0f253363cbc4ac9e7dd048ca571a267fbccfea084d6009ac3b/greenlet-3.5.5-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:816230f469381ad0a43abc9fa8dda5a699e32fb78958dde32ded93213b70a667", size = 292971, upload-time = "2026-08-10T13:28:09.837Z" }, { url = "https://files.pythonhosted.org/packages/24/35/426733bc24247ee17bb76df90f550c299ff5f8572b2bdd7cacb5c53fd994/greenlet-3.5.5-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a5433cf291e0ef9114bd14d0d824db6e5e4a43033234bca48181a9597acca07b", size = 609290, upload-time = "2026-08-10T14:14:32.273Z" }, { url = "https://files.pythonhosted.org/packages/9c/dc/17d3a5acceb2fd0bbc9682a228117b719cdfb68085e6dbb33fa325755f27/greenlet-3.5.5-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:19d59f068887d8c5907fc177f27683413ace3011b6ed646c0b309266e74a6502", size = 622650, upload-time = "2026-08-10T14:27:22.004Z" }, + { url = "https://files.pythonhosted.org/packages/74/3f/b31e6bd6adb8f80492efb6a47e8f9cd0e7335db5aac2795b1876d5afcfee/greenlet-3.5.5-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:86c5113d698cb8d927b2750bb1f1d59eefe3a37e0e0217491aee29a7f84ef52c", size = 629560, upload-time = "2026-08-10T14:30:04.733Z" }, { url = "https://files.pythonhosted.org/packages/51/91/00b3c0566316c6f383ea16ee05388ec4f57f6e0afa49e72ae471eda8c47f/greenlet-3.5.5-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ff00e12102358292087274dfb1669132387ff6e7920ebf9d85f4826ce0d3a56", size = 622819, upload-time = "2026-08-10T13:40:46.562Z" }, + { url = "https://files.pythonhosted.org/packages/18/5e/58c561efde575c4ca070030e2e0513e8d1b07b76d8a2d84a9bcef1becd42/greenlet-3.5.5-cp310-cp310-manylinux_2_39_riscv64.whl", hash = "sha256:c69bed34470abfcd456984fdadaa18e62169af4480335c45f3c32d1d9c12e638", size = 425489, upload-time = "2026-08-10T14:29:59.768Z" }, { url = "https://files.pythonhosted.org/packages/3c/78/52de4f7ac9152ad1dbc8f437895c1e573d30ee1e1427e0f91a280e2417b6/greenlet-3.5.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:523bb8e27614d77101ea7a8cf59f8d91219b72d5c29f6a038c92b50828bfa8d0", size = 1582164, upload-time = "2026-08-10T14:15:02.645Z" }, { url = "https://files.pythonhosted.org/packages/f6/ff/c3855a00c2417e8f61c7b9f0bc4f8f599c6928f5c15681ad251e78a91e05/greenlet-3.5.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f1e2db190db51c17433eee424803818cf0670bf049d9cfe0dd07be111d1aa7c4", size = 1648807, upload-time = "2026-08-10T13:40:27.471Z" }, { url = "https://files.pythonhosted.org/packages/70/21/d29ff6a79dbd1ec1fe74c155d25d4c5a85e221d6b9ffc2cc7a709e7c8c39/greenlet-3.5.5-cp310-cp310-win_amd64.whl", hash = "sha256:740e544169527b82695ce76af2f7ad6f030904658f2f3921a1d245771fb88cfc", size = 322832, upload-time = "2026-08-10T13:28:10.85Z" }, { url = "https://files.pythonhosted.org/packages/4e/a3/07297917485ee2ca85bc3c8dc6ed85ad3fffcf424047fba62671dba68e97/greenlet-3.5.5-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:be63afcbbccfad3dd95a1ba12ada84dab2ef32031973d80b5b92df67fa763a61", size = 294165, upload-time = "2026-08-10T13:25:17.987Z" }, { url = "https://files.pythonhosted.org/packages/db/51/6f732f9314cda54c5fd48a7620c7160f4f286967e8045ad94b9d66ce80b7/greenlet-3.5.5-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a268024ce2d7d2b04694bf1594058981a9fa663d1df4b762dee499211ed7c1c", size = 613610, upload-time = "2026-08-10T14:14:33.829Z" }, { url = "https://files.pythonhosted.org/packages/d8/c0/b27589e25d220289edcd4d582b2b17b83058d1a56d53d971b6ea1a34f10d/greenlet-3.5.5-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:35cbb8bf55ace57fbccb4fb8622c4521713acd8691e77f4696d416ea7ca527da", size = 625481, upload-time = "2026-08-10T14:27:23.647Z" }, + { url = "https://files.pythonhosted.org/packages/39/82/5c873dbb4fb001d22fbbd50e80d4c1b0181ddae106856132160f84b94e88/greenlet-3.5.5-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:abc8bc8d9f935cd685457545b6a53863a877fdc12c2c0f5ee9beee18d9db139c", size = 633329, upload-time = "2026-08-10T14:30:06.062Z" }, { url = "https://files.pythonhosted.org/packages/51/2d/f2c928218ac52f26d7a2c188c171d1b7e728b23782cb3347e7b4fce1493a/greenlet-3.5.5-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:74cc6df89ec5302337adc9cf096221cbed2510fd444b0e0f1586cf0470740864", size = 624562, upload-time = "2026-08-10T13:40:48.064Z" }, + { url = "https://files.pythonhosted.org/packages/70/12/f7df98e72a8eb4a7edfec5a08d6d1a4ab53a52c95ba0b2ea6c10b8dd9bd0/greenlet-3.5.5-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:3134291427bb0f3526e9d90311988caf336eb43730e95244997a4fb15f45144f", size = 428145, upload-time = "2026-08-10T14:30:01.071Z" }, { url = "https://files.pythonhosted.org/packages/3e/4a/92fc51d5d35912f4f06eec037ba347985defd0be47463a010a325634d9d2/greenlet-3.5.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6d9b454c5fc48aeaa7c4337813dbf513a6870468e426438a04d922c6d0fe63db", size = 1584909, upload-time = "2026-08-10T14:15:04.343Z" }, { url = "https://files.pythonhosted.org/packages/ac/58/ed98b80ac5738c149a5258544843c45601ade1fd70f61740cdaead6351b3/greenlet-3.5.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03551ed792cb1b4fc0277a0c60dfd8c343894a0ba06fe60dcd22f568b433da39", size = 1651184, upload-time = "2026-08-10T13:40:28.879Z" }, { url = "https://files.pythonhosted.org/packages/d8/be/b582ceb80cefdf9d8da34078714e4b12b3d16f509dee0f65e40a5cc8fc7d/greenlet-3.5.5-cp311-cp311-win_amd64.whl", hash = "sha256:ab3df3dffb58bf70564e93a5cec7941e4d9faa5a36cc4234a10d3131afe04f53", size = 323280, upload-time = "2026-08-10T13:26:07.495Z" }, @@ -1522,7 +1526,9 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2e/7e/9ecd0285e3153532ae07aeb88063c43c72b4221cf0d4d123b02f3682e3ff/greenlet-3.5.5-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:49520f0c95a48b42cf55414b8e8479beb274ea70431afc33e3f79903c71f4380", size = 295809, upload-time = "2026-08-10T13:25:34.023Z" }, { url = "https://files.pythonhosted.org/packages/35/73/60e4bbcc89252037b18087f2ec16405d5b2d5be42dde191bbf3667e96102/greenlet-3.5.5-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55272212cbc5f43d1d723725ab931f1939969b7e9523882ca58b55061769d053", size = 611910, upload-time = "2026-08-10T14:14:35.18Z" }, { url = "https://files.pythonhosted.org/packages/a4/17/cd5134be659cd4a443e7a61ae670dabec165a814c51162916d637b6dd38e/greenlet-3.5.5-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655bca754a2ef4efcb0eb48a94d3f4593536d0f3d48f8ed44343c01d16a92f95", size = 624198, upload-time = "2026-08-10T14:27:25.229Z" }, + { url = "https://files.pythonhosted.org/packages/9b/30/87c212b5c684d0e72974f1063b7a9687631e8985902c06e1016542c874e7/greenlet-3.5.5-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6ca5d6ae0739e5764f2cfcfaa562ac5a990cbdaedca93251c5e3cf07c362371f", size = 629504, upload-time = "2026-08-10T14:30:07.967Z" }, { url = "https://files.pythonhosted.org/packages/78/ac/5c5b959999b6f09c3026b5dfe171575bc3121c5236ce74f495096f25b203/greenlet-3.5.5-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:147b25a42e5ca5be3d42356e8f608b37af715a1c196e9bf9d1627f3341adfe1d", size = 621439, upload-time = "2026-08-10T13:40:49.391Z" }, + { url = "https://files.pythonhosted.org/packages/63/2c/eb487fafc9f50ffff2b1e0b697f70fb34bf150821c08ab225aacf5583a7e/greenlet-3.5.5-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:1b5ed9162c0c098e0bbc2cf88a94f433c1b8926f831745252e099e5d83e17759", size = 432462, upload-time = "2026-08-10T14:30:02.309Z" }, { url = "https://files.pythonhosted.org/packages/c8/8b/6acf112ed8aee499f25b4d6949820fb02ac950ff9c1f3d793bd5be0599f2/greenlet-3.5.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:27493374cff1d1b7919dc8126547f2aea582737e3046147b434b1e12de56389b", size = 1581342, upload-time = "2026-08-10T14:15:05.653Z" }, { url = "https://files.pythonhosted.org/packages/b8/d7/734e5f198888876b42d7616ff6644c075baf6b8a2412deadd6b0e1b8b20c/greenlet-3.5.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:12e2ee66c2aba86133f10fd99d6a8856c6d351ffb7be0e4d52ef2cc5fbb705b2", size = 1645744, upload-time = "2026-08-10T13:40:30.353Z" }, { url = "https://files.pythonhosted.org/packages/de/30/1f42b88dc587b5899ee50616ad56ee40cafaf225df4fb829f10183c62a5c/greenlet-3.5.5-cp312-cp312-win_amd64.whl", hash = "sha256:49ddacd36af37735fab103846f4ee4d18a492dde72730d1699c0c8ebe30d9f18", size = 324171, upload-time = "2026-08-10T13:28:44.472Z" }, @@ -1530,7 +1536,9 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fb/3d/8cef5f724ec0d4add2af8961d504535ec60c3cca9e464f6d03bdba29d85b/greenlet-3.5.5-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:b79fd2a5bc099b5e744f34c4c9a58954a5f4cb7529fb4b6e8446057d61b6edaa", size = 294730, upload-time = "2026-08-10T13:27:51.206Z" }, { url = "https://files.pythonhosted.org/packages/88/4b/8e7aa3f514273aecff30a16ab1bac09ff54cfc7e6860fdd8058c37ff2499/greenlet-3.5.5-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:634cf15a233a949136879dd388e25d3296e16f3f1e217d2456797b8579ebc6ed", size = 614536, upload-time = "2026-08-10T14:14:36.589Z" }, { url = "https://files.pythonhosted.org/packages/85/48/4e95e9dd5a8a397dc6a6345dd7f1935113d0fca4f85e89d3976da9cd988d/greenlet-3.5.5-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:499adea519f748407fc6806d20eedabac2884fd73b9f38d81236e190ba20dfef", size = 626924, upload-time = "2026-08-10T14:27:27.048Z" }, + { url = "https://files.pythonhosted.org/packages/0e/84/eaa476d6bf3816828d0d70e80dcc36bf30a058233bd889e707e693f6e860/greenlet-3.5.5-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f7278591501941bb2456af102bb9cd59aab48c6cfd6e2dd68fa1290bb0c49a42", size = 632726, upload-time = "2026-08-10T14:30:09.874Z" }, { url = "https://files.pythonhosted.org/packages/89/5d/398a1c71fa7a277deeb376c999979de6786f08fc2d5747a0b9d6e11738dd/greenlet-3.5.5-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2eabb980975cba5b93a95f6f69287d05fc05ac955bfd6a320a7c083eeb52c0b0", size = 623906, upload-time = "2026-08-10T13:40:50.501Z" }, + { url = "https://files.pythonhosted.org/packages/d0/f2/0cc2849ede68579291e9c59b3ab6ec1958f98681cca5b14d8fc75bf674a4/greenlet-3.5.5-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:4dfc7c4470354e7b09184d1a3a985761053a2fd694ddb5b5c80242afc2c8c90b", size = 434966, upload-time = "2026-08-10T14:30:03.729Z" }, { url = "https://files.pythonhosted.org/packages/04/1b/745450fc5ea9e0cb17d840d248f284db3363de736d362c7d2d883e3eadba/greenlet-3.5.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:03115c2e0a371999bf8ae616aa8d653f96641d4705c457aebaa187276e9f7537", size = 1581430, upload-time = "2026-08-10T14:15:06.853Z" }, { url = "https://files.pythonhosted.org/packages/d4/29/d51b296e3191bb15d3d81ec375af1909e4466c0f395d744ed475801798a9/greenlet-3.5.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4441153ffba21b90d3ca89fe3d31f5c093ae6c0bf0cfdfc98f54cde22f95b62e", size = 1645684, upload-time = "2026-08-10T13:40:32.133Z" }, { url = "https://files.pythonhosted.org/packages/12/63/369f1a1625e64e9e31df3963c6044056e3fdfa3fa3fdba3c54ffefa6e987/greenlet-3.5.5-cp313-cp313-win_amd64.whl", hash = "sha256:95c5b1f4b3a193f8a0c2de4bfdcb48d119f7f1063941f1de1f2168051b3e52dd", size = 324075, upload-time = "2026-08-10T13:26:58.974Z" }, @@ -1538,7 +1546,9 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7f/8c/080e881fa2be95ff1ddbd6994b2bab3b1a78df3b3fcab39306011764fcc7/greenlet-3.5.5-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:d4a389a852e392a6366058651a20fa5ba40d979865aa81bea2ccbdc44805070d", size = 295309, upload-time = "2026-08-10T13:26:03.032Z" }, { url = "https://files.pythonhosted.org/packages/25/cc/0ac614e6586c0e42d4cc281a5819150f4f43685744a4c5ff77139286409d/greenlet-3.5.5-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70b157cd319873e8b544ddc2de158f55bbd0a9b0218c8ce9332039801518e328", size = 661185, upload-time = "2026-08-10T14:14:37.867Z" }, { url = "https://files.pythonhosted.org/packages/5e/b9/6808725354be8ad305dfe5172377664fc9642d4fc043be246b3314cf4482/greenlet-3.5.5-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8bdfd1424abcf26832961e766570cae79efdb9599d709088c9cb6ef82b194926", size = 673419, upload-time = "2026-08-10T14:27:28.652Z" }, + { url = "https://files.pythonhosted.org/packages/eb/52/f005d579acde46c3d1cc3cab1c9f3d5708c8a3006a4120e8cf5da801afe9/greenlet-3.5.5-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d98ef6f92e67c6dbf299dbfd8facc1b0d2d9cedf91e325e73b3d0373fe4309d8", size = 677863, upload-time = "2026-08-10T14:30:11.663Z" }, { url = "https://files.pythonhosted.org/packages/42/2e/40c509967da7f254680826a2fa0dd22138ec79946c70b97542d74cde8b43/greenlet-3.5.5-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:182de51c6b572a705f2fafaab2e783bcf7d2760940229dfe73086cbae037af3e", size = 670822, upload-time = "2026-08-10T13:40:51.833Z" }, + { url = "https://files.pythonhosted.org/packages/c4/8a/a75f8a2bdcef3c358a3147cdc9db3aa83755f0a038f766ab0bedb66f512c/greenlet-3.5.5-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:159df1942d88e8f784cbb38d6f18bdb365cd11319cfbb3e89623de2b97892d53", size = 480554, upload-time = "2026-08-10T14:30:05.171Z" }, { url = "https://files.pythonhosted.org/packages/2d/22/c3c2eee4a8fe191d6d1d183086c56133d646024e3d70bfd414829f64560b/greenlet-3.5.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8fec3f165dfe332e490c3247c0f6c23b0bfc45f06496ad7f00ddb00e3d35e4dc", size = 1628469, upload-time = "2026-08-10T14:15:08.11Z" }, { url = "https://files.pythonhosted.org/packages/f7/87/25babd09b94cb1f03e71db815fde463f0262e40cfbd953d58a8d77311351/greenlet-3.5.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c6ce25fee6cabc8bf22cb8b52e642cbb821be5b9aec8094d07ff03378141b8e9", size = 1691952, upload-time = "2026-08-10T13:40:33.502Z" }, { url = "https://files.pythonhosted.org/packages/2e/3d/5cc9701117ea4dc0eb7bf1f4f9b7888a6e2e5277ddfae095805ace50f2b6/greenlet-3.5.5-cp314-cp314-win_amd64.whl", hash = "sha256:7dffc5c859fe6059974df1e37d7923d654a83e2ae18fdd616994270e001115e1", size = 327458, upload-time = "2026-08-10T13:27:02.868Z" }, @@ -1546,14 +1556,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/24/e0/50cd600b469e5734c72709b6b1838b6bc63f307b573c772c3132d6ecfe92/greenlet-3.5.5-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:0e5a7de979d764aea1f5b6e95cf92b5b37741b9823702041f34b126e7f690277", size = 305471, upload-time = "2026-08-10T13:26:20.568Z" }, { url = "https://files.pythonhosted.org/packages/75/a3/77acd66dfc6387b5219b2080806c0cabb73c10eb1bb44b413c40a62015ba/greenlet-3.5.5-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fef01bd457f11fc158b130ca0027a3c365693280e8e231b65bdaf57999f39f5b", size = 672470, upload-time = "2026-08-10T14:14:39.058Z" }, { url = "https://files.pythonhosted.org/packages/b9/71/0d178142dca3ec19f46fb2212ae73d30ad53b9d548dc64804086033a7089/greenlet-3.5.5-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5173a72310725a74afc82c164f0e52cb8ad0de62f2bb623f24f6c0cc07d80272", size = 679973, upload-time = "2026-08-10T14:27:30.072Z" }, + { url = "https://files.pythonhosted.org/packages/aa/ac/0d7887aa4bbfc9eba075cc428244dfc96f623478454d5ec81180d0d6bd5a/greenlet-3.5.5-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5e9ec2e7c98e895fcea0c5cc57b2606cf86ece6d0a56578f3eb225e2af4f0387", size = 681587, upload-time = "2026-08-10T14:30:13.519Z" }, { url = "https://files.pythonhosted.org/packages/6e/31/46eb8567302eaf787abf88d09df014e14ae3baf460af1b8b0efdbd3efcd5/greenlet-3.5.5-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44f08341873200ba8a60a8bc14ace3d91f1754f7fa7bc66157714a8cd420a476", size = 676634, upload-time = "2026-08-10T13:40:53.004Z" }, + { url = "https://files.pythonhosted.org/packages/4f/18/8d58ba1c429b0383e3219a3d0e0bba241d0444d8ed05b73349953c7d7c7b/greenlet-3.5.5-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:102817506f6090b5176c746a82603341a549b40e5c3d5b72a4c672228a918c41", size = 510175, upload-time = "2026-08-10T14:30:07.047Z" }, { url = "https://files.pythonhosted.org/packages/a3/e9/b88bbf5b29970cb84172dc2c32aa3e5e579ceb94c808e81c826454138850/greenlet-3.5.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d246c0db9a2513cd45f019ba178ea4d4d4705bd210ee465e2c15d76a1ab13874", size = 1637320, upload-time = "2026-08-10T14:15:09.317Z" }, { url = "https://files.pythonhosted.org/packages/6d/8c/7631ed29cc6f0392f11830076e172ce4885e70b0bc2c1bce1731176d4b4e/greenlet-3.5.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:72507285b5caa1d17904a3f7c322ca780823a54170a0e04ec3f37bcc60d4db71", size = 1697412, upload-time = "2026-08-10T13:40:34.924Z" }, { url = "https://files.pythonhosted.org/packages/da/0f/f7dd935f9c4cb1be49098770587f54d8a78518e55c89bce86c4fb4109057/greenlet-3.5.5-cp314-cp314t-win_amd64.whl", hash = "sha256:7805655781fb8f28a55d05fe57ed61f5f10f1892fb587673e3bb5264f28041f0", size = 331514, upload-time = "2026-08-10T13:29:20.611Z" }, { url = "https://files.pythonhosted.org/packages/b7/e5/681b01f8fbc1b55232822f99e8f8afeb78a55a7c76a7bf9dbdc7ccb03a6d/greenlet-3.5.5-cp315-cp315-macosx_11_0_universal2.whl", hash = "sha256:c0db80fcd5b8aece93f66c64f78a786bbb6b96c5fe63ef5a5a4581ecf8bab206", size = 295975, upload-time = "2026-08-10T13:28:45.985Z" }, { url = "https://files.pythonhosted.org/packages/11/f2/69b488cd9e7267bf4b0fe8cdebf25d8d6df680d21bdf41150d23e23d6652/greenlet-3.5.5-cp315-cp315-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b241c32f912ada659808d68e308c568baf577eebf757d15471472de0c18cfad", size = 666823, upload-time = "2026-08-10T14:14:40.222Z" }, { url = "https://files.pythonhosted.org/packages/84/d4/d5bc2fdebbdda0c94555925ba79948b8395d75a7f6a36cc85dce5bab9f11/greenlet-3.5.5-cp315-cp315-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ef6a08349401d8eaf3cb12688ac8557de95788556b8631ef17555a4a173022c0", size = 677613, upload-time = "2026-08-10T14:27:31.543Z" }, + { url = "https://files.pythonhosted.org/packages/65/53/4e13642efc4d7ad6554ecb2242a5be42666b2e1a067323e88dfc0124a04b/greenlet-3.5.5-cp315-cp315-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:37faa97daccb6d9f4c2141ce3118d023c3c5506864a7d8bdf726f665018c1f76", size = 681436, upload-time = "2026-08-10T14:30:14.839Z" }, { url = "https://files.pythonhosted.org/packages/bd/93/542d8a3a90f3b35c6ad8bf7e56a03010287f2cafa289a5b7985b5207db39/greenlet-3.5.5-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f2e3d061b8e13aec2f0441689b3c71b244a20e5d274a52cb0f7e31bd1d139552", size = 675930, upload-time = "2026-08-10T13:40:54.205Z" }, + { url = "https://files.pythonhosted.org/packages/cd/32/188447c9a468d6977d2989397226b0c6b65ab6f4cf943f931643328512fc/greenlet-3.5.5-cp315-cp315-manylinux_2_39_riscv64.whl", hash = "sha256:b18007dc2473a7942fd157366b55f01da6fed7ce85318591005b419e0a439474", size = 487404, upload-time = "2026-08-10T14:30:08.903Z" }, { url = "https://files.pythonhosted.org/packages/52/b5/89c9f2e8460d71101037d47a1feed11928615a5edd42370be290e0657eeb/greenlet-3.5.5-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:9ab5f5b93655e77fe0d6c2dfd22b5eac751bb1f876d8ec21761b7c1fb9266007", size = 1633878, upload-time = "2026-08-10T14:15:10.693Z" }, { url = "https://files.pythonhosted.org/packages/b8/60/297de93f3b02ac78a5e04d32bb8bbe3080f4a73d8ed95016561463b70618/greenlet-3.5.5-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:f0e5a21bd4452a88cf032fc43c4a5b307ab1380eacb63b5988f9c0317885e773", size = 1696597, upload-time = "2026-08-10T13:40:36.252Z" }, { url = "https://files.pythonhosted.org/packages/18/25/54c6eaff4f337fb670215e89eb2d00d9499487b658e709d4b477be4a342e/greenlet-3.5.5-cp315-cp315-win_amd64.whl", hash = "sha256:469dbb0a78625642f4a626cfd0c6e8bccc0385b5e49189b6308bbe849ec88a8e", size = 327700, upload-time = "2026-08-10T13:28:06.752Z" }, @@ -1561,7 +1575,9 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/10/e2/3144c0a116067ac1e30457b0139a94d60d1d36a86e015de68e9ac87cb3bc/greenlet-3.5.5-cp315-cp315t-macosx_11_0_universal2.whl", hash = "sha256:68184dfcf50ccaa8e864770fe0633a7e27250ea9329f8192ef47ee9ecfd78e1c", size = 306387, upload-time = "2026-08-10T13:27:00.897Z" }, { url = "https://files.pythonhosted.org/packages/5c/a1/cb4223a7e9b9f43b8807e8eb212358bfe2dfaa174a9ea2889eb1714dcba2/greenlet-3.5.5-cp315-cp315t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9ec0dc0e59dc9c61af5c47348365ccbbd7addfafe0a93b00336ff3da2907bdc6", size = 676472, upload-time = "2026-08-10T14:14:41.417Z" }, { url = "https://files.pythonhosted.org/packages/9e/cd/a154b4498e5d8f12ada291cfb3b8d596eadde2177f5bf09a9be699d2a446/greenlet-3.5.5-cp315-cp315t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e604f58e35833fc46ef20302bcb314dddbfd3fcf33a4f936216d51dd678d63ae", size = 684238, upload-time = "2026-08-10T14:27:32.946Z" }, + { url = "https://files.pythonhosted.org/packages/ce/f4/e450a68a152f819491d8c7df6a8254e761d87e6a78759268961f8c5bd4dd/greenlet-3.5.5-cp315-cp315t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2888a3a38bc5ee5bb6c438372197152e815837e4fab7ed7a1f86ef18ffd58ad1", size = 686022, upload-time = "2026-08-10T14:30:15.96Z" }, { url = "https://files.pythonhosted.org/packages/bf/bb/b0031d260c2968a3c87deebc51d80c64e499377f993aafe06ee3b7488cc2/greenlet-3.5.5-cp315-cp315t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:40239b5384f96da3963585cc6d7eaa9b56f8ae67e8d92cc82dd9e202fc847de3", size = 681246, upload-time = "2026-08-10T13:40:55.402Z" }, + { url = "https://files.pythonhosted.org/packages/18/23/17e63d6bf3b9c9b9dbea981b7f643a71f79603bdfb4f1c3a9cf353e22aed/greenlet-3.5.5-cp315-cp315t-manylinux_2_39_riscv64.whl", hash = "sha256:1e8d9391fe77f15649589a907cef972dbbd6352ef7ff7dc0492f658c0c26495f", size = 516951, upload-time = "2026-08-10T14:30:10.907Z" }, { url = "https://files.pythonhosted.org/packages/9a/07/da554b71ab88e649da146e1065d86a48a5c5d92e50ab74ef41b504aa7f56/greenlet-3.5.5-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:a1eaccf5c3a1d3e46dead602c72e6836731e8e245c9de6a27764567b6b62d4c0", size = 1642735, upload-time = "2026-08-10T14:15:11.92Z" }, { url = "https://files.pythonhosted.org/packages/78/76/26a3782a051677668af9d92beaa47cd87ba9dd5072f762961144a03dd4c6/greenlet-3.5.5-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:19e4e026fe20691f333b8eb1a3bc9625eceba8c3f9d62ec5a6f8581afbc6b5a5", size = 1700925, upload-time = "2026-08-10T13:40:37.656Z" }, { url = "https://files.pythonhosted.org/packages/28/d9/fe7baf4190c2ae71f267efb9de21b3172bb35bc0ed1ef53dd6027d658e33/greenlet-3.5.5-cp315-cp315t-win_amd64.whl", hash = "sha256:712aee154f648bde84634654bb38bb78c69ac640c37a45c9effed800735049d8", size = 331829, upload-time = "2026-08-10T13:26:48.851Z" }, @@ -1715,7 +1731,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filelock" }, { name = "fsspec" }, - { name = "hf-xet", marker = "platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" }, + { name = "hf-xet", marker = "platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "httpx" }, { name = "packaging" }, { name = "pyyaml" }, @@ -2088,7 +2104,7 @@ name = "langchain-classic" version = "1.0.8" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "async-timeout", marker = "python_full_version < '3.11'" }, + { name = "async-timeout", marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "langchain-core" }, { name = "langchain-text-splitters" }, { name = "langsmith" }, @@ -2113,9 +2129,9 @@ dependencies = [ { name = "langchain-classic" }, { name = "langchain-core" }, { name = "langsmith" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "pydantic-settings" }, { name = "pyyaml" }, { name = "requests" }, @@ -2268,7 +2284,7 @@ dependencies = [ { name = "anyio" }, { name = "distro" }, { name = "httpx" }, - { name = "orjson", marker = "platform_python_implementation != 'PyPy'" }, + { name = "orjson", marker = "platform_python_implementation != 'PyPy' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "packaging" }, { name = "pydantic" }, { name = "requests" }, @@ -2393,12 +2409,12 @@ dependencies = [ { name = "pydantic-settings" }, { name = "pyjwt", extra = ["crypto"] }, { name = "python-multipart" }, - { name = "pywin32", marker = "sys_platform == 'win32'" }, + { name = "pywin32", marker = "sys_platform == 'win32' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "sse-starlette" }, { name = "starlette" }, { name = "typing-extensions" }, { name = "typing-inspection" }, - { name = "uvicorn", marker = "sys_platform != 'emscripten'" }, + { name = "uvicorn", marker = "sys_platform != 'emscripten' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/27/3c/347cf965d313f5d41764e7d46bea6ffe7d9ef13b983cc429b0340962a082/mcp-1.27.2.tar.gz", hash = "sha256:8e02db104096d1c25b28e64bde29a5c32b31bc241710213e12fd4d84985bdfef", size = 621116, upload-time = "2026-05-29T17:16:04.039Z" } wheels = [ @@ -2411,7 +2427,7 @@ version = "1.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "boto3" }, - { name = "botocore", extra = ["crt"], marker = "extra != 'extra-17-bedrock-agentcore-a2a' or extra == 'extra-17-bedrock-agentcore-a2a-v1' or extra == 'group-17-bedrock-agentcore-dev'" }, + { name = "botocore", extra = ["crt"], marker = "(extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra != 'extra-17-bedrock-agentcore-a2a-v1' and extra == 'group-17-bedrock-agentcore-dev') or (extra != 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "fastmcp" }, ] sdist = { url = "https://files.pythonhosted.org/packages/15/a3/19c3ae54c5659edc105261820e13b9224a75e0c957ae8ae9fed7a7db5cb4/mcp_proxy_for_aws-1.6.0.tar.gz", hash = "sha256:b902240aafc087cd0252270bc69a59ec0c3bf971b9679def99479228a3fa48b4", size = 431203, upload-time = "2026-05-29T14:51:10.655Z" } @@ -2471,7 +2487,7 @@ name = "multidict" version = "6.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/80/1e/5492c365f222f907de1039b91f922b93fa4f764c713ee858d235495d8f50/multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5", size = 101834, upload-time = "2025-10-06T14:52:30.657Z" } wheels = [ @@ -3215,10 +3231,10 @@ resolution-markers = [ "python_full_version < '3.11'", ] dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, - { name = "python-dateutil" }, - { name = "pytz" }, - { name = "tzdata" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "python-dateutil", marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "pytz", marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "tzdata", marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } wheels = [ @@ -3290,10 +3306,10 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, - { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, - { name = "python-dateutil" }, - { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "python-dateutil", marker = "python_full_version >= '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "tzdata", marker = "(python_full_version >= '3.11' and sys_platform == 'emscripten') or (python_full_version >= '3.11' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev') or (sys_platform == 'emscripten' and extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (sys_platform == 'emscripten' and extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev') or (sys_platform == 'win32' and extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (sys_platform == 'win32' and extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/be/4f/5f3422a2afec5ffc46308b79e53291365a93748b498ac2e58bead0197916/pandas-3.0.5.tar.gz", hash = "sha256:dca3734d6ab7c906e6730f0788b0a1dbb9f2467731f9711f77995c8e9d62d712", size = 4658219, upload-time = "2026-07-22T22:19:28.819Z" } wheels = [ @@ -3541,7 +3557,7 @@ name = "portalocker" version = "3.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pywin32", marker = "sys_platform == 'win32'" }, + { name = "pywin32", marker = "sys_platform == 'win32' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/5e/77/65b857a69ed876e1951e88aaba60f5ce6120c33703f7cb61a3c894b8c1b6/portalocker-3.2.0.tar.gz", hash = "sha256:1f3002956a54a8c3730586c5c77bf18fae4149e07eaf1c29fc3faf4d5a3f89ac", size = 95644, upload-time = "2025-06-14T13:20:40.03Z" } wheels = [ @@ -3747,8 +3763,8 @@ wheels = [ [package.optional-dependencies] filetree = [ - { name = "aiofile", version = "3.9.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and extra != 'extra-17-bedrock-agentcore-a2a') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, - { name = "aiofile", version = "3.11.1", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and extra != 'extra-17-bedrock-agentcore-a2a') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "aiofile", version = "3.9.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and extra == 'group-17-bedrock-agentcore-dev') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "aiofile", version = "3.11.1", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and extra == 'group-17-bedrock-agentcore-dev') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "anyio" }, ] keyring = [ @@ -3982,7 +3998,7 @@ name = "pyjwt" version = "2.13.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/3b/81/58d0ac84e1ef3a3843791d6954d94c0b33d526c75eeb1efbce9d0a4c4077/pyjwt-2.13.0.tar.gz", hash = "sha256:41571c89ca91598c79e8ef18a2d07367d4810fbbd6f637794879baf1b7703423", size = 107515, upload-time = "2026-05-21T19:54:36.618Z" } wheels = [ @@ -4008,13 +4024,13 @@ name = "pytest" version = "8.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "colorama", marker = "sys_platform == 'win32' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, { name = "pygments" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "tomli", marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } wheels = [ @@ -4026,7 +4042,7 @@ name = "pytest-asyncio" version = "1.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "backports-asyncio-runner", marker = "python_full_version < '3.11'" }, + { name = "backports-asyncio-runner", marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "pytest" }, ] sdist = { url = "https://files.pythonhosted.org/packages/4e/51/f8794af39eeb870e87a8c8068642fc07bce0c854d6865d7dd0f2a9d338c2/pytest_asyncio-1.1.0.tar.gz", hash = "sha256:796aa822981e01b68c12e4827b8697108f7205020f24b5793b3c41555dab68ea", size = 46652, upload-time = "2025-07-16T04:29:26.393Z" } @@ -4039,7 +4055,7 @@ name = "pytest-cov" version = "6.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "coverage", extra = ["toml"], marker = "extra != 'extra-17-bedrock-agentcore-a2a' or extra == 'extra-17-bedrock-agentcore-a2a-v1' or extra == 'group-17-bedrock-agentcore-dev'" }, + { name = "coverage", extra = ["toml"], marker = "(extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra != 'extra-17-bedrock-agentcore-a2a-v1' and extra == 'group-17-bedrock-agentcore-dev') or (extra != 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "pluggy" }, { name = "pytest" }, ] @@ -4238,11 +4254,11 @@ dependencies = [ { name = "langchain-core" }, { name = "langchain-openai" }, { name = "nest-asyncio" }, - { name = "networkx", version = "3.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "networkx", version = "3.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "networkx", version = "3.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "networkx", version = "3.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "openai" }, { name = "pillow" }, { name = "pydantic" }, @@ -4264,7 +4280,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, { name = "rpds-py" }, - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "typing-extensions", marker = "python_full_version < '3.13' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload-time = "2025-01-25T08:48:16.138Z" } wheels = [ @@ -4627,12 +4643,12 @@ name = "scikit-network" version = "0.33.5" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, - { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "scipy", version = "1.18.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, + { name = "scipy", version = "1.18.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/46/6d/28b00fbef9ff7d8ba31861bf16705a1a74a1696fb65aab2a7c584f966bec/scikit_network-0.33.5.tar.gz", hash = "sha256:ae2149d9a280fdc4bbadd5f8a7b17c8af61c054bc3f834792bc61483e6783c12", size = 1784205, upload-time = "2025-11-19T09:45:14.402Z" } wheels = [ @@ -4666,7 +4682,7 @@ resolution-markers = [ "python_full_version < '3.11'", ] dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0f/37/6964b830433e654ec7485e45a00fc9a27cf868d622838f6b6d9c5ec0d532/scipy-1.15.3.tar.gz", hash = "sha256:eae3cf522bc7df64b42cad3925c876e1b0b6c35c1337c93e12c0f366f55b0eaf", size = 59419214, upload-time = "2025-05-08T16:13:05.955Z" } wheels = [ @@ -4727,7 +4743,7 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" } }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7a/97/5a3609c4f8d58b039179648e62dd220f89864f56f7357f5d4f45c29eb2cc/scipy-1.17.1.tar.gz", hash = "sha256:95d8e012d8cb8816c226aef832200b1d45109ed4464303e997c5b13122b297c0", size = 30573822, upload-time = "2026-02-23T00:26:24.851Z" } wheels = [ @@ -4809,7 +4825,7 @@ resolution-markers = [ "python_full_version == '3.12.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" } }, + { name = "numpy", version = "2.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7e/74/66de6258867beb2ef08f35f9f2ac017a52cacd5081714d239ff1a442d458/scipy-1.18.1.tar.gz", hash = "sha256:52c4b7422442aba924d03ad4019852b08a92e64ea187b933135687bfe2747307", size = 30781235, upload-time = "2026-08-21T23:28:50.599Z" } wheels = [ @@ -4880,8 +4896,8 @@ name = "secretstorage" version = "3.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "cryptography", marker = "python_full_version < '3.11' or (sys_platform != 'emscripten' and sys_platform != 'win32')" }, - { name = "jeepney", marker = "python_full_version < '3.11' or (sys_platform != 'emscripten' and sys_platform != 'win32')" }, + { name = "cryptography", marker = "(python_full_version < '3.11' and sys_platform == 'emscripten') or (python_full_version < '3.11' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'win32')" }, + { name = "jeepney", marker = "(python_full_version < '3.11' and sys_platform == 'emscripten') or (python_full_version < '3.11' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'win32')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/1c/03/e834bcd866f2f8a49a85eaff47340affa3bfa391ee9912a952a1faa68c7b/secretstorage-3.5.0.tar.gz", hash = "sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be", size = 19884, upload-time = "2025-11-23T19:02:53.191Z" } wheels = [ @@ -4972,7 +4988,7 @@ name = "sqlalchemy" version = "2.0.52" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, + { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/3b/21/77b4c147963073040dc3c3a5cb7a8c3001a1893c0209432cb77f9df836aa/sqlalchemy-2.0.52.tar.gz", hash = "sha256:5e2d46356ac2ccb7d268ab6c2319ac6a2b42f1b8d5fd8bd3d46855cd82abee97", size = 9945637, upload-time = "2026-08-11T19:07:09.829Z" } @@ -5034,7 +5050,7 @@ version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "typing-extensions", marker = "python_full_version < '3.13' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/eb/e3/7c1dc7381d9f8ab7d854328ebfa884e62cb3f3d8549ddfd37c7814f42afa/starlette-1.3.1.tar.gz", hash = "sha256:05d0213193f2fbaae60e2ecb593b4add4262ad4e46536b54abe36f11a71724e0", size = 2703240, upload-time = "2026-06-12T09:23:11.602Z" } wheels = [ @@ -5106,7 +5122,7 @@ dependencies = [ { name = "sympy" }, { name = "tenacity" }, { name = "typing-extensions" }, - { name = "tzdata", marker = "sys_platform == 'win32'" }, + { name = "tzdata", marker = "sys_platform == 'win32' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "watchdog" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c1/4e/c8c355cd7ca6d28f98231fd66fe5d4627c9ecd9ea79db21980ec429247e9/strands_agents_tools-0.2.22.tar.gz", hash = "sha256:99d202b329f12df8568f104d5301452526640fd0e4db164c0be23e0b22e3d350", size = 474105, upload-time = "2026-03-04T21:19:38.858Z" } @@ -5256,7 +5272,7 @@ name = "tqdm" version = "4.70.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "colorama", marker = "sys_platform == 'win32' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/21/3b/6c24bec5be5e743ffd99576daa5cc077722fc7d5bbc00bd133fa0c698dc6/tqdm-4.70.0.tar.gz", hash = "sha256:55b0b0dbd97462d06ebee91e4dac24ed4d4702be82b24f07e6c1d27e08cea220", size = 795438, upload-time = "2026-07-27T11:33:15.271Z" } wheels = [ @@ -5269,7 +5285,7 @@ version = "0.27.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-doc" }, - { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "colorama", marker = "sys_platform == 'win32' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, { name = "rich" }, { name = "shellingham" }, ] @@ -5447,7 +5463,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "h11" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11' or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'extra-17-bedrock-agentcore-a2a-v1') or (extra == 'extra-17-bedrock-agentcore-a2a' and extra == 'group-17-bedrock-agentcore-dev')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/5e/42/e0e305207bb88c6b8d3061399c6a961ffe5fbb7e2aa63c9234df7259e9cd/uvicorn-0.35.0.tar.gz", hash = "sha256:bc662f087f7cf2ce11a1d7fd70b90c9f98ef2e2831556dd078d131b96cc94a01", size = 78473, upload-time = "2025-06-28T16:15:46.058Z" } wheels = [