Skip to content

Commit 3a8babf

Browse files
committed
2 parents 064496c + 03fa4c2 commit 3a8babf

File tree

25 files changed

+976
-26
lines changed

25 files changed

+976
-26
lines changed

.github/actions/spelling/allow.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,14 @@ initdb
4747
inmemory
4848
INR
4949
isready
50+
jku
5051
JPY
5152
JSONRPCt
53+
jwk
54+
jwks
5255
JWS
56+
jws
57+
kid
5358
kwarg
5459
langgraph
5560
lifecycles

.github/workflows/stale.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ name: Mark stale issues and pull requests
77

88
on:
99
schedule:
10-
# Scheduled to run at 10.30PM UTC everyday (1530PDT/1430PST)
10+
# Scheduled to run at 10.30PM UTC every day (1530PDT/1430PST)
1111
- cron: "30 22 * * *"
1212
workflow_dispatch:
1313

CHANGELOG.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22

3+
## [0.3.21](https://github.com/a2aproject/a2a-python/compare/v0.3.20...v0.3.21) (2025-12-12)
4+
5+
6+
### Documentation
7+
8+
* Fixing typos ([#586](https://github.com/a2aproject/a2a-python/issues/586)) ([5fea21f](https://github.com/a2aproject/a2a-python/commit/5fea21fb34ecea55e588eb10139b5d47020a76cb))
9+
310
## [0.3.20](https://github.com/a2aproject/a2a-python/compare/v0.3.19...v0.3.20) (2025-12-03)
411

512

@@ -101,7 +108,7 @@
101108
### Bug Fixes
102109

103110
* apply `history_length` for `message/send` requests ([#498](https://github.com/a2aproject/a2a-python/issues/498)) ([a49f94e](https://github.com/a2aproject/a2a-python/commit/a49f94ef23d81b8375e409b1c1e51afaf1da1956))
104-
* **client:** `A2ACardResolver.get_agent_card` will auto-populate with `agent_card_path` when `relative_card_path` is empty ([#508](https://github.com/a2aproject/a2a-python/issues/508)) ([ba24ead](https://github.com/a2aproject/a2a-python/commit/ba24eadb5b6fcd056a008e4cbcef03b3f72a37c3))
111+
* **client:** `A2ACardResolver.get_agent_card` will autopopulate with `agent_card_path` when `relative_card_path` is empty ([#508](https://github.com/a2aproject/a2a-python/issues/508)) ([ba24ead](https://github.com/a2aproject/a2a-python/commit/ba24eadb5b6fcd056a008e4cbcef03b3f72a37c3))
105112

106113

107114
### Documentation
@@ -438,8 +445,8 @@
438445
* Event consumer should stop on input_required ([#167](https://github.com/a2aproject/a2a-python/issues/167)) ([51c2d8a](https://github.com/a2aproject/a2a-python/commit/51c2d8addf9e89a86a6834e16deb9f4ac0e05cc3))
439446
* Fix Release Version ([#161](https://github.com/a2aproject/a2a-python/issues/161)) ([011d632](https://github.com/a2aproject/a2a-python/commit/011d632b27b201193813ce24cf25e28d1335d18e))
440447
* generate StrEnum types for enums ([#134](https://github.com/a2aproject/a2a-python/issues/134)) ([0c49dab](https://github.com/a2aproject/a2a-python/commit/0c49dabcdb9d62de49fda53d7ce5c691b8c1591c))
441-
* library should released as 0.2.6 ([d8187e8](https://github.com/a2aproject/a2a-python/commit/d8187e812d6ac01caedf61d4edaca522e583d7da))
442-
* remove error types from enqueable events ([#138](https://github.com/a2aproject/a2a-python/issues/138)) ([511992f](https://github.com/a2aproject/a2a-python/commit/511992fe585bd15e956921daeab4046dc4a50a0a))
448+
* library should be released as 0.2.6 ([d8187e8](https://github.com/a2aproject/a2a-python/commit/d8187e812d6ac01caedf61d4edaca522e583d7da))
449+
* remove error types from enqueueable events ([#138](https://github.com/a2aproject/a2a-python/issues/138)) ([511992f](https://github.com/a2aproject/a2a-python/commit/511992fe585bd15e956921daeab4046dc4a50a0a))
443450
* **stream:** don't block event loop in EventQueue ([#151](https://github.com/a2aproject/a2a-python/issues/151)) ([efd9080](https://github.com/a2aproject/a2a-python/commit/efd9080b917c51d6e945572fd123b07f20974a64))
444451
* **task_updater:** fix potential duplicate artifact_id from default v… ([#156](https://github.com/a2aproject/a2a-python/issues/156)) ([1f0a769](https://github.com/a2aproject/a2a-python/commit/1f0a769c1027797b2f252e4c894352f9f78257ca))
445452

Gemini.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
- uv as package manager
55

66
## How to run all tests
7-
1. If dependencies are not installed install them using following command
7+
1. If dependencies are not installed, install them using the following command
88
```
99
uv sync --all-extras
1010
```

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ grpc = ["grpcio>=1.60", "grpcio-tools>=1.60", "grpcio_reflection>=1.7.0"]
3535
telemetry = ["opentelemetry-api>=1.33.0", "opentelemetry-sdk>=1.33.0"]
3636
postgresql = ["sqlalchemy[asyncio,postgresql-asyncpg]>=2.0.0"]
3737
mysql = ["sqlalchemy[asyncio,aiomysql]>=2.0.0"]
38+
signing = ["PyJWT>=2.0.0"]
3839
sqlite = ["sqlalchemy[asyncio,aiosqlite]>=2.0.0"]
3940

4041
sql = ["a2a-sdk[postgresql,mysql,sqlite]"]
@@ -45,6 +46,7 @@ all = [
4546
"a2a-sdk[encryption]",
4647
"a2a-sdk[grpc]",
4748
"a2a-sdk[telemetry]",
49+
"a2a-sdk[signing]",
4850
]
4951

5052
[project.urls]
@@ -86,6 +88,7 @@ style = "pep440"
8688
dev = [
8789
"datamodel-code-generator>=0.30.0",
8890
"mypy>=1.15.0",
91+
"PyJWT>=2.0.0",
8992
"pytest>=8.3.5",
9093
"pytest-asyncio>=0.26.0",
9194
"pytest-cov>=6.1.1",

src/a2a/client/base_client.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from collections.abc import AsyncIterator
1+
from collections.abc import AsyncIterator, Callable
22
from typing import Any
33

44
from a2a.client.client import (
@@ -261,6 +261,7 @@ async def get_card(
261261
*,
262262
context: ClientCallContext | None = None,
263263
extensions: list[str] | None = None,
264+
signature_verifier: Callable[[AgentCard], None] | None = None,
264265
) -> AgentCard:
265266
"""Retrieves the agent's card.
266267
@@ -270,12 +271,15 @@ async def get_card(
270271
Args:
271272
context: The client call context.
272273
extensions: List of extensions to be activated.
274+
signature_verifier: A callable used to verify the agent card's signatures.
273275
274276
Returns:
275277
The `AgentCard` for the agent.
276278
"""
277279
card = await self._transport.get_card(
278-
context=context, extensions=extensions
280+
context=context,
281+
extensions=extensions,
282+
signature_verifier=signature_verifier,
279283
)
280284
self._card = card
281285
return card

src/a2a/client/client.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ async def get_card(
185185
*,
186186
context: ClientCallContext | None = None,
187187
extensions: list[str] | None = None,
188+
signature_verifier: Callable[[AgentCard], None] | None = None,
188189
) -> AgentCard:
189190
"""Retrieves the agent's card."""
190191

src/a2a/client/client_factory.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ def minimal_agent_card(
256256
"""Generates a minimal card to simplify bootstrapping client creation.
257257
258258
This minimal card is not viable itself to interact with the remote agent.
259-
Instead this is a short hand way to take a known url and transport option
259+
Instead this is a shorthand way to take a known url and transport option
260260
and interact with the get card endpoint of the agent server to get the
261261
correct agent card. This pattern is necessary for gRPC based card access
262262
as typically these servers won't expose a well known path card.

src/a2a/client/transports/base.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from abc import ABC, abstractmethod
2-
from collections.abc import AsyncGenerator
2+
from collections.abc import AsyncGenerator, Callable
33

44
from a2a.client.middleware import ClientCallContext
55
from a2a.types import (
@@ -103,6 +103,7 @@ async def get_card(
103103
*,
104104
context: ClientCallContext | None = None,
105105
extensions: list[str] | None = None,
106+
signature_verifier: Callable[[AgentCard], None] | None = None,
106107
) -> AgentCard:
107108
"""Retrieves the AgentCard."""
108109

src/a2a/client/transports/grpc.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import logging
22

3-
from collections.abc import AsyncGenerator
3+
from collections.abc import AsyncGenerator, Callable
44

55

66
try:
@@ -223,6 +223,7 @@ async def get_card(
223223
*,
224224
context: ClientCallContext | None = None,
225225
extensions: list[str] | None = None,
226+
signature_verifier: Callable[[AgentCard], None] | None = None,
226227
) -> AgentCard:
227228
"""Retrieves the agent's card."""
228229
card = self.agent_card
@@ -236,6 +237,9 @@ async def get_card(
236237
metadata=self._get_grpc_metadata(extensions),
237238
)
238239
card = proto_utils.FromProto.agent_card(card_pb)
240+
if signature_verifier is not None:
241+
signature_verifier(card)
242+
239243
self.agent_card = card
240244
self._needs_extended_card = False
241245
return card

0 commit comments

Comments
 (0)