snap-python 0.1.2__py3-none-any.whl → 0.1.4__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.
- snap_python/components/store.py +98 -0
- snap_python/schemas/store/refresh.py +13 -0
- snap_python/schemas/store/search.py +33 -1
- snap_python/scrape.py +0 -1
- {snap_python-0.1.2.dist-info → snap_python-0.1.4.dist-info}/METADATA +1 -1
- {snap_python-0.1.2.dist-info → snap_python-0.1.4.dist-info}/RECORD +8 -8
- {snap_python-0.1.2.dist-info → snap_python-0.1.4.dist-info}/WHEEL +1 -1
- {snap_python-0.1.2.dist-info → snap_python-0.1.4.dist-info}/LICENSE +0 -0
snap_python/components/store.py
CHANGED
|
@@ -20,6 +20,7 @@ from snap_python.schemas.store.refresh import (
|
|
|
20
20
|
from snap_python.schemas.store.search import (
|
|
21
21
|
VALID_SEARCH_CATEGORY_FIELDS,
|
|
22
22
|
ArchSearchResponse,
|
|
23
|
+
PaginatedSnapSearchResponse,
|
|
23
24
|
SearchResponse,
|
|
24
25
|
)
|
|
25
26
|
|
|
@@ -396,3 +397,100 @@ class StoreEndpoints:
|
|
|
396
397
|
)
|
|
397
398
|
response.raise_for_status()
|
|
398
399
|
return RefreshRevisionResponse.model_validate_json(response.content)
|
|
400
|
+
|
|
401
|
+
async def get_many_snap_revision_info(
|
|
402
|
+
self,
|
|
403
|
+
snap_name: str,
|
|
404
|
+
from_revision: int,
|
|
405
|
+
to_revision: int,
|
|
406
|
+
arch: str,
|
|
407
|
+
fields=None,
|
|
408
|
+
) -> RefreshRevisionResponse:
|
|
409
|
+
"""Get information about a snap revision.
|
|
410
|
+
|
|
411
|
+
:param snap_name: The name of the snap.
|
|
412
|
+
:type snap_name: str
|
|
413
|
+
:param revision: The revision of the snap.
|
|
414
|
+
:type revision: int
|
|
415
|
+
:param arch: The architecture of the snap to retrieve details about (e.g. amd64, arm64, riscv64, etc).
|
|
416
|
+
:type arch: str
|
|
417
|
+
|
|
418
|
+
:returns: The snap revision information.
|
|
419
|
+
:rtype: RefreshRevisionResponse
|
|
420
|
+
"""
|
|
421
|
+
|
|
422
|
+
# cast revision to int
|
|
423
|
+
from_revision = int(from_revision)
|
|
424
|
+
to_revision = int(to_revision)
|
|
425
|
+
extra_headers = {"Snap-Device-Architecture": arch}
|
|
426
|
+
snap_info = await self.get_snap_info(snap_name=snap_name)
|
|
427
|
+
|
|
428
|
+
# I don't think this matters for the "context" field, so using info from the first available
|
|
429
|
+
channel_map_item = snap_info.channel_map[0]
|
|
430
|
+
|
|
431
|
+
payload = {
|
|
432
|
+
"context": [
|
|
433
|
+
{
|
|
434
|
+
"tracking-channel": "stable",
|
|
435
|
+
"snap-id": snap_info.snap_id,
|
|
436
|
+
"revision": channel_map_item.revision,
|
|
437
|
+
"instance-key": str(uuid.uuid4()),
|
|
438
|
+
}
|
|
439
|
+
],
|
|
440
|
+
"actions": [],
|
|
441
|
+
}
|
|
442
|
+
for revision in range(from_revision, to_revision + 1):
|
|
443
|
+
payload["actions"].append(
|
|
444
|
+
{
|
|
445
|
+
"action": "download",
|
|
446
|
+
"name": snap_name,
|
|
447
|
+
"revision": revision,
|
|
448
|
+
"instance-key": str(uuid.uuid4()),
|
|
449
|
+
}
|
|
450
|
+
)
|
|
451
|
+
|
|
452
|
+
if fields is not None:
|
|
453
|
+
if not all(field in VALID_SNAP_REFRESH_FIELDS for field in fields):
|
|
454
|
+
raise ValueError(
|
|
455
|
+
f"Invalid fields. Allowed fields: {VALID_SNAP_REFRESH_FIELDS}"
|
|
456
|
+
)
|
|
457
|
+
payload["fields"] = fields
|
|
458
|
+
|
|
459
|
+
response = await self.snap_refresh(
|
|
460
|
+
snap_name=snap_name,
|
|
461
|
+
payload=payload,
|
|
462
|
+
extra_headers=extra_headers,
|
|
463
|
+
)
|
|
464
|
+
response.raise_for_status()
|
|
465
|
+
return RefreshRevisionResponse.model_validate_json(response.content)
|
|
466
|
+
|
|
467
|
+
async def get_snap_search_paginated(
|
|
468
|
+
self,
|
|
469
|
+
q: str = "",
|
|
470
|
+
scope: str = "wide",
|
|
471
|
+
arch: str = "wide",
|
|
472
|
+
page: int = 1,
|
|
473
|
+
limit: int = 100,
|
|
474
|
+
confinement: str = "strict,classic",
|
|
475
|
+
) -> PaginatedSnapSearchResponse:
|
|
476
|
+
payload = {
|
|
477
|
+
"scope": scope,
|
|
478
|
+
"arch": arch,
|
|
479
|
+
"page": page,
|
|
480
|
+
"size": limit,
|
|
481
|
+
"confinement": confinement,
|
|
482
|
+
}
|
|
483
|
+
if q:
|
|
484
|
+
payload["q"] = q
|
|
485
|
+
|
|
486
|
+
response = await self.store_client.get(
|
|
487
|
+
f"{self._raw_base_url}/api/v1/snaps/search",
|
|
488
|
+
params=payload,
|
|
489
|
+
)
|
|
490
|
+
|
|
491
|
+
response.raise_for_status()
|
|
492
|
+
response_json = response.json()
|
|
493
|
+
response_json["page"] = page
|
|
494
|
+
response_json["limit"] = limit
|
|
495
|
+
|
|
496
|
+
return PaginatedSnapSearchResponse.model_validate(response_json)
|
|
@@ -72,6 +72,12 @@ class StoreRefreshSnap(Snap, SnapRefreshFields):
|
|
|
72
72
|
pass
|
|
73
73
|
|
|
74
74
|
|
|
75
|
+
class RefreshResultError(BaseModel):
|
|
76
|
+
code: str
|
|
77
|
+
message: str
|
|
78
|
+
extra: Optional[dict] = None
|
|
79
|
+
|
|
80
|
+
|
|
75
81
|
class RefreshResultData(BaseModel):
|
|
76
82
|
model_config = ConfigDict(extra="forbid", exclude_unset=True)
|
|
77
83
|
|
|
@@ -98,6 +104,13 @@ class RefreshResultData(BaseModel):
|
|
|
98
104
|
snap_id: str = Field(
|
|
99
105
|
..., alias=AliasChoices("snap-id", "snap_id"), serialization_alias="snap-id"
|
|
100
106
|
)
|
|
107
|
+
error: RefreshResultError | None = None
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def is_error(self) -> bool:
|
|
111
|
+
if self.error:
|
|
112
|
+
return True
|
|
113
|
+
return False
|
|
101
114
|
|
|
102
115
|
|
|
103
116
|
class RefreshRevisionResponse(BaseModel):
|
|
@@ -7,6 +7,7 @@ from pydantic import (
|
|
|
7
7
|
BaseModel,
|
|
8
8
|
ConfigDict,
|
|
9
9
|
Field,
|
|
10
|
+
computed_field,
|
|
10
11
|
)
|
|
11
12
|
|
|
12
13
|
from snap_python.schemas.common import Revision
|
|
@@ -144,4 +145,35 @@ class ArchSearchResponse(BaseModel):
|
|
|
144
145
|
results: list[ArchSearchItem] = Field(
|
|
145
146
|
alias=AliasChoices(AliasPath("_embedded", "clickindex:package"), "results")
|
|
146
147
|
)
|
|
147
|
-
arch: str
|
|
148
|
+
arch: str = "wide"
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class PaginatedResponse(BaseModel):
|
|
152
|
+
total: int
|
|
153
|
+
page: int = Field(ge=0)
|
|
154
|
+
limit: int = Field(ge=1, le=100)
|
|
155
|
+
|
|
156
|
+
@computed_field
|
|
157
|
+
@property
|
|
158
|
+
def next_page(self) -> Optional[int]:
|
|
159
|
+
if self.page * self.limit + self.limit < self.total:
|
|
160
|
+
return self.page + 1
|
|
161
|
+
return None
|
|
162
|
+
|
|
163
|
+
@computed_field
|
|
164
|
+
@property
|
|
165
|
+
def previous_page(self) -> Optional[int]:
|
|
166
|
+
if self.page > 0:
|
|
167
|
+
return self.page - 1
|
|
168
|
+
return None
|
|
169
|
+
|
|
170
|
+
@computed_field
|
|
171
|
+
@property
|
|
172
|
+
def has_more(self) -> bool:
|
|
173
|
+
return self.page * self.limit + self.limit < self.total
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class PaginatedSnapSearchResponse(PaginatedResponse):
|
|
177
|
+
results: list[ArchSearchItem] = Field(
|
|
178
|
+
alias=AliasChoices(AliasPath("_embedded", "clickindex:package"), "results")
|
|
179
|
+
)
|
snap_python/scrape.py
CHANGED
|
@@ -3,7 +3,7 @@ snap_python/client.py,sha256=rZAfzcQNhdtTyjQml1N-9-nAianFyEwOaI4H_0FMaFE,6612
|
|
|
3
3
|
snap_python/components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
snap_python/components/config.py,sha256=IO_gCrumphEZioINFmXxb8I5OVsKC9cgSa28sQbZ700,1775
|
|
5
5
|
snap_python/components/snaps.py,sha256=FQ362L83jmhu3MLKszOU1w5jGP8l5-WNBlUTLnR6IW8,13176
|
|
6
|
-
snap_python/components/store.py,sha256=
|
|
6
|
+
snap_python/components/store.py,sha256=lxN-6cVslAeen-yfZqMPQ2iNvDUNBCClWIvLn5PZi2Q,16971
|
|
7
7
|
snap_python/schemas/changes.py,sha256=7SYUFXAQq9arl7hAA3YQ0YubMurPJtknTOVxP8ryqew,1919
|
|
8
8
|
snap_python/schemas/common.py,sha256=GLtC9aBo3O8vLKX9PNvzE-_DKN02OGpwsS7Ik2WK9-8,2608
|
|
9
9
|
snap_python/schemas/config.py,sha256=xXTGhk6TpwI8RlR6_qnfWlBHrBnTwr3hRCO5qCnN-6U,107
|
|
@@ -15,11 +15,11 @@ snap_python/schemas/store/json/category_by_name_schema.json,sha256=3-95m6V2WXaPC
|
|
|
15
15
|
snap_python/schemas/store/json/category_schema.json,sha256=c4h_eyyBbChOiNby3hYfjAh9i_1MDbPJnHHU4rGOGss,1898
|
|
16
16
|
snap_python/schemas/store/json/snaps_find_schema.json,sha256=TfKpnievs5QOc7ah97ATMCQTOEfKspONTZnwSwq_0fI,8866
|
|
17
17
|
snap_python/schemas/store/json/snaps_info_schema.json,sha256=udoOovb6Ea7EnE_R9RuZ1CpY1wOJ3-K8xP4-8zKHgrQ,15888
|
|
18
|
-
snap_python/schemas/store/refresh.py,sha256=
|
|
19
|
-
snap_python/schemas/store/search.py,sha256
|
|
20
|
-
snap_python/scrape.py,sha256=
|
|
18
|
+
snap_python/schemas/store/refresh.py,sha256=HAlt-rKfy7vmZSCujMXtW9HHXlVYbHGFwy_BKfD1uCU,3190
|
|
19
|
+
snap_python/schemas/store/search.py,sha256=4ghZb8xY6IESxZuAvzSjM9RaEwZAH3zjiC06zLc0zvU,4561
|
|
20
|
+
snap_python/scrape.py,sha256=ZDJAROp8jwossaAA78gBFTKQzrfnO11RgyyOZqevNd0,4576
|
|
21
21
|
snap_python/utils.py,sha256=cmUooPg5DzNL197Xxvu7LGD4Gwk3xxsT68wbVytRtV0,1240
|
|
22
|
-
snap_python-0.1.
|
|
23
|
-
snap_python-0.1.
|
|
24
|
-
snap_python-0.1.
|
|
25
|
-
snap_python-0.1.
|
|
22
|
+
snap_python-0.1.4.dist-info/LICENSE,sha256=lYXNZszxC_l2rlBvrHYs-esDegxWh8MKtjrdxA24uOk,1072
|
|
23
|
+
snap_python-0.1.4.dist-info/METADATA,sha256=jT6zFn5qHbXNkM8oS4fZQbdGqgFytApIIL85IydP_6M,1883
|
|
24
|
+
snap_python-0.1.4.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
|
25
|
+
snap_python-0.1.4.dist-info/RECORD,,
|
|
File without changes
|