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

Fix upload_from_file with "application/json" #162

Merged
merged 1 commit into from
Apr 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions gcp_storage_emulator/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,15 @@ def _decode_raw_data(raw_data, request_handler):
return raw_data


def _read_data(request_handler):
def _read_data(request_handler, query):
raw_data = _decode_raw_data(_read_raw_data(request_handler), request_handler)

if not raw_data:
return None

content_type = request_handler.headers["Content-Type"] or "application/octet-stream"

if content_type.startswith("application/json"):
if content_type.startswith("application/json") and "upload_id" not in query:
return json.loads(raw_data)

if content_type.startswith("multipart/"):
Expand Down Expand Up @@ -251,7 +251,7 @@ def params(self):
@property
def data(self):
if not self._data:
self._data = _read_data(self._request_handler)
self._data = _read_data(self._request_handler, self._query)
return self._data

def get_header(self, key, default=None):
Expand Down
10 changes: 6 additions & 4 deletions gcp_storage_emulator/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ def add_to_resumable_upload(self, file_id, content, total_size):
"""
safe_id = self.safe_id(file_id)
try:
file_content = self.get_file(RESUMABLE_DIR, safe_id)
file_content = self.get_file(RESUMABLE_DIR, safe_id, False)
except NotFound:
file_content = b""
file_content += content
Expand Down Expand Up @@ -292,12 +292,13 @@ def get_resumable_file_obj(self, file_id):
except KeyError:
raise NotFound

def get_file(self, bucket_name, file_name):
def get_file(self, bucket_name, file_name, show_error=True):
"""Get the raw data of a file within a bucket

Arguments:
bucket_name {str} -- Name of the bucket
file_name {str} -- File name
show_error {bool} -- Show error if the file is missing

Raises:
NotFound: Raised when the object doesn't exist
Expand All @@ -310,8 +311,9 @@ def get_file(self, bucket_name, file_name):
bucket_dir = self._fs.opendir(bucket_name)
return bucket_dir.open(file_name, mode="rb").read()
except (FileExpected, ResourceNotFound) as e:
logger.error("Resource not found:")
logger.error(e)
if show_error:
logger.error("Resource not found:")
logger.error(e)
raise NotFound

def delete_resumable_file_obj(self, file_id):
Expand Down
16 changes: 16 additions & 0 deletions tests/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,22 @@ def test_media_upload_without_metadata(self):
self.assertEqual(blob_content, file.read())
self.assertEqual(blob.content_type, "text/plain")

def test_upload_from_file_content_type_json(self):
file_name = "test.json"
content = b'[{"a": 1}]'
bucket = self._client.create_bucket("testbucket")
blob = bucket.blob(file_name)

with NamedTemporaryFile() as temp_file:
temp_file.write(content)
temp_file.flush()
temp_file.seek(0)
blob.upload_from_file(temp_file, content_type="application/json")

blob = bucket.get_blob(file_name)
self.assertEqual(blob.name, file_name)
self.assertEqual(blob.download_as_bytes(), content)


class HttpEndpointsTest(ServerBaseCase):
"""Tests for the HTTP endpoints defined by server.HANDLERS."""
Expand Down