files-com 1.5.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 files-com might be problematic. Click here for more details.

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