def upload(self, stream, path, conflict='replace', **kwargs): if path.identifier and conflict == 'keep': path, _ = self.handle_name_conflict(path, conflict=conflict, kind='folder') path._parts[-1]._id = None data_stream = streams.FormDataStream( attributes=json.dumps({ 'name': path.name, 'parent': { 'id': path.parent.identifier } }) ) data_stream.add_file('file', stream, path.name, disposition='form-data') resp = yield from self.make_request( 'POST', self._build_upload_url(*filter(lambda x: x is not None, ('files', path.identifier, 'content'))), data=data_stream, headers=data_stream.headers, expects=(201,), throws=exceptions.UploadError, ) data = yield from resp.json() return BoxFileMetadata(data['entries'][0], path), path.identifier is None
def test_headers_calls_finalize(self): stream = streams.FormDataStream(valjean='24601') orig = stream.finalize stream.finalize = mock.Mock(side_effect=orig) stream.headers assert stream.finalize.called
async def test_content_length(self): stream = streams.FormDataStream() stream.add_field('Master of the house', 'Isnt worth my spit') expected_length = int(stream.headers['Content-Length']) data = await stream.read() assert len(data) == stream.size assert len(data) == expected_length
async def test_add_field(self): stream = streams.FormDataStream() stream.add_field('Master of the house', 'Isnt worth my spit') data = await stream.read() expected = '\r\n'.join([ '--thisisaknownvalue', 'Content-Disposition: form-data; name="Master of the house"', '', 'Isnt worth my spit', '--thisisaknownvalue--', '' ]).encode('utf-8') assert data == expected
async def test_file(self): stream = streams.FormDataStream( file=streams.StringStream('Empty chairs at empty tables')) data = await stream.read() expected = sorted([ '--thisisaknownvalue', 'Content-Disposition: file; name="file"', 'Content-Type: application/octet-stream', 'Content-Transfer-Encoding: binary', '', 'Empty chairs at empty tables', '--thisisaknownvalue--', '' ]) actual = sorted(data.decode('utf-8').split('\r\n')) assert expected == actual
def upload(self, stream, path, **kwargs): article_json = yield from self._get_article_json() stream = streams.FormDataStream(filedata=(stream, path.name)) response = yield from self.make_request( 'PUT', self.build_url('articles', self.article_id, 'files'), data=stream, expects=(200, ), headers=stream.headers, ) data = yield from response.json() return metadata.FigshareFileMetadata( data, parent=article_json, child=self.child).serialized(), True
async def test_add_field_is_ordered(self): stream = streams.FormDataStream() stream.boundary = 'thisisaknownvalue' stream.add_field('Master of the house', 'Isnt worth my spit') stream.add_field('Comforter, Philosopher', 'A life long prick') data = await stream.read() expected = '\r\n'.join([ '--thisisaknownvalue', 'Content-Disposition: form-data; name="Master of the house"', '', 'Isnt worth my spit', '--thisisaknownvalue', 'Content-Disposition: form-data; name="Comforter, Philosopher"', '', 'A life long prick', '--thisisaknownvalue--', '' ]).encode('utf-8') assert expected == data
async def upload( self, # type: ignore stream: streams.BaseStream, path: WaterButlerPath, conflict: str = 'replace', **kwargs) -> Tuple[BoxFileMetadata, bool]: if path.identifier and conflict == 'keep': path, _ = await self.handle_name_conflict(path, conflict=conflict, kind='folder') path._parts[-1]._id = None stream.add_writer('sha1', streams.HashStreamWriter(hashlib.sha1)) data_stream = streams.FormDataStream( attributes=json.dumps({ 'name': path.name, 'parent': { 'id': path.parent.identifier } })) data_stream.add_file('file', stream, path.name, disposition='form-data') async with self.request( 'POST', self._build_upload_url( *filter(lambda x: x is not None, ('files', path.identifier, 'content'))), data=data_stream, headers=data_stream.headers, expects=(201, ), throws=exceptions.UploadError, ) as resp: data = await resp.json() entry = data['entries'][0] if stream.writers['sha1'].hexdigest != entry['sha1']: raise exceptions.UploadChecksumMismatchError() created = path.identifier is None path._parts[-1]._id = entry['id'] return BoxFileMetadata(entry, path), created
async def _contiguous_upload(self, path: WaterButlerPath, stream: streams.BaseStream) -> dict: """Upload a file to Box using a single request. This will only be called if the file is smaller than the ``NONCHUNKED_UPLOAD_LIMIT``. API Docs: https://developer.box.com/reference#upload-a-file """ assert stream.size <= self.NONCHUNKED_UPLOAD_LIMIT stream.add_writer('sha1', streams.HashStreamWriter(hashlib.sha1)) data_stream = streams.FormDataStream( attributes=json.dumps({ 'name': path.name, 'parent': { 'id': path.parent.identifier } })) data_stream.add_file('file', stream, path.name, disposition='form-data') if path.identifier is not None: segments = ['files', path.identifier, 'content'] else: segments = ['files', 'content'] response = await self.make_request( 'POST', self._build_upload_url(*segments), data=data_stream, headers=data_stream.headers, expects=(201, ), throws=exceptions.UploadError, ) data = await response.json() entry = data['entries'][0] if stream.writers['sha1'].hexdigest != entry['sha1']: raise exceptions.UploadChecksumMismatchError() return entry
async def test_add_fields(self): stream = streams.FormDataStream() stream.add_fields( **{ 'Master of the house': 'Isnt worth my spit', 'Comforter, Philosopher': 'A life long prick' }) data = await stream.read() expected = '\r\n'.join( sorted([ '--thisisaknownvalue', 'Content-Disposition: form-data; name="Comforter, Philosopher"', '', 'A life long prick', '--thisisaknownvalue', 'Content-Disposition: form-data; name="Master of the house"', '', 'Isnt worth my spit', '--thisisaknownvalue--', '' ])) to_compare = '\r\n'.join(sorted(data.decode('utf-8').split('\r\n'))) assert expected == to_compare
def test_cant_add_after_finalize(self): stream = streams.FormDataStream(valjean='24601') stream.finalize() with pytest.raises(AssertionError): stream.add_field('javer', 'thelaw')
def test_finalize_empty(self): stream = streams.FormDataStream() with pytest.raises(AssertionError): stream.finalize()