kaggle 1.7.4.5__py3-none-any.whl → 1.8.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.
- kaggle/__init__.py +10 -6
- kaggle/api/kaggle_api.py +574 -598
- kaggle/api/kaggle_api_extended.py +5251 -4769
- kaggle/cli.py +1335 -1585
- kaggle/models/api_blob_type.py +3 -3
- kaggle/models/dataset_column.py +165 -174
- kaggle/models/dataset_new_request.py +83 -41
- kaggle/models/dataset_new_version_request.py +32 -25
- kaggle/models/dataset_update_settings_request.py +35 -27
- kaggle/models/kaggle_models_extended.py +169 -172
- kaggle/models/kernel_push_request.py +66 -49
- kaggle/models/model_instance_new_version_request.py +10 -18
- kaggle/models/model_instance_update_request.py +103 -34
- kaggle/models/model_new_instance_request.py +138 -41
- kaggle/models/model_new_request.py +35 -27
- kaggle/models/model_update_request.py +32 -25
- kaggle/models/start_blob_upload_request.py +192 -195
- kaggle/models/start_blob_upload_response.py +98 -98
- kaggle/models/upload_file.py +114 -120
- kaggle/test/test_authenticate.py +23 -23
- {kaggle-1.7.4.5.dist-info → kaggle-1.8.0.dist-info}/METADATA +11 -15
- kaggle-1.8.0.dist-info/RECORD +148 -0
- kagglesdk/__init__.py +5 -1
- kagglesdk/benchmarks/services/__init__.py +0 -0
- kagglesdk/benchmarks/services/benchmarks_api_service.py +19 -0
- kagglesdk/benchmarks/types/__init__.py +0 -0
- kagglesdk/benchmarks/types/benchmark_types.py +307 -0
- kagglesdk/benchmarks/types/benchmarks_api_service.py +243 -0
- kagglesdk/blobs/services/blob_api_service.py +1 -1
- kagglesdk/blobs/types/blob_api_service.py +2 -2
- kagglesdk/common/services/__init__.py +0 -0
- kagglesdk/common/services/operations_service.py +46 -0
- kagglesdk/common/types/file_download.py +1 -1
- kagglesdk/common/types/http_redirect.py +1 -1
- kagglesdk/common/types/operations.py +194 -0
- kagglesdk/common/types/operations_service.py +48 -0
- kagglesdk/community/__init__.py +0 -0
- kagglesdk/community/types/__init__.py +0 -0
- kagglesdk/community/types/content_enums.py +44 -0
- kagglesdk/community/types/organization.py +410 -0
- kagglesdk/competitions/services/competition_api_service.py +49 -12
- kagglesdk/competitions/types/competition.py +14 -0
- kagglesdk/competitions/types/competition_api_service.py +1639 -1275
- kagglesdk/competitions/types/search_competitions.py +28 -0
- kagglesdk/datasets/databundles/__init__.py +0 -0
- kagglesdk/datasets/databundles/types/__init__.py +0 -0
- kagglesdk/datasets/databundles/types/databundle_api_types.py +540 -0
- kagglesdk/datasets/services/dataset_api_service.py +39 -14
- kagglesdk/datasets/types/dataset_api_service.py +554 -300
- kagglesdk/datasets/types/dataset_enums.py +21 -0
- kagglesdk/datasets/types/dataset_service.py +145 -0
- kagglesdk/datasets/types/dataset_types.py +74 -74
- kagglesdk/datasets/types/search_datasets.py +6 -0
- kagglesdk/discussions/__init__.py +0 -0
- kagglesdk/discussions/types/__init__.py +0 -0
- kagglesdk/discussions/types/search_discussions.py +43 -0
- kagglesdk/discussions/types/writeup_enums.py +11 -0
- kagglesdk/education/services/education_api_service.py +1 -1
- kagglesdk/education/types/education_api_service.py +1 -1
- kagglesdk/kaggle_client.py +46 -23
- kagglesdk/kaggle_creds.py +148 -0
- kagglesdk/kaggle_env.py +89 -25
- kagglesdk/kaggle_http_client.py +216 -306
- kagglesdk/kaggle_oauth.py +200 -0
- kagglesdk/kaggle_object.py +286 -293
- kagglesdk/kernels/services/kernels_api_service.py +46 -9
- kagglesdk/kernels/types/kernels_api_service.py +635 -159
- kagglesdk/kernels/types/kernels_enums.py +6 -0
- kagglesdk/kernels/types/search_kernels.py +6 -0
- kagglesdk/licenses/__init__.py +0 -0
- kagglesdk/licenses/types/__init__.py +0 -0
- kagglesdk/licenses/types/licenses_types.py +182 -0
- kagglesdk/models/services/model_api_service.py +41 -17
- kagglesdk/models/types/model_api_service.py +987 -637
- kagglesdk/models/types/model_enums.py +8 -0
- kagglesdk/models/types/model_service.py +71 -71
- kagglesdk/models/types/model_types.py +1057 -5
- kagglesdk/models/types/search_models.py +8 -0
- kagglesdk/search/__init__.py +0 -0
- kagglesdk/search/services/__init__.py +0 -0
- kagglesdk/search/services/search_api_service.py +19 -0
- kagglesdk/search/types/__init__.py +0 -0
- kagglesdk/search/types/search_api_service.py +2435 -0
- kagglesdk/search/types/search_content_shared.py +50 -0
- kagglesdk/search/types/search_enums.py +45 -0
- kagglesdk/search/types/search_service.py +303 -0
- kagglesdk/security/services/iam_service.py +31 -0
- kagglesdk/security/services/oauth_service.py +27 -1
- kagglesdk/security/types/authentication.py +63 -63
- kagglesdk/security/types/iam_service.py +496 -0
- kagglesdk/security/types/oauth_service.py +797 -10
- kagglesdk/security/types/roles.py +8 -0
- kagglesdk/security/types/security_types.py +159 -0
- kagglesdk/test/__init__.py +0 -0
- kagglesdk/test/test_client.py +20 -22
- kagglesdk/users/services/account_service.py +13 -1
- kagglesdk/users/services/group_api_service.py +31 -0
- kagglesdk/users/types/account_service.py +169 -28
- kagglesdk/users/types/group_api_service.py +315 -0
- kagglesdk/users/types/group_types.py +165 -0
- kagglesdk/users/types/groups_enum.py +8 -0
- kagglesdk/users/types/progression_service.py +9 -0
- kagglesdk/users/types/search_users.py +23 -0
- kagglesdk/users/types/user_avatar.py +226 -0
- kaggle/configuration.py +0 -206
- kaggle-1.7.4.5.dist-info/RECORD +0 -98
- {kaggle-1.7.4.5.dist-info → kaggle-1.8.0.dist-info}/WHEEL +0 -0
- {kaggle-1.7.4.5.dist-info → kaggle-1.8.0.dist-info}/entry_points.txt +0 -0
- {kaggle-1.7.4.5.dist-info → kaggle-1.8.0.dist-info}/licenses/LICENSE.txt +0 -0
- {kaggle/test → kagglesdk/benchmarks}/__init__.py +0 -0
|
@@ -30,29 +30,40 @@ class DatasetUpdateSettingsRequest(object):
|
|
|
30
30
|
attribute_map (dict): The key is attribute name
|
|
31
31
|
and the value is json key in definition.
|
|
32
32
|
"""
|
|
33
|
+
|
|
33
34
|
project_types = {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
"title": "str",
|
|
36
|
+
"subtitle": "str",
|
|
37
|
+
"description": "str",
|
|
38
|
+
"is_private": "bool",
|
|
39
|
+
"licenses": "list[object]",
|
|
40
|
+
"keywords": "list[str]",
|
|
41
|
+
"collaborators": "list[object]",
|
|
42
|
+
"data": "list[object]",
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
attribute_map = {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
"title": "title",
|
|
47
|
+
"subtitle": "subtitle",
|
|
48
|
+
"description": "description",
|
|
49
|
+
"is_private": "isPrivate",
|
|
50
|
+
"licenses": "licenses",
|
|
51
|
+
"keywords": "keywords",
|
|
52
|
+
"collaborators": "collaborators",
|
|
53
|
+
"data": "data",
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
def __init__(
|
|
56
|
+
def __init__(
|
|
57
|
+
self,
|
|
58
|
+
title=None,
|
|
59
|
+
subtitle=None,
|
|
60
|
+
description=None,
|
|
61
|
+
is_private=None,
|
|
62
|
+
licenses=None,
|
|
63
|
+
keywords=None,
|
|
64
|
+
collaborators=None,
|
|
65
|
+
data=None,
|
|
66
|
+
): # noqa: E501
|
|
56
67
|
|
|
57
68
|
self._title = None
|
|
58
69
|
self._subtitle = None
|
|
@@ -298,18 +309,16 @@ class DatasetUpdateSettingsRequest(object):
|
|
|
298
309
|
for attr, _ in six.iteritems(self.project_types):
|
|
299
310
|
value = getattr(self, attr)
|
|
300
311
|
if isinstance(value, list):
|
|
301
|
-
result[attr] = list(map(
|
|
302
|
-
lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
|
|
303
|
-
value
|
|
304
|
-
))
|
|
312
|
+
result[attr] = list(map(lambda x: x.to_dict() if hasattr(x, "to_dict") else x, value))
|
|
305
313
|
elif hasattr(value, "to_dict"):
|
|
306
314
|
result[attr] = value.to_dict()
|
|
307
315
|
elif isinstance(value, dict):
|
|
308
|
-
result[attr] = dict(
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
316
|
+
result[attr] = dict(
|
|
317
|
+
map(
|
|
318
|
+
lambda item: (item[0], item[1].to_dict()) if hasattr(item[1], "to_dict") else item,
|
|
319
|
+
value.items(),
|
|
320
|
+
)
|
|
321
|
+
)
|
|
313
322
|
else:
|
|
314
323
|
result[attr] = value
|
|
315
324
|
|
|
@@ -333,4 +342,3 @@ class DatasetUpdateSettingsRequest(object):
|
|
|
333
342
|
def __ne__(self, other):
|
|
334
343
|
"""Returns true if both objects are not equal."""
|
|
335
344
|
return not self == other
|
|
336
|
-
|
|
@@ -20,260 +20,257 @@ from datetime import datetime
|
|
|
20
20
|
|
|
21
21
|
class Competition(object):
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
def __init__(self, init_dict):
|
|
24
|
+
parsed_dict = {k: parse(v) for k, v in init_dict.items()}
|
|
25
|
+
self.__dict__.update(parsed_dict)
|
|
26
|
+
self.tags = [Tag(t) for t in self.tags]
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
def __repr__(self):
|
|
29
|
+
return self.ref
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
class SubmitResult(object):
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
def __init__(self, init_dict):
|
|
35
|
+
parsed_dict = {k: parse(v) for k, v in init_dict.items()}
|
|
36
|
+
self.__dict__.update(parsed_dict)
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
def __repr__(self):
|
|
39
|
+
return self.message
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
class Submission(object):
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
def __init__(self, init_dict):
|
|
45
|
+
parsed_dict = {k: parse(v) for k, v in init_dict.items()}
|
|
46
|
+
self.__dict__.update(parsed_dict)
|
|
47
|
+
if self.totalBytes is None:
|
|
48
|
+
self.size = None
|
|
49
|
+
else:
|
|
50
|
+
self.size = File.get_size(self.totalBytes)
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
def __repr__(self):
|
|
53
|
+
return str(self.ref)
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
class LeaderboardEntry(object):
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
def __init__(self, init_dict):
|
|
59
|
+
parsed_dict = {k: parse(v) for k, v in init_dict.items()}
|
|
60
|
+
self.__dict__.update(parsed_dict)
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
def __repr__(self):
|
|
63
|
+
return self.teamId
|
|
64
64
|
|
|
65
65
|
|
|
66
66
|
class Dataset(object):
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
68
|
+
def __init__(self, init_dict):
|
|
69
|
+
parsed_dict = {k: parse(v) for k, v in init_dict.items()}
|
|
70
|
+
self.__dict__.update(parsed_dict)
|
|
71
|
+
self.tags = [Tag(t) for t in self.tags]
|
|
72
|
+
self.files = [File(f) for f in self.files]
|
|
73
|
+
self.versions = [DatasetVersion(v) for v in self.versions]
|
|
74
|
+
self.size = File.get_size(self.totalBytes)
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
def __repr__(self):
|
|
77
|
+
return self.ref
|
|
78
78
|
|
|
79
79
|
|
|
80
80
|
class Model(object):
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
def __init__(self, init_dict):
|
|
83
|
+
parsed_dict = {k: parse(v) for k, v in init_dict.items()}
|
|
84
|
+
self.__dict__.update(parsed_dict)
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
def __repr__(self):
|
|
87
|
+
return self.ref
|
|
88
88
|
|
|
89
89
|
|
|
90
90
|
class Metadata(object):
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
92
|
+
def __init__(self, init_info):
|
|
93
|
+
parsed_info = {k: parse(v) for k, v in init_info.items()}
|
|
94
|
+
# backwards compatibility
|
|
95
|
+
self.id = parsed_info["ownerUser"] + "/" + parsed_info["datasetSlug"]
|
|
96
|
+
self.id_no = parsed_info["datasetId"]
|
|
97
|
+
self.__dict__.update(parsed_info)
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
def __repr__(self):
|
|
100
|
+
return str(self.datasetId)
|
|
101
101
|
|
|
102
102
|
|
|
103
103
|
class DatasetVersion(object):
|
|
104
104
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
def __init__(self, init_dict):
|
|
106
|
+
parsed_dict = {k: parse(v) for k, v in init_dict.items()}
|
|
107
|
+
self.__dict__.update(parsed_dict)
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
def __repr__(self):
|
|
110
|
+
return str(self.versionNumber)
|
|
111
111
|
|
|
112
112
|
|
|
113
113
|
class File(object):
|
|
114
114
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
115
|
+
def __init__(self, init_dict):
|
|
116
|
+
try: # TODO Remove try-block
|
|
117
|
+
parsed_dict = {k: parse(v) for k, v in init_dict.items()}
|
|
118
|
+
self.__dict__.update(parsed_dict)
|
|
119
|
+
self.size = File.get_size(self.totalBytes)
|
|
120
|
+
except AttributeError:
|
|
121
|
+
self.name = init_dict.name
|
|
122
|
+
self.creation_date = init_dict.creation_date
|
|
123
|
+
try:
|
|
124
|
+
self.size = File.get_size(init_dict.total_bytes)
|
|
125
|
+
except Exception: # AttributeError would be preferred but doesn't work.
|
|
126
|
+
self.size = File.get_size(init_dict.size)
|
|
127
|
+
self.total_bytes = self.size
|
|
128
|
+
|
|
129
|
+
def __repr__(self):
|
|
130
|
+
return self.name
|
|
131
|
+
|
|
132
|
+
@staticmethod
|
|
133
|
+
def get_size(size, precision=0):
|
|
134
|
+
suffixes = ["B", "KB", "MB", "GB", "TB"]
|
|
135
|
+
suffix_index = 0
|
|
136
|
+
while size >= 1024 and suffix_index < 4:
|
|
137
|
+
suffix_index += 1
|
|
138
|
+
size /= 1024.0
|
|
139
|
+
return "%.*f%s" % (precision, size, suffixes[suffix_index])
|
|
139
140
|
|
|
140
141
|
|
|
141
142
|
class Tag(object):
|
|
142
143
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
def __init__(self, init_dict):
|
|
145
|
+
parsed_dict = {k: parse(v) for k, v in init_dict.items()}
|
|
146
|
+
self.__dict__.update(parsed_dict)
|
|
146
147
|
|
|
147
|
-
|
|
148
|
-
|
|
148
|
+
def __repr__(self):
|
|
149
|
+
return self.ref
|
|
149
150
|
|
|
150
151
|
|
|
151
152
|
class DatasetNewVersionResponse(object):
|
|
152
153
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
def __init__(self, init_dict):
|
|
155
|
+
parsed_dict = {k: parse(v) for k, v in init_dict.items()}
|
|
156
|
+
self.__dict__.update(parsed_dict)
|
|
156
157
|
|
|
157
|
-
|
|
158
|
-
|
|
158
|
+
def __repr__(self):
|
|
159
|
+
return self.url
|
|
159
160
|
|
|
160
161
|
|
|
161
162
|
class DatasetNewResponse(object):
|
|
162
163
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
164
|
+
def __init__(self, init_dict):
|
|
165
|
+
parsed_dict = {k: parse(v) for k, v in init_dict.items()}
|
|
166
|
+
self.__dict__.update(parsed_dict)
|
|
166
167
|
|
|
167
|
-
|
|
168
|
-
|
|
168
|
+
def __repr__(self):
|
|
169
|
+
return self.url
|
|
169
170
|
|
|
170
171
|
|
|
171
172
|
class ListFilesResult(object):
|
|
172
173
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
174
|
+
def __init__(self, init_dict):
|
|
175
|
+
try: # TODO Remove try-block
|
|
176
|
+
self.error_message = init_dict["errorMessage"]
|
|
177
|
+
files = init_dict["datasetFiles"]
|
|
178
|
+
token = init_dict["nextPageToken"]
|
|
179
|
+
except TypeError:
|
|
180
|
+
self.error_message = init_dict.error_message
|
|
181
|
+
files = init_dict.dataset_files
|
|
182
|
+
token = init_dict.next_page_token
|
|
183
|
+
if files:
|
|
184
|
+
self.files = [File(f) for f in files]
|
|
185
|
+
else:
|
|
186
|
+
self.files = {}
|
|
187
|
+
if token:
|
|
188
|
+
self.nextPageToken = token
|
|
189
|
+
else:
|
|
190
|
+
self.nextPageToken = ""
|
|
191
|
+
|
|
192
|
+
def __repr__(self):
|
|
193
|
+
return self.error_message
|
|
193
194
|
|
|
194
195
|
|
|
195
196
|
class Kernel:
|
|
196
197
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
198
|
+
def __init__(self, init_dict):
|
|
199
|
+
parsed_dict = {k: parse(v) for k, v in init_dict.items()}
|
|
200
|
+
self.__dict__.update(parsed_dict)
|
|
200
201
|
|
|
201
|
-
|
|
202
|
-
|
|
202
|
+
def __repr__(self):
|
|
203
|
+
return self.title
|
|
203
204
|
|
|
204
205
|
|
|
205
206
|
class KernelPushResponse(object):
|
|
206
207
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
208
|
+
def __init__(self, init_dict):
|
|
209
|
+
parsed_dict = {k: parse(v) for k, v in init_dict.items()}
|
|
210
|
+
self.__dict__.update(parsed_dict)
|
|
210
211
|
|
|
211
|
-
|
|
212
|
-
|
|
212
|
+
def __repr__(self):
|
|
213
|
+
return self.newUrl
|
|
213
214
|
|
|
214
215
|
|
|
215
216
|
class ModelNewResponse(object):
|
|
216
217
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
218
|
+
def __init__(self, init_dict):
|
|
219
|
+
parsed_dict = {k: parse(v) for k, v in init_dict.items()}
|
|
220
|
+
self.__dict__.update(parsed_dict)
|
|
220
221
|
|
|
221
|
-
|
|
222
|
-
|
|
222
|
+
def __repr__(self):
|
|
223
|
+
return self.url
|
|
223
224
|
|
|
224
225
|
|
|
225
226
|
class ModelDeleteResponse(object):
|
|
226
227
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
228
|
+
def __init__(self, init_dict):
|
|
229
|
+
parsed_dict = {k: parse(v) for k, v in init_dict.items()}
|
|
230
|
+
self.__dict__.update(parsed_dict)
|
|
230
231
|
|
|
231
|
-
|
|
232
|
-
|
|
232
|
+
def __repr__(self):
|
|
233
|
+
return self.error
|
|
233
234
|
|
|
234
235
|
|
|
235
236
|
def parse(string):
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
except:
|
|
245
|
-
pass
|
|
246
|
-
return string
|
|
237
|
+
time_formats = ["%Y-%m-%dT%H:%M:%S", "%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%dT%H:%M:%S.%f", "%Y-%m-%dT%H:%M:%S.%fZ"]
|
|
238
|
+
for t in time_formats:
|
|
239
|
+
try:
|
|
240
|
+
result = datetime.strptime(string[:26], t).replace(microsecond=0)
|
|
241
|
+
return result
|
|
242
|
+
except:
|
|
243
|
+
pass
|
|
244
|
+
return string
|
|
247
245
|
|
|
248
246
|
|
|
249
247
|
class ResumableUploadResult(object):
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
bytes_uploaded)
|
|
248
|
+
# Upload was complete, i.e., all bytes were received by the server.
|
|
249
|
+
COMPLETE = 1
|
|
250
|
+
|
|
251
|
+
# There was a non-transient error during the upload or the upload expired.
|
|
252
|
+
# The upload cannot be resumed so it should be restarted from scratch
|
|
253
|
+
# (i.e., call /api/v1/files/upload to initiate the upload and get the
|
|
254
|
+
# create/upload url and token).
|
|
255
|
+
FAILED = 2
|
|
256
|
+
|
|
257
|
+
# Upload was interrupted due to some (transient) failure but it can be
|
|
258
|
+
# safely resumed.
|
|
259
|
+
INCOMPLETE = 3
|
|
260
|
+
|
|
261
|
+
def __init__(self, result, bytes_uploaded=None):
|
|
262
|
+
self.result = result
|
|
263
|
+
self.bytes_uploaded = bytes_uploaded
|
|
264
|
+
self.start_at = 0 if bytes_uploaded is None else bytes_uploaded + 1
|
|
265
|
+
|
|
266
|
+
@staticmethod
|
|
267
|
+
def Complete():
|
|
268
|
+
return ResumableUploadResult(ResumableUploadResult.COMPLETE)
|
|
269
|
+
|
|
270
|
+
@staticmethod
|
|
271
|
+
def Failed():
|
|
272
|
+
return ResumableUploadResult(ResumableUploadResult.FAILED)
|
|
273
|
+
|
|
274
|
+
@staticmethod
|
|
275
|
+
def Incomplete(bytes_uploaded=None):
|
|
276
|
+
return ResumableUploadResult(ResumableUploadResult.INCOMPLETE, bytes_uploaded)
|