pyvikunja 0.17__tar.gz → 0.18__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,8 +1,9 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: pyvikunja
3
- Version: 0.17
3
+ Version: 0.18
4
4
  Summary: A Python wrapper for Vikunja API
5
5
  Author: Joseph Shufflebotham
6
6
  License: AGPL
7
7
  License-File: LICENSE
8
8
  Requires-Dist: httpx==0.28.1
9
+ Dynamic: license-file
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pyvikunja"
7
- version = "0.17"
7
+ version = "0.18"
8
8
  description = "A Python wrapper for Vikunja API"
9
9
  authors = [
10
10
  {name = "Joseph Shufflebotham"}
@@ -64,14 +64,18 @@ class VikunjaAPI:
64
64
  return f"{host}/api/v1"
65
65
  return host
66
66
 
67
-
68
67
  async def _request(self, method: str, endpoint: str, params: Optional[Dict] = None, data: Optional[Dict] = None) -> \
69
- Optional[Any]:
68
+ Optional[Dict[str, Any]]:
70
69
  url = f"{self.api_base_url}{endpoint}"
71
70
  try:
72
71
  response = await self.client.request(method, url, headers=self.headers, params=params, json=data)
73
72
  response.raise_for_status()
74
- return response.json()
73
+
74
+ # Return JSON data and headers
75
+ return {
76
+ "data": response.json(),
77
+ "headers": response.headers
78
+ }
75
79
  except httpx.HTTPStatusError as e:
76
80
  logger.error(f"HTTP error occurred: {e.response.status_code} | {e.response.text} | URL: {url}")
77
81
  except httpx.RequestError as e:
@@ -96,76 +100,105 @@ class VikunjaAPI:
96
100
  except httpx.HTTPError as e:
97
101
  raise e
98
102
 
103
+ async def get_paginated_data(self, endpoint: str) -> List[Dict[str, Any]]:
104
+ all_data = []
105
+ page = 1
106
+ per_page = 20
107
+
108
+ while True:
109
+ response = await self._request("GET", endpoint, params={"page": page, "per_page": per_page})
110
+ if not response:
111
+ break
112
+
113
+ all_data.extend(response["data"])
114
+ total_pages = int(response["headers"].get("x-pagination-total-pages", 1))
115
+ if page >= total_pages:
116
+ break
117
+
118
+ page += 1
119
+
120
+ return all_data
121
+
99
122
  # Projects
100
- async def get_projects(self, page: int = 1, per_page: int = 20) -> List[Project]:
101
- response = await self._request("GET", "/projects", params={"page": page, "per_page": per_page})
102
- return [Project(self, project_data) for project_data in response or []]
123
+ async def get_projects(self) -> List[Project]:
124
+ data = await self.get_paginated_data("/projects")
125
+ return [Project(self, project) for project in data]
103
126
 
104
127
  async def get_project(self, project_id: int) -> Optional[Project]:
105
128
  response = await self._request("GET", f"/projects/{project_id}")
106
- return Project(self, response)
129
+ return Project(self, response['data'])
107
130
 
108
131
  async def create_project(self, project: Dict) -> Optional[Dict]:
109
- return await self._request("PUT", "/projects", data=project)
132
+ result = await self._request("PUT", "/projects", data=project)
133
+ return result['data']
110
134
 
111
135
  async def update_project(self, project_id: int, project: Dict) -> Optional[Dict]:
112
- return await self._request("POST", f"/projects/{project_id}", data=project)
136
+ result = await self._request("POST", f"/projects/{project_id}", data=project)
137
+ return result['data']
113
138
 
114
139
  async def delete_project(self, project_id: int) -> Optional[Dict]:
115
- return await self._request("DELETE", f"/projects/{project_id}")
140
+ result = await self._request("DELETE", f"/projects/{project_id}")
141
+ return result['data']
116
142
 
117
143
  # Tasks
118
- async def get_tasks(self, project_id: int, page: int = 1, per_page: int = 20) -> List[Task]:
119
- response = await self._request("GET", f"/projects/{project_id}/tasks",
120
- params={"page": page, "per_page": per_page})
144
+ async def get_tasks(self, project_id: int) -> List[Task]:
145
+ response = await self.get_paginated_data(f"/projects/{project_id}/tasks")
121
146
  return [Task(self, task_data) for task_data in response or []]
122
147
 
123
148
  async def get_task(self, task_id: int) -> Task:
124
149
  data = await self._request("GET", f"/tasks/{task_id}")
125
- return Task(self, data)
150
+ return Task(self, data['data'])
126
151
 
127
152
  async def create_task(self, project_id: int, task: Dict) -> Optional[Dict]:
128
- return await self._request("PUT", f"/projects/{project_id}/tasks", data=task)
153
+ result = await self._request("PUT", f"/projects/{project_id}/tasks", data=task)
154
+ return result['data']
129
155
 
130
156
  async def update_task(self, task_id: int, task: Dict) -> Optional[Dict]:
131
- return await self._request("POST", f"/tasks/{task_id}", data=task)
157
+ result = await self._request("POST", f"/tasks/{task_id}", data=task)
158
+ return result['data']
132
159
 
133
160
  async def delete_task(self, task_id: int) -> Optional[Dict]:
134
- return await self._request("DELETE", f"/tasks/{task_id}")
161
+ result = await self._request("DELETE", f"/tasks/{task_id}")
162
+ return result['data']
135
163
 
136
164
  # Labels
137
- async def get_labels(self, page: int = 1, per_page: int = 20) -> List[Label]:
138
- response = await self._request("GET", "/labels", params={"page": page, "per_page": per_page})
165
+ async def get_labels(self) -> List[Label]:
166
+ response = await self.get_paginated_data("/labels")
139
167
  return [Label(label_data) for label_data in response or []]
140
168
 
141
169
  async def get_label(self, label_id: int) -> Optional[Dict]:
142
- return await self._request("GET", f"/labels/{label_id}")
170
+ result = await self._request("GET", f"/labels/{label_id}")
171
+ return result['data']
143
172
 
144
173
  async def create_label(self, label: Dict) -> Optional[Dict]:
145
- return await self._request("PUT", "/labels", data=label)
174
+ result = await self._request("PUT", "/labels", data=label)
175
+ return result['data']
146
176
 
147
177
  async def update_label(self, label_id: int, label: Dict) -> Optional[Dict]:
148
- return await self._request("PUT", f"/labels/{label_id}", data=label)
178
+ result = await self._request("PUT", f"/labels/{label_id}", data=label)
179
+ return result['data']
149
180
 
150
181
  async def delete_label(self, label_id: int) -> Optional[Dict]:
151
- return await self._request("DELETE", f"/labels/{label_id}")
182
+ result = await self._request("DELETE", f"/labels/{label_id}")
183
+ return result['data']
152
184
 
153
185
  # Teams
154
- async def get_teams(self, page: int = 1, per_page: int = 20) -> List[Team]:
155
- response = await self._request("GET", "/teams", params={"page": page, "per_page": per_page})
186
+ async def get_teams(self) -> List[Team]:
187
+ response = await self.get_paginated_data("/teams")
156
188
  return [Team(self, team_data) for team_data in response or []]
157
189
 
158
190
  async def get_team(self, team_id: int) -> Optional[Team]:
159
191
  response = await self._request("GET", f"/teams/{team_id}")
160
- return Team(self, response)
192
+ return Team(self, response['data'])
161
193
 
162
194
  async def create_team(self, team: Dict) -> Optional[Team]:
163
195
  response = await self._request("PUT", "/teams", data=team)
164
- return Team(self, response)
196
+ return Team(self, response['data'])
165
197
 
166
198
  async def update_team(self, team_id: int, team: Dict) -> Optional[Team]:
167
199
  response = await self._request("POST", f"/teams/{team_id}", data=team)
168
- return Team(self, response)
200
+ return Team(self, response['data'])
169
201
 
170
202
  async def delete_team(self, team_id: int) -> Optional[Team]:
171
- return await self._request("DELETE", f"/teams/{team_id}")
203
+ result = await self._request("DELETE", f"/teams/{team_id}")
204
+ return result['data']
@@ -15,8 +15,8 @@ class Project(BaseModel):
15
15
  self.hex_color: Optional[str] = data.get('hex_color')
16
16
  self.owner: 'User' = User(data.get('owner') or {})
17
17
 
18
- async def get_tasks(self, page: int = 1, per_page: int = 20) -> List['Task']:
19
- return await self.api.get_tasks(self.id, page, per_page)
18
+ async def get_tasks(self) -> List['Task']:
19
+ return await self.api.get_tasks(self.id)
20
20
 
21
21
  async def create_task(self, task: Dict) -> 'Task':
22
22
  from pyvikunja.models.task import Task
@@ -1,8 +1,9 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: pyvikunja
3
- Version: 0.17
3
+ Version: 0.18
4
4
  Summary: A Python wrapper for Vikunja API
5
5
  Author: Joseph Shufflebotham
6
6
  License: AGPL
7
7
  License-File: LICENSE
8
8
  Requires-Dist: httpx==0.28.1
9
+ Dynamic: license-file
File without changes
File without changes
File without changes
File without changes