| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -274,6 +274,11 @@ def upload_from_file(self, file_obj, rewind=False, size=None, | |||
| 274 | 274 | content_type=None, num_retries=6): | |
| 275 | 275 | """Upload the contents of this blob from a file-like object. | |
| 276 | 276 | ||
| 277 | + The content type of the upload will either be | ||
| 278 | + - The value passed in to the function (if any) | ||
| 279 | + - The value stored on the current blob | ||
| 280 | + - The default value of 'application/octet-stream' | ||
| 281 | + | ||
| 277 | 282 | .. note:: | |
| 278 | 283 | The effect of uploading to an existing blob depends on the | |
| 279 | 284 | "versioning" and "lifecycle" policies defined on the blob's | |
@@ -296,7 +301,16 @@ def upload_from_file(self, file_obj, rewind=False, size=None, | |||
| 296 | 301 | :param size: The number of bytes to read from the file handle. | |
| 297 | 302 | If not provided, we'll try to guess the size using | |
| 298 | 303 | :func:`os.fstat` | |
| 304 | + | ||
| 305 | + :type content_type: string or ``NoneType`` | ||
| 306 | + :param content_type: Optional type of content being uploaded. | ||
| 307 | + | ||
| 308 | + :type num_retries: integer | ||
| 309 | + :param num_retries: Number of upload retries. Defaults to 6. | ||
| 299 | 310 | """ | |
| 311 | + content_type = (content_type or self._properties.get('contentType') or | ||
| 312 | + 'application/octet-stream') | ||
| 313 | + | ||
| 300 | 314 | # Rewind the file if desired. | |
| 301 | 315 | if rewind: | |
| 302 | 316 | file_obj.seek(0, os.SEEK_SET) | |
@@ -310,9 +324,8 @@ def upload_from_file(self, file_obj, rewind=False, size=None, | |||
| 310 | 324 | 'User-Agent': conn.USER_AGENT, | |
| 311 | 325 | } | |
| 312 | 326 | ||
| 313 | - upload = transfer.Upload(file_obj, | ||
| 314 | - content_type or 'application/unknown', | ||
| 315 | - total_bytes, auto_transfer=False, | ||
| 327 | + upload = transfer.Upload(file_obj, content_type, total_bytes, | ||
| 328 | + auto_transfer=False, | ||
| 316 | 329 | chunksize=self.CHUNK_SIZE) | |
| 317 | 330 | ||
| 318 | 331 | url_builder = _UrlBuilder(bucket_name=self.bucket.name, | |
@@ -342,9 +355,14 @@ def upload_from_file(self, file_obj, rewind=False, size=None, | |||
| 342 | 355 | else: | |
| 343 | 356 | http_wrapper.MakeRequest(conn.http, request, retries=num_retries) | |
| 344 | 357 | ||
| 345 | - def upload_from_filename(self, filename): | ||
| 358 | + def upload_from_filename(self, filename, content_type=None): | ||
| 346 | 359 | """Upload this blob's contents from the content of a named file. | |
| 347 | 360 | ||
| 361 | + The content type of the upload will either be | ||
| 362 | + - The value passed in to the function (if any) | ||
| 363 | + - The value stored on the current blob | ||
| 364 | + - The value given by mimetypes.guess_type | ||
| 365 | + | ||
| 348 | 366 | .. note:: | |
| 349 | 367 | The effect of uploading to an existing blob depends on the | |
| 350 | 368 | "versioning" and "lifecycle" policies defined on the blob's | |
@@ -358,8 +376,13 @@ def upload_from_filename(self, filename): | |||
| 358 | 376 | ||
| 359 | 377 | :type filename: string | |
| 360 | 378 | :param filename: The path to the file. | |
| 379 | + | ||
| 380 | + :type content_type: string or ``NoneType`` | ||
| 381 | + :param content_type: Optional type of content being uploaded. | ||
| 361 | 382 | """ | |
| 362 | - content_type, _ = mimetypes.guess_type(filename) | ||
| 383 | + content_type = content_type or self._properties.get('contentType') | ||
| 384 | + if content_type is None: | ||
| 385 | + content_type, _ = mimetypes.guess_type(filename) | ||
| 363 | 386 | ||
| 364 | 387 | with open(filename, 'rb') as file_obj: | |
| 365 | 388 | self.upload_from_file(file_obj, content_type=content_type) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -327,7 +327,9 @@ def test_download_as_string(self): | |||
| 327 | 327 | fetched = blob.download_as_string() | |
| 328 | 328 | self.assertEqual(fetched, b'abcdef') | |
| 329 | 329 | ||
| 330 | - def test_upload_from_file_simple(self): | ||
| 330 | + def _upload_from_file_simple_test_helper(self, properties=None, | ||
| 331 | + content_type_arg=None, | ||
| 332 | + expected_content_type=None): | ||
| 331 | 333 | from six.moves.http_client import OK | |
| 332 | 334 | from six.moves.urllib.parse import parse_qsl | |
| 333 | 335 | from six.moves.urllib.parse import urlsplit | |
@@ -339,12 +341,13 @@ def test_upload_from_file_simple(self): | |||
| 339 | 341 | (response, b''), | |
| 340 | 342 | ) | |
| 341 | 343 | bucket = _Bucket(connection) | |
| 342 | - blob = self._makeOne(BLOB_NAME, bucket=bucket) | ||
| 344 | + blob = self._makeOne(BLOB_NAME, bucket=bucket, properties=properties) | ||
| 343 | 345 | blob.CHUNK_SIZE = 5 | |
| 344 | 346 | with NamedTemporaryFile() as fh: | |
| 345 | 347 | fh.write(DATA) | |
| 346 | 348 | fh.flush() | |
| 347 | - blob.upload_from_file(fh, rewind=True) | ||
| 349 | + blob.upload_from_file(fh, rewind=True, | ||
| 350 | + content_type=content_type_arg) | ||
| 348 | 351 | rq = connection.http._requested | |
| 349 | 352 | self.assertEqual(len(rq), 1) | |
| 350 | 353 | self.assertEqual(rq[0]['method'], 'POST') | |
@@ -358,7 +361,31 @@ def test_upload_from_file_simple(self): | |||
| 358 | 361 | headers = dict( | |
| 359 | 362 | [(x.title(), str(y)) for x, y in rq[0]['headers'].items()]) | |
| 360 | 363 | self.assertEqual(headers['Content-Length'], '6') | |
| 361 | - self.assertEqual(headers['Content-Type'], 'application/unknown') | ||
| 364 | + self.assertEqual(headers['Content-Type'], expected_content_type) | ||
| 365 | + | ||
| 366 | + def test_upload_from_file_simple(self): | ||
| 367 | + self._upload_from_file_simple_test_helper( | ||
| 368 | + expected_content_type='application/octet-stream') | ||
| 369 | + | ||
| 370 | + def test_upload_from_file_simple_with_content_type(self): | ||
| 371 | + EXPECTED_CONTENT_TYPE = 'foo/bar' | ||
| 372 | + self._upload_from_file_simple_test_helper( | ||
| 373 | + properties={'contentType': EXPECTED_CONTENT_TYPE}, | ||
| 374 | + expected_content_type=EXPECTED_CONTENT_TYPE) | ||
| 375 | + | ||
| 376 | + def test_upload_from_file_simple_with_content_type_passed(self): | ||
| 377 | + EXPECTED_CONTENT_TYPE = 'foo/bar' | ||
| 378 | + self._upload_from_file_simple_test_helper( | ||
| 379 | + content_type_arg=EXPECTED_CONTENT_TYPE, | ||
| 380 | + expected_content_type=EXPECTED_CONTENT_TYPE) | ||
| 381 | + | ||
| 382 | + def test_upload_from_file_simple_both_content_type_sources(self): | ||
| 383 | + EXPECTED_CONTENT_TYPE = 'foo/bar' | ||
| 384 | + ALT_CONTENT_TYPE = 'foo/baz' | ||
| 385 | + self._upload_from_file_simple_test_helper( | ||
| 386 | + properties={'contentType': ALT_CONTENT_TYPE}, | ||
| 387 | + content_type_arg=EXPECTED_CONTENT_TYPE, | ||
| 388 | + expected_content_type=EXPECTED_CONTENT_TYPE) | ||
| 362 | 389 | ||
| 363 | 390 | def test_upload_from_file_resumable(self): | |
| 364 | 391 | from six.moves.http_client import OK | |
@@ -403,7 +430,7 @@ def test_upload_from_file_resumable(self): | |||
| 403 | 430 | [(x.title(), str(y)) for x, y in rq[0]['headers'].items()]) | |
| 404 | 431 | self.assertEqual(headers['X-Upload-Content-Length'], '6') | |
| 405 | 432 | self.assertEqual(headers['X-Upload-Content-Type'], | |
| 406 | - 'application/unknown') | ||
| 433 | + 'application/octet-stream') | ||
| 407 | 434 | self.assertEqual(rq[1]['method'], 'PUT') | |
| 408 | 435 | self.assertEqual(rq[1]['uri'], UPLOAD_URL) | |
| 409 | 436 | headers = dict( | |
@@ -457,9 +484,11 @@ def test_upload_from_file_w_slash_in_name(self): | |||
| 457 | 484 | headers = dict( | |
| 458 | 485 | [(x.title(), str(y)) for x, y in rq[0]['headers'].items()]) | |
| 459 | 486 | self.assertEqual(headers['Content-Length'], '6') | |
| 460 | - self.assertEqual(headers['Content-Type'], 'application/unknown') | ||
| 487 | + self.assertEqual(headers['Content-Type'], 'application/octet-stream') | ||
| 461 | 488 | ||
| 462 | - def test_upload_from_filename(self): | ||
| 489 | + def _upload_from_filename_test_helper(self, properties=None, | ||
| 490 | + content_type_arg=None, | ||
| 491 | + expected_content_type=None): | ||
| 463 | 492 | from six.moves.http_client import OK | |
| 464 | 493 | from six.moves.urllib.parse import parse_qsl | |
| 465 | 494 | from six.moves.urllib.parse import urlsplit | |
@@ -478,12 +507,13 @@ def test_upload_from_filename(self): | |||
| 478 | 507 | (chunk2_response, ''), | |
| 479 | 508 | ) | |
| 480 | 509 | bucket = _Bucket(connection) | |
| 481 | - blob = self._makeOne(BLOB_NAME, bucket=bucket) | ||
| 510 | + blob = self._makeOne(BLOB_NAME, bucket=bucket, | ||
| 511 | + properties=properties) | ||
| 482 | 512 | blob.CHUNK_SIZE = 5 | |
| 483 | 513 | with NamedTemporaryFile(suffix='.jpeg') as fh: | |
| 484 | 514 | fh.write(DATA) | |
| 485 | 515 | fh.flush() | |
| 486 | - blob.upload_from_filename(fh.name) | ||
| 516 | + blob.upload_from_filename(fh.name, content_type=content_type_arg) | ||
| 487 | 517 | rq = connection.http._requested | |
| 488 | 518 | self.assertEqual(len(rq), 1) | |
| 489 | 519 | self.assertEqual(rq[0]['method'], 'POST') | |
@@ -497,7 +527,31 @@ def test_upload_from_filename(self): | |||
| 497 | 527 | headers = dict( | |
| 498 | 528 | [(x.title(), str(y)) for x, y in rq[0]['headers'].items()]) | |
| 499 | 529 | self.assertEqual(headers['Content-Length'], '6') | |
| 500 | - self.assertEqual(headers['Content-Type'], 'image/jpeg') | ||
| 530 | + self.assertEqual(headers['Content-Type'], expected_content_type) | ||
| 531 | + | ||
| 532 | + def test_upload_from_filename(self): | ||
| 533 | + self._upload_from_filename_test_helper( | ||
| 534 | + expected_content_type='image/jpeg') | ||
| 535 | + | ||
| 536 | + def test_upload_from_filename_with_content_type(self): | ||
| 537 | + EXPECTED_CONTENT_TYPE = 'foo/bar' | ||
| 538 | + self._upload_from_filename_test_helper( | ||
| 539 | + properties={'contentType': EXPECTED_CONTENT_TYPE}, | ||
| 540 | + expected_content_type=EXPECTED_CONTENT_TYPE) | ||
| 541 | + | ||
| 542 | + def test_upload_from_filename_with_content_type_passed(self): | ||
| 543 | + EXPECTED_CONTENT_TYPE = 'foo/bar' | ||
| 544 | + self._upload_from_filename_test_helper( | ||
| 545 | + content_type_arg=EXPECTED_CONTENT_TYPE, | ||
| 546 | + expected_content_type=EXPECTED_CONTENT_TYPE) | ||
| 547 | + | ||
| 548 | + def test_upload_from_filename_both_content_type_sources(self): | ||
| 549 | + EXPECTED_CONTENT_TYPE = 'foo/bar' | ||
| 550 | + ALT_CONTENT_TYPE = 'foo/baz' | ||
| 551 | + self._upload_from_filename_test_helper( | ||
| 552 | + properties={'contentType': ALT_CONTENT_TYPE}, | ||
| 553 | + content_type_arg=EXPECTED_CONTENT_TYPE, | ||
| 554 | + expected_content_type=EXPECTED_CONTENT_TYPE) | ||
| 501 | 555 | ||
| 502 | 556 | def test_upload_from_string_w_bytes(self): | |
| 503 | 557 | from six.moves.http_client import OK | |
| Back | FazBrowse Home | New Git URL |
0 commit comments