Skip to content

Commit 3b5f75a

Browse files
author
jitsuineccles
authored
Fix error parsing when uploading file (#4)
* Fix error parsing when uploading file * Fix response handling when downloading a file * formatted merged code
1 parent cd4ab52 commit 3b5f75a

4 files changed

Lines changed: 61 additions & 10 deletions

File tree

archivist/archivist.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ def get_file(self, subpath, identity, fd, *, headers=None):
124124
subpath: e.g. v2 or iam/v1
125125
identity: e.g. assets/xxxxxxxxxxxxxxxxxxxxxxxxxxxx`
126126
fd: an iterable representing a file (usually from open())
127+
the file must be opened in binary mode
127128
"""
128129
response = requests.get(
129130
SEP.join((self.url, ROOT, subpath, identity)),
@@ -140,7 +141,7 @@ def get_file(self, subpath, identity, fd, *, headers=None):
140141
if chunk:
141142
fd.write(chunk)
142143

143-
return response.json()
144+
return response
144145

145146
def post(self, path, request, *, headers=None):
146147
"""
@@ -168,6 +169,7 @@ def post_file(self, path, fd, mtype):
168169
169170
path: e.g. v1/blobs
170171
fd: an iterable representing a file (usually from open())
172+
the file must be opened in binary mode
171173
mtype: mime tiype (image/jpg)
172174
"""
173175

archivist/attachments.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@ def upload(self, fd, *, mtype="image/jpg"):
2323
)
2424

2525
def download(self, identity, fd):
26-
"""docstring"""
27-
return Attachment(
28-
**self._archivist.get_file(
29-
ATTACHMENTS_SUBPATH,
30-
identity,
31-
fd,
32-
)
26+
"""
27+
Note that returns the response as the body will be consumed by the
28+
fd iterator
29+
"""
30+
return self._archivist.get_file(
31+
ATTACHMENTS_SUBPATH,
32+
identity,
33+
fd,
3334
)
3435

3536

archivist/errors.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,14 @@ def __identity(response):
6363
req = response.request
6464
body = getattr(req, "body", None)
6565
if body:
66-
body = json.loads(body)
67-
identity = body.get("identity", "unknown")
66+
# when uploading a file the body attribute is a
67+
# MultiPartEncoder
68+
try:
69+
body = json.loads(body)
70+
except TypeError:
71+
pass
72+
else:
73+
identity = body.get("identity", "unknown")
6874

6975
return identity
7076

unittests/testerrors.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
from unittest import TestCase
1212

13+
from requests_toolbelt.multipart.encoder import MultipartEncoder
14+
1315
from archivist.errors import (
1416
parse_response,
1517
Archivist4xxError,
@@ -37,6 +39,7 @@ def test_errors_200(self):
3739
"""
3840
response = MockResponse(200)
3941
error = parse_response(response)
42+
4043
self.assertEqual(
4144
error,
4245
None,
@@ -49,6 +52,7 @@ def test_errors_300(self):
4952
"""
5053
response = MockResponse(300)
5154
error = parse_response(response)
55+
5256
self.assertEqual(
5357
error,
5458
None,
@@ -61,12 +65,14 @@ def test_errors_400(self):
6165
"""
6266
response = MockResponse(400, error="some error")
6367
error = parse_response(response)
68+
6469
self.assertIsNotNone(
6570
error,
6671
msg="error should not be None",
6772
)
6873
with self.assertRaises(ArchivistBadRequestError) as ex:
6974
raise error
75+
7076
self.assertEqual(
7177
str(ex.exception),
7278
'{"error": "some error"} (400)',
@@ -79,12 +85,14 @@ def test_errors_401(self):
7985
"""
8086
response = MockResponse(401, error="some error")
8187
error = parse_response(response)
88+
8289
self.assertIsNotNone(
8390
error,
8491
msg="error should not be None",
8592
)
8693
with self.assertRaises(ArchivistUnauthenticatedError) as ex:
8794
raise error
95+
8896
self.assertEqual(
8997
str(ex.exception),
9098
'{"error": "some error"} (401)',
@@ -97,12 +105,46 @@ def test_errors_403(self):
97105
"""
98106
response = MockResponse(403, error="some error")
99107
error = parse_response(response)
108+
100109
self.assertIsNotNone(
101110
error,
102111
msg="error should not be None",
103112
)
104113
with self.assertRaises(ArchivistForbiddenError) as ex:
105114
raise error
115+
116+
self.assertEqual(
117+
str(ex.exception),
118+
'{"error": "some error"} (403)',
119+
)
120+
121+
def test_errors_403_multipartencoder(self):
122+
"""
123+
Test errors
124+
"""
125+
126+
class Object:
127+
pass
128+
129+
request = Object()
130+
request.body = MultipartEncoder(
131+
fields={
132+
"file": ("filename", "filecontents", "image/jpg"),
133+
}
134+
)
135+
response = MockResponse(
136+
403,
137+
request=request,
138+
error="some error",
139+
)
140+
error = parse_response(response)
141+
self.assertIsNotNone(
142+
error,
143+
msg="error should not be None",
144+
)
145+
with self.assertRaises(ArchivistForbiddenError) as ex:
146+
raise error
147+
106148
self.assertEqual(
107149
str(ex.exception),
108150
'{"error": "some error"} (403)',

0 commit comments

Comments
 (0)