canonicalwebteam.store-api 5.0.0__py3-none-any.whl → 6.0.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.
@@ -1,770 +0,0 @@
1
- from os import getenv
2
-
3
- import requests
4
-
5
- from canonicalwebteam.store_api.store import Store
6
- from canonicalwebteam.store_api.publisher import Publisher
7
-
8
- SNAPSTORE_API_URL = getenv("SNAPSTORE_API_URL", "https://api.snapcraft.io/")
9
- SNAPSTORE_DASHBOARD_API_URL = getenv(
10
- "SNAPSTORE_DASHBOARD_API_URL", "https://dashboard.snapcraft.io/"
11
- )
12
- SNAPSTORE_PUBLISHERWG_API_URL = getenv(
13
- "SNAPSTORE_PUBLISHERWG_API_URL", "https://api.charmhub.io/"
14
- )
15
-
16
-
17
- class SnapStore(Store):
18
- def __init__(self, session=requests.Session(), store=None):
19
- super().__init__(session, store)
20
-
21
- self.config = {
22
- 1: {
23
- "base_url": f"{SNAPSTORE_API_URL}api/v1/snaps/",
24
- "headers": {"X-Ubuntu-Series": "16"},
25
- },
26
- 2: {
27
- "base_url": f"{SNAPSTORE_API_URL}v2/snaps/",
28
- "headers": {"Snap-Device-Series": "16"},
29
- },
30
- }
31
-
32
- if store:
33
- self.config[1]["headers"].update({"X-Ubuntu-Store": store})
34
- self.config[2]["headers"].update({"Snap-Device-Store": store})
35
-
36
- def get_item_details(
37
- self,
38
- name,
39
- fields=[
40
- "title",
41
- "summary",
42
- "description",
43
- "license",
44
- "contact",
45
- "website",
46
- "publisher",
47
- "media",
48
- "download",
49
- "version",
50
- "created-at",
51
- "confinement",
52
- "categories",
53
- "trending",
54
- "unlisted",
55
- "links",
56
- ],
57
- api_version=1,
58
- ):
59
- return super(SnapStore, self).get_item_details(
60
- name, None, fields, api_version
61
- )
62
-
63
- def find(
64
- self,
65
- query="",
66
- category="",
67
- architecture="",
68
- publisher="",
69
- featured="false",
70
- fields=[],
71
- ):
72
- """
73
- Documentation: https://api.snapcraft.io/docs/search.html#snaps_find
74
- Endpoint: [GET] https://api.snapcraft.io/v2/snaps/find
75
- """
76
- url = self.get_endpoint_url("find", 2)
77
- headers = self.config[2].get("headers")
78
- params = {
79
- "q": query,
80
- "category": category,
81
- "architecture": architecture,
82
- "publisher": publisher,
83
- "featured": featured,
84
- }
85
- if fields:
86
- params["fields"] = ",".join(fields)
87
- response = self.session.get(url, params=params, headers=headers)
88
- return self.process_response(response)
89
-
90
-
91
- class SnapPublisher(Publisher):
92
- def __init__(self, session=requests.Session()):
93
- super().__init__(session)
94
-
95
- self.config = {
96
- 1: {"base_url": f"{SNAPSTORE_DASHBOARD_API_URL}dev/api/"},
97
- 2: {"base_url": f"{SNAPSTORE_DASHBOARD_API_URL}api/v2/"},
98
- }
99
-
100
- def get_macaroon(self, permissions):
101
- """
102
- Return a bakery v2 macaroon from the publisher API to be discharged
103
- Documemntation:
104
- https://dashboard.snapcraft.io/docs/reference/v1/macaroon.html
105
- Endpoint: [POST] https://dashboard.snapcraft.iodev/api/acl
106
- """
107
- response = self.session.post(
108
- url=self.get_endpoint_url("tokens", 2),
109
- json={"permissions": permissions},
110
- )
111
-
112
- return self.process_response(response)["macaroon"]
113
-
114
- def whoami(self, session):
115
- """
116
- Get the authenticated user details.
117
- Documentation:
118
- https://dashboard.snapcraft.io/docs/reference/v2/en/tokens.html#api-tokens-whoami
119
- Endpoint: [GET] https://dashboard.snapcraft.io/api/v2/tokens/whoami
120
- """
121
- response = self.session.get(
122
- url=self.get_endpoint_url("tokens/whoami", 2),
123
- headers=self._get_authorization_header(session),
124
- )
125
-
126
- return self.process_response(response)
127
-
128
- def get_dashboard_endpoint_url(self, endpoint):
129
- return f"{SNAPSTORE_DASHBOARD_API_URL}api/v2/{endpoint}"
130
-
131
- def get_publisherwg_endpoint_url(self, endpoint):
132
- return f"{SNAPSTORE_PUBLISHERWG_API_URL}v1/{endpoint}"
133
-
134
- def _get_publisherwg_authorization_header(self, session):
135
- return {"Authorization": f"Macaroon {session['developer_token']}"}
136
-
137
- def exchange_dashboard_macaroons(self, session):
138
- """
139
- Exchange dashboard.snapcraft.io SSO discharged macaroons
140
- Documentation:
141
- https://api.charmhub.io/docs/default.html#exchange_dashboard_macaroons
142
- Endpoint: [POST] https://api.charmhub.io/v1/tokens/dashboard/exchange
143
- """
144
- response = self.session.post(
145
- url=self.get_publisherwg_endpoint_url("tokens/dashboard/exchange"),
146
- headers=self._get_authorization_header(session),
147
- json={},
148
- )
149
-
150
- return self.process_response(response)["macaroon"]
151
-
152
- def get_collaborators(self, session, name):
153
- """
154
- Get collaborators (accepted invites) for the given package.
155
- Documentation:
156
- https://api.charmhub.io/docs/collaborator.html#get_collaborators
157
- Endpoint: [GET]
158
- https://api.charmhub.io/v1/snap/{snap_name}/collaborators
159
- """
160
- response = self.session.get(
161
- url=self.get_publisherwg_endpoint_url(
162
- f"snap/{name}/collaborators"
163
- ),
164
- headers=self._get_publisherwg_authorization_header(session),
165
- )
166
- return self.process_response(response)
167
-
168
- def get_pending_invites(self, session, name):
169
- """
170
- Get pending collaborator invites for the given package.
171
- Documentation:
172
- https://api.charmhub.io/docs/collaborator.html#get_pending_invites
173
- Endpoint: [GET]
174
- https://api.charmhub.io/v1/snap/{snap_name}/collaborators/invites
175
- """
176
- response = self.session.get(
177
- url=self.get_publisherwg_endpoint_url(
178
- f"snap/{name}/collaborators/invites"
179
- ),
180
- headers=self._get_publisherwg_authorization_header(session),
181
- )
182
- return self.process_response(response)
183
-
184
- def invite_collaborators(self, session, name, emails):
185
- """
186
- Invite one or more collaborators for a package.
187
- Documentation:
188
- https://api.charmhub.io/docs/collaborator.html#invite_collaborators
189
- Endpoint: [POST]
190
- https://api.charmhub.io/v1/snap/{snap_name}/collaborators/invites
191
- """
192
- payload = {"invites": []}
193
-
194
- for email in emails:
195
- payload["invites"].append({"email": email})
196
-
197
- response = self.session.post(
198
- url=self.get_publisherwg_endpoint_url(
199
- f"snap/{name}/collaborators/invites"
200
- ),
201
- headers=self._get_publisherwg_authorization_header(session),
202
- json=payload,
203
- )
204
- return self.process_response(response)
205
-
206
- def revoke_invites(self, session, name, emails):
207
- """
208
- Revoke invites to the specified emails for the package.
209
- Documentation:
210
- https://api.charmhub.io/docs/collaborator.html#revoke_invites
211
- Endpoint: [POST]
212
- https://api.charmhub.io/v1/snap/{snap_name}/collaborators/invites/revoke
213
- """
214
- payload = {"invites": []}
215
-
216
- for email in emails:
217
- payload["invites"].append({"email": email})
218
-
219
- response = self.session.post(
220
- url=self.get_publisherwg_endpoint_url(
221
- f"snap/{name}/collaborators/invites/revoke"
222
- ),
223
- headers=self._get_publisherwg_authorization_header(session),
224
- json=payload,
225
- )
226
- return self.process_response(response)
227
-
228
- def accept_invite(self, session, name, token):
229
- """
230
- Accept a collaborator invite.
231
- Documentation:
232
- https://api.charmhub.io/docs/collaborator.html#accept_invite
233
- Endpoint: [POST]
234
- https://api.charmhub.io/v1/snap/{snap_name}/collaborators/invites/accept
235
- """
236
- response = self.session.post(
237
- url=self.get_publisherwg_endpoint_url(
238
- f"snap/{name}/collaborators/invites/accept"
239
- ),
240
- headers=self._get_publisherwg_authorization_header(session),
241
- json={"token": token},
242
- )
243
- return self.process_response(response)
244
-
245
- def reject_invite(self, session, name, token):
246
- """
247
- Reject a collaborator invite.
248
- Documentation:
249
- https://api.charmhub.io/docs/collaborator.html#reject_invite
250
- Endpoint: [POST]
251
- https://api.charmhub.io/v1/snap/{snap_name}/collaborators/invites/reject
252
- """
253
- response = self.session.post(
254
- url=self.get_publisherwg_endpoint_url(
255
- f"snap/{name}/collaborators/invites/reject"
256
- ),
257
- headers=self._get_publisherwg_authorization_header(session),
258
- json={"token": token},
259
- )
260
- return self.process_response(response)
261
-
262
- def create_track(
263
- self,
264
- session,
265
- snap_name,
266
- track_name,
267
- version_pattern=None,
268
- auto_phasing_percentage=None,
269
- ):
270
- """
271
- Create a track for a snap base on the snap's guardrail pattern.
272
- Documentation: https://api.charmhub.io/docs/default.html#create_tracks
273
- Endpoint: [POST] https://api.charmhub.io/v1/snap/{snap_name}/tracks
274
- Args:
275
- publisher_auth: Serialized macaroon to consume the API.
276
- snap_name: Name of the snap
277
- track_name: Name of the track
278
- version_pattern: Version pattern for the track (optional)
279
- auto_phasing_percentage: phasing percentage for track (optional)
280
- """
281
- payload = {
282
- "name": track_name,
283
- "version-pattern": version_pattern,
284
- "automatic-phasing-percentage": auto_phasing_percentage,
285
- }
286
- response = self.session.post(
287
- url=self.get_publisherwg_endpoint_url(f"snap/{snap_name}/tracks"),
288
- headers=self._get_publisherwg_authorization_header(session),
289
- json=[payload],
290
- )
291
- return response
292
-
293
- def get_package_metadata(self, publisher_auth, package_type, snap_name):
294
- """
295
- Get general metadata for a package.
296
- Documentation:
297
- https://api.charmhub.io/docs/default.html#package_metadata
298
- Endpoint: [GET] https://api.charmhub.io/v1/{package_type}/{snap_name}
299
- Args:
300
- publisher_auth: Serialized macaroon to consume the API.
301
- package_type: Type of packages to obtain.
302
- Returns:
303
- Package general metadata
304
- """
305
- response = self.session.get(
306
- url=self.get_publisherwg_endpoint_url(
307
- f"{package_type}/{snap_name}"
308
- ),
309
- headers=self._get_publisherwg_authorization_header(publisher_auth),
310
- )
311
- return response.json()
312
-
313
- def unregister_package_name(self, publisher_auth, snap_name):
314
- """
315
- Unregister a package name.
316
- Documentation: https://api.charmhub.io/docs/default.html#register_name
317
- Endpoint: [DELETE] https://api.charmhub.io/v1/snap/{snap_name}
318
-
319
- Args:
320
- publisher_auth: Serialized macaroon to consume the API.
321
- name: Name of the package to unregister
322
- Returns:
323
- The package name ID if successful
324
- Otherwise, returns an error list
325
- """
326
- url = self.get_publisherwg_endpoint_url(f"snap/{snap_name}")
327
- response = self.session.delete(
328
- url=url,
329
- headers=self._get_authorization_header(publisher_auth),
330
- )
331
- return response
332
-
333
- def get_validation_sets(self, publisher_auth):
334
- """
335
- Return a list of validation sets for the current account
336
- Documentation:
337
- https://dashboard.snapcraft.io/docs/reference/v2/en/validation-sets.html
338
- Endpoint: [GET] https://dashboard.snapcraft.io/api/v2/validation-sets
339
- """
340
- url = self.get_dashboard_endpoint_url("validation-sets")
341
- response = self.session.get(
342
- url, headers=self._get_authorization_header(publisher_auth)
343
- )
344
- return self.process_response(response)
345
-
346
- def get_validation_set(self, publisher_auth, validation_set_id):
347
- """
348
- Return a validation set for the current account
349
- Documentation:
350
- https://dashboard.snapcraft.io/docs/reference/v2/en/validation-sets.html
351
- Endpoint:
352
- [GET] https://dashboard.snapcraft.io/api/v2/validation-sets/{id}
353
- """
354
- url = self.get_dashboard_endpoint_url(
355
- f"validation-sets/{validation_set_id}?sequence=all"
356
- )
357
- response = self.session.get(
358
- url, headers=self._get_authorization_header(publisher_auth)
359
- )
360
- return self.process_response(response)
361
-
362
-
363
- class SnapStoreAdmin(SnapPublisher):
364
- def get_endpoint_url(self, endpoint, api_version=2):
365
- return super().get_endpoint_url(f"stores/{endpoint}", api_version)
366
-
367
- def get_stores(self, session, roles=["admin", "review", "view", "access"]):
368
- """Return a list a stores with the given roles
369
- Documentation:
370
- https://dashboard.snapcraft.io/docs/reference/v1/account.html#get--dev-api-account
371
- Endpoint: [GET] https://dashboard.snapcraft.io/dev/api/account
372
-
373
- :return: A list of stores
374
- """
375
- headers = self._get_authorization_header(session)
376
-
377
- response = self.session.get(
378
- url=super().get_endpoint_url("account", 1), headers=headers
379
- )
380
-
381
- account_info = self.process_response(response)
382
- stores = account_info.get("stores", [])
383
- user_stores = []
384
-
385
- for store in stores:
386
- if not set(roles).isdisjoint(store["roles"]):
387
- user_stores.append(store)
388
-
389
- return user_stores
390
-
391
- def get_store(self, session, store_id):
392
- """Return a store where the user is an admin
393
- Documentation:
394
- https://dashboard.snapcraft.io/docs/reference/v2/en/stores.html#list-the-details-of-a-brand-store
395
- Endpoint: [GET]
396
- https://dashboard.snapcraft.io/api/v2/stores/{store_id}
397
-
398
- :return: Store details
399
- """
400
- headers = self._get_authorization_header(session)
401
-
402
- response = self.session.get(
403
- url=self.get_endpoint_url(store_id), headers=headers
404
- )
405
-
406
- return self.process_response(response)["store"]
407
-
408
- def get_store_snaps(
409
- self, session, store_id, query=None, allowed_for_inclusion=None
410
- ):
411
- """
412
- Documentation:
413
- https://dashboard.snapcraft.io/docs/reference/v2/en/stores.html#get
414
- Endpoint: [GET]
415
- https://dashboard.snapcraft.io/api/v2/stores/{store_id}/snaps
416
- """
417
- headers = self._get_authorization_header(session)
418
- params = {}
419
-
420
- if query:
421
- params["q"] = query
422
-
423
- if allowed_for_inclusion:
424
- params["allowed-for-inclusion"] = allowed_for_inclusion
425
-
426
- response = self.session.get(
427
- url=self.get_endpoint_url(f"{store_id}/snaps"),
428
- params=params,
429
- headers=headers,
430
- )
431
-
432
- return self.process_response(response).get("snaps", [])
433
-
434
- def get_store_members(self, session, store_id):
435
- """
436
- Documentation:
437
- https://dashboard.snapcraft.io/docs/reference/v2/en/stores.html#list-the-details-of-a-brand-store
438
- Endpoint: [GET] https://dashboard.snapcraft.io/api/v2/stores/{store_id}
439
- """
440
- headers = self._get_authorization_header(session)
441
-
442
- response = self.session.get(
443
- url=self.get_endpoint_url(f"{store_id}"),
444
- headers=headers,
445
- )
446
-
447
- return self.process_response(response).get("users", [])
448
-
449
- def update_store_members(self, session, store_id, members):
450
- """
451
- Documentation:
452
- https://dashboard.snapcraft.io/docs/reference/v2/en/stores.html#add-remove-or-edit-users-roles
453
- Endpoint: [POST]
454
- https://dashboard.snapcraft.io/api/v2/stores/{store_id}/users
455
- """
456
- headers = self._get_authorization_header(session)
457
-
458
- response = self.session.post(
459
- url=self.get_endpoint_url(f"{store_id}/users"),
460
- headers=headers,
461
- json=members,
462
- )
463
-
464
- return self.process_response(response)
465
-
466
- def invite_store_members(self, session, store_id, members):
467
- """
468
- Documentation:
469
- https://dashboard.snapcraft.io/docs/reference/v2/en/stores.html#manage-store-invitations
470
- Endpoint: [POST]
471
- https://dashboard.snapcraft.io/api/v2/stores/{store_id}/invites
472
- """
473
- headers = self._get_authorization_header(session)
474
-
475
- response = self.session.post(
476
- url=self.get_endpoint_url(f"{store_id}/invites"),
477
- headers=headers,
478
- json=members,
479
- )
480
-
481
- return self.process_response(response)
482
-
483
- def change_store_settings(self, session, store_id, settings):
484
- """
485
- Documentation:
486
- https://dashboard.snapcraft.io/docs/reference/v2/en/stores.html#change-store-settings
487
- Endpoint: [PUT]
488
- https://dashboard.snapcraft.io/api/v2/stores/{store_id}/settings
489
- """
490
- headers = self._get_authorization_header(session)
491
-
492
- response = self.session.put(
493
- url=self.get_endpoint_url(f"{store_id}/settings"),
494
- headers=headers,
495
- json=settings,
496
- )
497
-
498
- return self.process_response(response)
499
-
500
- def update_store_snaps(self, session, store_id, snaps):
501
- """
502
- Documentation:
503
- https://dashboard.snapcraft.io/docs/reference/v2/en/stores.html#post
504
- Endpoint: [POST]
505
- https://dashboard.snapcraft.io/api/v2/stores/{store_id}/snaps
506
- """
507
- headers = self._get_authorization_header(session)
508
-
509
- response = self.session.post(
510
- url=self.get_endpoint_url(f"{store_id}/snaps"),
511
- headers=headers,
512
- json=snaps,
513
- )
514
-
515
- return self.process_response(response)
516
-
517
- def update_store_invites(self, session, store_id, invites):
518
- """
519
- Documentation:
520
- https://dashboard.snapcraft.io/docs/reference/v2/en/stores.html#manage-store-invitations
521
- Endpoint: [PUT]
522
- https://dashboard.snapcraft.io/api/v2/stores/{store_id}/invites
523
- """
524
- headers = self._get_authorization_header(session)
525
-
526
- response = self.session.put(
527
- url=self.get_endpoint_url(f"{store_id}/invites"),
528
- headers=headers,
529
- json=invites,
530
- )
531
-
532
- return self.process_response(response)
533
-
534
- def get_store_invites(self, session, store_id):
535
- """
536
- Documentation:
537
- https://dashboard.snapcraft.io/docs/reference/v2/en/stores.html#list-the-details-of-a-brand-store
538
- Endpoint: [GET] https://dashboard.snapcraft.io/api/v2/stores/{store_id}
539
- """
540
- headers = self._get_authorization_header(session)
541
-
542
- response = self.session.get(
543
- url=self.get_endpoint_url(f"{store_id}"),
544
- headers=headers,
545
- )
546
-
547
- return self.process_response(response).get("invites", [])
548
-
549
- # MODEL SERVICE ADMIN
550
- def get_store_models(self, session, store_id):
551
- """
552
- Documentation:
553
- https://api.charmhub.io/docs/model-service-admin.html#read_models
554
- Endpoint: [GET] https://api.charmhub.io/v1/brand/{store_id}/model
555
- """
556
- response = self.session.get(
557
- url=self.get_publisherwg_endpoint_url(f"brand/{store_id}/model"),
558
- headers=self._get_publisherwg_authorization_header(session),
559
- )
560
-
561
- return self.process_response(response)
562
-
563
- def create_store_model(self, session, store_id, name, api_key=None):
564
- """
565
- Documentation:
566
- https://api.charmhub.io/docs/model-service-admin.html#create_model
567
- Endpoint: [POST] https://api.charmhub.io/v1/brand/{store_id}/model
568
- """
569
- if api_key:
570
- payload = {"name": name, "api-key": api_key, "series": "16"}
571
- else:
572
- payload = {"name": name, "series": "16"}
573
- response = self.session.post(
574
- url=self.get_publisherwg_endpoint_url(f"brand/{store_id}/model"),
575
- headers=self._get_publisherwg_authorization_header(session),
576
- json=payload,
577
- )
578
-
579
- return self.process_response(response)
580
-
581
- def update_store_model(self, session, store_id, model_name, api_key):
582
- """
583
- Doucumentation:
584
- https://api.charmhub.io/docs/model-service-admin.html#update_model
585
- Endpoint: [PATCH]
586
- https://api.charmhub.io/v1/brand/{store_id}/model/{model_name}
587
- """
588
- response = self.session.patch(
589
- url=self.get_publisherwg_endpoint_url(
590
- f"brand/{store_id}/model/{model_name}"
591
- ),
592
- headers=self._get_publisherwg_authorization_header(session),
593
- json={"api-key": api_key},
594
- )
595
-
596
- return self.process_response(response)
597
-
598
- def get_store_model_policies(self, session, store_id, model_name):
599
- """
600
- Documentation:
601
- https://api.charmhub.io/docs/model-service-admin.html#read_serial_policies
602
- Endpoint: [GET]
603
- https://api.charmhub.io/v1/brand/{store_id}/model/<model_name>/serial_policy
604
- """
605
- response = self.session.get(
606
- url=self.get_publisherwg_endpoint_url(
607
- f"brand/{store_id}/model/{model_name}/serial_policy"
608
- ),
609
- headers=self._get_publisherwg_authorization_header(session),
610
- )
611
-
612
- return self.process_response(response)
613
-
614
- def create_store_model_policy(
615
- self, session, store_id, model_name, signing_key
616
- ):
617
- """
618
- Documentation:
619
- https://api.charmhub.io/docs/model-service-admin.html#create_serial_policy
620
- Endpoint: [POST]
621
- https://api.charmhub.io/v1/brand/{store_id}/model/{model_name}/serial_policy
622
- """
623
- response = self.session.post(
624
- url=self.get_publisherwg_endpoint_url(
625
- f"brand/{store_id}/model/{model_name}/serial_policy"
626
- ),
627
- headers=self._get_publisherwg_authorization_header(session),
628
- json={"signing-key-sha3-384": signing_key},
629
- )
630
-
631
- return self.process_response(response)
632
-
633
- def delete_store_model_policy(
634
- self, session, store_id, model_name, revision
635
- ):
636
- """
637
- Documentation:
638
- https://api.charmhub.io/docs/model-service-admin.html#delete_serial_policy
639
- Endpoint: [DELETE]
640
- https://api.charmhub.io/v1/brand/{store_id}/model/{model_name}/serial_policy/{serial_policy_revision}
641
- """
642
- response = self.session.delete(
643
- url=self.get_publisherwg_endpoint_url(
644
- f"brand/{store_id}/model/{model_name}/serial_policy/{revision}"
645
- ),
646
- headers=self._get_publisherwg_authorization_header(session),
647
- )
648
-
649
- return response
650
-
651
- def get_store_signing_keys(self, session, store_id):
652
- """
653
- Documentation:
654
- https://api.charmhub.io/docs/model-service-admin.html#read_signing_keys
655
- Endpoint: [GET] https://api.charmhub.io/v1/brand/{store_id}/signing_key
656
- """
657
- headers = self._get_publisherwg_authorization_header(session)
658
- url = self.get_publisherwg_endpoint_url(
659
- f"brand/{store_id}/signing_key"
660
- )
661
- response = self.session.get(
662
- url=url,
663
- headers=headers,
664
- )
665
- return self.process_response(response)
666
-
667
- def create_store_signing_key(self, session, store_id, name):
668
- """
669
- Documentation:
670
- https://api.charmhub.io/docs/model-service-admin.html#create_signing_key
671
- Endpoint: [POST]
672
- https://api.charmhub.io/v1/brand/{store_id}/signing_key
673
- """
674
- headers = self._get_publisherwg_authorization_header(session)
675
- url = self.get_publisherwg_endpoint_url(
676
- f"brand/{store_id}/signing_key"
677
- )
678
- response = self.session.post(
679
- url=url,
680
- headers=headers,
681
- json={"name": name},
682
- )
683
- return self.process_response(response)
684
-
685
- def delete_store_signing_key(
686
- self, session, store_id, signing_key_sha3_384
687
- ):
688
- """
689
- Documentation:
690
- https://api.charmhub.io/docs/model-service-admin.html#delete_signing_key
691
- Endpoint: [DELETE]
692
- https://api.charmhub.io/v1/brand/{store_id}/signing_key/<signing_key_sha3_384}
693
- """
694
- headers = self._get_publisherwg_authorization_header(session)
695
- url = self.get_publisherwg_endpoint_url(
696
- f"brand/{store_id}/signing_key/{signing_key_sha3_384}"
697
- )
698
- response = self.session.delete(
699
- url=url,
700
- headers=headers,
701
- )
702
-
703
- return response
704
-
705
- def get_brand(self, session, store_id):
706
- """
707
- Documentation:
708
- https://api.charmhub.io/docs/model-service-admin.html#read_brand
709
- Endpoint: [GET] https://api.charmhub.io/v1/brand/{store_id}
710
- """
711
- headers = self._get_publisherwg_authorization_header(session)
712
- url = self.get_publisherwg_endpoint_url(f"brand/{store_id}")
713
- response = self.session.get(
714
- url=url,
715
- headers=headers,
716
- )
717
-
718
- return self.process_response(response)
719
-
720
- # FEATURED SNAPS AUTOMATION
721
- def delete_featured_snaps(self, session, snaps):
722
- """
723
- Documentation: (link to spec)
724
- https://docs.google.com/document/d/1UAybxuZyErh3ayqb4nzL3T4BbvMtnmKKEPu-ixcCj_8
725
- Endpoint: [DELETE] https://api.charmhub.io/v1/snap/featured
726
- """
727
- headers = self._get_publisherwg_authorization_header(session)
728
- url = self.get_publisherwg_endpoint_url("snap/featured")
729
- response = self.session.delete(
730
- url=url,
731
- headers=headers,
732
- json=snaps,
733
- )
734
- return response
735
-
736
- def update_featured_snaps(self, session, snaps):
737
- """
738
- Documentation: (link to spec)
739
- https://docs.google.com/document/d/1UAybxuZyErh3ayqb4nzL3T4BbvMtnmKKEPu-ixcCj_8
740
- Endpoint: [PUT] https://api.charmhub.io/v1/snap/featured
741
- """
742
- headers = self._get_publisherwg_authorization_header(session)
743
- url = self.get_publisherwg_endpoint_url("snap/featured")
744
- response = self.session.put(
745
- url=url,
746
- headers=headers,
747
- json=snaps,
748
- )
749
- return response
750
-
751
- def get_featured_snaps(self, session, api_version=1, fields="snap_id"):
752
- """
753
- Documentation: (link to spec)
754
- https://docs.google.com/document/d/1UAybxuZyErh3ayqb4nzL3T4BbvMtnmKKEPu-ixcCj_8/edit
755
- Endpoint: https://api.snapcraft.io/api/v1/snaps/search
756
- """
757
- url = f"{SNAPSTORE_API_URL}api/v1/snaps/search"
758
- headers = self.config[api_version].get("headers")
759
-
760
- params = {
761
- "scope": "wide",
762
- "arch": "wide",
763
- "confinement": "strict,classic,devmode",
764
- "fields": fields,
765
- "section": "featured",
766
- }
767
-
768
- return self.process_response(
769
- self.session.get(url, params=params, headers=headers)
770
- )