Skip to content

Commit 7cdef10

Browse files
Merge branch 'updates' of https://github.com/google/a2a-python into updates
2 parents 50539f4 + 52117a7 commit 7cdef10

37 files changed

+238
-136
lines changed

.github/actions/spelling/allow.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,24 @@ ACard
22
AClient
33
AError
44
AFast
5+
AGrpc
56
ARequest
67
ARun
78
AServer
89
AServers
10+
AService
911
AStarlette
1012
EUR
1113
GBP
1214
INR
1315
JPY
1416
JSONRPCt
1517
Llm
18+
RUF
1619
aconnect
1720
adk
1821
agentic
22+
aio
1923
autouse
2024
cla
2125
cls
@@ -34,6 +38,7 @@ linting
3438
oauthoidc
3539
opensource
3640
protoc
41+
pyi
3742
pyversions
3843
socio
3944
sse

.github/actions/spelling/excludes.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@
8585
\.zip$
8686
^\.github/actions/spelling/
8787
^\.github/workflows/
88-
^\Qsrc/a2a/auth/__init__.py\E$
89-
^\Qsrc/a2a/server/request_handlers/context.py\E$
9088
CHANGELOG.md
9189
noxfile.py
90+
^src/a2a/grpc/

.github/linters/.jscpd.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"ignore": ["**/.github/**", "**/.git/**", "**/tests/**", "**/examples/**"],
2+
"ignore": ["**/.github/**", "**/.git/**", "**/tests/**", "**/src/a2a/grpc/**", "**/.nox/**", "**/.venv/**"],
33
"threshold": 3,
44
"reporters": ["html", "markdown"]
55
}

.ruff.toml renamed to .github/linters/.ruff.toml

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,22 @@ target-version = "py310" # Minimum Python version
1313

1414
[lint]
1515
ignore = [
16-
"COM812",
17-
"FBT001",
18-
"FBT002",
19-
"D203",
20-
"D213",
21-
"D100", # Ignore Missing docstring in public module (often desired at top level __init__.py)
22-
"D104", # Ignore Missing docstring in public package (often desired at top level __init__.py)
23-
"D107", # Ignore Missing docstring in __init__ (use class docstring)
24-
"TD002", # Ignore Missing author in TODOs (often not required)
25-
"TD003", # Ignore Missing issue link in TODOs (often not required/available)
26-
"T201", # Ignore print presence
16+
"COM812", # Trailing comma missing.
17+
"FBT001", # Boolean positional arg in function definition
18+
"FBT002", # Boolean default value in function definition
19+
"D203", # 1 blank line required before class docstring (Google: 0)
20+
"D213", # Multi-line docstring summary should start at the second line (Google: first line)
21+
"D100", # Ignore Missing docstring in public module (often desired at top level __init__.py)
22+
"D104", # Ignore Missing docstring in public package (often desired at top level __init__.py)
23+
"D107", # Ignore Missing docstring in __init__ (use class docstring)
24+
"TD002", # Ignore Missing author in TODOs (often not required)
25+
"TD003", # Ignore Missing issue link in TODOs (often not required/available)
26+
"T201", # Ignore print presence
2727
"RUF012", # Ignore Mutable class attributes should be annotated with `typing.ClassVar`
28-
"RUF013", # Ignore implicit optional
28+
"E501", # Ignore line length (handled by Ruff's dynamic line length)
29+
"ANN002",
30+
"ANN003",
31+
"ANN401",
2932
]
3033

3134
select = [
@@ -46,12 +49,14 @@ select = [
4649
"PTH",# flake8-use-pathlib (use pathlib instead of os.path where possible)
4750
"PL", # Pylint rules ported to Ruff (PLC, PLE, PLR, PLW)
4851
"PIE",# flake8-pie (misc code improvements, e.g., no-unnecessary-pass)
49-
"RUF",# Ruff-specific rules (e.g., RUF001-003 ambiguous unicode)
52+
"RUF",# Ruff-specific rules (e.g., RUF001-003 ambiguous unicode, RUF013 implicit optional)
5053
"RET",# flake8-return (consistency in return statements)
5154
"SLF",# flake8-self (check for private member access via `self`)
5255
"TID",# flake8-tidy-imports (relative imports, banned imports - configure if needed)
5356
"YTT",# flake8-boolean-trap (checks for boolean positional arguments, truthiness tests - Google Style §3.10)
5457
"TD", # flake8-todos (check TODO format - Google Style §3.7)
58+
"TCH",# flake8-type-checking (helps manage TYPE_CHECKING blocks and imports)
59+
"PYI",# flake8-pyi (best practices for .pyi stub files, some rules are useful for .py too)
5560
]
5661

5762
exclude = [
@@ -76,7 +81,8 @@ exclude = [
7681
"node_modules",
7782
"venv",
7883
"*/migrations/*",
79-
"test_*",
84+
"noxfile.py",
85+
"src/a2a/grpc/*.*",
8086
]
8187

8288
[lint.isort]
@@ -94,6 +100,8 @@ lines-between-types = 1
94100

95101
[lint.pydocstyle]
96102
convention = "google"
103+
ignore-decorators = ["typing.overload", "abc.abstractmethod"]
104+
ignore-var-parameters = true
97105

98106
[lint.flake8-annotations]
99107
mypy-init-return = true
@@ -113,11 +121,26 @@ inline-quotes = "single"
113121

114122
[lint.per-file-ignores]
115123
"__init__.py" = ["F401", "D", "ANN"] # Ignore unused imports in __init__.py
116-
"*_test.py" = ["D", "ANN"] # Ignore docstring and annotation issues in test files
117-
"test_*.py" = ["D", "ANN"] # Ignore docstring and annotation issues in test files
124+
"*_test.py" = [
125+
"D", # All pydocstyle rules
126+
"ANN", # Missing type annotation for function argument
127+
"RUF013", # Implicit optional type in test function signatures
128+
"S101", # Use of `assert` detected (expected in tests)
129+
"PLR2004",
130+
"SLF001",
131+
]
132+
"test_*.py" = [
133+
"D",
134+
"ANN",
135+
"RUF013",
136+
"S101",
137+
"PLR2004",
138+
"SLF001",
139+
]
118140
"types.py" = ["D", "E501", "N815"] # Ignore docstring and annotation issues in types.py
119141

120142
[format]
143+
exclude = ["types.py", "src/a2a/grpc/**"]
121144
docstring-code-format = true
122145
docstring-code-line-length = "dynamic" # Or set to 80
123146
quote-style = "single"

.github/workflows/linter.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,5 @@ jobs:
6363
VALIDATE_TYPESCRIPT_STANDARD: false
6464
VALIDATE_GIT_COMMITLINT: false
6565
PYTHON_MYPY_CONFIG_FILE: .mypy.ini
66-
FILTER_REGEX_INCLUDE: "^src/**"
66+
FILTER_REGEX_INCLUDE: ".*src/**/*"
6767
PYTHON_RUFF_CONFIG_FILE: .ruff.toml

.vscode/settings.json

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,17 @@
77
"editor.defaultFormatter": "charliermarsh.ruff",
88
"editor.formatOnSave": true,
99
"editor.codeActionsOnSave": {
10-
"source.organizeImports": "always"
10+
"source.organizeImports": "always",
11+
"source.fixAll.ruff": "explicit"
1112
}
1213
},
13-
"ruff.importStrategy": "fromEnvironment"
14+
"ruff.importStrategy": "fromEnvironment",
15+
"ruff.lint.args": [
16+
"--config",
17+
".github/linters/.ruff.toml"
18+
],
19+
"ruff.format.args": [
20+
"--config",
21+
".github/linters/.ruff.toml"
22+
]
1423
}

noxfile.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737

3838
@nox.session(python=DEFAULT_PYTHON_VERSION)
39-
def format(session):
39+
def format(session) -> None:
4040
"""Format Python code using autoflake, pyupgrade, and ruff."""
4141
# Sort Spelling Allowlist
4242
spelling_allow_file = '.github/actions/spelling/allow.txt'
@@ -141,10 +141,14 @@ def format(session):
141141
'ruff',
142142
'check',
143143
'--fix-only',
144+
'--config',
145+
'.github/linters/.ruff.toml',
144146
*lint_paths_py,
145147
)
146148
session.run(
147149
'ruff',
148150
'format',
151+
'--config',
152+
'.github/linters/.ruff.toml',
149153
*lint_paths_py,
150154
)

src/a2a/auth/user.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ class UnauthenticatedUser(User):
2121
"""A representation that no user has been authenticated in the request."""
2222

2323
@property
24-
def is_authenticated(self):
24+
def is_authenticated(self) -> bool:
25+
"""Returns whether the current user is authenticated."""
2526
return False
2627

2728
@property
2829
def user_name(self) -> str:
30+
"""Returns the user name of the current user."""
2931
return ''

src/a2a/server/agent_execution/agent_executor.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ class AgentExecutor(ABC):
1212
"""
1313

1414
@abstractmethod
15-
async def execute(self, context: RequestContext, event_queue: EventQueue):
15+
async def execute(
16+
self, context: RequestContext, event_queue: EventQueue
17+
) -> None:
1618
"""Execute the agent's logic for a given request context.
1719
1820
The agent should read necessary information from the `context` and
@@ -27,7 +29,9 @@ async def execute(self, context: RequestContext, event_queue: EventQueue):
2729
"""
2830

2931
@abstractmethod
30-
async def cancel(self, context: RequestContext, event_queue: EventQueue):
32+
async def cancel(
33+
self, context: RequestContext, event_queue: EventQueue
34+
) -> None:
3135
"""Request the agent to cancel an ongoing task.
3236
3337
The agent should attempt to stop the task identified by the task_id

src/a2a/server/agent_execution/context.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class RequestContext:
2020
tasks.
2121
"""
2222

23-
def __init__(
23+
def __init__( # noqa: PLR0913
2424
self,
2525
request: MessageSendParams | None = None,
2626
task_id: str | None = None,
@@ -37,6 +37,7 @@ def __init__(
3737
context_id: The ID of the context explicitly provided in the request or path.
3838
task: The existing `Task` object retrieved from the store, if any.
3939
related_tasks: A list of other tasks related to the current request (e.g., for tool use).
40+
call_context: The server call context associated with this request.
4041
"""
4142
if related_tasks is None:
4243
related_tasks = []
@@ -64,7 +65,7 @@ def __init__(
6465
else:
6566
self._check_or_generate_context_id()
6667

67-
def get_user_input(self, delimiter='\n') -> str:
68+
def get_user_input(self, delimiter: str = '\n') -> str:
6869
"""Extracts text content from the user's message parts.
6970
7071
Args:
@@ -80,7 +81,7 @@ def get_user_input(self, delimiter='\n') -> str:
8081

8182
return get_message_text(self._params.message, delimiter)
8283

83-
def attach_related_task(self, task: Task):
84+
def attach_related_task(self, task: Task) -> None:
8485
"""Attaches a related task to the context.
8586
8687
This is useful for scenarios like tool execution where a new task

0 commit comments

Comments
 (0)