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

Allow returning raw bytes from a request, without attempting to decode. #136

Merged
merged 7 commits into from Jan 3, 2023

Conversation

hnefatl
Copy link
Contributor

@hnefatl hnefatl commented Dec 30, 2022

Some API calls can return binary data, e.g. fetching a user's profile image (e.g. api path like /api/image/serve/<hash>/512x512).

Currently this library attempts to decode all responses from bytes to str using the default utf-8 encoding, which fails for API calls returning binary data since the first byte of e.g. JPEG data (0xFF) can't be decoded to text.

This PR adds a by-default-no-change-to-external-behaviour flag to the RawClient.request method to optionally disable decoding for that request, just returning the raw bytes.

@hnefatl
Copy link
Contributor Author

hnefatl commented Dec 30, 2022

Example usage to fetch a user's profile image to a file:

url = "..."
token = "..."
person_id = "person.keith"

with Client(api_url=url, token=token) as client:
    state = client.get_state(entity_id=person_id)
    image_path = state.attributes.get("entity_picture")
    image_path = image_path.removeprefix("/api/")
    with open('out.jpeg', 'wb') as f:
        image_data = client.request(image_path, decode_bytes=False)
        f.write(image_data)

@GrandMoff100
Copy link
Owner

Oh! That's actually pretty cool.
I'll review it shortly and we can ship it in the next release in about two weeks.

@codecov
Copy link

codecov bot commented Jan 2, 2023

Codecov Report

Merging #136 (d61b20a) into dev (ec431cd) will not change coverage.
The diff coverage is 100.00%.

❗ Current head d61b20a differs from pull request most recent head d1dd678. Consider uploading reports for the commit d1dd678 to get more accurate results

@@            Coverage Diff            @@
##               dev      #136   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           20        20           
  Lines          947       953    +6     
=========================================
+ Hits           947       953    +6     
Impacted Files Coverage Δ
homeassistant_api/errors.py 100.00% <100.00%> (ø)
homeassistant_api/processing.py 100.00% <100.00%> (ø)
homeassistant_api/rawclient.py 100.00% <100.00%> (ø)

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

… `poetry run mypy homeassistant_api --show-error-codes`
For some reason, mypy didn't like the typechecking in the ternary operator, but is fine with the statement.
@hnefatl
Copy link
Contributor Author

hnefatl commented Jan 3, 2023

TIL how to use poetry properly :) Previous commits weren't done from poetry shell so were missing out on the precommit checks.

There was a type error detected by mypy unrelated to my changes (self._response.method) which weirdly seemed to be fixed by switching from ternary operator to if statement ¯\_(ツ)_/¯

@GrandMoff100
Copy link
Owner

Mypy can be weird like that sometimes lol

GrandMoff100
GrandMoff100 previously approved these changes Jan 3, 2023
Copy link
Owner

@GrandMoff100 GrandMoff100 left a comment

Choose a reason for hiding this comment

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

Looks good

@hnefatl
Copy link
Contributor Author

hnefatl commented Jan 3, 2023

Sorry, one last tweak - copied the wrong line earlier, thank you type-checking.

@GrandMoff100 GrandMoff100 merged commit 2d69843 into GrandMoff100:dev Jan 3, 2023
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.

None yet

2 participants