snap-python 0.1.6__py3-none-any.whl → 0.1.7__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,5 +1,6 @@
1
1
  import functools
2
2
  import uuid
3
+ from typing import Optional
3
4
 
4
5
  import retry
5
6
  from httpx import AsyncClient, Response
@@ -77,8 +78,19 @@ class StoreEndpoints:
77
78
  response.raise_for_status()
78
79
  return response.json()
79
80
 
81
+ async def get_snap_name_from_snap_id(self, snap_id: str) -> str | None:
82
+ response = await self.store_client.get(
83
+ f"https://api.snapcraft.io/v2/assertions/snap-declaration/16/{snap_id}"
84
+ )
85
+ response.raise_for_status()
86
+ response_json = response.json()
87
+ return response_json.get("headers", {}).get("snap-name", None)
88
+
80
89
  async def get_snap_info(
81
- self, snap_name: str, fields: list[str] | None = None
90
+ self,
91
+ snap_name: Optional[str] = None,
92
+ snap_id: Optional[str] = None,
93
+ fields: list[str] | None = None,
82
94
  ) -> InfoResponse:
83
95
  """
84
96
  Get information about a snap.
@@ -93,6 +105,15 @@ class StoreEndpoints:
93
105
 
94
106
  :raises ValueError: If invalid fields are provided.
95
107
  """
108
+ if snap_name is None and snap_id is None:
109
+ raise ValueError("Either snap_name or snap_id must be provided.")
110
+ if snap_name is not None and snap_id is not None:
111
+ raise ValueError("Only one of snap_name or snap_id must be provided.")
112
+
113
+ # get snap name from id, then proceed as usual
114
+ if snap_id is not None:
115
+ snap_name = await self.get_snap_name_from_snap_id(snap_id)
116
+
96
117
  query = {}
97
118
  if fields is not None:
98
119
  if not all(field in VALID_SNAP_INFO_FIELDS for field in fields):
@@ -52,7 +52,7 @@ class SnapApp(BaseModel):
52
52
 
53
53
 
54
54
  class Media(BaseModel):
55
- model_config = ConfigDict(extra="forbid", exclude_unset=True)
55
+ model_config = ConfigDict(exclude_unset=True)
56
56
 
57
57
  height: Optional[float] = None
58
58
  type: str
@@ -65,13 +65,13 @@ class AsyncResponse(BaseResponse):
65
65
 
66
66
 
67
67
  class Download(BaseModel):
68
- model_config = ConfigDict(extra="forbid", exclude_unset=True)
68
+ model_config = ConfigDict(exclude_unset=True)
69
69
 
70
70
  size: float
71
71
 
72
72
 
73
73
  class Revision(BaseModel):
74
- model_config = ConfigDict(extra="forbid", exclude_unset=True)
74
+ model_config = ConfigDict(exclude_unset=True)
75
75
 
76
76
  base: Optional[SnapBaseVersion] = None
77
77
  channel: Optional[str] = None
@@ -86,7 +86,7 @@ class Revision(BaseModel):
86
86
 
87
87
 
88
88
  class Publisher(BaseModel):
89
- model_config = ConfigDict(extra="forbid", exclude_unset=True)
89
+ model_config = ConfigDict(exclude_unset=True)
90
90
 
91
91
  display_name: str = Field(
92
92
  ...,
@@ -1,6 +1,6 @@
1
1
  from typing import Optional
2
2
 
3
- from pydantic import AliasChoices, AwareDatetime, BaseModel, ConfigDict, Field
3
+ from pydantic import AliasChoices, AwareDatetime, BaseModel, Field
4
4
 
5
5
  from snap_python.schemas.common import (
6
6
  BaseErrorResult,
@@ -66,8 +66,6 @@ class StoreSnapFields(BaseModel):
66
66
 
67
67
 
68
68
  class Snap(BaseModel):
69
- model_config = ConfigDict(extra="forbid")
70
-
71
69
  contact: Optional[str] = None
72
70
  description: Optional[str] = None
73
71
  license: str = "unset"
@@ -10,7 +10,7 @@ VALID_CATEGORY_FIELDS = ["name", "type", "title", "summary", "description", "med
10
10
 
11
11
 
12
12
  class Media(BaseModel):
13
- model_config = ConfigDict(extra="forbid", exclude_unset=True)
13
+ model_config = ConfigDict(exclude_unset=True)
14
14
 
15
15
  height: Optional[float] = None
16
16
  type: str
@@ -19,7 +19,7 @@ class Media(BaseModel):
19
19
 
20
20
 
21
21
  class Category(BaseModel):
22
- model_config = ConfigDict(extra="forbid", exclude_unset=True)
22
+ model_config = ConfigDict(exclude_unset=True)
23
23
 
24
24
  description: Optional[str] = None
25
25
  media: Optional[Media] = None
@@ -31,12 +31,12 @@ class Category(BaseModel):
31
31
 
32
32
 
33
33
  class CategoryResponse(BaseModel):
34
- model_config = ConfigDict(extra="forbid", exclude_unset=True)
34
+ model_config = ConfigDict(exclude_unset=True)
35
35
 
36
36
  categories: Optional[List[Category]] = None
37
37
 
38
38
 
39
39
  class SingleCategoryResponse(BaseModel):
40
- model_config = ConfigDict(extra="forbid", exclude_unset=True)
40
+ model_config = ConfigDict(exclude_unset=True)
41
41
 
42
42
  category: Category
@@ -45,7 +45,7 @@ VALID_SNAP_INFO_FIELDS = [
45
45
 
46
46
 
47
47
  class Channel(BaseModel):
48
- model_config = ConfigDict(extra="forbid", exclude_unset=True)
48
+ model_config = ConfigDict(exclude_unset=True)
49
49
 
50
50
  architecture: str
51
51
  name: str
@@ -59,7 +59,7 @@ class Channel(BaseModel):
59
59
 
60
60
 
61
61
  class Delta(BaseModel):
62
- model_config = ConfigDict(extra="forbid", exclude_unset=True)
62
+ model_config = ConfigDict(exclude_unset=True)
63
63
 
64
64
  format: str
65
65
  sha3_384: Optional[str] = Field(
@@ -72,7 +72,7 @@ class Delta(BaseModel):
72
72
 
73
73
 
74
74
  class Download(BaseModel):
75
- model_config = ConfigDict(extra="forbid", exclude_unset=True)
75
+ model_config = ConfigDict(exclude_unset=True)
76
76
 
77
77
  deltas: List[Delta]
78
78
  sha3_384: Optional[str] = Field(
@@ -83,7 +83,7 @@ class Download(BaseModel):
83
83
 
84
84
 
85
85
  class Epoch(BaseModel):
86
- model_config = ConfigDict(extra="forbid", exclude_unset=True)
86
+ model_config = ConfigDict(exclude_unset=True)
87
87
 
88
88
  read: List[float]
89
89
  write: List[float]
@@ -98,7 +98,7 @@ class Download1(BaseModel):
98
98
 
99
99
 
100
100
  class Resource(BaseModel):
101
- model_config = ConfigDict(extra="forbid", exclude_unset=True)
101
+ model_config = ConfigDict(exclude_unset=True)
102
102
 
103
103
  architectures: Optional[List[str]] = None
104
104
  created_at: Optional[str] = Field(
@@ -115,7 +115,7 @@ class Resource(BaseModel):
115
115
 
116
116
 
117
117
  class ChannelMapItem(BaseModel):
118
- model_config = ConfigDict(extra="forbid", exclude_unset=True)
118
+ model_config = ConfigDict(exclude_unset=True)
119
119
 
120
120
  architectures: Optional[List[str]] = None
121
121
  base: Optional[str] = None
@@ -145,14 +145,14 @@ class ChannelMapItem(BaseModel):
145
145
 
146
146
 
147
147
  class ErrorListItem(BaseModel):
148
- model_config = ConfigDict(extra="forbid", exclude_unset=True)
148
+ model_config = ConfigDict(exclude_unset=True)
149
149
 
150
150
  code: str
151
151
  message: str
152
152
 
153
153
 
154
154
  class InfoResponse(BaseModel):
155
- model_config = ConfigDict(extra="forbid", exclude_unset=True)
155
+ model_config = ConfigDict(exclude_unset=True)
156
156
 
157
157
  channel_map: List[ChannelMapItem] = Field(
158
158
  ...,
@@ -79,7 +79,7 @@ class RefreshResultError(BaseModel):
79
79
 
80
80
 
81
81
  class RefreshResultData(BaseModel):
82
- model_config = ConfigDict(extra="forbid", exclude_unset=True)
82
+ model_config = ConfigDict(exclude_unset=True)
83
83
 
84
84
  default_track: Optional[str] = Field(
85
85
  None,
@@ -38,7 +38,7 @@ VALID_SEARCH_CATEGORY_FIELDS = [
38
38
 
39
39
 
40
40
  class ErrorListItem(BaseModel):
41
- model_config = ConfigDict(extra="forbid", exclude_unset=True)
41
+ model_config = ConfigDict(exclude_unset=True)
42
42
 
43
43
  code: str
44
44
  message: str
@@ -90,8 +90,6 @@ class SnapDetails(BaseModel):
90
90
 
91
91
 
92
92
  class SearchResult(BaseModel):
93
- model_config = ConfigDict(extra="forbid")
94
-
95
93
  name: str
96
94
  revision: Optional[Revision] = None
97
95
  snap: StoreSnap
@@ -124,15 +122,11 @@ class SearchResult(BaseModel):
124
122
 
125
123
 
126
124
  class SearchResponse(BaseModel):
127
- model_config = ConfigDict(extra="forbid")
128
-
129
125
  error_list: Optional[List[ErrorListItem]] = Field(None, alias="error-list")
130
126
  results: List[SearchResult]
131
127
 
132
128
 
133
129
  class ArchSearchItem(BaseModel):
134
- model_config = ConfigDict(extra="ignore")
135
-
136
130
  aliases: Optional[list[dict[str, str]]]
137
131
  apps: list[str]
138
132
  package_name: str
@@ -13,6 +13,13 @@ logger = logging.getLogger("snap_python.schemas.store.track")
13
13
 
14
14
 
15
15
  class TrackRevisionDetails(BaseModel):
16
+ """Contains details for a specific track/risk/architecture
17
+
18
+
19
+ Raises:
20
+ ValueError: If the architecture is invalid.
21
+ """
22
+
16
23
  arch: str
17
24
  base: str
18
25
  channel: Channel
@@ -44,6 +51,8 @@ class TrackRevisionDetails(BaseModel):
44
51
 
45
52
 
46
53
  class TrackRiskMap(BaseModel):
54
+ """Map of architectures to their revision details for a specific risk level."""
55
+
47
56
  amd64: Optional[TrackRevisionDetails] = None
48
57
  arm64: Optional[TrackRevisionDetails] = None
49
58
  armhf: Optional[TrackRevisionDetails] = None
@@ -63,10 +72,7 @@ class TrackRiskMap(BaseModel):
63
72
  def channel_map_to_current_track_map(
64
73
  channel_map: list[ChannelMapItem],
65
74
  ) -> dict[str, dict[str, TrackRiskMap]]:
66
- """Convert a list of ChannelMapItem to a map of TrackRiskMap.
67
-
68
- track -> risk -> arch
69
- """
75
+ """Convert a list of ChannelMapItem to a map of track -> risk -> TrackRiskMap."""
70
76
  # track -> risk -> arch
71
77
  current_track_map: dict[str, dict[str, TrackRiskMap]] = {}
72
78
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: snap-python
3
- Version: 0.1.6
3
+ Version: 0.1.7
4
4
  Summary: Interact with snapd and snapstore(s) from Python
5
5
  License: MIT
6
6
  Author: Alexander Lukens
@@ -12,8 +12,8 @@ Classifier: Programming Language :: Python :: 3.10
12
12
  Classifier: Programming Language :: Python :: 3.11
13
13
  Classifier: Programming Language :: Python :: 3.12
14
14
  Classifier: Programming Language :: Python :: 3.13
15
- Requires-Dist: httpx (>=0.27.2,<0.28.0)
16
- Requires-Dist: pydantic (>=2.9.2,<3.0.0)
15
+ Requires-Dist: httpx (>0.27,<1)
16
+ Requires-Dist: pydantic (>2.9,<3)
17
17
  Requires-Dist: retry (>=0.9.2,<0.10.0)
18
18
  Project-URL: Documentation, https://alexdlukens.github.io/snap-python/
19
19
  Project-URL: Repository, https://github.com/alexdlukens/snap-python
@@ -3,24 +3,24 @@ snap_python/client.py,sha256=HrgLu0ebhPci8cN3GmfOWc9-ccri80Pk4Oys2RVdoQY,6539
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=NfZAgoNvsvf-aJa-ZZJoJxS-KrwrG6gBe1ScN2WM5To,18003
6
- snap_python/components/store.py,sha256=gryTStqw4Wu7S7book4arqzfyzFcITRSCbW5BK89ce4,17839
6
+ snap_python/components/store.py,sha256=tN7LNsSpEjRLZBE1JTrUdQdcuWYZ6h7srZY7xQyZBf8,18735
7
7
  snap_python/schemas/changes.py,sha256=7SYUFXAQq9arl7hAA3YQ0YubMurPJtknTOVxP8ryqew,1919
8
- snap_python/schemas/common.py,sha256=GLtC9aBo3O8vLKX9PNvzE-_DKN02OGpwsS7Ik2WK9-8,2608
8
+ snap_python/schemas/common.py,sha256=-_a9o45piK0jzwwrW96swAuaXvh_jh9WwlxKU_waCEA,2544
9
9
  snap_python/schemas/config.py,sha256=xXTGhk6TpwI8RlR6_qnfWlBHrBnTwr3hRCO5qCnN-6U,107
10
- snap_python/schemas/snaps.py,sha256=GTDi6_n5P7o9h7-cDllkkFYn8wS9EQ6VZ32rwYJD07A,3657
10
+ snap_python/schemas/snaps.py,sha256=nh2LaqSVFJl6Enpo_SiPZllndRcSK-9bk4E4Q_CxI6w,3598
11
11
  snap_python/schemas/store/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- snap_python/schemas/store/categories.py,sha256=PewotRqoPs7cMKtlZKsHVNfnJoItmNKMekS1Be-46l0,1082
13
- snap_python/schemas/store/info.py,sha256=C5T88QMgMJZzG5BwRXGeSDVMlElefjv30i-Gqm8qRyA,4318
12
+ snap_python/schemas/store/categories.py,sha256=6NZyfi23zWpL2jEgoIKLrTzX9AIjq2APdiQEuCaUzEQ,1018
13
+ snap_python/schemas/store/info.py,sha256=6TqxAqFAXf_z1bkz9MjiNKYpbd87eXL20w4rkgJZQnM,4190
14
14
  snap_python/schemas/store/json/category_by_name_schema.json,sha256=3-95m6V2WXaPCu_DZw-STa9YHPEbr7CI8fbhjaq881s,1674
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=HAlt-rKfy7vmZSCujMXtW9HHXlVYbHGFwy_BKfD1uCU,3190
19
- snap_python/schemas/store/search.py,sha256=4ghZb8xY6IESxZuAvzSjM9RaEwZAH3zjiC06zLc0zvU,4561
20
- snap_python/schemas/store/track.py,sha256=peOjBVccukjud7_Wn_M2hX6KvoJhyhX74FX5HeeHpm8,4099
18
+ snap_python/schemas/store/refresh.py,sha256=fKYffBNki2-rLUk2oVnjAdQTO6P6kJTfcMtAZ1gouTo,3174
19
+ snap_python/schemas/store/search.py,sha256=pFdWXwscM36M9pRfHcpqpbQyNazAW0IOxy5iv4c_tWI,4404
20
+ snap_python/schemas/store/track.py,sha256=5x8UIXhLxDVCtG8H-JJaaaUe_5nFLOth9TkpZ51w474,4307
21
21
  snap_python/scrape.py,sha256=ZDJAROp8jwossaAA78gBFTKQzrfnO11RgyyOZqevNd0,4576
22
22
  snap_python/utils.py,sha256=cmUooPg5DzNL197Xxvu7LGD4Gwk3xxsT68wbVytRtV0,1240
23
- snap_python-0.1.6.dist-info/LICENSE,sha256=lYXNZszxC_l2rlBvrHYs-esDegxWh8MKtjrdxA24uOk,1072
24
- snap_python-0.1.6.dist-info/METADATA,sha256=cfN_x0M8MSEtVq0Du6RlDQTrt6xzbd144tH6jyr_w34,1883
25
- snap_python-0.1.6.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
26
- snap_python-0.1.6.dist-info/RECORD,,
23
+ snap_python-0.1.7.dist-info/LICENSE,sha256=lYXNZszxC_l2rlBvrHYs-esDegxWh8MKtjrdxA24uOk,1072
24
+ snap_python-0.1.7.dist-info/METADATA,sha256=aCfIUhlj5WgeIOQgwKMisa60GUSEPO6OM01JqrBySZ8,1868
25
+ snap_python-0.1.7.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
26
+ snap_python-0.1.7.dist-info/RECORD,,