Habiticalib 0.1.0a2__tar.gz → 0.2.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.
Files changed (45) hide show
  1. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/.github/labels.yml +0 -3
  2. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/.github/workflows/build.yml +1 -1
  3. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/PKG-INFO +3 -3
  4. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/pyproject.toml +3 -2
  5. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/src/habiticalib/__init__.py +34 -2
  6. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/src/habiticalib/const.py +3 -1
  7. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/src/habiticalib/exceptions.py +13 -4
  8. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/src/habiticalib/helpers.py +25 -1
  9. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/src/habiticalib/lib.py +508 -25
  10. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/src/habiticalib/types.py +488 -66
  11. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/tests/__snapshots__/test_avatar.ambr +1 -1
  12. habiticalib-0.2.0/tests/__snapshots__/test_lib.ambr +7 -0
  13. habiticalib-0.2.0/tests/fixtures/login.json +10 -0
  14. habiticalib-0.1.0a2/tests/test_user.py → habiticalib-0.2.0/tests/test_lib.py +12 -0
  15. habiticalib-0.1.0a2/tests/__snapshots__/test_user.ambr +0 -4
  16. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/.cruft.json +0 -0
  17. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/.editorconfig +0 -0
  18. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/.github/FUNDING.yml +0 -0
  19. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/.github/dependabot.yml +0 -0
  20. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/.github/release-drafter.yml +0 -0
  21. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/.github/workflows/documentation.yml +0 -0
  22. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/.github/workflows/draft.yml +0 -0
  23. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/.github/workflows/labeler.yml +0 -0
  24. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/.gitignore +0 -0
  25. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/.pre-commit-config.yaml +0 -0
  26. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/.vscode/settings.json +0 -0
  27. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/LICENSE +0 -0
  28. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/README.md +0 -0
  29. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/docs/index.md +0 -0
  30. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/docs/reference/habiticalib.md +0 -0
  31. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/mkdocs.yml +0 -0
  32. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/src/habiticalib/py.typed +0 -0
  33. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/tests/__init__.py +0 -0
  34. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/tests/conftest.py +0 -0
  35. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/tests/fixtures/user.json +0 -0
  36. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/tests/fixtures/user_styles.json +0 -0
  37. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/tests/fixtures/user_styles_kickstarter.json +0 -0
  38. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/tests/fixtures/user_styles_seafoam.json +0 -0
  39. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/tests/fixtures/user_styles_shinySeed.json +0 -0
  40. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/tests/fixtures/user_styles_sleeping.json +0 -0
  41. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/tests/fixtures/user_styles_snowball.json +0 -0
  42. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/tests/fixtures/user_styles_spookySparkles.json +0 -0
  43. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/tests/fixtures/user_styles_with_chair.json +0 -0
  44. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/tests/test_avatar.py +0 -0
  45. {habiticalib-0.1.0a2 → habiticalib-0.2.0}/tests/test_init.py +0 -0
@@ -28,7 +28,6 @@
28
28
  - name: feature
29
29
  description: New feature or request
30
30
  color: a2eeef
31
- from_name: enhancement
32
31
  - name: github_actions
33
32
  description: Pull requests that update Github_actions code
34
33
  color: "000000"
@@ -53,11 +52,9 @@
53
52
  - name: code quality
54
53
  description: Code quality improvements
55
54
  color: ef67c4
56
- from_name: refactor
57
55
  - name: deprecation
58
56
  description: Removals and Deprecations
59
57
  color: 9ae7ea
60
- from_name: removal
61
58
  - name: style
62
59
  description: Style
63
60
  color: c120e5
@@ -27,7 +27,7 @@ jobs:
27
27
  - name: Test
28
28
  run: |
29
29
  hatch run test-cov-xml
30
- - uses: codecov/codecov-action@v4
30
+ - uses: codecov/codecov-action@v5
31
31
  with:
32
32
  token: ${{ secrets.CODECOV_TOKEN }}
33
33
  fail_ci_if_error: true
@@ -1,20 +1,20 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: Habiticalib
3
- Version: 0.1.0a2
3
+ Version: 0.2.0
4
4
  Summary: Asynchronous Python client library for the Habitica API
5
5
  Project-URL: Documentation, https://tr4nt0r.github.io/habiticalib/
6
6
  Project-URL: Source, https://github.com/tr4nt0r/habiticalib
7
7
  Author-email: Manfred Dennerlein Rodelo <manfred@dennerlein.name>
8
8
  License: MIT License
9
- License-File: LICENSE
10
9
  Classifier: License :: OSI Approved :: MIT License
11
10
  Classifier: Operating System :: OS Independent
12
11
  Classifier: Programming Language :: Python :: 3 :: Only
13
12
  Requires-Python: >=3.12
14
13
  Requires-Dist: aiohttp~=3.9
14
+ Requires-Dist: habitipy~=0.3.3
15
15
  Requires-Dist: mashumaro~=3.13
16
16
  Requires-Dist: orjson~=3.10
17
- Requires-Dist: pillow~=10.4
17
+ Requires-Dist: pillow~=11.0
18
18
  Description-Content-Type: text/markdown
19
19
 
20
20
  # Habiticalib
@@ -69,7 +69,7 @@ dependencies = [
69
69
  "aiohttp==3.10.10",
70
70
  "mashumaro==3.13.1",
71
71
  "orjson==3.10.7",
72
- "Pillow==10.4.0",
72
+ "Pillow==11.0.0",
73
73
  "mypy==1.12.0",
74
74
  "ruff==0.7.0",
75
75
  "pytest==8.3.3",
@@ -125,7 +125,8 @@ dependencies = [
125
125
  "aiohttp~=3.9",
126
126
  "mashumaro~=3.13",
127
127
  "orjson~=3.10",
128
- "Pillow~=10.4"
128
+ "Pillow~=11.0",
129
+ "habitipy~=0.3.3"
129
130
  ]
130
131
 
131
132
  [project.urls]
@@ -6,18 +6,26 @@ from .exceptions import (
6
6
  HabiticaException,
7
7
  NotAuthorizedError,
8
8
  NotFoundError,
9
+ TooManyRequestsError,
9
10
  )
11
+ from .helpers import deserialize_task
10
12
  from .lib import Habitica
11
13
  from .types import (
12
14
  Attributes,
13
- Class,
15
+ ChangeClassData,
16
+ ContentData,
14
17
  Direction,
15
18
  Frequency,
19
+ HabiticaClass,
16
20
  HabiticaClassSystemResponse,
21
+ HabiticaContentResponse,
17
22
  HabiticaErrorResponse,
23
+ HabiticaGroupMembersResponse,
18
24
  HabiticaLoginResponse,
25
+ HabiticaQuestResponse,
19
26
  HabiticaResponse,
20
27
  HabiticaScoreResponse,
28
+ HabiticaSleepResponse,
21
29
  HabiticaStatsResponse,
22
30
  HabiticaTagResponse,
23
31
  HabiticaTagsResponse,
@@ -27,10 +35,18 @@ from .types import (
27
35
  HabiticaUserExport,
28
36
  HabiticaUserResponse,
29
37
  Language,
38
+ LoginData,
39
+ QuestData,
40
+ ScoreData,
30
41
  Skill,
42
+ StatsUser,
43
+ TagsUser,
31
44
  Task,
45
+ TaskData,
32
46
  TaskFilter,
47
+ TaskPriority,
33
48
  TaskType,
49
+ UserData,
34
50
  UserStyles,
35
51
  )
36
52
 
@@ -39,17 +55,24 @@ __all__ = [
39
55
  "ASSETS_URL",
40
56
  "Attributes",
41
57
  "BadRequestError",
42
- "Class",
58
+ "ChangeClassData",
59
+ "ContentData",
43
60
  "DEFAULT_URL",
61
+ "deserialize_task",
44
62
  "Direction",
45
63
  "Frequency",
46
64
  "Habitica",
65
+ "HabiticaClass",
47
66
  "HabiticaClassSystemResponse",
67
+ "HabiticaContentResponse",
48
68
  "HabiticaErrorResponse",
49
69
  "HabiticaException",
70
+ "HabiticaGroupMembersResponse",
50
71
  "HabiticaLoginResponse",
72
+ "HabiticaQuestResponse",
51
73
  "HabiticaResponse",
52
74
  "HabiticaScoreResponse",
75
+ "HabiticaSleepResponse",
53
76
  "HabiticaStatsResponse",
54
77
  "HabiticaTagResponse",
55
78
  "HabiticaTagsResponse",
@@ -59,11 +82,20 @@ __all__ = [
59
82
  "HabiticaUserExport",
60
83
  "HabiticaUserResponse",
61
84
  "Language",
85
+ "LoginData",
62
86
  "NotAuthorizedError",
63
87
  "NotFoundError",
88
+ "QuestData",
89
+ "ScoreData",
64
90
  "Skill",
91
+ "StatsUser",
92
+ "TagsUser",
65
93
  "Task",
94
+ "TaskData",
66
95
  "TaskFilter",
96
+ "TaskPriority",
67
97
  "TaskType",
98
+ "TooManyRequestsError",
99
+ "UserData",
68
100
  "UserStyles",
69
101
  ]
@@ -1,6 +1,6 @@
1
1
  """Constants for Habiticalib."""
2
2
 
3
- __version__ = "0.1.0a2"
3
+ __version__ = "0.2.0"
4
4
 
5
5
  DEFAULT_URL = "https://habitica.com/"
6
6
  ASSETS_URL = "https://habitica-assets.s3.amazonaws.com/mobileApp/images/"
@@ -14,3 +14,5 @@ BACKER_ONLY_GEAR = {
14
14
  "shield_special_ks2019": "BackerOnly-Equip-MythicGryphonShield.gif",
15
15
  "weapon_special_ks2019": "BackerOnly-Equip-MythicGryphonGlaive.gif",
16
16
  }
17
+
18
+ PAGE_LIMIT = 60
@@ -1,5 +1,6 @@
1
1
  """Exceptions for Habiticalib."""
2
2
 
3
+ from datetime import datetime
3
4
  from typing import Self
4
5
 
5
6
  from multidict import CIMultiDictProxy
@@ -17,10 +18,18 @@ class HabiticaException(Exception): # noqa: N818
17
18
  ) -> None:
18
19
  """Initialize the Exception."""
19
20
  self.error = error
20
- self.rate_limit = headers.get("x-ratelimit-limit")
21
- self.rate_limit_remaining = headers.get("x-ratelimit-remaining")
22
- self.rate_limit_reset = headers.get("x-ratelimit-reset")
23
- self.retry_after = headers.get("retry-after")
21
+ self.rate_limit: int | None = (
22
+ int(r) if (r := headers.get("x-ratelimit-limit")) else None
23
+ )
24
+ self.rate_limit_remaining: int | None = (
25
+ int(r) if (r := headers.get("x-ratelimit-remaining")) else None
26
+ )
27
+ self.rate_limit_reset: datetime | None = (
28
+ datetime.strptime(r[:33], "%a %b %d %Y %H:%M:%S %Z%z")
29
+ if (r := headers.get("x-ratelimit-reset"))
30
+ else None
31
+ )
32
+ self.retry_after: int = round(float(headers.get("retry-after", 0)))
24
33
 
25
34
  super().__init__(error.message)
26
35
 
@@ -1,7 +1,10 @@
1
1
  """Helper functions for Habiticalib."""
2
2
 
3
- from dataclasses import asdict
3
+ from dataclasses import asdict, is_dataclass
4
+ from datetime import date, datetime
5
+ from enum import Enum
4
6
  import platform
7
+ from typing import Any
5
8
  import uuid
6
9
 
7
10
  import aiohttp
@@ -112,3 +115,24 @@ def extract_user_styles(user_data: HabiticaUserResponse) -> UserStyles:
112
115
  """Extract user styles from a user data object."""
113
116
  data: UserData = user_data.data
114
117
  return UserStyles.from_dict(asdict(data))
118
+
119
+
120
+ def deserialize_task(value: Any) -> Any: # noqa: PLR0911
121
+ """Recursively convert Enums to values, dates to ISO strings, UUIDs to strings."""
122
+
123
+ if is_dataclass(value) and not isinstance(value, type):
124
+ # Convert dataclass to dict and recursively deserialize
125
+ return deserialize_task(asdict(value))
126
+ if isinstance(value, Enum):
127
+ return value.value # Convert Enum to its value
128
+ if isinstance(value, uuid.UUID):
129
+ return str(value) # Convert UUID to string
130
+ if isinstance(value, datetime | date):
131
+ return value.isoformat() # Convert datetime/date to ISO string
132
+ if isinstance(value, list):
133
+ # Recursively apply deserialization to each item in the list
134
+ return [deserialize_task(item) for item in value]
135
+ if isinstance(value, dict):
136
+ # Recursively apply deserialization to each key-value pair in the dictionary
137
+ return {k: deserialize_task(v) for k, v in value.items()}
138
+ return value # Return other types unchanged