Skip to content

Commit

Permalink
Add json_load method to StoredFile (#1485)
Browse files Browse the repository at this point in the history
* Add `SOURCE` size and `json_load` method to `StoredFile`

Introduced a new `SOURCE` size to `StoredFileSize` enum and updated the `_download` method to accommodate this new size. Additionally, added a `json_load` method to `StoredFile` to download and deserialize JSON data, ensuring compatibility with attachment properties.

* Add test cassette for JSON file upload and download

This commit introduces a new test cassette for the `TestStoredFilesDownload.test_upload_and_download_of_json_file` test case. The cassette records HTTP interactions for the JSON file upload and download process, aiding in consistent and reliable test results.

* Update CHANGELOG with issue reference for json_load method

The `json_load()` method entry was updated to include issue reference #1485 in the UNRELEASED section. This helps in tracking the change and linking it to the discussed issue for better documentation.

* Refactor docstring in _download method

Updated the docstring in the `_download` method for clarity and conciseness. This change ensures that the description aligns better with standard documentation practices and improves readability.

---------

Co-authored-by: Jochem Berends <jochem.berends@ke-works.com>
  • Loading branch information
jberends and Jochem Berends authored Nov 14, 2024
1 parent 5226b50 commit ac37528
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Change Log
==========

UNRELEASED
----------
* :star: We added a `json_load()` method on the `StoredFile` to be compatible with the same interface as the attachment property. (#1485)

v4.14.0 (20SEP24)
-----------------
* :star: We added the concept of the `Signature` property. With this property we handle signature's better and more explicit in KE-chain. Signatures are stored as `StoredFiles` in the backend. (#1467)
Expand Down
2 changes: 2 additions & 0 deletions pykechain/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -1321,6 +1321,7 @@ class StoredFileSize(Enum):
:cvar L: L (1024, None)
:cvar XL: XL (2048, None)
:cvar FULL_SIZE: full_size
:cvar SOURCE: source file
"""

XS = "XS"
Expand All @@ -1329,6 +1330,7 @@ class StoredFileSize(Enum):
L = "L"
XL = "XL"
FULL_SIZE = "full_size"
SOURCE = "source"


class FormCategory(Enum):
Expand Down
34 changes: 31 additions & 3 deletions pykechain/models/stored_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,18 +258,46 @@ def save_as(
"""
filename = filename or os.path.join(os.getcwd(), self.filename)
with open(filename, "w+b") as f:
for chunk in self._download(size=size, **kwargs):
for chunk in self._download(size=size, stream=True, **kwargs):
f.write(chunk)

def _download(self, size: StoredFileSize.FULL_SIZE, **kwargs):
def _download(self, size: StoredFileSize = StoredFileSize.SOURCE, **kwargs):
"""
Download the file as file object with an optional image size.
Detects whether the content type falls under predefined image mime types and manages URL
accordingly. Raises APIError if the download fails.
When the file is not an image the 'source' file will be donwloaded. If the image
size is not specified the full size image will be downloaded.
:param size: Specifies the size of the file to be downloaded based
:param kwargs: Additional keyword arguments
:return: Response object of the download request as file descriptor
:raises APIError: If the download request does not succeed
"""
if self.content_type in predefined_mimes["image/*"]:
url = self.file.get(size, "full_size")
else:
url = self.file.get("source")

response = requests.get(url)
# handle kwargs
request_params = dict()
do_stream = kwargs.pop("stream", False)
if kwargs:
request_params.update(**kwargs)

response = requests.get(url, params=request_params, stream=do_stream)

if response.status_code != requests.codes.ok: # pragma: no cover
raise APIError("Could not download property value.", response=response)

return response

def json_load(self):
"""Download the data from the storedfile and deserialise the contained json.
:return: deserialised json data as :class:`dict`
:raises APIError: When unable to retrieve the json from KE-chain
:raises JSONDecodeError: When there was a problem in deserialising the json
"""
return self._download(size=StoredFileSize.SOURCE, stream=False).json()

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions tests/test_stored_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,12 @@ def test_download_image_from_stored_file(self):
self.assertEqual(image.height, 105)
self.assertEqual(image.format, "JPEG")

def test_upload_and_download_of_json_file(self):
with temp_chdir() as target_dir:
the_json = {"foo": "bar", "hello": "world"}
self.stored_pdf_file._upload_json(content=the_json)
downloaded_json = self.stored_pdf_file.json_load()
self.assertDictEqual(the_json, downloaded_json)

class TestStoredFilesUpload(TestStoredFilesBaseTestCase):
def setUp(self):
Expand Down

0 comments on commit ac37528

Please sign in to comment.