vc-utils 2.1__tar.gz → 3.0__tar.gz

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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vc-utils
3
- Version: 2.1
3
+ Version: 3.0
4
4
  Summary: Vulcan Coalition Python Utility Library
5
5
  Home-page: https://github.com/vulcan-coalition/vulcan-utils
6
6
  Author: Chatavut Viriyasuthee
@@ -1 +1,2 @@
1
1
  from .session import init, Linkage_Application, get_user_data, get_authn_req_url, get_token, revoke
2
+ from .achievement import Achievement
@@ -0,0 +1,9 @@
1
+ from pydantic import BaseModel
2
+ from typing import Any, List, Optional
3
+
4
+
5
+ class Achievement(BaseModel):
6
+ title: str
7
+ description: str
8
+ metadata: Any = None
9
+ files: Optional[List[str]] = None # paths to files to be uploaded
@@ -3,6 +3,7 @@ import logging
3
3
  from . import key_generator
4
4
  import aiohttp
5
5
  from urllib.parse import urlencode
6
+ from .achievement import Achievement
6
7
 
7
8
 
8
9
  AUTHORIZE_ENDPOINT = "/authorize"
@@ -126,7 +127,89 @@ class Linkage_Application:
126
127
  error_data = await resp.json()
127
128
  raise Exception(error_data)
128
129
  return await resp.json()
130
+
131
+
132
+ async def update_achievement(self, session, user_id, achievement):
133
+ """
134
+ POST /achievements/user/{user_id}
135
+ title: str = Form(...),
136
+ description: str = Form(...),
137
+ metadata: Any = Form(None),
138
+ files: List[UploadFile] = File([]),
139
+ """
140
+ uri = f"{LINKAGE_M2M_HOST}/achievements/user/{user_id}"
141
+ opened_files = []
142
+ try:
143
+ data = aiohttp.FormData()
144
+ data.add_field("title", achievement.title)
145
+ data.add_field("description", achievement.description)
146
+ if achievement.metadata is not None:
147
+ data.add_field("metadata", str(achievement.metadata))
148
+ if achievement.files:
149
+ for file_path in achievement.files:
150
+ f = open(file_path, "rb")
151
+ opened_files.append(f)
152
+ data.add_field("files", f, filename=os.path.basename(file_path))
153
+ resp = await self.linkage_post(session, uri, data=data)
154
+ if resp.status != 200:
155
+ error_data = await resp.json()
156
+ raise Exception(error_data)
157
+ except Exception as e:
158
+ raise e
159
+ finally:
160
+ for f in opened_files:
161
+ f.close()
162
+
163
+ return await resp.json()
164
+
165
+
166
+ async def batch_read_achievements(self, session, user_ids, app_ids, expiration=300):
167
+ """
168
+ POST /achievements/batch
129
169
 
170
+ user_ids: List[str] = Body(..., embed=True),
171
+ app_ids: List[str] = Body(..., embed=True),
172
+ expiration: int = Query(300, description="Expiration time for signed URLs in seconds"),
173
+
174
+ """
175
+ uri = f"{LINKAGE_M2M_HOST}/achievements/batch?expiration={expiration}"
176
+ payload = {
177
+ "user_ids": user_ids,
178
+ "app_ids": app_ids,
179
+ }
180
+ resp = await self.linkage_post(session, uri, json=payload)
181
+ if resp.status != 200:
182
+ error_data = await resp.json()
183
+ raise Exception(error_data)
184
+
185
+ # convert the response to a dict of user_id -> list of achievements
186
+ # data has this format: {user_id: {"s": status, "achievements": {"app_id": {"s": status, "data": {title, description, metadata, files}}}}}
187
+ data = await resp.json()
188
+ result = {}
189
+ for user_id, value in data.items():
190
+ if value.get("s") != "ok":
191
+ logging.warning(f"Failed to fetch achievements for user {user_id}, status: {value.get('s')}")
192
+ continue
193
+
194
+ achs = []
195
+ for app_id, ach_value in value.get("achievements", {}).items():
196
+ if app_id not in app_ids:
197
+ logging.warning(f"Received achievement data for unexpected app_id {app_id}, skipping")
198
+ continue
199
+ if ach_value.get("s") != "ok":
200
+ logging.warning(f"Failed to fetch achievement for user {user_id} and app {app_id}, status: {ach_value.get('s')}")
201
+ continue
202
+ ach_data = ach_value.get("data", {})
203
+ ach = Achievement(
204
+ title=ach_data.get("title", ""),
205
+ description=ach_data.get("description", ""),
206
+ metadata=ach_data.get("metadata", None),
207
+ files=[d['url_download'] for d in ach_data.get("download_links", [])]
208
+ )
209
+ achs.append(ach)
210
+ result[user_id] = achs
211
+ return result
212
+
130
213
 
131
214
  async def get_user_data(token, spec_id=None):
132
215
  if not token:
@@ -11,7 +11,7 @@ import shutil
11
11
 
12
12
  setup(
13
13
  name="vc-utils",
14
- version="2.1",
14
+ version="3.0",
15
15
  author="Chatavut Viriyasuthee",
16
16
  author_email="chatavut@lab.ai",
17
17
  description="Vulcan Coalition Python Utility Library",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vc-utils
3
- Version: 2.1
3
+ Version: 3.0
4
4
  Summary: Vulcan Coalition Python Utility Library
5
5
  Home-page: https://github.com/vulcan-coalition/vulcan-utils
6
6
  Author: Chatavut Viriyasuthee
@@ -1,6 +1,7 @@
1
1
  README.md
2
2
  setup.py
3
3
  linkage/__init__.py
4
+ linkage/achievement.py
4
5
  linkage/key_generator.py
5
6
  linkage/session.py
6
7
  vc_utils.egg-info/PKG-INFO
File without changes
File without changes
File without changes