{{ message }}
Repository navigation
Commit ae9dc88
authored
feat: add async context manager support to BaseClient (a2aproject#688)
# Description
Thank you for opening a Pull Request!
Before submitting your PR, there are a few things you can do to make
sure it goes smoothly:
- [x] Follow the [`CONTRIBUTING`
Guide](https://github.com/a2aproject/a2a-python/blob/main/CONTRIBUTING.md).
- [x] Make your Pull Request title in the
<https://www.conventionalcommits.org/> specification.
- Important Prefixes for
[release-please](https://github.com/googleapis/release-please):
- `fix:` which represents bug fixes, and correlates to a
[SemVer](https://semver.org/) patch.
- `feat:` represents a new feature, and correlates to a SemVer minor.
- `feat!:`, or `fix!:`, `refactor!:`, etc., which represent a breaking
change (indicated by the `!`) and will result in a SemVer major.
- [x] Ensure the tests and linter pass (Run `bash scripts/format.sh`
from the repository root to format)
- [x] Appropriate docs were updated (if necessary)
Follow-up to a2aproject#682, as suggested by @ishymko in the
[review](a2aproject#682 (review)).
This extends the async context manager pattern to `BaseClient`, which
wraps `ClientTransport` and also exposes a `close()` method.
Fixes a2aproject#674 🦕
## Problem
`BaseClient` delegates resource cleanup to its underlying
`ClientTransport` via `close()`, but doesn't implement
`__aenter__`/`__aexit__`. This means clients cannot be used with `async
with`, leading to the same resource leak risk that a2aproject#682 solved for
transports:
```python
client = BaseClient(card=card, config=config, transport=transport, consumers=[], middleware=[])
result = await client.send_message(msg) # if this raises, close() is never called
await client.close()
```
## Fix
Added `__aenter__` and `__aexit__` methods to `BaseClient` in
`src/a2a/client/base_client.py`:
`__aenter__` returns `self`
`__aexit__ `awaits `close()`
This enables the standard async context manager pattern:
```python
async with BaseClient(card=card, config=config, transport=transport, consumers=[], middleware=[]) as client:
async for event in client.send_message(msg):
...
# close() called automatically, even on exceptions
```
This is a non-breaking, additive change. Calling `close()` manually or
via `try/finally` continues to work exactly as before.
## Test
Tests were added to `tests/client/test_base_client.py`, following the
same approach as the `ClientTransport` tests from a2aproject#682.
Release-As: 0.3.231 parent d3c973f commit ae9dc88
2 files changed
Lines changed: 36 additions & 0 deletions

0 commit comments