databricks-sdk 0.19.1__py3-none-any.whl → 0.21.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of databricks-sdk might be problematic. Click here for more details.

Files changed (35) hide show
  1. databricks/sdk/__init__.py +28 -6
  2. databricks/sdk/_widgets/__init__.py +2 -2
  3. databricks/sdk/config.py +3 -2
  4. databricks/sdk/core.py +4 -2
  5. databricks/sdk/mixins/workspace.py +2 -1
  6. databricks/sdk/oauth.py +1 -1
  7. databricks/sdk/runtime/__init__.py +85 -11
  8. databricks/sdk/runtime/dbutils_stub.py +1 -1
  9. databricks/sdk/service/_internal.py +1 -1
  10. databricks/sdk/service/billing.py +64 -1
  11. databricks/sdk/service/catalog.py +796 -84
  12. databricks/sdk/service/compute.py +391 -13
  13. databricks/sdk/service/dashboards.py +15 -0
  14. databricks/sdk/service/files.py +289 -15
  15. databricks/sdk/service/iam.py +214 -0
  16. databricks/sdk/service/jobs.py +242 -143
  17. databricks/sdk/service/ml.py +407 -0
  18. databricks/sdk/service/oauth2.py +83 -0
  19. databricks/sdk/service/pipelines.py +78 -8
  20. databricks/sdk/service/provisioning.py +108 -36
  21. databricks/sdk/service/serving.py +101 -35
  22. databricks/sdk/service/settings.py +1316 -186
  23. databricks/sdk/service/sharing.py +94 -18
  24. databricks/sdk/service/sql.py +230 -13
  25. databricks/sdk/service/vectorsearch.py +105 -60
  26. databricks/sdk/service/workspace.py +175 -1
  27. databricks/sdk/version.py +1 -1
  28. {databricks_sdk-0.19.1.dist-info → databricks_sdk-0.21.0.dist-info}/METADATA +3 -1
  29. databricks_sdk-0.21.0.dist-info/RECORD +53 -0
  30. databricks/sdk/runtime/stub.py +0 -48
  31. databricks_sdk-0.19.1.dist-info/RECORD +0 -54
  32. {databricks_sdk-0.19.1.dist-info → databricks_sdk-0.21.0.dist-info}/LICENSE +0 -0
  33. {databricks_sdk-0.19.1.dist-info → databricks_sdk-0.21.0.dist-info}/NOTICE +0 -0
  34. {databricks_sdk-0.19.1.dist-info → databricks_sdk-0.21.0.dist-info}/WHEEL +0 -0
  35. {databricks_sdk-0.19.1.dist-info → databricks_sdk-0.21.0.dist-info}/top_level.txt +0 -0
@@ -39,6 +39,20 @@ class PublishRequest:
39
39
  warehouse_id=d.get('warehouse_id', None))
40
40
 
41
41
 
42
+ @dataclass
43
+ class PublishResponse:
44
+
45
+ def as_dict(self) -> dict:
46
+ """Serializes the PublishResponse into a dictionary suitable for use as a JSON request body."""
47
+ body = {}
48
+ return body
49
+
50
+ @classmethod
51
+ def from_dict(cls, d: Dict[str, any]) -> PublishResponse:
52
+ """Deserializes the PublishResponse from a dictionary."""
53
+ return cls()
54
+
55
+
42
56
  class LakeviewAPI:
43
57
  """These APIs provide specific management operations for Lakeview dashboards. Generic resource management can
44
58
  be done with Workspace API (import, export, get-status, list, delete)."""
@@ -69,6 +83,7 @@ class LakeviewAPI:
69
83
  if embed_credentials is not None: body['embed_credentials'] = embed_credentials
70
84
  if warehouse_id is not None: body['warehouse_id'] = warehouse_id
71
85
  headers = {'Accept': 'application/json', 'Content-Type': 'application/json', }
86
+
72
87
  self._api.do('POST',
73
88
  f'/api/2.0/lakeview/dashboards/{dashboard_id}/published',
74
89
  body=body,
@@ -34,6 +34,20 @@ class AddBlock:
34
34
  return cls(data=d.get('data', None), handle=d.get('handle', None))
35
35
 
36
36
 
37
+ @dataclass
38
+ class AddBlockResponse:
39
+
40
+ def as_dict(self) -> dict:
41
+ """Serializes the AddBlockResponse into a dictionary suitable for use as a JSON request body."""
42
+ body = {}
43
+ return body
44
+
45
+ @classmethod
46
+ def from_dict(cls, d: Dict[str, any]) -> AddBlockResponse:
47
+ """Deserializes the AddBlockResponse from a dictionary."""
48
+ return cls()
49
+
50
+
37
51
  @dataclass
38
52
  class Close:
39
53
  handle: int
@@ -51,6 +65,20 @@ class Close:
51
65
  return cls(handle=d.get('handle', None))
52
66
 
53
67
 
68
+ @dataclass
69
+ class CloseResponse:
70
+
71
+ def as_dict(self) -> dict:
72
+ """Serializes the CloseResponse into a dictionary suitable for use as a JSON request body."""
73
+ body = {}
74
+ return body
75
+
76
+ @classmethod
77
+ def from_dict(cls, d: Dict[str, any]) -> CloseResponse:
78
+ """Deserializes the CloseResponse from a dictionary."""
79
+ return cls()
80
+
81
+
54
82
  @dataclass
55
83
  class Create:
56
84
  path: str
@@ -72,6 +100,20 @@ class Create:
72
100
  return cls(overwrite=d.get('overwrite', None), path=d.get('path', None))
73
101
 
74
102
 
103
+ @dataclass
104
+ class CreateDirectoryResponse:
105
+
106
+ def as_dict(self) -> dict:
107
+ """Serializes the CreateDirectoryResponse into a dictionary suitable for use as a JSON request body."""
108
+ body = {}
109
+ return body
110
+
111
+ @classmethod
112
+ def from_dict(cls, d: Dict[str, any]) -> CreateDirectoryResponse:
113
+ """Deserializes the CreateDirectoryResponse from a dictionary."""
114
+ return cls()
115
+
116
+
75
117
  @dataclass
76
118
  class CreateResponse:
77
119
  handle: Optional[int] = None
@@ -112,6 +154,34 @@ class Delete:
112
154
  return cls(path=d.get('path', None), recursive=d.get('recursive', None))
113
155
 
114
156
 
157
+ @dataclass
158
+ class DeleteDirectoryResponse:
159
+
160
+ def as_dict(self) -> dict:
161
+ """Serializes the DeleteDirectoryResponse into a dictionary suitable for use as a JSON request body."""
162
+ body = {}
163
+ return body
164
+
165
+ @classmethod
166
+ def from_dict(cls, d: Dict[str, any]) -> DeleteDirectoryResponse:
167
+ """Deserializes the DeleteDirectoryResponse from a dictionary."""
168
+ return cls()
169
+
170
+
171
+ @dataclass
172
+ class DeleteResponse:
173
+
174
+ def as_dict(self) -> dict:
175
+ """Serializes the DeleteResponse into a dictionary suitable for use as a JSON request body."""
176
+ body = {}
177
+ return body
178
+
179
+ @classmethod
180
+ def from_dict(cls, d: Dict[str, any]) -> DeleteResponse:
181
+ """Deserializes the DeleteResponse from a dictionary."""
182
+ return cls()
183
+
184
+
115
185
  @dataclass
116
186
  class DirectoryEntry:
117
187
  file_size: Optional[int] = None
@@ -124,7 +194,7 @@ class DirectoryEntry:
124
194
  """Last modification time of given file in milliseconds since unix epoch."""
125
195
 
126
196
  name: Optional[str] = None
127
- """The name of the file or directory."""
197
+ """The name of the file or directory. This is the last component of the path."""
128
198
 
129
199
  path: Optional[str] = None
130
200
  """The absolute path of the file or directory."""
@@ -151,8 +221,31 @@ class DirectoryEntry:
151
221
 
152
222
  @dataclass
153
223
  class DownloadResponse:
224
+ content_length: Optional[int] = None
225
+
226
+ content_type: Optional[str] = None
227
+
154
228
  contents: Optional[BinaryIO] = None
155
229
 
230
+ last_modified: Optional[str] = None
231
+
232
+ def as_dict(self) -> dict:
233
+ """Serializes the DownloadResponse into a dictionary suitable for use as a JSON request body."""
234
+ body = {}
235
+ if self.content_length is not None: body['content-length'] = self.content_length
236
+ if self.content_type is not None: body['content-type'] = self.content_type
237
+ if self.contents: body['contents'] = self.contents
238
+ if self.last_modified is not None: body['last-modified'] = self.last_modified
239
+ return body
240
+
241
+ @classmethod
242
+ def from_dict(cls, d: Dict[str, any]) -> DownloadResponse:
243
+ """Deserializes the DownloadResponse from a dictionary."""
244
+ return cls(content_length=int(d.get('content-length', None)),
245
+ content_type=d.get('content-type', None),
246
+ contents=d.get('contents', None),
247
+ last_modified=d.get('last-modified', None))
248
+
156
249
 
157
250
  @dataclass
158
251
  class FileInfo:
@@ -186,6 +279,44 @@ class FileInfo:
186
279
  path=d.get('path', None))
187
280
 
188
281
 
282
+ @dataclass
283
+ class GetDirectoryMetadataResponse:
284
+
285
+ def as_dict(self) -> dict:
286
+ """Serializes the GetDirectoryMetadataResponse into a dictionary suitable for use as a JSON request body."""
287
+ body = {}
288
+ return body
289
+
290
+ @classmethod
291
+ def from_dict(cls, d: Dict[str, any]) -> GetDirectoryMetadataResponse:
292
+ """Deserializes the GetDirectoryMetadataResponse from a dictionary."""
293
+ return cls()
294
+
295
+
296
+ @dataclass
297
+ class GetMetadataResponse:
298
+ content_length: Optional[int] = None
299
+
300
+ content_type: Optional[str] = None
301
+
302
+ last_modified: Optional[str] = None
303
+
304
+ def as_dict(self) -> dict:
305
+ """Serializes the GetMetadataResponse into a dictionary suitable for use as a JSON request body."""
306
+ body = {}
307
+ if self.content_length is not None: body['content-length'] = self.content_length
308
+ if self.content_type is not None: body['content-type'] = self.content_type
309
+ if self.last_modified is not None: body['last-modified'] = self.last_modified
310
+ return body
311
+
312
+ @classmethod
313
+ def from_dict(cls, d: Dict[str, any]) -> GetMetadataResponse:
314
+ """Deserializes the GetMetadataResponse from a dictionary."""
315
+ return cls(content_length=int(d.get('content-length', None)),
316
+ content_type=d.get('content-type', None),
317
+ last_modified=d.get('last-modified', None))
318
+
319
+
189
320
  @dataclass
190
321
  class ListDirectoryResponse:
191
322
  contents: Optional[List[DirectoryEntry]] = None
@@ -242,6 +373,20 @@ class MkDirs:
242
373
  return cls(path=d.get('path', None))
243
374
 
244
375
 
376
+ @dataclass
377
+ class MkDirsResponse:
378
+
379
+ def as_dict(self) -> dict:
380
+ """Serializes the MkDirsResponse into a dictionary suitable for use as a JSON request body."""
381
+ body = {}
382
+ return body
383
+
384
+ @classmethod
385
+ def from_dict(cls, d: Dict[str, any]) -> MkDirsResponse:
386
+ """Deserializes the MkDirsResponse from a dictionary."""
387
+ return cls()
388
+
389
+
245
390
  @dataclass
246
391
  class Move:
247
392
  source_path: str
@@ -263,6 +408,20 @@ class Move:
263
408
  return cls(destination_path=d.get('destination_path', None), source_path=d.get('source_path', None))
264
409
 
265
410
 
411
+ @dataclass
412
+ class MoveResponse:
413
+
414
+ def as_dict(self) -> dict:
415
+ """Serializes the MoveResponse into a dictionary suitable for use as a JSON request body."""
416
+ body = {}
417
+ return body
418
+
419
+ @classmethod
420
+ def from_dict(cls, d: Dict[str, any]) -> MoveResponse:
421
+ """Deserializes the MoveResponse from a dictionary."""
422
+ return cls()
423
+
424
+
266
425
  @dataclass
267
426
  class Put:
268
427
  path: str
@@ -290,6 +449,20 @@ class Put:
290
449
  path=d.get('path', None))
291
450
 
292
451
 
452
+ @dataclass
453
+ class PutResponse:
454
+
455
+ def as_dict(self) -> dict:
456
+ """Serializes the PutResponse into a dictionary suitable for use as a JSON request body."""
457
+ body = {}
458
+ return body
459
+
460
+ @classmethod
461
+ def from_dict(cls, d: Dict[str, any]) -> PutResponse:
462
+ """Deserializes the PutResponse from a dictionary."""
463
+ return cls()
464
+
465
+
293
466
  @dataclass
294
467
  class ReadResponse:
295
468
  bytes_read: Optional[int] = None
@@ -312,6 +485,20 @@ class ReadResponse:
312
485
  return cls(bytes_read=d.get('bytes_read', None), data=d.get('data', None))
313
486
 
314
487
 
488
+ @dataclass
489
+ class UploadResponse:
490
+
491
+ def as_dict(self) -> dict:
492
+ """Serializes the UploadResponse into a dictionary suitable for use as a JSON request body."""
493
+ body = {}
494
+ return body
495
+
496
+ @classmethod
497
+ def from_dict(cls, d: Dict[str, any]) -> UploadResponse:
498
+ """Deserializes the UploadResponse from a dictionary."""
499
+ return cls()
500
+
501
+
315
502
  class DbfsAPI:
316
503
  """DBFS API makes it simple to interact with various data sources without having to include a users
317
504
  credentials every time to read a file."""
@@ -338,6 +525,7 @@ class DbfsAPI:
338
525
  if data is not None: body['data'] = data
339
526
  if handle is not None: body['handle'] = handle
340
527
  headers = {'Accept': 'application/json', 'Content-Type': 'application/json', }
528
+
341
529
  self._api.do('POST', '/api/2.0/dbfs/add-block', body=body, headers=headers)
342
530
 
343
531
  def close(self, handle: int):
@@ -354,6 +542,7 @@ class DbfsAPI:
354
542
  body = {}
355
543
  if handle is not None: body['handle'] = handle
356
544
  headers = {'Accept': 'application/json', 'Content-Type': 'application/json', }
545
+
357
546
  self._api.do('POST', '/api/2.0/dbfs/close', body=body, headers=headers)
358
547
 
359
548
  def create(self, path: str, *, overwrite: Optional[bool] = None) -> CreateResponse:
@@ -379,6 +568,7 @@ class DbfsAPI:
379
568
  if overwrite is not None: body['overwrite'] = overwrite
380
569
  if path is not None: body['path'] = path
381
570
  headers = {'Accept': 'application/json', 'Content-Type': 'application/json', }
571
+
382
572
  res = self._api.do('POST', '/api/2.0/dbfs/create', body=body, headers=headers)
383
573
  return CreateResponse.from_dict(res)
384
574
 
@@ -412,6 +602,7 @@ class DbfsAPI:
412
602
  if path is not None: body['path'] = path
413
603
  if recursive is not None: body['recursive'] = recursive
414
604
  headers = {'Accept': 'application/json', 'Content-Type': 'application/json', }
605
+
415
606
  self._api.do('POST', '/api/2.0/dbfs/delete', body=body, headers=headers)
416
607
 
417
608
  def get_status(self, path: str) -> FileInfo:
@@ -429,6 +620,7 @@ class DbfsAPI:
429
620
  query = {}
430
621
  if path is not None: query['path'] = path
431
622
  headers = {'Accept': 'application/json', }
623
+
432
624
  res = self._api.do('GET', '/api/2.0/dbfs/get-status', query=query, headers=headers)
433
625
  return FileInfo.from_dict(res)
434
626
 
@@ -454,6 +646,7 @@ class DbfsAPI:
454
646
  query = {}
455
647
  if path is not None: query['path'] = path
456
648
  headers = {'Accept': 'application/json', }
649
+
457
650
  json = self._api.do('GET', '/api/2.0/dbfs/list', query=query, headers=headers)
458
651
  parsed = ListStatusResponse.from_dict(json).files
459
652
  return parsed if parsed is not None else []
@@ -474,6 +667,7 @@ class DbfsAPI:
474
667
  body = {}
475
668
  if path is not None: body['path'] = path
476
669
  headers = {'Accept': 'application/json', 'Content-Type': 'application/json', }
670
+
477
671
  self._api.do('POST', '/api/2.0/dbfs/mkdirs', body=body, headers=headers)
478
672
 
479
673
  def move(self, source_path: str, destination_path: str):
@@ -495,6 +689,7 @@ class DbfsAPI:
495
689
  if destination_path is not None: body['destination_path'] = destination_path
496
690
  if source_path is not None: body['source_path'] = source_path
497
691
  headers = {'Accept': 'application/json', 'Content-Type': 'application/json', }
692
+
498
693
  self._api.do('POST', '/api/2.0/dbfs/move', body=body, headers=headers)
499
694
 
500
695
  def put(self, path: str, *, contents: Optional[str] = None, overwrite: Optional[bool] = None):
@@ -525,6 +720,7 @@ class DbfsAPI:
525
720
  if overwrite is not None: body['overwrite'] = overwrite
526
721
  if path is not None: body['path'] = path
527
722
  headers = {'Accept': 'application/json', 'Content-Type': 'application/json', }
723
+
528
724
  self._api.do('POST', '/api/2.0/dbfs/put', body=body, headers=headers)
529
725
 
530
726
  def read(self, path: str, *, length: Optional[int] = None, offset: Optional[int] = None) -> ReadResponse:
@@ -554,12 +750,26 @@ class DbfsAPI:
554
750
  if offset is not None: query['offset'] = offset
555
751
  if path is not None: query['path'] = path
556
752
  headers = {'Accept': 'application/json', }
753
+
557
754
  res = self._api.do('GET', '/api/2.0/dbfs/read', query=query, headers=headers)
558
755
  return ReadResponse.from_dict(res)
559
756
 
560
757
 
561
758
  class FilesAPI:
562
- """The Files API allows you to read, write, and delete files and directories in Unity Catalog volumes."""
759
+ """The Files API is a standard HTTP API that allows you to read, write, list, and delete files and
760
+ directories by referring to their URI. The API makes working with file content as raw bytes easier and
761
+ more efficient.
762
+
763
+ The API supports [Unity Catalog volumes], where files and directories to operate on are specified using
764
+ their volume URI path, which follows the format
765
+ /Volumes/<catalog_name>/<schema_name>/<volume_name>/<path_to_file>.
766
+
767
+ The Files API has two distinct endpoints, one for working with files (`/fs/files`) and another one for
768
+ working with directories (`/fs/directories`). Both endpoints, use the standard HTTP methods GET, HEAD,
769
+ PUT, and DELETE to manage files and directories specified using their URI path. The path is always
770
+ absolute.
771
+
772
+ [Unity Catalog volumes]: https://docs.databricks.com/en/connect/unity-catalog/volumes.html"""
563
773
 
564
774
  def __init__(self, api_client):
565
775
  self._api = api_client
@@ -567,7 +777,9 @@ class FilesAPI:
567
777
  def create_directory(self, directory_path: str):
568
778
  """Create a directory.
569
779
 
570
- Creates an empty directory. If called on an existing directory, the API returns a success response.
780
+ Creates an empty directory. If necessary, also creates any parent directories of the new, empty
781
+ directory (like the shell command `mkdir -p`). If called on an existing directory, returns a success
782
+ response; this method is idempotent (it will succeed if the directory already exists).
571
783
 
572
784
  :param directory_path: str
573
785
  The absolute path of a directory.
@@ -576,12 +788,13 @@ class FilesAPI:
576
788
  """
577
789
 
578
790
  headers = {}
791
+
579
792
  self._api.do('PUT', f'/api/2.0/fs/directories{directory_path}', headers=headers)
580
793
 
581
794
  def delete(self, file_path: str):
582
795
  """Delete a file.
583
796
 
584
- Deletes a file.
797
+ Deletes a file. If the request is successful, there is no response body.
585
798
 
586
799
  :param file_path: str
587
800
  The absolute path of the file.
@@ -590,12 +803,16 @@ class FilesAPI:
590
803
  """
591
804
 
592
805
  headers = {}
806
+
593
807
  self._api.do('DELETE', f'/api/2.0/fs/files{file_path}', headers=headers)
594
808
 
595
809
  def delete_directory(self, directory_path: str):
596
810
  """Delete a directory.
597
811
 
598
- Deletes an empty directory. If the directory is not empty, the API returns a HTTP 400 error.
812
+ Deletes an empty directory.
813
+
814
+ To delete a non-empty directory, first delete all of its contents. This can be done by listing the
815
+ directory contents and deleting each file and subdirectory recursively.
599
816
 
600
817
  :param directory_path: str
601
818
  The absolute path of a directory.
@@ -604,12 +821,14 @@ class FilesAPI:
604
821
  """
605
822
 
606
823
  headers = {}
824
+
607
825
  self._api.do('DELETE', f'/api/2.0/fs/directories{directory_path}', headers=headers)
608
826
 
609
827
  def download(self, file_path: str) -> DownloadResponse:
610
828
  """Download a file.
611
829
 
612
- Downloads a file of up to 5 GiB.
830
+ Downloads a file of up to 5 GiB. The file contents are the response body. This is a standard HTTP file
831
+ download, not a JSON RPC.
613
832
 
614
833
  :param file_path: str
615
834
  The absolute path of the file.
@@ -618,8 +837,53 @@ class FilesAPI:
618
837
  """
619
838
 
620
839
  headers = {'Accept': 'application/octet-stream', }
621
- res = self._api.do('GET', f'/api/2.0/fs/files{file_path}', headers=headers, raw=True)
622
- return DownloadResponse(contents=res)
840
+ response_headers = ['content-length', 'content-type', 'last-modified', ]
841
+ res = self._api.do('GET',
842
+ f'/api/2.0/fs/files{file_path}',
843
+ headers=headers,
844
+ response_headers=response_headers,
845
+ raw=True)
846
+ return DownloadResponse.from_dict(res)
847
+
848
+ def get_directory_metadata(self, directory_path: str):
849
+ """Get directory metadata.
850
+
851
+ Get the metadata of a directory. The response HTTP headers contain the metadata. There is no response
852
+ body.
853
+
854
+ This method is useful to check if a directory exists and the caller has access to it.
855
+
856
+ If you wish to ensure the directory exists, you can instead use `PUT`, which will create the directory
857
+ if it does not exist, and is idempotent (it will succeed if the directory already exists).
858
+
859
+ :param directory_path: str
860
+ The absolute path of a directory.
861
+
862
+
863
+ """
864
+
865
+ headers = {}
866
+
867
+ self._api.do('HEAD', f'/api/2.0/fs/directories{directory_path}', headers=headers)
868
+
869
+ def get_metadata(self, file_path: str) -> GetMetadataResponse:
870
+ """Get file metadata.
871
+
872
+ Get the metadata of a file. The response HTTP headers contain the metadata. There is no response body.
873
+
874
+ :param file_path: str
875
+ The absolute path of the file.
876
+
877
+ :returns: :class:`GetMetadataResponse`
878
+ """
879
+
880
+ headers = {}
881
+ response_headers = ['content-length', 'content-type', 'last-modified', ]
882
+ res = self._api.do('HEAD',
883
+ f'/api/2.0/fs/files{file_path}',
884
+ headers=headers,
885
+ response_headers=response_headers)
886
+ return GetMetadataResponse.from_dict(res)
623
887
 
624
888
  def list_directory_contents(self,
625
889
  directory_path: str,
@@ -634,16 +898,22 @@ class FilesAPI:
634
898
  :param directory_path: str
635
899
  The absolute path of a directory.
636
900
  :param page_size: int (optional)
637
- The maximum number of directory entries to return. The API may return fewer than this value.
638
- Receiving fewer results does not imply there are no more results. As long as the response contains a
639
- next_page_token, there may be more results.
901
+ The maximum number of directory entries to return. The response may contain fewer entries. If the
902
+ response contains a `next_page_token`, there may be more entries, even if fewer than `page_size`
903
+ entries are in the response.
904
+
905
+ We recommend not to set this value unless you are intentionally listing less than the complete
906
+ directory contents.
640
907
 
641
908
  If unspecified, at most 1000 directory entries will be returned. The maximum value is 1000. Values
642
909
  above 1000 will be coerced to 1000.
643
910
  :param page_token: str (optional)
644
- A page token, received from a previous `list` call. Provide this to retrieve the subsequent page.
645
- When paginating, all other parameters provided to `list` must match the call that provided the page
646
- token.
911
+ An opaque page token which was the `next_page_token` in the response of the previous request to list
912
+ the contents of this directory. Provide this token to retrieve the next page of directory entries.
913
+ When providing a `page_token`, all other parameters provided to the request must match the previous
914
+ request. To list all of the entries in a directory, it is necessary to continue requesting pages of
915
+ entries until the response contains no `next_page_token`. Note that the number of entries returned
916
+ must not be used to determine when the listing is complete.
647
917
 
648
918
  :returns: Iterator over :class:`DirectoryEntry`
649
919
  """
@@ -668,7 +938,10 @@ class FilesAPI:
668
938
  def upload(self, file_path: str, contents: BinaryIO, *, overwrite: Optional[bool] = None):
669
939
  """Upload a file.
670
940
 
671
- Uploads a file of up to 5 GiB.
941
+ Uploads a file of up to 5 GiB. The file contents should be sent as the request body as raw bytes (an
942
+ octet stream); do not encode or otherwise modify the bytes before sending. The contents of the
943
+ resulting file will be exactly the bytes sent in the request body. If the request is successful, there
944
+ is no response body.
672
945
 
673
946
  :param file_path: str
674
947
  The absolute path of the file.
@@ -682,4 +955,5 @@ class FilesAPI:
682
955
  query = {}
683
956
  if overwrite is not None: query['overwrite'] = overwrite
684
957
  headers = {'Content-Type': 'application/octet-stream', }
958
+
685
959
  self._api.do('PUT', f'/api/2.0/fs/files{file_path}', query=query, headers=headers, data=contents)