files-com 1.6.208__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 files-com might be problematic. Click here for more details.
- README.md +758 -0
- _VERSION +1 -0
- files_com-1.6.208.dist-info/METADATA +770 -0
- files_com-1.6.208.dist-info/RECORD +126 -0
- files_com-1.6.208.dist-info/WHEEL +5 -0
- files_com-1.6.208.dist-info/licenses/LICENSE +21 -0
- files_com-1.6.208.dist-info/top_level.txt +1 -0
- files_sdk/__init__.py +309 -0
- files_sdk/api.py +63 -0
- files_sdk/api_client.py +336 -0
- files_sdk/error.py +2981 -0
- files_sdk/list_obj.py +42 -0
- files_sdk/models/__init__.py +119 -0
- files_sdk/models/account_line_item.py +51 -0
- files_sdk/models/action.py +49 -0
- files_sdk/models/action_notification_export.py +153 -0
- files_sdk/models/action_notification_export_result.py +88 -0
- files_sdk/models/agent_push_update.py +44 -0
- files_sdk/models/api_key.py +318 -0
- files_sdk/models/api_request_log.py +105 -0
- files_sdk/models/app.py +89 -0
- files_sdk/models/as2_incoming_message.py +117 -0
- files_sdk/models/as2_outgoing_message.py +113 -0
- files_sdk/models/as2_partner.py +415 -0
- files_sdk/models/as2_station.py +282 -0
- files_sdk/models/auto.py +36 -0
- files_sdk/models/automation.py +823 -0
- files_sdk/models/automation_log.py +94 -0
- files_sdk/models/automation_run.py +112 -0
- files_sdk/models/bandwidth_snapshot.py +91 -0
- files_sdk/models/behavior.py +340 -0
- files_sdk/models/bundle.py +686 -0
- files_sdk/models/bundle_action.py +93 -0
- files_sdk/models/bundle_download.py +94 -0
- files_sdk/models/bundle_notification.py +252 -0
- files_sdk/models/bundle_path.py +37 -0
- files_sdk/models/bundle_recipient.py +133 -0
- files_sdk/models/bundle_registration.py +82 -0
- files_sdk/models/child_site_management_policy.py +278 -0
- files_sdk/models/clickwrap.py +268 -0
- files_sdk/models/dns_record.py +59 -0
- files_sdk/models/email_incoming_message.py +102 -0
- files_sdk/models/email_log.py +84 -0
- files_sdk/models/errors.py +37 -0
- files_sdk/models/exavault_api_request_log.py +102 -0
- files_sdk/models/external_event.py +148 -0
- files_sdk/models/file.py +851 -0
- files_sdk/models/file_action.py +39 -0
- files_sdk/models/file_comment.py +191 -0
- files_sdk/models/file_comment_reaction.py +125 -0
- files_sdk/models/file_migration.py +69 -0
- files_sdk/models/file_migration_log.py +88 -0
- files_sdk/models/file_upload_part.py +54 -0
- files_sdk/models/folder.py +186 -0
- files_sdk/models/form_field.py +43 -0
- files_sdk/models/form_field_set.py +265 -0
- files_sdk/models/ftp_action_log.py +104 -0
- files_sdk/models/gpg_key.py +333 -0
- files_sdk/models/group.py +338 -0
- files_sdk/models/group_user.py +235 -0
- files_sdk/models/history.py +236 -0
- files_sdk/models/history_export.py +238 -0
- files_sdk/models/history_export_result.py +98 -0
- files_sdk/models/holiday_region.py +58 -0
- files_sdk/models/image.py +37 -0
- files_sdk/models/inbound_s3_log.py +95 -0
- files_sdk/models/inbox_recipient.py +124 -0
- files_sdk/models/inbox_registration.py +79 -0
- files_sdk/models/inbox_upload.py +80 -0
- files_sdk/models/invoice.py +91 -0
- files_sdk/models/invoice_line_item.py +51 -0
- files_sdk/models/ip_address.py +119 -0
- files_sdk/models/key_lifecycle_rule.py +243 -0
- files_sdk/models/lock.py +174 -0
- files_sdk/models/message.py +244 -0
- files_sdk/models/message_comment.py +223 -0
- files_sdk/models/message_comment_reaction.py +181 -0
- files_sdk/models/message_reaction.py +170 -0
- files_sdk/models/notification.py +451 -0
- files_sdk/models/outbound_connection_log.py +105 -0
- files_sdk/models/partner.py +307 -0
- files_sdk/models/payment.py +91 -0
- files_sdk/models/payment_line_item.py +42 -0
- files_sdk/models/permission.py +190 -0
- files_sdk/models/preview.py +40 -0
- files_sdk/models/priority.py +63 -0
- files_sdk/models/project.py +205 -0
- files_sdk/models/public_hosting_request_log.py +101 -0
- files_sdk/models/public_ip_address.py +42 -0
- files_sdk/models/public_key.py +269 -0
- files_sdk/models/remote_bandwidth_snapshot.py +91 -0
- files_sdk/models/remote_mount_backend.py +438 -0
- files_sdk/models/remote_server.py +1854 -0
- files_sdk/models/remote_server_configuration_file.py +73 -0
- files_sdk/models/remote_server_credential.py +855 -0
- files_sdk/models/request.py +184 -0
- files_sdk/models/restore.py +142 -0
- files_sdk/models/scim_log.py +88 -0
- files_sdk/models/session.py +100 -0
- files_sdk/models/settings_change.py +71 -0
- files_sdk/models/sftp_action_log.py +108 -0
- files_sdk/models/sftp_host_key.py +215 -0
- files_sdk/models/share_group.py +228 -0
- files_sdk/models/share_group_member.py +41 -0
- files_sdk/models/siem_http_destination.py +1074 -0
- files_sdk/models/site.py +1289 -0
- files_sdk/models/snapshot.py +255 -0
- files_sdk/models/sso_strategy.py +168 -0
- files_sdk/models/status.py +42 -0
- files_sdk/models/style.py +152 -0
- files_sdk/models/sync.py +588 -0
- files_sdk/models/sync_log.py +86 -0
- files_sdk/models/sync_run.py +124 -0
- files_sdk/models/usage_by_top_level_dir.py +41 -0
- files_sdk/models/usage_daily_snapshot.py +93 -0
- files_sdk/models/usage_snapshot.py +73 -0
- files_sdk/models/user.py +1232 -0
- files_sdk/models/user_cipher_use.py +91 -0
- files_sdk/models/user_lifecycle_rule.py +355 -0
- files_sdk/models/user_request.py +166 -0
- files_sdk/models/user_sftp_client_use.py +68 -0
- files_sdk/models/web_dav_action_log.py +104 -0
- files_sdk/models/webhook_test.py +116 -0
- files_sdk/models/workspace.py +202 -0
- files_sdk/path_util.py +42 -0
- files_sdk/util.py +34 -0
files_sdk/models/file.py
ADDED
|
@@ -0,0 +1,851 @@
|
|
|
1
|
+
import builtins # noqa: F401
|
|
2
|
+
from builtins import open as builtin_open
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
import io
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from files_sdk.models.file_action import FileAction
|
|
7
|
+
from files_sdk.models.file_upload_part import FileUploadPart
|
|
8
|
+
from files_sdk.api import Api # noqa: F401
|
|
9
|
+
from files_sdk.error import ( # noqa: F401
|
|
10
|
+
InvalidParameterError,
|
|
11
|
+
MissingParameterError,
|
|
12
|
+
NotImplementedError,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class File:
|
|
17
|
+
default_attributes = {
|
|
18
|
+
"path": None, # string - File/Folder path. This must be slash-delimited, but it must neither start nor end with a slash. Maximum of 5000 characters.
|
|
19
|
+
"created_by_id": None, # int64 - User ID of the User who created the file/folder
|
|
20
|
+
"created_by_api_key_id": None, # int64 - ID of the API key that created the file/folder
|
|
21
|
+
"created_by_as2_incoming_message_id": None, # int64 - ID of the AS2 Incoming Message that created the file/folder
|
|
22
|
+
"created_by_automation_id": None, # int64 - ID of the Automation that created the file/folder
|
|
23
|
+
"created_by_bundle_registration_id": None, # int64 - ID of the Bundle Registration that created the file/folder
|
|
24
|
+
"created_by_inbox_id": None, # int64 - ID of the Inbox that created the file/folder
|
|
25
|
+
"created_by_remote_server_id": None, # int64 - ID of the Remote Server that created the file/folder
|
|
26
|
+
"created_by_sync_id": None, # int64 - ID of the Sync that created the file/folder
|
|
27
|
+
"custom_metadata": None, # object - Custom metadata map of keys and values. Limited to 32 keys, 256 characters per key and 1024 characters per value.
|
|
28
|
+
"display_name": None, # string - File/Folder display name
|
|
29
|
+
"type": None, # string - Type: `directory` or `file`.
|
|
30
|
+
"size": None, # int64 - File/Folder size
|
|
31
|
+
"created_at": None, # date-time - File created date/time
|
|
32
|
+
"last_modified_by_id": None, # int64 - User ID of the User who last modified the file/folder
|
|
33
|
+
"last_modified_by_api_key_id": None, # int64 - ID of the API key that last modified the file/folder
|
|
34
|
+
"last_modified_by_automation_id": None, # int64 - ID of the Automation that last modified the file/folder
|
|
35
|
+
"last_modified_by_bundle_registration_id": None, # int64 - ID of the Bundle Registration that last modified the file/folder
|
|
36
|
+
"last_modified_by_remote_server_id": None, # int64 - ID of the Remote Server that last modified the file/folder
|
|
37
|
+
"last_modified_by_sync_id": None, # int64 - ID of the Sync that last modified the file/folder
|
|
38
|
+
"mtime": None, # date-time - File last modified date/time, according to the server. This is the timestamp of the last Files.com operation of the file, regardless of what modified timestamp was sent.
|
|
39
|
+
"provided_mtime": None, # date-time - File last modified date/time, according to the client who set it. Files.com allows desktop, FTP, SFTP, and WebDAV clients to set modified at times. This allows Desktop<->Cloud syncing to preserve modified at times.
|
|
40
|
+
"crc32": None, # string - File CRC32 checksum. This is sometimes delayed, so if you get a blank response, wait and try again.
|
|
41
|
+
"md5": None, # string - File MD5 checksum. This is sometimes delayed, so if you get a blank response, wait and try again.
|
|
42
|
+
"sha1": None, # string - File SHA1 checksum. This is sometimes delayed, so if you get a blank response, wait and try again.
|
|
43
|
+
"sha256": None, # string - File SHA256 checksum. This is sometimes delayed, so if you get a blank response, wait and try again.
|
|
44
|
+
"mime_type": None, # string - MIME Type. This is determined by the filename extension and is not stored separately internally.
|
|
45
|
+
"region": None, # string - Region location
|
|
46
|
+
"permissions": None, # string - A short string representing the current user's permissions. Can be `r` (Read),`w` (Write),`d` (Delete), `l` (List) or any combination
|
|
47
|
+
"subfolders_locked?": None, # boolean - Are subfolders locked and unable to be modified?
|
|
48
|
+
"is_locked": None, # boolean - Is this folder locked and unable to be modified?
|
|
49
|
+
"download_uri": None, # string - Link to download file. Provided only in response to a download request.
|
|
50
|
+
"priority_color": None, # string - Bookmark/priority color of file/folder
|
|
51
|
+
"preview_id": None, # int64 - File preview ID
|
|
52
|
+
"preview": None, # Preview - File preview
|
|
53
|
+
"action": None, # string - The action to perform. Can be `append`, `attachment`, `end`, `upload`, `put`, or may not exist
|
|
54
|
+
"length": None, # int64 - Length of file.
|
|
55
|
+
"mkdir_parents": None, # boolean - Create parent directories if they do not exist?
|
|
56
|
+
"part": None, # int64 - Part if uploading a part.
|
|
57
|
+
"parts": None, # int64 - How many parts to fetch?
|
|
58
|
+
"ref": None, # string -
|
|
59
|
+
"restart": None, # int64 - File byte offset to restart from.
|
|
60
|
+
"structure": None, # string - If copying folder, copy just the structure?
|
|
61
|
+
"with_rename": None, # boolean - Allow file rename instead of overwrite?
|
|
62
|
+
"buffered_upload": None, # boolean - If true, and the path refers to a destination not stored on Files.com (such as a remote server mount), the upload will be uploaded first to Files.com before being sent to the remote server mount. This can allow clients to upload using parallel parts to a remote server destination that does not offer parallel parts support natively.
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
def __init__(self, *args):
|
|
66
|
+
self.set_attributes({})
|
|
67
|
+
self.options = {}
|
|
68
|
+
self.mode = "r"
|
|
69
|
+
self.upload = None
|
|
70
|
+
self.etags = None
|
|
71
|
+
self.io_obj = io.StringIO()
|
|
72
|
+
self.closed = True
|
|
73
|
+
|
|
74
|
+
self.bytes_written = 0
|
|
75
|
+
if len(args) >= 1:
|
|
76
|
+
if isinstance(args[0], dict):
|
|
77
|
+
self.set_attributes(args[0])
|
|
78
|
+
elif isinstance(args[0], str):
|
|
79
|
+
self.set_attributes({"path": args[0]})
|
|
80
|
+
if len(args) >= 2:
|
|
81
|
+
if isinstance(args[1], dict):
|
|
82
|
+
self.options = args[1]
|
|
83
|
+
elif isinstance(args[1], str):
|
|
84
|
+
self.mode = args[1]
|
|
85
|
+
if len(args) >= 3:
|
|
86
|
+
if isinstance(args[2], dict):
|
|
87
|
+
self.options = args[2]
|
|
88
|
+
|
|
89
|
+
def set_attributes(self, attributes):
|
|
90
|
+
for attribute, default_value in File.default_attributes.items():
|
|
91
|
+
setattr(self, attribute, attributes.get(attribute, default_value))
|
|
92
|
+
|
|
93
|
+
def get_attributes(self):
|
|
94
|
+
return {
|
|
95
|
+
k: getattr(self, k, None)
|
|
96
|
+
for k in File.default_attributes
|
|
97
|
+
if getattr(self, k, None) is not None
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
def __enter__(self):
|
|
101
|
+
return self
|
|
102
|
+
|
|
103
|
+
def __exit__(self, type, value, traceback):
|
|
104
|
+
self.close()
|
|
105
|
+
|
|
106
|
+
def __del__(self):
|
|
107
|
+
if not self.io_obj.closed:
|
|
108
|
+
self.io_obj.close()
|
|
109
|
+
|
|
110
|
+
def close(self):
|
|
111
|
+
self.flush()
|
|
112
|
+
|
|
113
|
+
if self.upload:
|
|
114
|
+
end_options = {
|
|
115
|
+
"action": "end",
|
|
116
|
+
"etags": self.etags,
|
|
117
|
+
"provided_mtime": datetime.now().isoformat(),
|
|
118
|
+
"ref": self.upload.ref,
|
|
119
|
+
"size": self.bytes_written,
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
file = create(self.path, end_options, self.options)
|
|
123
|
+
self.set_attributes(file.get_attributes())
|
|
124
|
+
self.mode = "r"
|
|
125
|
+
self.upload = None
|
|
126
|
+
self.etags = None
|
|
127
|
+
self.io_obj = io.StringIO()
|
|
128
|
+
self.io_obj.close
|
|
129
|
+
self.closed = True
|
|
130
|
+
|
|
131
|
+
def fileno(self):
|
|
132
|
+
raise OSError
|
|
133
|
+
|
|
134
|
+
def flush(self, *_args):
|
|
135
|
+
if "w" in self.mode:
|
|
136
|
+
if self.io_obj.seekable():
|
|
137
|
+
self.io_obj.seek(0)
|
|
138
|
+
|
|
139
|
+
self.upload, self.etags, bytes_written = upload_chunks(
|
|
140
|
+
self.io_obj, self.path, self.options, self.upload, self.etags
|
|
141
|
+
)
|
|
142
|
+
self.bytes_written += bytes_written
|
|
143
|
+
elif "a" in self.mode:
|
|
144
|
+
raise io.UnsupportedOperation("Append is not a supported mode")
|
|
145
|
+
|
|
146
|
+
def isatty(self):
|
|
147
|
+
return False
|
|
148
|
+
|
|
149
|
+
def read(self):
|
|
150
|
+
if self.readable():
|
|
151
|
+
self.download_content(
|
|
152
|
+
self.io_obj, False if "b" in self.mode else True
|
|
153
|
+
)
|
|
154
|
+
self.io_obj.seek(0)
|
|
155
|
+
return self.io_obj.read()
|
|
156
|
+
else:
|
|
157
|
+
raise OSError("read mode not indicated")
|
|
158
|
+
|
|
159
|
+
def readable(self):
|
|
160
|
+
if "r" in self.mode and not self.closed:
|
|
161
|
+
return True
|
|
162
|
+
return False
|
|
163
|
+
|
|
164
|
+
def readall(self):
|
|
165
|
+
self.read()
|
|
166
|
+
|
|
167
|
+
def readinto(self):
|
|
168
|
+
return NotImplementedError
|
|
169
|
+
|
|
170
|
+
def readline(self):
|
|
171
|
+
return NotImplementedError
|
|
172
|
+
|
|
173
|
+
def seek(self):
|
|
174
|
+
raise OSError
|
|
175
|
+
|
|
176
|
+
def seekable(self):
|
|
177
|
+
return False
|
|
178
|
+
|
|
179
|
+
def tell(self):
|
|
180
|
+
raise OSError
|
|
181
|
+
|
|
182
|
+
def truncate(self):
|
|
183
|
+
raise OSError
|
|
184
|
+
|
|
185
|
+
def writeable(self):
|
|
186
|
+
if "w" in self.mode and not self.closed:
|
|
187
|
+
return True
|
|
188
|
+
return False
|
|
189
|
+
|
|
190
|
+
def write(self, *args):
|
|
191
|
+
if self.writeable():
|
|
192
|
+
self.io_obj.write(*args)
|
|
193
|
+
else:
|
|
194
|
+
raise OSError("write mode not indicated")
|
|
195
|
+
|
|
196
|
+
def download_uri_with_load(self):
|
|
197
|
+
if self.download_uri:
|
|
198
|
+
return self.download_uri
|
|
199
|
+
|
|
200
|
+
f = download(self.path, {}, self.options)
|
|
201
|
+
self.set_attributes(f.get_attributes())
|
|
202
|
+
return self.download_uri
|
|
203
|
+
|
|
204
|
+
def download_content(self, io, is_string_io=False):
|
|
205
|
+
Api.client().stream_download(
|
|
206
|
+
self.download_uri_with_load(), io, is_string_io
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
def download_file(self, output_file):
|
|
210
|
+
with builtin_open(output_file, "wb") as file:
|
|
211
|
+
self.download_content(file)
|
|
212
|
+
|
|
213
|
+
# Download File
|
|
214
|
+
#
|
|
215
|
+
# Parameters:
|
|
216
|
+
# action - string - Can be blank, `redirect` or `stat`. If set to `stat`, we will return file information but without a download URL, and without logging a download. If set to `redirect` we will serve a 302 redirect directly to the file. This is used for integrations with Zapier, and is not recommended for most integrations.
|
|
217
|
+
# preview_size - string - Request a preview size. Can be `small` (default), `large`, `xlarge`, or `pdf`.
|
|
218
|
+
# with_previews - boolean - Include file preview information?
|
|
219
|
+
# with_priority_color - boolean - Include file priority color information?
|
|
220
|
+
def download(self, params=None):
|
|
221
|
+
if not isinstance(params, dict):
|
|
222
|
+
params = {}
|
|
223
|
+
|
|
224
|
+
if hasattr(self, "path") and self.path:
|
|
225
|
+
params["path"] = self.path
|
|
226
|
+
else:
|
|
227
|
+
raise MissingParameterError("Current object doesn't have a path")
|
|
228
|
+
if "path" not in params:
|
|
229
|
+
raise MissingParameterError("Parameter missing: path")
|
|
230
|
+
if "path" in params and not isinstance(params["path"], str):
|
|
231
|
+
raise InvalidParameterError("Bad parameter: path must be an str")
|
|
232
|
+
if "action" in params and not isinstance(params["action"], str):
|
|
233
|
+
raise InvalidParameterError("Bad parameter: action must be an str")
|
|
234
|
+
if "preview_size" in params and not isinstance(
|
|
235
|
+
params["preview_size"], str
|
|
236
|
+
):
|
|
237
|
+
raise InvalidParameterError(
|
|
238
|
+
"Bad parameter: preview_size must be an str"
|
|
239
|
+
)
|
|
240
|
+
response, _options = Api.send_request(
|
|
241
|
+
"GET",
|
|
242
|
+
"/files/{path}".format(path=params["path"]),
|
|
243
|
+
params,
|
|
244
|
+
self.options,
|
|
245
|
+
)
|
|
246
|
+
return response.data
|
|
247
|
+
|
|
248
|
+
# Parameters:
|
|
249
|
+
# custom_metadata - object - Custom metadata map of keys and values. Limited to 32 keys, 256 characters per key and 1024 characters per value.
|
|
250
|
+
# provided_mtime - string - Modified time of file.
|
|
251
|
+
# priority_color - string - Priority/Bookmark color of file.
|
|
252
|
+
def update(self, params=None):
|
|
253
|
+
if not isinstance(params, dict):
|
|
254
|
+
params = {}
|
|
255
|
+
|
|
256
|
+
if hasattr(self, "path") and self.path:
|
|
257
|
+
params["path"] = self.path
|
|
258
|
+
else:
|
|
259
|
+
raise MissingParameterError("Current object doesn't have a path")
|
|
260
|
+
if "path" not in params:
|
|
261
|
+
raise MissingParameterError("Parameter missing: path")
|
|
262
|
+
if "path" in params and not isinstance(params["path"], str):
|
|
263
|
+
raise InvalidParameterError("Bad parameter: path must be an str")
|
|
264
|
+
if "provided_mtime" in params and not isinstance(
|
|
265
|
+
params["provided_mtime"], str
|
|
266
|
+
):
|
|
267
|
+
raise InvalidParameterError(
|
|
268
|
+
"Bad parameter: provided_mtime must be an str"
|
|
269
|
+
)
|
|
270
|
+
if "priority_color" in params and not isinstance(
|
|
271
|
+
params["priority_color"], str
|
|
272
|
+
):
|
|
273
|
+
raise InvalidParameterError(
|
|
274
|
+
"Bad parameter: priority_color must be an str"
|
|
275
|
+
)
|
|
276
|
+
response, _options = Api.send_request(
|
|
277
|
+
"PATCH",
|
|
278
|
+
"/files/{path}".format(path=params["path"]),
|
|
279
|
+
params,
|
|
280
|
+
self.options,
|
|
281
|
+
)
|
|
282
|
+
return response.data
|
|
283
|
+
|
|
284
|
+
# Parameters:
|
|
285
|
+
# recursive - boolean - If true, will recursively delete folders. Otherwise, will error on non-empty folders.
|
|
286
|
+
def delete(self, params=None):
|
|
287
|
+
if not isinstance(params, dict):
|
|
288
|
+
params = {}
|
|
289
|
+
|
|
290
|
+
if hasattr(self, "path") and self.path:
|
|
291
|
+
params["path"] = self.path
|
|
292
|
+
else:
|
|
293
|
+
raise MissingParameterError("Current object doesn't have a path")
|
|
294
|
+
if "path" not in params:
|
|
295
|
+
raise MissingParameterError("Parameter missing: path")
|
|
296
|
+
if "path" in params and not isinstance(params["path"], str):
|
|
297
|
+
raise InvalidParameterError("Bad parameter: path must be an str")
|
|
298
|
+
Api.send_request(
|
|
299
|
+
"DELETE",
|
|
300
|
+
"/files/{path}".format(path=params["path"]),
|
|
301
|
+
params,
|
|
302
|
+
self.options,
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
def destroy(self, params=None):
|
|
306
|
+
self.delete(params)
|
|
307
|
+
|
|
308
|
+
# Copy File/Folder
|
|
309
|
+
#
|
|
310
|
+
# Parameters:
|
|
311
|
+
# destination (required) - string - Copy destination path.
|
|
312
|
+
# structure - boolean - Copy structure only?
|
|
313
|
+
# overwrite - boolean - Overwrite existing file(s) in the destination?
|
|
314
|
+
def copy(self, params=None):
|
|
315
|
+
if not isinstance(params, dict):
|
|
316
|
+
params = {}
|
|
317
|
+
|
|
318
|
+
if hasattr(self, "path") and self.path:
|
|
319
|
+
params["path"] = self.path
|
|
320
|
+
else:
|
|
321
|
+
raise MissingParameterError("Current object doesn't have a path")
|
|
322
|
+
if "path" not in params:
|
|
323
|
+
raise MissingParameterError("Parameter missing: path")
|
|
324
|
+
if "destination" not in params:
|
|
325
|
+
raise MissingParameterError("Parameter missing: destination")
|
|
326
|
+
if "path" in params and not isinstance(params["path"], str):
|
|
327
|
+
raise InvalidParameterError("Bad parameter: path must be an str")
|
|
328
|
+
if "destination" in params and not isinstance(
|
|
329
|
+
params["destination"], str
|
|
330
|
+
):
|
|
331
|
+
raise InvalidParameterError(
|
|
332
|
+
"Bad parameter: destination must be an str"
|
|
333
|
+
)
|
|
334
|
+
response, _options = Api.send_request(
|
|
335
|
+
"POST",
|
|
336
|
+
"/file_actions/copy/{path}".format(path=params["path"]),
|
|
337
|
+
params,
|
|
338
|
+
self.options,
|
|
339
|
+
)
|
|
340
|
+
return response.data
|
|
341
|
+
|
|
342
|
+
# Move File/Folder
|
|
343
|
+
#
|
|
344
|
+
# Parameters:
|
|
345
|
+
# destination (required) - string - Move destination path.
|
|
346
|
+
# overwrite - boolean - Overwrite existing file(s) in the destination?
|
|
347
|
+
def move(self, params=None):
|
|
348
|
+
if not isinstance(params, dict):
|
|
349
|
+
params = {}
|
|
350
|
+
|
|
351
|
+
if hasattr(self, "path") and self.path:
|
|
352
|
+
params["path"] = self.path
|
|
353
|
+
else:
|
|
354
|
+
raise MissingParameterError("Current object doesn't have a path")
|
|
355
|
+
if "path" not in params:
|
|
356
|
+
raise MissingParameterError("Parameter missing: path")
|
|
357
|
+
if "destination" not in params:
|
|
358
|
+
raise MissingParameterError("Parameter missing: destination")
|
|
359
|
+
if "path" in params and not isinstance(params["path"], str):
|
|
360
|
+
raise InvalidParameterError("Bad parameter: path must be an str")
|
|
361
|
+
if "destination" in params and not isinstance(
|
|
362
|
+
params["destination"], str
|
|
363
|
+
):
|
|
364
|
+
raise InvalidParameterError(
|
|
365
|
+
"Bad parameter: destination must be an str"
|
|
366
|
+
)
|
|
367
|
+
response, _options = Api.send_request(
|
|
368
|
+
"POST",
|
|
369
|
+
"/file_actions/move/{path}".format(path=params["path"]),
|
|
370
|
+
params,
|
|
371
|
+
self.options,
|
|
372
|
+
)
|
|
373
|
+
return response.data
|
|
374
|
+
|
|
375
|
+
# Begin File Upload
|
|
376
|
+
#
|
|
377
|
+
# Parameters:
|
|
378
|
+
# mkdir_parents - boolean - Create parent directories if they do not exist?
|
|
379
|
+
# part - int64 - Part if uploading a part.
|
|
380
|
+
# parts - int64 - How many parts to fetch?
|
|
381
|
+
# ref - string -
|
|
382
|
+
# restart - int64 - File byte offset to restart from.
|
|
383
|
+
# size - int64 - Total bytes of file being uploaded (include bytes being retained if appending/restarting).
|
|
384
|
+
# with_rename - boolean - Allow file rename instead of overwrite?
|
|
385
|
+
def begin_upload(self, params=None):
|
|
386
|
+
if not isinstance(params, dict):
|
|
387
|
+
params = {}
|
|
388
|
+
|
|
389
|
+
if hasattr(self, "path") and self.path:
|
|
390
|
+
params["path"] = self.path
|
|
391
|
+
else:
|
|
392
|
+
raise MissingParameterError("Current object doesn't have a path")
|
|
393
|
+
if "path" not in params:
|
|
394
|
+
raise MissingParameterError("Parameter missing: path")
|
|
395
|
+
if "path" in params and not isinstance(params["path"], str):
|
|
396
|
+
raise InvalidParameterError("Bad parameter: path must be an str")
|
|
397
|
+
if "part" in params and not isinstance(params["part"], int):
|
|
398
|
+
raise InvalidParameterError("Bad parameter: part must be an int")
|
|
399
|
+
if "parts" in params and not isinstance(params["parts"], int):
|
|
400
|
+
raise InvalidParameterError("Bad parameter: parts must be an int")
|
|
401
|
+
if "ref" in params and not isinstance(params["ref"], str):
|
|
402
|
+
raise InvalidParameterError("Bad parameter: ref must be an str")
|
|
403
|
+
if "restart" in params and not isinstance(params["restart"], int):
|
|
404
|
+
raise InvalidParameterError(
|
|
405
|
+
"Bad parameter: restart must be an int"
|
|
406
|
+
)
|
|
407
|
+
if "size" in params and not isinstance(params["size"], int):
|
|
408
|
+
raise InvalidParameterError("Bad parameter: size must be an int")
|
|
409
|
+
response, _options = Api.send_request(
|
|
410
|
+
"POST",
|
|
411
|
+
"/file_actions/begin_upload/{path}".format(path=params["path"]),
|
|
412
|
+
params,
|
|
413
|
+
self.options,
|
|
414
|
+
)
|
|
415
|
+
return response.data
|
|
416
|
+
|
|
417
|
+
def save(self):
|
|
418
|
+
new_obj = create(self.path, self.get_attributes(), self.options)
|
|
419
|
+
self.set_attributes(new_obj.get_attributes())
|
|
420
|
+
return True
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
# Download File
|
|
424
|
+
#
|
|
425
|
+
# Parameters:
|
|
426
|
+
# action - string - Can be blank, `redirect` or `stat`. If set to `stat`, we will return file information but without a download URL, and without logging a download. If set to `redirect` we will serve a 302 redirect directly to the file. This is used for integrations with Zapier, and is not recommended for most integrations.
|
|
427
|
+
# preview_size - string - Request a preview size. Can be `small` (default), `large`, `xlarge`, or `pdf`.
|
|
428
|
+
# with_previews - boolean - Include file preview information?
|
|
429
|
+
# with_priority_color - boolean - Include file priority color information?
|
|
430
|
+
def download(path, params=None, options=None):
|
|
431
|
+
if not isinstance(params, dict):
|
|
432
|
+
params = {}
|
|
433
|
+
if not isinstance(options, dict):
|
|
434
|
+
options = {}
|
|
435
|
+
params["path"] = path
|
|
436
|
+
if "path" in params and not isinstance(params["path"], str):
|
|
437
|
+
raise InvalidParameterError("Bad parameter: path must be an str")
|
|
438
|
+
if "action" in params and not isinstance(params["action"], str):
|
|
439
|
+
raise InvalidParameterError("Bad parameter: action must be an str")
|
|
440
|
+
if "preview_size" in params and not isinstance(
|
|
441
|
+
params["preview_size"], str
|
|
442
|
+
):
|
|
443
|
+
raise InvalidParameterError(
|
|
444
|
+
"Bad parameter: preview_size must be an str"
|
|
445
|
+
)
|
|
446
|
+
if "with_previews" in params and not isinstance(
|
|
447
|
+
params["with_previews"], bool
|
|
448
|
+
):
|
|
449
|
+
raise InvalidParameterError(
|
|
450
|
+
"Bad parameter: with_previews must be an bool"
|
|
451
|
+
)
|
|
452
|
+
if "with_priority_color" in params and not isinstance(
|
|
453
|
+
params["with_priority_color"], bool
|
|
454
|
+
):
|
|
455
|
+
raise InvalidParameterError(
|
|
456
|
+
"Bad parameter: with_priority_color must be an bool"
|
|
457
|
+
)
|
|
458
|
+
if "path" not in params:
|
|
459
|
+
raise MissingParameterError("Parameter missing: path")
|
|
460
|
+
response, options = Api.send_request(
|
|
461
|
+
"GET", "/files/{path}".format(path=params["path"]), params, options
|
|
462
|
+
)
|
|
463
|
+
return File(response.data, options)
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
# Parameters:
|
|
467
|
+
# path (required) - string - Path to operate on.
|
|
468
|
+
# action - string - The action to perform. Can be `append`, `attachment`, `end`, `upload`, `put`, or may not exist
|
|
469
|
+
# etags[etag] (required) - array(string) - etag identifier.
|
|
470
|
+
# etags[part] (required) - array(int64) - Part number.
|
|
471
|
+
# length - int64 - Length of file.
|
|
472
|
+
# mkdir_parents - boolean - Create parent directories if they do not exist?
|
|
473
|
+
# part - int64 - Part if uploading a part.
|
|
474
|
+
# parts - int64 - How many parts to fetch?
|
|
475
|
+
# provided_mtime - string - User provided modification time.
|
|
476
|
+
# ref - string -
|
|
477
|
+
# restart - int64 - File byte offset to restart from.
|
|
478
|
+
# size - int64 - Size of file.
|
|
479
|
+
# structure - string - If copying folder, copy just the structure?
|
|
480
|
+
# with_rename - boolean - Allow file rename instead of overwrite?
|
|
481
|
+
# buffered_upload - boolean - If true, and the path refers to a destination not stored on Files.com (such as a remote server mount), the upload will be uploaded first to Files.com before being sent to the remote server mount. This can allow clients to upload using parallel parts to a remote server destination that does not offer parallel parts support natively.
|
|
482
|
+
def create(path, params=None, options=None):
|
|
483
|
+
if not isinstance(params, dict):
|
|
484
|
+
params = {}
|
|
485
|
+
if not isinstance(options, dict):
|
|
486
|
+
options = {}
|
|
487
|
+
params["path"] = path
|
|
488
|
+
if "path" in params and not isinstance(params["path"], str):
|
|
489
|
+
raise InvalidParameterError("Bad parameter: path must be an str")
|
|
490
|
+
if "action" in params and not isinstance(params["action"], str):
|
|
491
|
+
raise InvalidParameterError("Bad parameter: action must be an str")
|
|
492
|
+
if "length" in params and not isinstance(params["length"], int):
|
|
493
|
+
raise InvalidParameterError("Bad parameter: length must be an int")
|
|
494
|
+
if "mkdir_parents" in params and not isinstance(
|
|
495
|
+
params["mkdir_parents"], bool
|
|
496
|
+
):
|
|
497
|
+
raise InvalidParameterError(
|
|
498
|
+
"Bad parameter: mkdir_parents must be an bool"
|
|
499
|
+
)
|
|
500
|
+
if "part" in params and not isinstance(params["part"], int):
|
|
501
|
+
raise InvalidParameterError("Bad parameter: part must be an int")
|
|
502
|
+
if "parts" in params and not isinstance(params["parts"], int):
|
|
503
|
+
raise InvalidParameterError("Bad parameter: parts must be an int")
|
|
504
|
+
if "provided_mtime" in params and not isinstance(
|
|
505
|
+
params["provided_mtime"], str
|
|
506
|
+
):
|
|
507
|
+
raise InvalidParameterError(
|
|
508
|
+
"Bad parameter: provided_mtime must be an str"
|
|
509
|
+
)
|
|
510
|
+
if "ref" in params and not isinstance(params["ref"], str):
|
|
511
|
+
raise InvalidParameterError("Bad parameter: ref must be an str")
|
|
512
|
+
if "restart" in params and not isinstance(params["restart"], int):
|
|
513
|
+
raise InvalidParameterError("Bad parameter: restart must be an int")
|
|
514
|
+
if "size" in params and not isinstance(params["size"], int):
|
|
515
|
+
raise InvalidParameterError("Bad parameter: size must be an int")
|
|
516
|
+
if "structure" in params and not isinstance(params["structure"], str):
|
|
517
|
+
raise InvalidParameterError("Bad parameter: structure must be an str")
|
|
518
|
+
if "with_rename" in params and not isinstance(params["with_rename"], bool):
|
|
519
|
+
raise InvalidParameterError(
|
|
520
|
+
"Bad parameter: with_rename must be an bool"
|
|
521
|
+
)
|
|
522
|
+
if "buffered_upload" in params and not isinstance(
|
|
523
|
+
params["buffered_upload"], bool
|
|
524
|
+
):
|
|
525
|
+
raise InvalidParameterError(
|
|
526
|
+
"Bad parameter: buffered_upload must be an bool"
|
|
527
|
+
)
|
|
528
|
+
if "path" not in params:
|
|
529
|
+
raise MissingParameterError("Parameter missing: path")
|
|
530
|
+
response, options = Api.send_request(
|
|
531
|
+
"POST", "/files/{path}".format(path=params["path"]), params, options
|
|
532
|
+
)
|
|
533
|
+
return File(response.data, options)
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
# Parameters:
|
|
537
|
+
# custom_metadata - object - Custom metadata map of keys and values. Limited to 32 keys, 256 characters per key and 1024 characters per value.
|
|
538
|
+
# provided_mtime - string - Modified time of file.
|
|
539
|
+
# priority_color - string - Priority/Bookmark color of file.
|
|
540
|
+
def update(path, params=None, options=None):
|
|
541
|
+
if not isinstance(params, dict):
|
|
542
|
+
params = {}
|
|
543
|
+
if not isinstance(options, dict):
|
|
544
|
+
options = {}
|
|
545
|
+
params["path"] = path
|
|
546
|
+
if "path" in params and not isinstance(params["path"], str):
|
|
547
|
+
raise InvalidParameterError("Bad parameter: path must be an str")
|
|
548
|
+
if "custom_metadata" in params and not isinstance(
|
|
549
|
+
params["custom_metadata"], dict
|
|
550
|
+
):
|
|
551
|
+
raise InvalidParameterError(
|
|
552
|
+
"Bad parameter: custom_metadata must be an dict"
|
|
553
|
+
)
|
|
554
|
+
if "provided_mtime" in params and not isinstance(
|
|
555
|
+
params["provided_mtime"], str
|
|
556
|
+
):
|
|
557
|
+
raise InvalidParameterError(
|
|
558
|
+
"Bad parameter: provided_mtime must be an str"
|
|
559
|
+
)
|
|
560
|
+
if "priority_color" in params and not isinstance(
|
|
561
|
+
params["priority_color"], str
|
|
562
|
+
):
|
|
563
|
+
raise InvalidParameterError(
|
|
564
|
+
"Bad parameter: priority_color must be an str"
|
|
565
|
+
)
|
|
566
|
+
if "path" not in params:
|
|
567
|
+
raise MissingParameterError("Parameter missing: path")
|
|
568
|
+
response, options = Api.send_request(
|
|
569
|
+
"PATCH", "/files/{path}".format(path=params["path"]), params, options
|
|
570
|
+
)
|
|
571
|
+
return File(response.data, options)
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
# Parameters:
|
|
575
|
+
# recursive - boolean - If true, will recursively delete folders. Otherwise, will error on non-empty folders.
|
|
576
|
+
def delete(path, params=None, options=None):
|
|
577
|
+
if not isinstance(params, dict):
|
|
578
|
+
params = {}
|
|
579
|
+
if not isinstance(options, dict):
|
|
580
|
+
options = {}
|
|
581
|
+
params["path"] = path
|
|
582
|
+
if "path" in params and not isinstance(params["path"], str):
|
|
583
|
+
raise InvalidParameterError("Bad parameter: path must be an str")
|
|
584
|
+
if "recursive" in params and not isinstance(params["recursive"], bool):
|
|
585
|
+
raise InvalidParameterError("Bad parameter: recursive must be an bool")
|
|
586
|
+
if "path" not in params:
|
|
587
|
+
raise MissingParameterError("Parameter missing: path")
|
|
588
|
+
Api.send_request(
|
|
589
|
+
"DELETE", "/files/{path}".format(path=params["path"]), params, options
|
|
590
|
+
)
|
|
591
|
+
|
|
592
|
+
|
|
593
|
+
def destroy(path, params=None, options=None):
|
|
594
|
+
delete(path, params, options)
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
# Parameters:
|
|
598
|
+
# path (required) - string - Path to operate on.
|
|
599
|
+
# preview_size - string - Request a preview size. Can be `small` (default), `large`, `xlarge`, or `pdf`.
|
|
600
|
+
# with_previews - boolean - Include file preview information?
|
|
601
|
+
# with_priority_color - boolean - Include file priority color information?
|
|
602
|
+
def find(path, params=None, options=None):
|
|
603
|
+
if not isinstance(params, dict):
|
|
604
|
+
params = {}
|
|
605
|
+
if not isinstance(options, dict):
|
|
606
|
+
options = {}
|
|
607
|
+
params["path"] = path
|
|
608
|
+
if "path" in params and not isinstance(params["path"], str):
|
|
609
|
+
raise InvalidParameterError("Bad parameter: path must be an str")
|
|
610
|
+
if "preview_size" in params and not isinstance(
|
|
611
|
+
params["preview_size"], str
|
|
612
|
+
):
|
|
613
|
+
raise InvalidParameterError(
|
|
614
|
+
"Bad parameter: preview_size must be an str"
|
|
615
|
+
)
|
|
616
|
+
if "with_previews" in params and not isinstance(
|
|
617
|
+
params["with_previews"], bool
|
|
618
|
+
):
|
|
619
|
+
raise InvalidParameterError(
|
|
620
|
+
"Bad parameter: with_previews must be an bool"
|
|
621
|
+
)
|
|
622
|
+
if "with_priority_color" in params and not isinstance(
|
|
623
|
+
params["with_priority_color"], bool
|
|
624
|
+
):
|
|
625
|
+
raise InvalidParameterError(
|
|
626
|
+
"Bad parameter: with_priority_color must be an bool"
|
|
627
|
+
)
|
|
628
|
+
if "path" not in params:
|
|
629
|
+
raise MissingParameterError("Parameter missing: path")
|
|
630
|
+
response, options = Api.send_request(
|
|
631
|
+
"GET",
|
|
632
|
+
"/file_actions/metadata/{path}".format(path=params["path"]),
|
|
633
|
+
params,
|
|
634
|
+
options,
|
|
635
|
+
)
|
|
636
|
+
return File(response.data, options)
|
|
637
|
+
|
|
638
|
+
|
|
639
|
+
def get(path, params=None, options=None):
|
|
640
|
+
find(path, params, options)
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
# Copy File/Folder
|
|
644
|
+
#
|
|
645
|
+
# Parameters:
|
|
646
|
+
# destination (required) - string - Copy destination path.
|
|
647
|
+
# structure - boolean - Copy structure only?
|
|
648
|
+
# overwrite - boolean - Overwrite existing file(s) in the destination?
|
|
649
|
+
def copy(path, params=None, options=None):
|
|
650
|
+
if not isinstance(params, dict):
|
|
651
|
+
params = {}
|
|
652
|
+
if not isinstance(options, dict):
|
|
653
|
+
options = {}
|
|
654
|
+
params["path"] = path
|
|
655
|
+
if "path" in params and not isinstance(params["path"], str):
|
|
656
|
+
raise InvalidParameterError("Bad parameter: path must be an str")
|
|
657
|
+
if "destination" in params and not isinstance(params["destination"], str):
|
|
658
|
+
raise InvalidParameterError(
|
|
659
|
+
"Bad parameter: destination must be an str"
|
|
660
|
+
)
|
|
661
|
+
if "structure" in params and not isinstance(params["structure"], bool):
|
|
662
|
+
raise InvalidParameterError("Bad parameter: structure must be an bool")
|
|
663
|
+
if "overwrite" in params and not isinstance(params["overwrite"], bool):
|
|
664
|
+
raise InvalidParameterError("Bad parameter: overwrite must be an bool")
|
|
665
|
+
if "path" not in params:
|
|
666
|
+
raise MissingParameterError("Parameter missing: path")
|
|
667
|
+
if "destination" not in params:
|
|
668
|
+
raise MissingParameterError("Parameter missing: destination")
|
|
669
|
+
response, options = Api.send_request(
|
|
670
|
+
"POST",
|
|
671
|
+
"/file_actions/copy/{path}".format(path=params["path"]),
|
|
672
|
+
params,
|
|
673
|
+
options,
|
|
674
|
+
)
|
|
675
|
+
return FileAction(response.data, options)
|
|
676
|
+
|
|
677
|
+
|
|
678
|
+
# Move File/Folder
|
|
679
|
+
#
|
|
680
|
+
# Parameters:
|
|
681
|
+
# destination (required) - string - Move destination path.
|
|
682
|
+
# overwrite - boolean - Overwrite existing file(s) in the destination?
|
|
683
|
+
def move(path, params=None, options=None):
|
|
684
|
+
if not isinstance(params, dict):
|
|
685
|
+
params = {}
|
|
686
|
+
if not isinstance(options, dict):
|
|
687
|
+
options = {}
|
|
688
|
+
params["path"] = path
|
|
689
|
+
if "path" in params and not isinstance(params["path"], str):
|
|
690
|
+
raise InvalidParameterError("Bad parameter: path must be an str")
|
|
691
|
+
if "destination" in params and not isinstance(params["destination"], str):
|
|
692
|
+
raise InvalidParameterError(
|
|
693
|
+
"Bad parameter: destination must be an str"
|
|
694
|
+
)
|
|
695
|
+
if "overwrite" in params and not isinstance(params["overwrite"], bool):
|
|
696
|
+
raise InvalidParameterError("Bad parameter: overwrite must be an bool")
|
|
697
|
+
if "path" not in params:
|
|
698
|
+
raise MissingParameterError("Parameter missing: path")
|
|
699
|
+
if "destination" not in params:
|
|
700
|
+
raise MissingParameterError("Parameter missing: destination")
|
|
701
|
+
response, options = Api.send_request(
|
|
702
|
+
"POST",
|
|
703
|
+
"/file_actions/move/{path}".format(path=params["path"]),
|
|
704
|
+
params,
|
|
705
|
+
options,
|
|
706
|
+
)
|
|
707
|
+
return FileAction(response.data, options)
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
# Begin File Upload
|
|
711
|
+
#
|
|
712
|
+
# Parameters:
|
|
713
|
+
# mkdir_parents - boolean - Create parent directories if they do not exist?
|
|
714
|
+
# part - int64 - Part if uploading a part.
|
|
715
|
+
# parts - int64 - How many parts to fetch?
|
|
716
|
+
# ref - string -
|
|
717
|
+
# restart - int64 - File byte offset to restart from.
|
|
718
|
+
# size - int64 - Total bytes of file being uploaded (include bytes being retained if appending/restarting).
|
|
719
|
+
# with_rename - boolean - Allow file rename instead of overwrite?
|
|
720
|
+
def begin_upload(path, params=None, options=None):
|
|
721
|
+
if not isinstance(params, dict):
|
|
722
|
+
params = {}
|
|
723
|
+
if not isinstance(options, dict):
|
|
724
|
+
options = {}
|
|
725
|
+
params["path"] = path
|
|
726
|
+
if "path" in params and not isinstance(params["path"], str):
|
|
727
|
+
raise InvalidParameterError("Bad parameter: path must be an str")
|
|
728
|
+
if "mkdir_parents" in params and not isinstance(
|
|
729
|
+
params["mkdir_parents"], bool
|
|
730
|
+
):
|
|
731
|
+
raise InvalidParameterError(
|
|
732
|
+
"Bad parameter: mkdir_parents must be an bool"
|
|
733
|
+
)
|
|
734
|
+
if "part" in params and not isinstance(params["part"], int):
|
|
735
|
+
raise InvalidParameterError("Bad parameter: part must be an int")
|
|
736
|
+
if "parts" in params and not isinstance(params["parts"], int):
|
|
737
|
+
raise InvalidParameterError("Bad parameter: parts must be an int")
|
|
738
|
+
if "ref" in params and not isinstance(params["ref"], str):
|
|
739
|
+
raise InvalidParameterError("Bad parameter: ref must be an str")
|
|
740
|
+
if "restart" in params and not isinstance(params["restart"], int):
|
|
741
|
+
raise InvalidParameterError("Bad parameter: restart must be an int")
|
|
742
|
+
if "size" in params and not isinstance(params["size"], int):
|
|
743
|
+
raise InvalidParameterError("Bad parameter: size must be an int")
|
|
744
|
+
if "with_rename" in params and not isinstance(params["with_rename"], bool):
|
|
745
|
+
raise InvalidParameterError(
|
|
746
|
+
"Bad parameter: with_rename must be an bool"
|
|
747
|
+
)
|
|
748
|
+
if "path" not in params:
|
|
749
|
+
raise MissingParameterError("Parameter missing: path")
|
|
750
|
+
response, options = Api.send_request(
|
|
751
|
+
"POST",
|
|
752
|
+
"/file_actions/begin_upload/{path}".format(path=params["path"]),
|
|
753
|
+
params,
|
|
754
|
+
options,
|
|
755
|
+
)
|
|
756
|
+
return [
|
|
757
|
+
FileUploadPart(entity_data, options) for entity_data in response.data
|
|
758
|
+
]
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
def open(path, mode="r", options=None):
|
|
762
|
+
if not isinstance(options, dict):
|
|
763
|
+
options = {}
|
|
764
|
+
file = File(path, mode, options)
|
|
765
|
+
|
|
766
|
+
if "w" in mode:
|
|
767
|
+
if "b" in mode:
|
|
768
|
+
file.io_obj = io.BytesIO()
|
|
769
|
+
else:
|
|
770
|
+
file.io_obj = io.StringIO()
|
|
771
|
+
|
|
772
|
+
if "r" in mode:
|
|
773
|
+
if "b" in mode:
|
|
774
|
+
file.io_obj = io.BytesIO()
|
|
775
|
+
else:
|
|
776
|
+
file.io_obj = io.StringIO()
|
|
777
|
+
file.closed = False
|
|
778
|
+
return file
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
def upload_chunks(io, path, options, upload=None, etags=None, params=None):
|
|
782
|
+
if not etags:
|
|
783
|
+
etags = []
|
|
784
|
+
if not params:
|
|
785
|
+
params = {}
|
|
786
|
+
bytes_written = 0
|
|
787
|
+
while True:
|
|
788
|
+
chunk_params = (
|
|
789
|
+
{"part": 1}
|
|
790
|
+
if not upload
|
|
791
|
+
else {"ref": upload.ref, "part": upload.part_number + 1}
|
|
792
|
+
)
|
|
793
|
+
params.update(chunk_params)
|
|
794
|
+
upload = begin_upload(path, params, options)[0]
|
|
795
|
+
buf = io.read(upload.partsize)
|
|
796
|
+
if buf is not None: # None means no data but io still open
|
|
797
|
+
bytes_written += len(buf)
|
|
798
|
+
response = Api.client().send_remote_request(
|
|
799
|
+
upload.http_method,
|
|
800
|
+
upload.upload_uri,
|
|
801
|
+
{"Content-Length": str(len(buf))},
|
|
802
|
+
buf,
|
|
803
|
+
)
|
|
804
|
+
if "ETag" in response.headers:
|
|
805
|
+
etags.append(
|
|
806
|
+
{
|
|
807
|
+
"etag": response.headers["ETag"].strip('"'),
|
|
808
|
+
"part": upload.part_number,
|
|
809
|
+
}
|
|
810
|
+
)
|
|
811
|
+
if buf in [b"", ""] or (
|
|
812
|
+
len(buf) < upload.partsize
|
|
813
|
+
): # Empty bytearray means EOF for BytesIO, Empty String means EOF for StringIO
|
|
814
|
+
return (upload, etags, bytes_written)
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
def upload_file(path, destination=None, options=None, params=None):
|
|
818
|
+
if not isinstance(options, dict):
|
|
819
|
+
options = {}
|
|
820
|
+
pth = Path(path)
|
|
821
|
+
stat = pth.stat()
|
|
822
|
+
with builtin_open(path, "rb") as local_file:
|
|
823
|
+
if destination is None:
|
|
824
|
+
destination = pth.name
|
|
825
|
+
upload, etags, _bytes_written = upload_chunks(
|
|
826
|
+
local_file, destination, options, params=params
|
|
827
|
+
)
|
|
828
|
+
|
|
829
|
+
final_params = {
|
|
830
|
+
"action": "end",
|
|
831
|
+
"etags": etags,
|
|
832
|
+
"provided_mtime": datetime.utcfromtimestamp(
|
|
833
|
+
stat.st_mtime
|
|
834
|
+
).isoformat(),
|
|
835
|
+
"ref": upload.ref,
|
|
836
|
+
"size": stat.st_size,
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
create(destination, final_params, options)
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
def download_file(path, local_path=None, options=None):
|
|
843
|
+
if not isinstance(options, dict):
|
|
844
|
+
options = {}
|
|
845
|
+
if local_path is None:
|
|
846
|
+
local_path = Path(path).name
|
|
847
|
+
return File(path, {}, options).download_file(local_path)
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
def new(*args, **kwargs):
|
|
851
|
+
return File(*args, **kwargs)
|