Skip to content

fix: Use POST method for REST endpoint /tasks/{id}:subscribe#843

Merged
bartek-w merged 2 commits into1.0-devfrom
bartekw-subscribe-post
Mar 17, 2026
Merged

fix: Use POST method for REST endpoint /tasks/{id}:subscribe#843
bartek-w merged 2 commits into1.0-devfrom
bartekw-subscribe-post

Conversation

@bartek-w
Copy link
Collaborator

POST should be always use for /tasks/{id}:subscribe.
Decisions for backward compatibility with invalid protocol implementations:
1.0 server: Accept both POST and GET
1.0 client: Always use POST
0.3 server: Accept both POST and GET
0.3 client: Try POST first, on HTTP 405 error retry with GET. Cache the retry state to ensure that there is at most one retry attempt per transport instance.

Fixes #840

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request standardizes the /tasks/{id}:subscribe endpoint to primarily use the POST method, which is more appropriate for operations that involve sending data in the request body. It introduces robust backward compatibility mechanisms, allowing both newer and older clients and servers to interact seamlessly without breaking existing integrations. The changes ensure that the system is more resilient to varying client behaviors and server configurations, while also improving the robustness of error handling for HTTP responses.

Highlights

  • Standardized Subscription Method: The /tasks/{id}:subscribe endpoint now consistently uses the POST method across both client and server implementations for version 1.0, aligning with REST best practices for operations that send data in the request body.
  • Backward Compatibility for v0.3 Clients: Version 0.3 clients are updated to first attempt a POST request for task subscriptions and gracefully fall back to a GET request if a 405 Method Not Allowed error is received, caching this preference for subsequent calls on the same transport instance.
  • Backward Compatibility for v0.3 Servers: Version 0.3 servers are configured to accept both POST and GET requests for the /v1/tasks/{id}:subscribe endpoint, ensuring compatibility with older clients that might still use GET.
  • Robust Error Handling: Improved error handling in the v0.3 REST transport to prevent crashes when encountering non-JSON error responses from the server by gracefully handling JSON decoding failures.
  • Request Body Parsing: The server-side handler for task subscriptions now correctly parses the request body for POST requests, allowing subscription parameters to be sent in the request payload.
Changelog
  • src/a2a/client/transports/rest.py
    • Changed the subscribe method to use 'POST' instead of 'GET' for the /tasks/{id}:subscribe endpoint.
    • Added json=MessageToDict(request) to the _send_stream_request call to send the request body.
  • src/a2a/compat/v0_3/rest_adapter.py
    • Added a route to handle 'POST' requests for /v1/tasks/{id}:subscribe by mapping it to on_subscribe_to_task.
  • src/a2a/compat/v0_3/rest_transport.py
    • Initialized _subscribe_method to 'POST' and _subscribe_retry_attempted to False for retry logic.
    • Implemented retry logic in the subscribe method: it now attempts 'POST' first, falls back to 'GET' on a 405 error, and caches the method preference.
    • Enhanced _handle_http_error to catch json.JSONDecodeError, ValueError, and httpx.ResponseNotRead when parsing error responses, defaulting to an empty dictionary if JSON decoding fails.
  • src/a2a/server/apps/rest/rest_adapter.py
    • Added a route to handle 'POST' requests for /tasks/{id}:subscribe by mapping it to on_subscribe_to_task.
  • src/a2a/server/request_handlers/rest_handler.py
    • Modified on_subscribe_to_task to parse the request body for SubscribeToTaskRequest parameters when the request method is 'POST'.
  • tests/client/transports/test_rest_client.py
    • Updated the test_streaming_client_methods test to assert that the subscribe method uses 'POST' and sends the request object as JSON.
  • tests/compat/v0_3/test_rest_handler.py
    • Added test_on_subscribe_to_task_post to verify that the on_subscribe_to_task handler correctly processes POST requests with a body.
  • tests/compat/v0_3/test_rest_transport.py
    • Added helper functions create_405_error and create_500_error for testing error scenarios.
    • Added test_compat_rest_transport_subscribe_post_works_no_retry to confirm POST works without retry.
    • Added test_compat_rest_transport_subscribe_post_405_retry_get_success to test the POST-to-GET retry mechanism on 405.
    • Added test_compat_rest_transport_subscribe_post_405_get_405_fails to test failure when both POST and GET return 405.
    • Added test_compat_rest_transport_subscribe_post_500_no_retry to ensure no retry occurs on 500 errors.
  • tests/server/apps/rest/test_rest_fastapi_app.py
    • Updated the agent_card fixture to enable streaming capabilities.
    • Added test_subscribe_to_task_get to verify GET requests to /tasks/{id}:subscribe.
    • Added test_subscribe_to_task_post to verify POST requests to /tasks/{id}:subscribe with a request body.
    • Modified configure_mocks to set a default mock for on_subscribe_to_task.
    • Added new test cases for test_tenant_extraction to include GET and POST for /tasks/1:subscribe.
Activity
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link

github-actions bot commented Mar 17, 2026

🧪 Code Coverage (vs 1.0-dev)

⬇️ Download Full Report

No coverage changes.

Generated by coverage-comment.yml

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request correctly updates the /tasks/{id}:subscribe endpoint to use the POST method, aligning with REST principles. The changes include backward compatibility for older protocol versions, allowing servers to accept both GET and POST, and implementing a retry mechanism in the v0.3 client. The implementation is well-tested, covering various scenarios including the new retry logic. I've identified one potential bug in the v0.3 client implementation and a small improvement for one of the tests.

@bartek-w bartek-w force-pushed the bartekw-subscribe-post branch 2 times, most recently from b0c84a1 to 0c33d48 Compare March 17, 2026 07:58
@bartek-w bartek-w changed the title Fix: Use POST method for REST endpoint /tasks/{id}:subscribe fix: Use POST method for REST endpoint /tasks/{id}:subscribe Mar 17, 2026
@bartek-w bartek-w requested a review from ishymko March 17, 2026 08:03
@bartek-w bartek-w marked this pull request as ready for review March 17, 2026 08:03
@bartek-w bartek-w requested a review from a team as a code owner March 17, 2026 08:03
Copy link
Member

@ishymko ishymko left a comment

Choose a reason for hiding this comment

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

Thank you for this! Feel free to follow-up on comments via a separate PR. This should be good for alpha.0

@bartek-w bartek-w force-pushed the bartekw-subscribe-post branch from 9e8d624 to 7a9477d Compare March 17, 2026 10:01
Copy link
Member

@ishymko ishymko left a comment

Choose a reason for hiding this comment

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

LGTM, but linter is unhappy.

@bartek-w bartek-w force-pushed the bartekw-subscribe-post branch from 7a9477d to c842e3e Compare March 17, 2026 10:12
@bartek-w bartek-w merged commit a0827d0 into 1.0-dev Mar 17, 2026
9 checks passed
@bartek-w bartek-w deleted the bartekw-subscribe-post branch March 17, 2026 10:14
ishymko added a commit that referenced this pull request Mar 17, 2026
🤖 I have created a release *beep* *boop*
---


### ⚠ BREAKING CHANGES

* **spec**: upgrade SDK to A2A 1.0 spec and use proto-based types
([#572](#572),
[#665](#665),
[#804](#804),
[#765](#765))
* **client:** introduce ServiceParameters for extensions and include it
in ClientCallContext
([#784](#784))
* **client:** rename "callback" -> "push_notification_config"
([#749](#749))
* **client:** transport agnostic interceptors
([#796](#796))
([a910cbc](a910cbc))
* add `protocol_version` column to Task and PushNotificationConfig
models and create a migration
([#789](#789))
([2e2d431](2e2d431))
* **server:** implement `Resource Scoping` for tasks and push
notifications
([#709](#709))
([f0d4669](f0d4669))

### Features

* add GetExtendedAgentCardRequest as input parameter to
GetExtendedAgentCard method
([#767](#767))
([13a092f](13a092f))
* add validation for the JSON-RPC version
([#808](#808))
([6eb7e41](6eb7e41))
* **client:** expose close() and async context manager support on
abstract Client
([#719](#719))
([e25ba7b](e25ba7b))
* **compat:** AgentCard backward compatibility helpers and tests
([#760](#760))
([81f3494](81f3494))
* **compat:** GRPC client compatible with 0.3 server
([#779](#779))
([0ebca93](0ebca93))
* **compat:** GRPC server compatible with 0.3 client
([#772](#772))
([80d827a](80d827a))
* **compat:** legacy v0.3 protocol models, conversion logic and
utilities ([#754](#754))
([26835ad](26835ad))
* **compat:** REST and JSONRPC clients compatible with 0.3 servers
([#798](#798))
([08794f7](08794f7))
* **compat:** REST and JSONRPC servers compatible with 0.3 clients
([#795](#795))
([9856054](9856054))
* **compat:** set a2a-version header to 1.0.0
([#764](#764))
([4cb68aa](4cb68aa))
* **compat:** unify v0.3 REST url prefix and expand cross-version tests
([#820](#820))
([0925f0a](0925f0a))
* database forward compatibility: make `owner` field optional
([#812](#812))
([cc29d1f](cc29d1f))
* handle tenant in Client
([#758](#758))
([5b354e4](5b354e4))
* implement missing push notifications related methods
([#711](#711))
([041f0f5](041f0f5))
* implement rich gRPC error details per A2A v1.0 spec
([#790](#790))
([245eca3](245eca3))
* **rest:** add tenant support to rest
([#773](#773))
([4771b5a](4771b5a))
* send task as a first subscribe event
([#716](#716))
([e71ac62](e71ac62))
* **server, grpc:** Implement tenant context propagation for gRPC
requests. ([#781](#781))
([164f919](164f919))
* **server, json-rpc:** Implement tenant context propagation for
JSON-RPC requests.
([#778](#778))
([72a330d](72a330d))
* **server:** add v0.3 legacy compatibility for database models
([#783](#783))
([08c491e](08c491e))
* **spec:** add `tasks/list` method with filtering and pagination to the
specification
([#511](#511))
([d5818e5](d5818e5))
* use StreamResponse as push notifications payload
([#724](#724))
([a149a09](a149a09))
* **rest:** update REST error handling to use `google.rpc.Status`
([#838](#838))
([ea7d3ad](ea7d3ad))


### Bug Fixes

* add history length and page size validations
([#726](#726))
([e67934b](e67934b))
* allign error codes with the latest spec
([#826](#826))
([709b1ff](709b1ff))
* **client:** align send_message signature with BaseClient
([#740](#740))
([57cb529](57cb529))
* get_agent_card trailing slash when agent_card_path=""
([#799](#799))
([#800](#800))
([a55c97e](a55c97e))
* handle parsing error in REST
([#806](#806))
([bbd09f2](bbd09f2))
* Improve error handling for Timeout exceptions on REST and JSON-RPC
clients ([#690](#690))
([2acd838](2acd838))
* Improve streaming errors handling
([#576](#576))
([7ea7475](7ea7475))
* properly handle unset and zero history length
([#717](#717))
([72a1007](72a1007))
* return entire history when history_length=0
([#537](#537))
([acdc0de](acdc0de))
* return mandatory fields from list_tasks
([#710](#710))
([6132053](6132053))
* taskslist error on invalid page token and response serialization
([#814](#814))
([a102d31](a102d31))
* use correct REST path for Get Extended Agent Card operation
([#769](#769))
([ced3f99](ced3f99))
* Use POST method for REST endpoint /tasks/{id}:subscribe
([#843](#843))
([a0827d0](a0827d0))

---
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: Ivan Shymko <ishymko@google.com>
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.

2 participants