pyvikunja 0.6__tar.gz → 0.7__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.2
2
2
  Name: pyvikunja
3
- Version: 0.6
3
+ Version: 0.7
4
4
  Summary: A Python wrapper for Vikunja API
5
5
  Author: Joseph Shufflebotham
6
6
  License: AGPL
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pyvikunja"
7
- version = "0.6"
7
+ version = "0.7"
8
8
  description = "A Python wrapper for Vikunja API"
9
9
  authors = [
10
10
  {name = "Joseph Shufflebotham"}
@@ -1,5 +1,6 @@
1
1
  import logging
2
2
  from typing import List, Dict, Any, Optional
3
+ from urllib.parse import urlparse, urlunparse
3
4
 
4
5
  import httpx
5
6
 
@@ -15,6 +16,7 @@ logger = logging.getLogger(__name__)
15
16
 
16
17
  class APIError(Exception):
17
18
  """Custom exception for API-related errors."""
19
+
18
20
  def __init__(self, status_code: int, message: str):
19
21
  super().__init__(f"HTTP {status_code}: {message}")
20
22
  self.status_code = status_code
@@ -23,12 +25,43 @@ class APIError(Exception):
23
25
 
24
26
  class VikunjaAPI:
25
27
  def __init__(self, base_url: str, token: str):
26
- self.base_url = base_url
28
+ self.host = self._normalize_host(base_url)
29
+ self.api_base_url = self._normalize_api_base_url(self.host)
27
30
  self.headers = {"Authorization": f"Bearer {token}"}
28
31
  self.client = httpx.AsyncClient()
29
32
 
30
- async def _request(self, method: str, endpoint: str, params: Optional[Dict] = None, data: Optional[Dict] = None) -> Optional[Any]:
31
- url = f"{self.base_url}{endpoint}"
33
+ @property
34
+ def web_ui_link(self):
35
+ return self.host
36
+
37
+ def _normalize_host(self, url: str) -> str:
38
+ """Ensures the host has a valid protocol and retains ports if provided."""
39
+ if "://" not in url:
40
+ url = f"https://{url}" # Default to HTTPS if no scheme provided
41
+
42
+ parsed = urlparse(url)
43
+
44
+ # Default to HTTPS if no scheme is provided
45
+ scheme = parsed.scheme if parsed.scheme else "https"
46
+
47
+ # Ensure netloc is correctly used (handles ports)
48
+ netloc = parsed.netloc if parsed.netloc else parsed.path # Handles cases where netloc is empty
49
+
50
+ # Rebuild the host URL
51
+ host = urlunparse((scheme, netloc, "", "", "", ""))
52
+
53
+ return host.rstrip("/")
54
+
55
+ def _normalize_api_base_url(self, host: str) -> str:
56
+ """Ensures the API base URL includes /api/v1."""
57
+ if not host.endswith("/api/v1"):
58
+ return f"{host}/api/v1"
59
+ return host
60
+
61
+
62
+ async def _request(self, method: str, endpoint: str, params: Optional[Dict] = None, data: Optional[Dict] = None) -> \
63
+ Optional[Any]:
64
+ url = f"{self.api_base_url}{endpoint}"
32
65
  try:
33
66
  response = await self.client.request(method, url, headers=self.headers, params=params, json=data)
34
67
  response.raise_for_status()
@@ -114,5 +147,3 @@ class VikunjaAPI:
114
147
 
115
148
  async def delete_team(self, team_id: int) -> Optional[Team]:
116
149
  return await self._request("DELETE", f"/teams/{team_id}")
117
-
118
-
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pyvikunja
3
- Version: 0.6
3
+ Version: 0.7
4
4
  Summary: A Python wrapper for Vikunja API
5
5
  Author: Joseph Shufflebotham
6
6
  License: AGPL
File without changes
File without changes
File without changes
File without changes