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.

Files changed (126) hide show
  1. README.md +758 -0
  2. _VERSION +1 -0
  3. files_com-1.6.208.dist-info/METADATA +770 -0
  4. files_com-1.6.208.dist-info/RECORD +126 -0
  5. files_com-1.6.208.dist-info/WHEEL +5 -0
  6. files_com-1.6.208.dist-info/licenses/LICENSE +21 -0
  7. files_com-1.6.208.dist-info/top_level.txt +1 -0
  8. files_sdk/__init__.py +309 -0
  9. files_sdk/api.py +63 -0
  10. files_sdk/api_client.py +336 -0
  11. files_sdk/error.py +2981 -0
  12. files_sdk/list_obj.py +42 -0
  13. files_sdk/models/__init__.py +119 -0
  14. files_sdk/models/account_line_item.py +51 -0
  15. files_sdk/models/action.py +49 -0
  16. files_sdk/models/action_notification_export.py +153 -0
  17. files_sdk/models/action_notification_export_result.py +88 -0
  18. files_sdk/models/agent_push_update.py +44 -0
  19. files_sdk/models/api_key.py +318 -0
  20. files_sdk/models/api_request_log.py +105 -0
  21. files_sdk/models/app.py +89 -0
  22. files_sdk/models/as2_incoming_message.py +117 -0
  23. files_sdk/models/as2_outgoing_message.py +113 -0
  24. files_sdk/models/as2_partner.py +415 -0
  25. files_sdk/models/as2_station.py +282 -0
  26. files_sdk/models/auto.py +36 -0
  27. files_sdk/models/automation.py +823 -0
  28. files_sdk/models/automation_log.py +94 -0
  29. files_sdk/models/automation_run.py +112 -0
  30. files_sdk/models/bandwidth_snapshot.py +91 -0
  31. files_sdk/models/behavior.py +340 -0
  32. files_sdk/models/bundle.py +686 -0
  33. files_sdk/models/bundle_action.py +93 -0
  34. files_sdk/models/bundle_download.py +94 -0
  35. files_sdk/models/bundle_notification.py +252 -0
  36. files_sdk/models/bundle_path.py +37 -0
  37. files_sdk/models/bundle_recipient.py +133 -0
  38. files_sdk/models/bundle_registration.py +82 -0
  39. files_sdk/models/child_site_management_policy.py +278 -0
  40. files_sdk/models/clickwrap.py +268 -0
  41. files_sdk/models/dns_record.py +59 -0
  42. files_sdk/models/email_incoming_message.py +102 -0
  43. files_sdk/models/email_log.py +84 -0
  44. files_sdk/models/errors.py +37 -0
  45. files_sdk/models/exavault_api_request_log.py +102 -0
  46. files_sdk/models/external_event.py +148 -0
  47. files_sdk/models/file.py +851 -0
  48. files_sdk/models/file_action.py +39 -0
  49. files_sdk/models/file_comment.py +191 -0
  50. files_sdk/models/file_comment_reaction.py +125 -0
  51. files_sdk/models/file_migration.py +69 -0
  52. files_sdk/models/file_migration_log.py +88 -0
  53. files_sdk/models/file_upload_part.py +54 -0
  54. files_sdk/models/folder.py +186 -0
  55. files_sdk/models/form_field.py +43 -0
  56. files_sdk/models/form_field_set.py +265 -0
  57. files_sdk/models/ftp_action_log.py +104 -0
  58. files_sdk/models/gpg_key.py +333 -0
  59. files_sdk/models/group.py +338 -0
  60. files_sdk/models/group_user.py +235 -0
  61. files_sdk/models/history.py +236 -0
  62. files_sdk/models/history_export.py +238 -0
  63. files_sdk/models/history_export_result.py +98 -0
  64. files_sdk/models/holiday_region.py +58 -0
  65. files_sdk/models/image.py +37 -0
  66. files_sdk/models/inbound_s3_log.py +95 -0
  67. files_sdk/models/inbox_recipient.py +124 -0
  68. files_sdk/models/inbox_registration.py +79 -0
  69. files_sdk/models/inbox_upload.py +80 -0
  70. files_sdk/models/invoice.py +91 -0
  71. files_sdk/models/invoice_line_item.py +51 -0
  72. files_sdk/models/ip_address.py +119 -0
  73. files_sdk/models/key_lifecycle_rule.py +243 -0
  74. files_sdk/models/lock.py +174 -0
  75. files_sdk/models/message.py +244 -0
  76. files_sdk/models/message_comment.py +223 -0
  77. files_sdk/models/message_comment_reaction.py +181 -0
  78. files_sdk/models/message_reaction.py +170 -0
  79. files_sdk/models/notification.py +451 -0
  80. files_sdk/models/outbound_connection_log.py +105 -0
  81. files_sdk/models/partner.py +307 -0
  82. files_sdk/models/payment.py +91 -0
  83. files_sdk/models/payment_line_item.py +42 -0
  84. files_sdk/models/permission.py +190 -0
  85. files_sdk/models/preview.py +40 -0
  86. files_sdk/models/priority.py +63 -0
  87. files_sdk/models/project.py +205 -0
  88. files_sdk/models/public_hosting_request_log.py +101 -0
  89. files_sdk/models/public_ip_address.py +42 -0
  90. files_sdk/models/public_key.py +269 -0
  91. files_sdk/models/remote_bandwidth_snapshot.py +91 -0
  92. files_sdk/models/remote_mount_backend.py +438 -0
  93. files_sdk/models/remote_server.py +1854 -0
  94. files_sdk/models/remote_server_configuration_file.py +73 -0
  95. files_sdk/models/remote_server_credential.py +855 -0
  96. files_sdk/models/request.py +184 -0
  97. files_sdk/models/restore.py +142 -0
  98. files_sdk/models/scim_log.py +88 -0
  99. files_sdk/models/session.py +100 -0
  100. files_sdk/models/settings_change.py +71 -0
  101. files_sdk/models/sftp_action_log.py +108 -0
  102. files_sdk/models/sftp_host_key.py +215 -0
  103. files_sdk/models/share_group.py +228 -0
  104. files_sdk/models/share_group_member.py +41 -0
  105. files_sdk/models/siem_http_destination.py +1074 -0
  106. files_sdk/models/site.py +1289 -0
  107. files_sdk/models/snapshot.py +255 -0
  108. files_sdk/models/sso_strategy.py +168 -0
  109. files_sdk/models/status.py +42 -0
  110. files_sdk/models/style.py +152 -0
  111. files_sdk/models/sync.py +588 -0
  112. files_sdk/models/sync_log.py +86 -0
  113. files_sdk/models/sync_run.py +124 -0
  114. files_sdk/models/usage_by_top_level_dir.py +41 -0
  115. files_sdk/models/usage_daily_snapshot.py +93 -0
  116. files_sdk/models/usage_snapshot.py +73 -0
  117. files_sdk/models/user.py +1232 -0
  118. files_sdk/models/user_cipher_use.py +91 -0
  119. files_sdk/models/user_lifecycle_rule.py +355 -0
  120. files_sdk/models/user_request.py +166 -0
  121. files_sdk/models/user_sftp_client_use.py +68 -0
  122. files_sdk/models/web_dav_action_log.py +104 -0
  123. files_sdk/models/webhook_test.py +116 -0
  124. files_sdk/models/workspace.py +202 -0
  125. files_sdk/path_util.py +42 -0
  126. files_sdk/util.py +34 -0
@@ -0,0 +1,336 @@
1
+ import json
2
+ import random
3
+ import requests
4
+ import time
5
+ from urllib.parse import urljoin
6
+
7
+ import files_sdk
8
+ from files_sdk.error import (
9
+ APIConnectionError,
10
+ APIError,
11
+ AuthenticationError,
12
+ Error,
13
+ )
14
+ import files_sdk.util as util
15
+ from requests_toolbelt.adapters import source
16
+
17
+
18
+ class ApiClient:
19
+ """
20
+ The Files.com API Client.
21
+ """
22
+
23
+ def __init__(self):
24
+ pass
25
+
26
+ self.session = requests.Session()
27
+
28
+ if (
29
+ files_sdk.get_source_ip() is not None
30
+ and self.session.adapters.get(files_sdk.base_url, None) is None
31
+ ):
32
+ self.session.mount(
33
+ files_sdk.base_url,
34
+ source.SourceAddressAdapter(files_sdk.get_source_ip()),
35
+ )
36
+
37
+ def send_remote_request(self, method, url, headers=None, body=None):
38
+ if headers is None:
39
+ headers = {}
40
+ req = requests.Request(method, url=url, headers=headers, data=body)
41
+
42
+ response = self.execute_request_with_auto_retry(req)
43
+ return response
44
+
45
+ def send_request(
46
+ self,
47
+ method,
48
+ path,
49
+ api_key=None,
50
+ session_id=None,
51
+ language=None,
52
+ headers=None,
53
+ params=None,
54
+ ):
55
+ if headers is None:
56
+ headers = {}
57
+ full_path = files_sdk.base_path + path
58
+ url = urljoin(files_sdk.base_url, full_path)
59
+
60
+ if files_sdk.session_id:
61
+ session_id = files_sdk.session_id
62
+
63
+ if session_id and session_id != "":
64
+ self.check_session_id(session_id)
65
+ elif not path.startswith("/sessions"):
66
+ if not api_key:
67
+ api_key = files_sdk.get_api_key()
68
+ self.check_api_key(api_key)
69
+
70
+ if files_sdk.language:
71
+ language = files_sdk.language
72
+
73
+ headers = {
74
+ **headers,
75
+ **self.request_headers(api_key, session_id, language),
76
+ }
77
+
78
+ data = None
79
+ query_params = None
80
+ if params:
81
+ if method in ["GET", "HEAD", "DELETE"]:
82
+ data = None
83
+ _params = {}
84
+ for k, v in params.items():
85
+ if isinstance(v, dict):
86
+ for k2, v2 in v.items():
87
+ _params[f"{k}[{k2}]"] = v2
88
+ else:
89
+ _params[k] = v
90
+ query_params = _params
91
+ else:
92
+ data = params
93
+ query_params = None
94
+
95
+ req = requests.Request(
96
+ method, url=url, headers=headers, params=query_params, json=data
97
+ )
98
+
99
+ response = self.execute_request_with_auto_retry(req)
100
+
101
+ if response.status_code != 204:
102
+ try:
103
+ response.data = response.json()
104
+ except json.decoder.JSONDecodeError:
105
+ if response.status_code == 403:
106
+ raise AuthenticationError(
107
+ response.content,
108
+ http_status=response.status_code,
109
+ headers=response.headers,
110
+ )
111
+ if response.status_code >= 500:
112
+ raise APIConnectionError(
113
+ response.content,
114
+ http_status=response.status_code,
115
+ headers=response.headers,
116
+ )
117
+ raise self.general_api_error(
118
+ response, "Error parsing JSON response"
119
+ )
120
+ else:
121
+ response.data = None
122
+
123
+ return response
124
+
125
+ def stream_download(self, uri, io, is_string_io=False):
126
+ # NOTE the stream=True parameter below
127
+ with requests.get(uri, stream=True) as r:
128
+ r.raise_for_status() # TODO check this later
129
+ for chunk in r.iter_content(
130
+ chunk_size=8192, decode_unicode=is_string_io
131
+ ):
132
+ # If you have chunk encoded response uncomment if
133
+ # and set chunk_size parameter to None.
134
+ # if chunk:
135
+ io.write(chunk)
136
+
137
+ def execute_request_with_auto_retry(
138
+ self, request, skip_body_logging=False
139
+ ):
140
+ for try_num in range(0, files_sdk.max_network_retries):
141
+ response = None
142
+ request_start = time.time()
143
+ try:
144
+ self.log_request(request, try_num)
145
+ prepped = request.prepare()
146
+ settings = self.session.merge_environment_settings(
147
+ prepped.url, {}, None, None, None
148
+ )
149
+ response = self.session.send(
150
+ prepped,
151
+ timeout=(files_sdk.open_timeout, files_sdk.read_timeout),
152
+ **settings,
153
+ )
154
+
155
+ self.log_response(
156
+ request,
157
+ request_start,
158
+ response.status_code,
159
+ response.content,
160
+ )
161
+ response.raise_for_status()
162
+ return response
163
+ except Exception as e:
164
+ if response is not None:
165
+ self.log_response(
166
+ request,
167
+ request_start,
168
+ response.status_code,
169
+ response.content,
170
+ )
171
+ else:
172
+ self.log_response_error(request, request_start, e)
173
+
174
+ if try_num + 1 == files_sdk.max_network_retries:
175
+ if response is not None:
176
+ self.handle_error_response(response)
177
+ else:
178
+ raise self.handle_network_error(
179
+ e, request, try_num
180
+ ) from None
181
+ raise
182
+
183
+ time.sleep(ApiClient.sleep_time(try_num))
184
+ raise APIConnectionError(
185
+ f"Request failed after {files_sdk.max_network_retries} attempts"
186
+ )
187
+
188
+ @staticmethod
189
+ def sleep_time(num_retries):
190
+ sleep_seconds = min(
191
+ files_sdk.initial_network_retry_delay * (2 ** (num_retries - 1)),
192
+ files_sdk.max_network_retry_delay,
193
+ )
194
+ sleep_seconds *= 0.5 * (1 + random.random())
195
+ return max(files_sdk.initial_network_retry_delay, sleep_seconds)
196
+
197
+ def request_headers(self, api_key, session_id, language):
198
+ user_agent = "Files.com Python SDK v{version}".format(
199
+ version=files_sdk.version
200
+ )
201
+ # user_agent += " " + format_app_info(Files.app_info) unless Files.app_info.nil?
202
+
203
+ headers = {
204
+ "User-Agent": user_agent,
205
+ "Content-Type": "application/json",
206
+ }
207
+ if api_key:
208
+ headers["X-FilesAPI-Key"] = api_key
209
+ if session_id:
210
+ headers["X-FilesAPI-Auth"] = session_id
211
+ if language:
212
+ headers["Accept-Language"] = language
213
+
214
+ return headers
215
+
216
+ def check_api_key(self, api_key):
217
+ if not api_key:
218
+ raise AuthenticationError(
219
+ "No Files.com API key provided. "
220
+ 'Set your API key using "Files.api_key = <API-KEY>". '
221
+ "You can generate API keys from the Files.com's web interface. "
222
+ )
223
+
224
+ if not api_key.isalnum():
225
+ raise AuthenticationError(
226
+ "Your API key is invalid (it contains whitespace)"
227
+ )
228
+
229
+ def check_session_id(self, session_id):
230
+ if not session_id.isalnum():
231
+ raise AuthenticationError(
232
+ "The provided Session ID is invalid (it contains whitespace)"
233
+ )
234
+
235
+ def general_api_error(self, response, extra_info=None):
236
+ msg = "Unexpected response object from API: {body} (HTTP response code was {status})".format(
237
+ body=repr(response.content), status=response.status_code
238
+ )
239
+ if extra_info is not None:
240
+ msg += " Additional Information: {}".format(extra_info)
241
+ return APIError(msg)
242
+
243
+ def handle_error_response(self, response):
244
+ error_data = None
245
+
246
+ try:
247
+ response.data = response.json()
248
+ except json.decoder.JSONDecodeError:
249
+ response.data = ""
250
+
251
+ try:
252
+ if "error" in response.data:
253
+ error_data = response.data["error"]
254
+ elif "errors" in response.data:
255
+ error_data = response.data["errors"]
256
+ if isinstance(error_data, list) and len(error_data) > 0:
257
+ error_data = error_data[0]
258
+ if isinstance(error_data, str):
259
+ error_data = {"message": error_data}
260
+
261
+ if not error_data:
262
+ raise Error("Unknown error")
263
+ except Error:
264
+ raise self.general_api_error(response, "Unknown error")
265
+
266
+ error = self.specific_api_error(response, error_data)
267
+
268
+ error.response = response
269
+ raise error
270
+
271
+ def specific_api_error(self, response, error_data):
272
+ import files_sdk.error
273
+
274
+ util.log_error(
275
+ "API error", status=response.status_code, error_message=error_data
276
+ )
277
+
278
+ opts = {
279
+ "http_body": response.content,
280
+ "headers": response.headers,
281
+ "http_status": response.status_code,
282
+ "json_body": response.data,
283
+ "code": error_data.get("code", response.status_code),
284
+ }
285
+
286
+ error_type = response.data["type"].split("/")[-1]
287
+ error_class_name = (
288
+ "".join(list(map(str.capitalize, error_type.split("-")))) + "Error"
289
+ )
290
+ try:
291
+ return getattr(files_sdk.error, error_class_name)(
292
+ error_data["message"], **opts
293
+ )
294
+ except AttributeError:
295
+ return APIError(error_data["message"], **opts)
296
+
297
+ def handle_network_error(self, error, request, num_retries):
298
+ util.log_error("Network error", error_message=error)
299
+ msg = "Could not connect to Files.com at URL {}. Please check your internet connection and try again. If this problem persists, you should check Files.com's service status at https://status.files.com, or contact your primary account representative.".format(
300
+ files_sdk.base_url
301
+ )
302
+ if num_retries > 0:
303
+ msg += " Request was retried {} times.".format(num_retries)
304
+ msg += "\n\n(Network error: {})".format(error)
305
+
306
+ return APIConnectionError(msg)
307
+
308
+ def log_request(self, request, num_retries):
309
+ util.log_info(
310
+ "Request",
311
+ method=request.method,
312
+ num_retries=num_retries,
313
+ url=request.url,
314
+ )
315
+ util.log_debug(
316
+ "Request details", body=request.data, query_params=request.params
317
+ )
318
+
319
+ def log_response(self, request, request_start, status, body):
320
+ util.log_info(
321
+ "Response",
322
+ elapsed=(time.time() - request_start),
323
+ method=request.method,
324
+ url=request.url,
325
+ status=status,
326
+ )
327
+ util.log_debug("Response details", body=body)
328
+
329
+ def log_response_error(self, request, request_start, error):
330
+ util.log_error(
331
+ "Error",
332
+ elapsed=(time.time() - request_start),
333
+ error_message=error,
334
+ method=request.method,
335
+ url=request.url,
336
+ )