Skip to content

Conversation

@martimfasantos
Copy link
Contributor

@martimfasantos martimfasantos commented May 24, 2025

Description

Summary

This PR introduces a A2AFastAPIApplication class that enables serving A2A endpoints using a FastAPI application, while preserving compatibility with the existing JSONRPC Starlette-based architecture.

Motivation

While the SDK currently provides a Starlette-based server app for A2A agent communication using JSONRPC, many production Python APIs are built with FastAPI due to its support for performance, extensibility, automatic OpenAPI schema generation, and strong async capabilities. Providing native FastAPI support enables seamless integration into such environments without requiring users to manually wrap the existing Starlette app.

This addition does not introduce any breaking changes. FastAPI is treated as an optional integration, and the core A2A logic continues to rely on shared base classes and request handlers.

Implementation Details

  • Introduced JSONRPCApplication, an abstract base class that encapsulates the shared request-handling logic for both Starlette and FastAPI JSONRPC applications. This isolates the common behavior, with the only required customization being the build(...) method used to register routes and return the appropriate application instance.

  • Added A2AFastAPIApplication, a concrete implementation of JSONRPCApplication that constructs a FastAPI app with the appropriate routes:

    • POST / (or custom RPC endpoint) for handling A2A JSON-RPC messages.
    • GET /.well-known/agent.json (or custom) for serving the agent card.
  • All request processing is shared via _handle_requests and _handle_get_agent_card.

  • SSE streaming support is preserved for SendStreamingMessageRequest and TaskResubscriptionRequest.

  • Added fastapi to the dependencies in pyproject.toml.

Usage Example

from a2a.server.apps.jsonrpc import A2AFastAPIApplication

app = A2AFastAPIApplication(agent_card=my_agent_card, http_handler=my_handler).build()

Hello World Example (examples/helloword/)

  1. Change A2AStarletteApplication to A2AFastAPIApplication

  2. Start the server

    uv run .

fastapi_app_running
fastapi_app_docs

  1. Run the test client
 uv run test_client.py

fastapi_results_server
fastapi_results_client


Continues #26
Fixes #21 🦕

@martimfasantos martimfasantos requested a review from a team as a code owner May 24, 2025 11:55
@martimfasantos martimfasantos requested a review from a team as a code owner May 31, 2025 18:25
Copy link
Member

@holtskinner holtskinner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's now a backwards-incompatible change:

==================================== ERRORS ====================================
______________ ERROR collecting tests/server/test_integration.py _______________
ImportError while importing test module '/home/runner/work/a2a-python/a2a-python/tests/server/test_integration.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/importlib/__init__.py:1[26](https://github.com/google-a2a/a2a-python/actions/runs/15398882285/job/43326395575#step:7:27): in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/server/test_integration.py:10: in <module>
    from a2a.server.apps.starlette_app import A2AStarletteApplication
src/a2a/server/apps/__init__.py:3: in <module>
    from a2a.server.apps.starlette_app import A2AStarletteApplication
E   ModuleNotFoundError: No module named 'a2a.server.apps.starlette_app'
================================ tests coverage ================================

Can you update the tests to fix this import error and any further usage of a2a.server.apps.starlette_app in the docs/other examples?

@martimfasantos
Copy link
Contributor Author

There's now a backwards-incompatible change:

==================================== ERRORS ====================================
______________ ERROR collecting tests/server/test_integration.py _______________
ImportError while importing test module '/home/runner/work/a2a-python/a2a-python/tests/server/test_integration.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/importlib/__init__.py:1[26](https://github.com/google-a2a/a2a-python/actions/runs/15398882285/job/43326395575#step:7:27): in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/server/test_integration.py:10: in <module>
    from a2a.server.apps.starlette_app import A2AStarletteApplication
src/a2a/server/apps/__init__.py:3: in <module>
    from a2a.server.apps.starlette_app import A2AStarletteApplication
E   ModuleNotFoundError: No module named 'a2a.server.apps.starlette_app'
================================ tests coverage ================================

Can you update the tests to fix this import error and any further usage of a2a.server.apps.starlette_app in the docs/other examples?

Fixed in 54747f8:

  • Updated Starlette test imports
  • Added FastAPI tests

Will update docs/examples after merge, if needed :)

@holtskinner
Copy link
Member

Seems like the tests are still failing

@martimfasantos
Copy link
Contributor Author

Seems like the tests are still failing

@holtskinner Oh right, my bad! The updates for the extended agent card didn't get merged correctly.
Fixed that and the tests too - should be all good now! 🚀

@holtskinner holtskinner enabled auto-merge (squash) June 4, 2025 15:18
@holtskinner holtskinner disabled auto-merge June 4, 2025 15:18
@holtskinner holtskinner changed the title feat: Add FastAPI JSONRPC Application feat!: Add FastAPI JSONRPC Application Jun 4, 2025
@holtskinner holtskinner merged commit 0e66e1f into a2aproject:main Jun 4, 2025
6 checks passed
@martimfasantos martimfasantos deleted the add-fastapi-app branch June 5, 2025 09:59
holtskinner pushed a commit that referenced this pull request Jun 9, 2025
🤖 I have created a release *beep* *boop*
---


##
[0.2.6](v0.2.5...v0.2.6)
(2025-06-09)


### ⚠ BREAKING CHANGES

* Add FastAPI JSONRPC Application
([#104](#104))

### Features

* Add FastAPI JSONRPC Application
([#104](#104))
([0e66e1f](0e66e1f))
* Add gRPC server and client support
([#162](#162))
([a981605](a981605))
* add reject method to task_updater
([#147](#147))
([2a6ef10](2a6ef10))
* Add timestamp to `TaskStatus` updates on `TaskUpdater`
([#140](#140))
([0c9df12](0c9df12))
* **spec:** Add an optional iconUrl field to the AgentCard 🤖
([a1025f4](a1025f4))


### Bug Fixes

* Correctly adapt starlette BaseUser to A2A User
([#133](#133))
([88d45eb](88d45eb))
* Event consumer should stop on input_required
([#167](#167))
([51c2d8a](51c2d8a))
* Fix Release Version
([#161](#161))
([011d632](011d632))
* generate StrEnum types for enums
([#134](#134))
([0c49dab](0c49dab))
* library should released as 0.2.6
([d8187e8](d8187e8))
* remove error types from enqueable events
([#138](#138))
([511992f](511992f))
* **stream:** don't block event loop in EventQueue
([#151](#151))
([efd9080](efd9080))
* **task_updater:** fix potential duplicate artifact_id from default v…
([#156](#156))
([1f0a769](1f0a769))


### Documentation

* remove final and metadata fields from docstring
([#66](#66))
([3c50ee1](3c50ee1))
* Update Links to Documentation Site
([5e7d418](5e7d418))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
holtskinner pushed a commit that referenced this pull request Jul 7, 2025
# Description

## Summary

This PR improves the current implementation of `A2AFastAPIApplication`
class that enables serving A2A endpoints using a FastAPI application.
(#104)

### Implementation Details

Refactors the `add_routes_to_app` method in
`src/a2a/server/apps/jsonrpc/fastapi_app.py` to simplify route
definitions by:

* Directly associating handler methods with FastAPI route decorators
* Removing unnecessary nested async function definitions by directly
passing handler methods (`self._handle_requests`,
`self._handle_get_agent_card`, and
`self._handle_get_authenticated_extended_agent_card`) to the FastAPI
decorators (`app.post` and `app.get`)
* Enabling method descriptions to appear in Swagger documentation,
improving developer experience

These changes make the code more readable, maintainable, and better
integrated with FastAPI's documentation features.


### Screenshots

#### Before

![image](https://github.com/user-attachments/assets/6b9487fe-010f-492d-98cf-9f28d0ad194e)

![image](https://github.com/user-attachments/assets/7fd5edd9-5849-427d-aa74-6cb392ad370b)

#### After

![image](https://github.com/user-attachments/assets/00e7265b-8f5f-4841-a76a-8445be8a3ee6)

![image](https://github.com/user-attachments/assets/6ffd81e7-646c-42fb-ab96-13807cbc00bd)

---

Continues #104 🦕
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat]: A2A FastAPI Application

3 participants