Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optionally return response data when calling services through the API #115046

Merged

Conversation

iamjackg
Copy link
Contributor

@iamjackg iamjackg commented Apr 6, 2024

Proposed change

This PR adds support for a new query/JSON parameter called return_response when calling /api/services/<domain>/<service>. It allows users to retrieve service response data instead of state changes when calling a service using the API. If the parameter is present in the query (?return_response) or in the JSON body ("return_response": true) the API call will return the service response data instead of the usual list of changed states.

If the service is SupportsResponse.ONLY and the parameter is not present, the API will return an error.
If the service is SupportsResponse.NONE and the parameter is present, the API will return an error.

It's slightly convoluted, but I didn't want to break existing functionality/expectations for people who are relying on the call always returning the changed states.

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Deprecation (breaking change to happen in the future)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

Checklist

  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • I have followed the perfect PR recommendations
  • The code has been formatted using Ruff (ruff format homeassistant tests)
  • Tests have been added to verify that the new code works.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • For the updated dependencies - a link to the changelog, or at minimum a diff between library versions is added to the PR description.
  • Untested files have been added to .coveragerc.

To help with the load of incoming pull requests:

@home-assistant
Copy link

home-assistant bot commented Apr 6, 2024

Hey there @home-assistant/core, mind taking a look at this pull request as it has been labeled with an integration (api) you are listed as a code owner for? Thanks!

Code owner commands

Code owners of api can trigger bot actions by commenting:

  • @home-assistant close Closes the pull request.
  • @home-assistant rename Awesome new title Renames the pull request.
  • @home-assistant reopen Reopen the pull request.
  • @home-assistant unassign api Removes the current integration label and assignees on the pull request, add the integration domain after the command.
  • @home-assistant add-label needs-more-information Add a label (needs-more-information, problem in dependency, problem in custom component) to the pull request.
  • @home-assistant remove-label needs-more-information Remove a label (needs-more-information, problem in dependency, problem in custom component) on the pull request.

@iamjackg
Copy link
Contributor Author

iamjackg commented Apr 6, 2024

Failing tests -- my bad. BRB!

…rvice do not exist

The documentation for the function mentions "Will return NONE if the service or domain do not exist as there is other error handling when calling the service if it does not exist." but this was simply raising a KeyError if the domain did not exist.
homeassistant/core.py Outdated Show resolved Hide resolved
@iamjackg
Copy link
Contributor Author

iamjackg commented Apr 6, 2024

Turns out this function was not doing what the documentation says:

    def supports_response(self, domain: str, service: str) -> SupportsResponse:
        """Return whether the service supports response data.

        This exists so that callers can return more helpful error messages given
        the context. Will return NONE if the service or domain do not exist as there is
        other error handling when calling the service if it does not exist.
        """
        try:
            handler = self._services[domain.lower()][service.lower()]
        except KeyError:
            return SupportsResponse.NONE

        if not handler:
            return SupportsResponse.NONE

        return handler.supports_response

I'm not sure if it ever did that in its original form? It used to just look like this:

    def supports_response(self, domain: str, service: str) -> SupportsResponse:
        """Return whether or not the service supports response data.

        This exists so that callers can return more helpful error messages given
        the context. Will return NONE if the service does not exist as there is
        other error handling when calling the service if it does not exist.
        """
        if not (handler := self._services[domain.lower()][service.lower()]):
            return SupportsResponse.NONE
        return handler.supports_response

self._services is a simple dict of dicts without any special magic, as far as I can see, so this should have always raised a KeyError.

The other places that call this either don't deal with the exception at all (like async_set_service_schema in helpers/service) or precede it with a call to:

if self._hass.services.has_service(params[CONF_DOMAIN], params[CONF_SERVICE])

This just doesn't strike me as the right pattern. I'd like to make the function properly raise ServiceNotFound when a service is not found, but I'd like to hear from a maintainer before making a bigger change.
It

bdraco
bdraco previously requested changes Apr 6, 2024
Copy link
Member

@bdraco bdraco left a comment

Choose a reason for hiding this comment

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

Please start an architecture discussion before making this change https://github.com/home-assistant/architecture/discussions

@home-assistant home-assistant bot marked this pull request as draft April 6, 2024 19:22
@home-assistant
Copy link

home-assistant bot commented Apr 6, 2024

Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍

Learn more about our pull request process.

@iamjackg
Copy link
Contributor Author

iamjackg commented Apr 6, 2024

Discussing this in home-assistant/architecture#1074

@sebsebseb1982
Copy link

Yep it would be a good feature to compensate for forecast disappearing.

@iamjackg
Copy link
Contributor Author

According to the architecture discussion, the REST API is no longer supported. Closing this.

@iamjackg iamjackg closed this Apr 23, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Apr 24, 2024
@emontnemery emontnemery reopened this May 16, 2024
@home-assistant home-assistant unlocked this conversation May 16, 2024
@emontnemery
Copy link
Contributor

emontnemery commented May 16, 2024

We discussed this again in the core team and we've accepted the proposal. I've reopened + unlocked the implementation PR.

Note: I don't mean that the exact details of the API changes as described in this proposal are necessarily OK, let's work those details out in the review of the implementation PR.

homeassistant/components/api/__init__.py Outdated Show resolved Hide resolved
homeassistant/components/api/__init__.py Outdated Show resolved Hide resolved
homeassistant/components/api/__init__.py Outdated Show resolved Hide resolved
@emontnemery
Copy link
Contributor

@iamjackg are you planning to pick this up again?

@bdraco
Copy link
Member

bdraco commented May 28, 2024

op has no github activity for May https://github.com/iamjackg ... might be on holiday.

homeassistant/core.py Outdated Show resolved Hide resolved
homeassistant/core.py Outdated Show resolved Hide resolved
@bdraco
Copy link
Member

bdraco commented Jun 21, 2024

Thanks for picking this back up.

I responded to the arch discussion at home-assistant/architecture#1074 (reply in thread)

@iamjackg
Copy link
Contributor Author

iamjackg commented Jul 3, 2024

@emontnemery and @bdraco, gentle ping

@frenck frenck added the smash Indicator this PR is close to finish for merging or closing label Jul 6, 2024
@sebsebseb1982
Copy link

Any news about this PR ?

@bdraco
Copy link
Member

bdraco commented Jul 26, 2024

Not yet. This was unblocked right around the time summer break started which means everyone will be time poor until after the break.

homeassistant/components/api/__init__.py Outdated Show resolved Hide resolved
homeassistant/components/api/__init__.py Outdated Show resolved Hide resolved
homeassistant/components/api/__init__.py Outdated Show resolved Hide resolved
@bdraco bdraco dismissed their stale review July 31, 2024 13:51

stale

Copy link
Contributor

@emontnemery emontnemery 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 I want a second opinion since the suggestion in the architecture discussion is not matching the implementation in this PR.

@emontnemery emontnemery added the second-opinion-wanted Add this label when a reviewer needs a second opinion from another member. label Jul 31, 2024
@emontnemery emontnemery added this to the 2024.8.0 milestone Jul 31, 2024
@frenck frenck modified the milestones: 2024.8.0, 2024.8.0b0 Jul 31, 2024
Copy link
Member

@frenck frenck left a comment

Choose a reason for hiding this comment

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

Nice! 👍

../Frenck

@frenck frenck merged commit 2910369 into home-assistant:dev Jul 31, 2024
26 checks passed
@iamjackg
Copy link
Contributor Author

iamjackg commented Aug 1, 2024

Yay!

@iamjackg
Copy link
Contributor Author

iamjackg commented Aug 1, 2024

@emontnemery @frenck would you mind merging the corresponding documentation PR? home-assistant/developers.home-assistant#2137

@MartinHjelmare MartinHjelmare removed the second-opinion-wanted Add this label when a reviewer needs a second opinion from another member. label Aug 1, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Aug 2, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Weather get_forecast service returns 500 on 2023.9.0
6 participants