canonicalwebteam.store-api 5.0.0__py3-none-any.whl → 6.1.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.
- canonicalwebteam/store_api/base.py +68 -0
- canonicalwebteam/store_api/dashboard.py +646 -0
- canonicalwebteam/store_api/{store.py → devicegw.py} +126 -78
- canonicalwebteam/store_api/publishergw.py +832 -0
- {canonicalwebteam_store_api-5.0.0.dist-info → canonicalwebteam_store_api-6.1.0.dist-info}/METADATA +7 -7
- canonicalwebteam_store_api-6.1.0.dist-info/RECORD +11 -0
- {canonicalwebteam_store_api-5.0.0.dist-info → canonicalwebteam_store_api-6.1.0.dist-info}/WHEEL +1 -1
- canonicalwebteam/store_api/publisher.py +0 -420
- canonicalwebteam/store_api/stores/__init__.py +0 -0
- canonicalwebteam/store_api/stores/charmstore.py +0 -525
- canonicalwebteam/store_api/stores/snapstore.py +0 -770
- canonicalwebteam_store_api-5.0.0.dist-info/RECORD +0 -12
- /canonicalwebteam/{store_api/exceptions.py → exceptions.py} +0 -0
- {canonicalwebteam_store_api-5.0.0.dist-info → canonicalwebteam_store_api-6.1.0.dist-info}/LICENSE +0 -0
|
@@ -1,71 +1,44 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class Store:
|
|
11
|
-
def __init__(self, session, store=None):
|
|
12
|
-
self.config = {1: {"base_url": "", "headers": {}}}
|
|
13
|
-
self.session = session
|
|
14
|
-
|
|
15
|
-
def process_response(self, response):
|
|
16
|
-
# 5xx responses are not in JSON format
|
|
17
|
-
if response.status_code >= 500:
|
|
18
|
-
raise StoreApiConnectionError("Service Unavailable")
|
|
19
|
-
|
|
20
|
-
try:
|
|
21
|
-
body = response.json()
|
|
22
|
-
except ValueError as decode_error:
|
|
23
|
-
raise StoreApiResponseDecodeError(
|
|
24
|
-
"JSON decoding failed: {}".format(decode_error)
|
|
25
|
-
)
|
|
1
|
+
from os import getenv
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from requests import Session
|
|
5
|
+
from canonicalwebteam.store_api.base import Base
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
DEVICEGW_URL = getenv("DEVICEGW_URL", "https://api.snapcraft.io/")
|
|
9
|
+
|
|
26
10
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
raise StoreApiResponseError(
|
|
47
|
-
"Unknown error from API", response.status_code
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
if "_embedded" in body:
|
|
51
|
-
body["results"] = body["_embedded"]["clickindex:package"]
|
|
52
|
-
del body["_embedded"]
|
|
53
|
-
|
|
54
|
-
return body
|
|
55
|
-
|
|
56
|
-
def get_endpoint_url(self, endpoint, api_version=1):
|
|
11
|
+
class DeviceGW(Base):
|
|
12
|
+
def __init__(self, namespace, session=Session(), store=None):
|
|
13
|
+
super().__init__(session)
|
|
14
|
+
self.config = {
|
|
15
|
+
1: {
|
|
16
|
+
"base_url": f"{DEVICEGW_URL}api/v1/{namespace}s/",
|
|
17
|
+
"headers": {"X-Ubuntu-Series": "16"},
|
|
18
|
+
},
|
|
19
|
+
2: {
|
|
20
|
+
"base_url": f"{DEVICEGW_URL}v2/{namespace}s/",
|
|
21
|
+
"headers": {"Snap-Device-Series": "16"},
|
|
22
|
+
},
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if store:
|
|
26
|
+
self.config[1]["headers"].update({"X-Ubuntu-Store": store})
|
|
27
|
+
self.config[2]["headers"].update({"Snap-Device-Store": store})
|
|
28
|
+
|
|
29
|
+
def get_endpoint_url(self, endpoint, api_version=1) -> str:
|
|
57
30
|
base_url = self.config[api_version]["base_url"]
|
|
58
31
|
return f"{base_url}{endpoint}"
|
|
59
32
|
|
|
60
33
|
def search(
|
|
61
34
|
self,
|
|
62
|
-
search,
|
|
63
|
-
size=100,
|
|
64
|
-
page=1,
|
|
65
|
-
category=None,
|
|
66
|
-
arch="wide",
|
|
67
|
-
api_version=1,
|
|
68
|
-
):
|
|
35
|
+
search: str,
|
|
36
|
+
size: int = 100,
|
|
37
|
+
page: int = 1,
|
|
38
|
+
category: Optional[str] = None,
|
|
39
|
+
arch: str = "wide",
|
|
40
|
+
api_version: int = 1,
|
|
41
|
+
) -> dict:
|
|
69
42
|
"""
|
|
70
43
|
Documentation: https://api.snapcraft.io/docs/search.html#snap_search
|
|
71
44
|
Endpoint: https://api.snapcraft.io/api/v1/snaps/search
|
|
@@ -116,7 +89,34 @@ class Store:
|
|
|
116
89
|
self.session.get(url, params=params, headers=headers)
|
|
117
90
|
)
|
|
118
91
|
|
|
119
|
-
def
|
|
92
|
+
def find(
|
|
93
|
+
self,
|
|
94
|
+
query: str = "",
|
|
95
|
+
category: str = "",
|
|
96
|
+
architecture: str = "",
|
|
97
|
+
publisher: str = "",
|
|
98
|
+
featured: str = "false",
|
|
99
|
+
fields: list = [],
|
|
100
|
+
) -> dict:
|
|
101
|
+
"""
|
|
102
|
+
Documentation: https://api.snapcraft.io/docs/search.html#snaps_find
|
|
103
|
+
Endpoint: [GET] https://api.snapcraft.io/v2/snaps/find
|
|
104
|
+
"""
|
|
105
|
+
url = self.get_endpoint_url("find", 2)
|
|
106
|
+
headers = self.config[2].get("headers")
|
|
107
|
+
params = {
|
|
108
|
+
"q": query,
|
|
109
|
+
"category": category,
|
|
110
|
+
"architecture": architecture,
|
|
111
|
+
"publisher": publisher,
|
|
112
|
+
"featured": featured,
|
|
113
|
+
}
|
|
114
|
+
if fields:
|
|
115
|
+
params["fields"] = ",".join(fields)
|
|
116
|
+
response = self.session.get(url, params=params, headers=headers)
|
|
117
|
+
return self.process_response(response)
|
|
118
|
+
|
|
119
|
+
def get_all_items(self, size: int, api_version: int = 1) -> dict:
|
|
120
120
|
"""
|
|
121
121
|
Documentation: https://api.snapcraft.io/docs/search.html#snap_search
|
|
122
122
|
Endpoint: https://api.snapcraft.io/api/v1/snaps/search
|
|
@@ -131,7 +131,13 @@ class Store:
|
|
|
131
131
|
)
|
|
132
132
|
)
|
|
133
133
|
|
|
134
|
-
def get_category_items(
|
|
134
|
+
def get_category_items(
|
|
135
|
+
self,
|
|
136
|
+
category: str,
|
|
137
|
+
size: int = 10,
|
|
138
|
+
page: int = 1,
|
|
139
|
+
api_version: int = 1,
|
|
140
|
+
) -> dict:
|
|
135
141
|
"""
|
|
136
142
|
Documentation: https://api.snapcraft.io/docs/search.html#snap_search
|
|
137
143
|
Endpoint: https://api.snapcraft.io/api/v1/snaps/search
|
|
@@ -144,7 +150,9 @@ class Store:
|
|
|
144
150
|
api_version=api_version,
|
|
145
151
|
)
|
|
146
152
|
|
|
147
|
-
def get_featured_items(
|
|
153
|
+
def get_featured_items(
|
|
154
|
+
self, size: int = 10, page: int = 1, api_version: int = 1
|
|
155
|
+
) -> dict:
|
|
148
156
|
"""
|
|
149
157
|
Documentation: https://api.snapcraft.io/docs/search.html#snap_search
|
|
150
158
|
Endpoint: https://api.snapcraft.io/api/v1/snaps/search
|
|
@@ -157,7 +165,13 @@ class Store:
|
|
|
157
165
|
api_version=api_version,
|
|
158
166
|
)
|
|
159
167
|
|
|
160
|
-
def get_publisher_items(
|
|
168
|
+
def get_publisher_items(
|
|
169
|
+
self,
|
|
170
|
+
publisher: str,
|
|
171
|
+
size: int = 500,
|
|
172
|
+
page: int = 1,
|
|
173
|
+
api_version: int = 1,
|
|
174
|
+
) -> dict:
|
|
161
175
|
"""
|
|
162
176
|
Documentation: https://api.snapcraft.io/docs/search.html#snap_search
|
|
163
177
|
Endpoint: https://api.snapcraft.io/api/v1/snaps/search
|
|
@@ -169,27 +183,34 @@ class Store:
|
|
|
169
183
|
api_version=api_version,
|
|
170
184
|
)
|
|
171
185
|
|
|
172
|
-
def get_item_details(
|
|
186
|
+
def get_item_details(
|
|
187
|
+
self,
|
|
188
|
+
name: str,
|
|
189
|
+
channel: Optional[str] = None,
|
|
190
|
+
fields: list = [],
|
|
191
|
+
api_version: int = 2,
|
|
192
|
+
) -> dict:
|
|
173
193
|
"""
|
|
174
194
|
Documentation: https://api.snapcraft.io/docs/info.html
|
|
175
195
|
Endpoint: [GET]
|
|
176
196
|
https://api.snapcraft.io/api/v2/{name_space}/info/{package_name}
|
|
177
197
|
"""
|
|
178
198
|
url = self.get_endpoint_url("info/" + name, api_version)
|
|
179
|
-
params = {
|
|
199
|
+
params = {}
|
|
200
|
+
if fields:
|
|
201
|
+
params = {"fields": ",".join(fields)}
|
|
202
|
+
headers = self.config[api_version].get("headers")
|
|
180
203
|
|
|
181
204
|
if channel:
|
|
182
205
|
params["channel"] = channel
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
params=params,
|
|
188
|
-
headers=self.config[api_version].get("headers"),
|
|
189
|
-
)
|
|
206
|
+
response = self.session.get(
|
|
207
|
+
url,
|
|
208
|
+
params=params,
|
|
209
|
+
headers=headers,
|
|
190
210
|
)
|
|
211
|
+
return self.process_response(response)
|
|
191
212
|
|
|
192
|
-
def get_public_metrics(self, json, api_version=1):
|
|
213
|
+
def get_public_metrics(self, json: dict, api_version: int = 1) -> dict:
|
|
193
214
|
"""
|
|
194
215
|
Documentation: https://api.snapcraft.io/docs/metrics.html
|
|
195
216
|
Endpoint: https://api.snapcraft.io/api/v1/snaps/metrics
|
|
@@ -203,7 +224,9 @@ class Store:
|
|
|
203
224
|
self.session.post(url, headers=headers, json=json)
|
|
204
225
|
)
|
|
205
226
|
|
|
206
|
-
def get_categories(
|
|
227
|
+
def get_categories(
|
|
228
|
+
self, api_version: int = 2, type: str = "shared"
|
|
229
|
+
) -> dict:
|
|
207
230
|
"""
|
|
208
231
|
Documentation: https://api.snapcraft.io/docs/categories.html
|
|
209
232
|
Endpoint: https://api.snapcraft.io/api/v2/{name_space}/categories
|
|
@@ -217,7 +240,9 @@ class Store:
|
|
|
217
240
|
)
|
|
218
241
|
)
|
|
219
242
|
|
|
220
|
-
def get_resource_revisions(
|
|
243
|
+
def get_resource_revisions(
|
|
244
|
+
self, name: str, resource_name: str, api_version: int = 2
|
|
245
|
+
) -> dict:
|
|
221
246
|
"""
|
|
222
247
|
Documentation:
|
|
223
248
|
https://api.snapcraft.io/docs/charms.html#list_resource_revisions
|
|
@@ -234,3 +259,26 @@ class Store:
|
|
|
234
259
|
headers=self.config[api_version].get("headers"),
|
|
235
260
|
)
|
|
236
261
|
)["revisions"]
|
|
262
|
+
|
|
263
|
+
def get_featured_snaps(
|
|
264
|
+
self, api_version: int = 1, fields: str = "snap_id"
|
|
265
|
+
) -> dict:
|
|
266
|
+
"""
|
|
267
|
+
Documentation: (link to spec)
|
|
268
|
+
https://docs.google.com/document/d/1UAybxuZyErh3ayqb4nzL3T4BbvMtnmKKEPu-ixcCj_8/edit
|
|
269
|
+
Endpoint: https://api.snapcraft.io/api/v1/snaps/search
|
|
270
|
+
"""
|
|
271
|
+
url = self.get_endpoint_url("search")
|
|
272
|
+
headers = self.config[api_version].get("headers")
|
|
273
|
+
|
|
274
|
+
params = {
|
|
275
|
+
"scope": "wide",
|
|
276
|
+
"arch": "wide",
|
|
277
|
+
"confinement": "strict,classic,devmode",
|
|
278
|
+
"fields": fields,
|
|
279
|
+
"section": "featured",
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return self.process_response(
|
|
283
|
+
self.session.get(url, params=params, headers=headers)
|
|
284
|
+
)
|