Habiticalib 0.1.0a1__py3-none-any.whl → 0.1.0a2__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.
habiticalib/__init__.py CHANGED
@@ -1,12 +1,69 @@
1
1
  """Modern asynchronous Python client library for the Habitica API."""
2
2
 
3
- from .exceptions import HabiticaException, NotAuthorizedError, NotFoundError
3
+ from .const import ASSETS_URL, DEFAULT_URL, __version__
4
+ from .exceptions import (
5
+ BadRequestError,
6
+ HabiticaException,
7
+ NotAuthorizedError,
8
+ NotFoundError,
9
+ )
4
10
  from .lib import Habitica
11
+ from .types import (
12
+ Attributes,
13
+ Class,
14
+ Direction,
15
+ Frequency,
16
+ HabiticaClassSystemResponse,
17
+ HabiticaErrorResponse,
18
+ HabiticaLoginResponse,
19
+ HabiticaResponse,
20
+ HabiticaScoreResponse,
21
+ HabiticaStatsResponse,
22
+ HabiticaTagResponse,
23
+ HabiticaTagsResponse,
24
+ HabiticaTaskOrderResponse,
25
+ HabiticaTaskResponse,
26
+ HabiticaTasksResponse,
27
+ HabiticaUserExport,
28
+ HabiticaUserResponse,
29
+ Language,
30
+ Skill,
31
+ Task,
32
+ TaskFilter,
33
+ TaskType,
34
+ UserStyles,
35
+ )
5
36
 
6
- __version__ = "0.1.0a1"
7
37
  __all__ = [
38
+ "__version__",
39
+ "ASSETS_URL",
40
+ "Attributes",
41
+ "BadRequestError",
42
+ "Class",
43
+ "DEFAULT_URL",
44
+ "Direction",
45
+ "Frequency",
8
46
  "Habitica",
47
+ "HabiticaClassSystemResponse",
48
+ "HabiticaErrorResponse",
9
49
  "HabiticaException",
50
+ "HabiticaLoginResponse",
51
+ "HabiticaResponse",
52
+ "HabiticaScoreResponse",
53
+ "HabiticaStatsResponse",
54
+ "HabiticaTagResponse",
55
+ "HabiticaTagsResponse",
56
+ "HabiticaTaskOrderResponse",
57
+ "HabiticaTaskResponse",
58
+ "HabiticaTasksResponse",
59
+ "HabiticaUserExport",
60
+ "HabiticaUserResponse",
61
+ "Language",
10
62
  "NotAuthorizedError",
11
63
  "NotFoundError",
64
+ "Skill",
65
+ "Task",
66
+ "TaskFilter",
67
+ "TaskType",
68
+ "UserStyles",
12
69
  ]
habiticalib/const.py CHANGED
@@ -1,5 +1,7 @@
1
1
  """Constants for Habiticalib."""
2
2
 
3
+ __version__ = "0.1.0a2"
4
+
3
5
  DEFAULT_URL = "https://habitica.com/"
4
6
  ASSETS_URL = "https://habitica-assets.s3.amazonaws.com/mobileApp/images/"
5
7
 
habiticalib/exceptions.py CHANGED
@@ -2,15 +2,25 @@
2
2
 
3
3
  from typing import Self
4
4
 
5
+ from multidict import CIMultiDictProxy
6
+
5
7
  from habiticalib.types import HabiticaErrorResponse
6
8
 
7
9
 
8
10
  class HabiticaException(Exception): # noqa: N818
9
11
  """Base class for Habitica errors."""
10
12
 
11
- def __init__(self: Self, error: HabiticaErrorResponse) -> None:
13
+ def __init__(
14
+ self: Self,
15
+ error: HabiticaErrorResponse,
16
+ headers: CIMultiDictProxy,
17
+ ) -> None:
12
18
  """Initialize the Exception."""
13
19
  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")
14
24
 
15
25
  super().__init__(error.message)
16
26
 
@@ -25,3 +35,7 @@ class NotFoundError(HabiticaException):
25
35
 
26
36
  class BadRequestError(HabiticaException):
27
37
  """BadRequest error."""
38
+
39
+
40
+ class TooManyRequestsError(HabiticaException):
41
+ """TooManyRequests error."""
habiticalib/helpers.py CHANGED
@@ -1,13 +1,12 @@
1
1
  """Helper functions for Habiticalib."""
2
2
 
3
3
  from dataclasses import asdict
4
- from importlib.metadata import version
5
4
  import platform
6
5
  import uuid
7
6
 
8
7
  import aiohttp
9
8
 
10
- from .const import DEVELOPER_ID
9
+ from .const import DEVELOPER_ID, __version__
11
10
  from .types import HabiticaUserResponse, UserData, UserStyles
12
11
 
13
12
 
@@ -58,7 +57,7 @@ def get_user_agent() -> str:
58
57
  os_info = f"{os_name} {os_release} ({os_version}); {arch}"
59
58
 
60
59
  return (
61
- f"Habiticalib/{version("habiticalib")} ({os_info}) "
60
+ f"Habiticalib/{__version__} ({os_info}) "
62
61
  f"aiohttp/{aiohttp.__version__} Python/{platform.python_version()} "
63
62
  " +https://github.com/tr4nt0r/habiticalib)"
64
63
  )
@@ -106,7 +105,7 @@ def get_x_client(x_client: str | None = None) -> str:
106
105
 
107
106
  return x_client
108
107
 
109
- return f"{DEVELOPER_ID} - Habiticalib/{version("habiticalib")}"
108
+ return f"{DEVELOPER_ID} - Habiticalib/{__version__}"
110
109
 
111
110
 
112
111
  def extract_user_styles(user_data: HabiticaUserResponse) -> UserStyles:
habiticalib/lib.py CHANGED
@@ -13,7 +13,12 @@ from PIL import Image
13
13
  from yarl import URL
14
14
 
15
15
  from .const import ASSETS_URL, BACKER_ONLY_GEAR, DEFAULT_URL
16
- from .exceptions import BadRequestError, NotAuthorizedError, NotFoundError
16
+ from .exceptions import (
17
+ BadRequestError,
18
+ NotAuthorizedError,
19
+ NotFoundError,
20
+ TooManyRequestsError,
21
+ )
17
22
  from .helpers import extract_user_styles, get_user_agent, get_x_client, join_fields
18
23
  from .types import (
19
24
  Attributes,
@@ -87,7 +92,7 @@ class Habitica:
87
92
  msg = "Both 'api_user' and 'api_key' must be provided together."
88
93
  raise ValueError(msg)
89
94
 
90
- self.url = URL(url if url else DEFAULT_URL) / "api"
95
+ self.url = URL(url if url else DEFAULT_URL)
91
96
 
92
97
  self._assets_cache: dict[str, IO[bytes]] = {}
93
98
  self._cache_order: list[str] = []
@@ -102,15 +107,19 @@ class Habitica:
102
107
  ) as r:
103
108
  if r.status == HTTPStatus.UNAUTHORIZED:
104
109
  raise NotAuthorizedError(
105
- HabiticaErrorResponse.from_json(await r.text()),
110
+ HabiticaErrorResponse.from_json(await r.text()), r.headers
106
111
  )
107
112
  if r.status == HTTPStatus.NOT_FOUND:
108
113
  raise NotFoundError(
109
- HabiticaErrorResponse.from_json(await r.text()),
114
+ HabiticaErrorResponse.from_json(await r.text()), r.headers
110
115
  )
111
116
  if r.status == HTTPStatus.BAD_REQUEST:
112
117
  raise BadRequestError(
113
- HabiticaErrorResponse.from_json(await r.text()),
118
+ HabiticaErrorResponse.from_json(await r.text()), r.headers
119
+ )
120
+ if r.status == HTTPStatus.TOO_MANY_REQUESTS:
121
+ raise TooManyRequestsError(
122
+ HabiticaErrorResponse.from_json(await r.text()), r.headers
114
123
  )
115
124
  r.raise_for_status()
116
125
  return await r.text()
@@ -169,7 +178,7 @@ class Habitica:
169
178
  >>> response.data.apiToken
170
179
  'api-token'
171
180
  """
172
- url = self.url / "v3/user/auth/local/login"
181
+ url = self.url / "api/v3/user/auth/local/login"
173
182
  data = {
174
183
  "username": username,
175
184
  "password": password,
@@ -229,7 +238,7 @@ class Habitica:
229
238
  >>> response = await habitica.get_user(user_fields="achievements,items.mounts")
230
239
  >>> response.data # Access the returned data from the response
231
240
  """
232
- url = self.url / "v3/user"
241
+ url = self.url / "api/v3/user"
233
242
  params = {}
234
243
 
235
244
  if user_fields:
@@ -290,7 +299,7 @@ class Habitica:
290
299
 
291
300
  >>> await habitica.get_tasks(TaskType.HABITS, due_date=datetime(2024, 10, 15))
292
301
  """
293
- url = self.url / "v3/tasks/user"
302
+ url = self.url / "api/v3/tasks/user"
294
303
  params = {}
295
304
 
296
305
  if task_type:
@@ -334,7 +343,7 @@ class Habitica:
334
343
  >>> task_response = await habitica.get_task(task_id)
335
344
  >>> print(task_response.data) # Displays the retrieved task information
336
345
  """
337
- url = self.url / "v3/tasks" / str(task_id)
346
+ url = self.url / "api/v3/tasks" / str(task_id)
338
347
 
339
348
  return HabiticaTaskResponse.from_json(
340
349
  await self._request("get", url=url),
@@ -373,7 +382,7 @@ class Habitica:
373
382
  >>> create_response = await habitica.create_task(new_task)
374
383
  >>> print(create_response.data) # Displays the created task information
375
384
  """
376
- url = self.url / "v3/tasks/user"
385
+ url = self.url / "api/v3/tasks/user"
377
386
 
378
387
  return HabiticaTaskResponse.from_json(
379
388
  await self._request("post", url=url, json=task.to_dict()),
@@ -416,7 +425,7 @@ class Habitica:
416
425
  >>> update_response = await habitica.update_task(task_id, updated_task)
417
426
  >>> print(update_response.data) # Displays the updated task information
418
427
  """
419
- url = self.url / "v3/tasks" / str(task_id)
428
+ url = self.url / "api/v3/tasks" / str(task_id)
420
429
 
421
430
  return HabiticaTaskResponse.from_json(
422
431
  await self._request("put", url=url, json=task.to_dict()),
@@ -455,7 +464,7 @@ class Habitica:
455
464
  >>> delete_response = await habitica.delete_task(task_id)
456
465
  >>> print(delete_response.success) # True if successfully deleted
457
466
  """
458
- url = self.url / "v3/tasks" / str(task_id)
467
+ url = self.url / "api/v3/tasks" / str(task_id)
459
468
 
460
469
  return HabiticaResponse.from_json(
461
470
  await self._request("delete", url=url),
@@ -497,7 +506,7 @@ class Habitica:
497
506
  >>> reorder_response = await habitica.reorder_task(task_id, 2)
498
507
  >>> print(reorder_response.data) # Displays a list of task IDs in the new order
499
508
  """
500
- url = self.url / "v3/tasks" / str(task_id) / "move/to" / str(to)
509
+ url = self.url / "api/v3/tasks" / str(task_id) / "move/to" / str(to)
501
510
 
502
511
  return HabiticaTaskOrderResponse.from_json(
503
512
  await self._request("post", url=url),
@@ -531,7 +540,7 @@ class Habitica:
531
540
  TimeoutError
532
541
  If the connection times out.
533
542
  """
534
- url = self.url.parent / "export/userdata.json"
543
+ url = self.url / "export/userdata.json"
535
544
 
536
545
  return HabiticaUserExport.from_json(
537
546
  await self._request("get", url=url),
@@ -576,7 +585,7 @@ class Habitica:
576
585
  TimeoutError
577
586
  If the connection times out.
578
587
  """
579
- url = self.url / "v3/content"
588
+ url = self.url / "api/v3/content"
580
589
  params = {}
581
590
 
582
591
  if language:
@@ -612,7 +621,7 @@ class Habitica:
612
621
  TimeoutError
613
622
  If the connection times out.
614
623
  """
615
- url = self.url / "v3/cron"
624
+ url = self.url / "api/v3/cron"
616
625
  return HabiticaResponse.from_json(await self._request("post", url=url))
617
626
 
618
627
  async def allocate_single_stat_point(
@@ -656,7 +665,7 @@ class Habitica:
656
665
  Allocate a single stat point to Strength (default):
657
666
  >>> await habitica.allocate_single_stat_point()
658
667
  """
659
- url = self.url / "v3/user/allocate"
668
+ url = self.url / "api/v3/user/allocate"
660
669
  params = {"stat": stat}
661
670
 
662
671
  return HabiticaStatsResponse.from_json(
@@ -690,7 +699,7 @@ class Habitica:
690
699
  TimeoutError
691
700
  If the connection times out.
692
701
  """
693
- url = self.url / "v3/user/allocate-now"
702
+ url = self.url / "api/v3/user/allocate-now"
694
703
 
695
704
  return HabiticaStatsResponse.from_json(
696
705
  await self._request("post", url=url),
@@ -743,7 +752,7 @@ class Habitica:
743
752
  Allocate 2 points to INT and 1 point to STR:
744
753
  >>> await allocate_bulk_stat_points(int_points=2, str_points=1)
745
754
  """
746
- url = self.url / "v3/user/allocate-bulk"
755
+ url = self.url / "api/v3/user/allocate-bulk"
747
756
  json = {
748
757
  "stats": {
749
758
  "int": int_points,
@@ -782,7 +791,7 @@ class Habitica:
782
791
  TimeoutError
783
792
  If the connection times out.
784
793
  """
785
- url = self.url / "v3/user/buy-health-potion"
794
+ url = self.url / "api/v3/user/buy-health-potion"
786
795
 
787
796
  return HabiticaStatsResponse.from_json(
788
797
  await self._request("post", url=url),
@@ -823,7 +832,7 @@ class Habitica:
823
832
  TimeoutError
824
833
  If the connection times out.
825
834
  """
826
- url = self.url / "v3/class/cast" / spell
835
+ url = self.url / "api/v3/class/cast" / spell
827
836
  params = {}
828
837
 
829
838
  if target_id:
@@ -854,7 +863,7 @@ class Habitica:
854
863
  TimeoutError
855
864
  If the connection times out.
856
865
  """
857
- url = self.url / "v3/user/sleep"
866
+ url = self.url / "api/v3/user/sleep"
858
867
 
859
868
  return HabiticaResponse.from_json(await self._request("post", url=url))
860
869
 
@@ -876,7 +885,7 @@ class Habitica:
876
885
  TimeoutError
877
886
  If the connection times out.
878
887
  """
879
- url = self.url / "v3/user/revive"
888
+ url = self.url / "api/v3/user/revive"
880
889
 
881
890
  return HabiticaResponse.from_json(await self._request("post", url=url))
882
891
 
@@ -915,7 +924,7 @@ class Habitica:
915
924
  >>> change_response = await habitica.change_class(new_class)
916
925
  >>> print(change_response.data.stats) # Displays the user's stats after class change
917
926
  """
918
- url = self.url / "v3/user/change-class"
927
+ url = self.url / "api/v3/user/change-class"
919
928
  params = {"class": Class.value}
920
929
 
921
930
  return HabiticaClassSystemResponse.from_json(
@@ -948,7 +957,7 @@ class Habitica:
948
957
  >>> disable_response = await habitica.disable_classes()
949
958
  >>> print(disable_response.data.stats) # Displays the user's stats after disabling the class system
950
959
  """
951
- url = self.url / "v3/user/disable-classes"
960
+ url = self.url / "api/v3/user/disable-classes"
952
961
 
953
962
  return HabiticaClassSystemResponse.from_json(
954
963
  await self._request("post", url=url)
@@ -981,7 +990,7 @@ class Habitica:
981
990
  >>> delete_response = await habitica.delete_completed_todos()
982
991
  >>> print(delete_response.success) # True if successfully cleared completed to-dos
983
992
  """
984
- url = self.url / "v3/tasks/clearCompletedTodos"
993
+ url = self.url / "api/v3/tasks/clearCompletedTodos"
985
994
 
986
995
  return HabiticaClassSystemResponse.from_json(
987
996
  await self._request("post", url=url)
@@ -1023,7 +1032,7 @@ class Habitica:
1023
1032
  TimeoutError
1024
1033
  If the connection times out.
1025
1034
  """
1026
- url = self.url / "v3/tasks" / str(task_id) / "score" / direction.value
1035
+ url = self.url / "api/v3/tasks" / str(task_id) / "score" / direction.value
1027
1036
 
1028
1037
  return HabiticaScoreResponse.from_json(
1029
1038
  await self._request("post", url=url),
@@ -1056,7 +1065,7 @@ class Habitica:
1056
1065
  >>> tags_response = await habitica.get_tags()
1057
1066
  >>> print(tags_response.data)
1058
1067
  """
1059
- url = self.url / "v3/tags"
1068
+ url = self.url / "api/v3/tags"
1060
1069
 
1061
1070
  return HabiticaTagsResponse.from_json(
1062
1071
  await self._request("post", url=url),
@@ -1094,7 +1103,7 @@ class Habitica:
1094
1103
  >>> tag_response = await habitica.get_tag()
1095
1104
  >>> print(tag_response.data)
1096
1105
  """
1097
- url = self.url / "v3/tags" / str(tag_id)
1106
+ url = self.url / "api/v3/tags" / str(tag_id)
1098
1107
 
1099
1108
  return HabiticaTagResponse.from_json(
1100
1109
  await self._request("post", url=url),
@@ -1133,7 +1142,7 @@ class Habitica:
1133
1142
  >>> delete_response = await habitica.delete_tag(tag_id)
1134
1143
  >>> print(delete_response.success) # True if successfully deleted
1135
1144
  """
1136
- url = self.url / "v3/tags" / str(tag_id)
1145
+ url = self.url / "api/v3/tags" / str(tag_id)
1137
1146
 
1138
1147
  return HabiticaTagResponse.from_json(
1139
1148
  await self._request("delete", url=url),
@@ -1172,7 +1181,7 @@ class Habitica:
1172
1181
  >>> new_tag_response = await habitica.create_tag("New Tag Name")
1173
1182
  >>> print(new_tag_response.data.id) # Displays the id of the new tag
1174
1183
  """
1175
- url = self.url / "v3/tags"
1184
+ url = self.url / "api/v3/tags"
1176
1185
  json = {"name": name}
1177
1186
  return HabiticaTagResponse.from_json(
1178
1187
  await self._request("post", url=url, json=json),
@@ -1213,7 +1222,7 @@ class Habitica:
1213
1222
  >>> update_response = await habitica.update_tag(tag_id, "New Tag Name")
1214
1223
  >>> print(update_response.data) # Displays the updated tag information
1215
1224
  """
1216
- url = self.url / "v3/tags" / str(tag_id)
1225
+ url = self.url / "api/v3/tags" / str(tag_id)
1217
1226
  json = {"name": name}
1218
1227
  return HabiticaTagResponse.from_json(
1219
1228
  await self._request("put", url=url, json=json),
@@ -1254,7 +1263,7 @@ class Habitica:
1254
1263
  >>> reorder_response = await habitica.reorder_tag(tag_id, 2)
1255
1264
  >>> print(reorder_response.success) # True if reorder is successful
1256
1265
  """
1257
- url = self.url / "v3/reorder-tags"
1266
+ url = self.url / "api/v3/reorder-tags"
1258
1267
  json = {"tagId": str(tag_id), "to": to}
1259
1268
 
1260
1269
  return HabiticaTagResponse.from_json(
habiticalib/types.py CHANGED
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
 
6
6
  from dataclasses import dataclass, field
7
7
  from datetime import UTC, datetime
8
- from enum import StrEnum
8
+ from enum import Enum, StrEnum
9
9
  from typing import Any
10
10
  from uuid import UUID # noqa: TCH003
11
11
 
@@ -17,13 +17,14 @@ from mashumaro.mixins.orjson import DataClassORJSONMixin
17
17
  def serialize_datetime(date: str | int | None) -> datetime | None:
18
18
  """Convert an iso date to a datetime.date object."""
19
19
  if isinstance(date, int):
20
- datetime.fromtimestamp(date / 1000, tz=UTC)
20
+ return datetime.fromtimestamp(date / 1000, tz=UTC)
21
21
  if isinstance(date, str):
22
22
  try:
23
23
  return datetime.fromisoformat(date)
24
24
  except ValueError:
25
25
  # sometimes nextDue dates are JavaScript datetime strings
26
26
  # instead of iso: "Mon May 06 2024 00:00:00 GMT+0200"
27
+ # This was fixed in Habitica v5.28.9, nextDue dates are now isoformat
27
28
  try:
28
29
  return datetime.strptime(date, "%a %b %d %Y %H:%M:%S %Z%z")
29
30
  except ValueError:
@@ -865,10 +866,10 @@ class Task(DataClassORJSONMixin):
865
866
  tags: list[UUID] | None = None
866
867
  collapseChecklist: bool | None = None
867
868
  date: datetime | None = None
868
- priority: float | None = None
869
+ priority: TaskPriority | None = None
869
870
  reminders: list[Reminders] | None = None
870
871
  checklist: list[str] | None = None
871
- task_type: TaskType | None = None
872
+ Type: TaskType | None = field(default=None, metadata=field_options(alias="type"))
872
873
  up: bool | None = None
873
874
  down: bool | None = None
874
875
  counterUp: int | None = None
@@ -894,7 +895,7 @@ class TaskData:
894
895
  notes: str | None = None
895
896
  tags: list[UUID] | None = None
896
897
  value: float | None = None
897
- priority: float | None = None
898
+ priority: TaskPriority | None = None
898
899
  attribute: Attributes | None = None
899
900
  byHabitica: bool | None = None
900
901
  createdAt: datetime | None = None
@@ -1200,3 +1201,12 @@ class Direction(StrEnum):
1200
1201
 
1201
1202
  UP = "up"
1202
1203
  DOWN = "down"
1204
+
1205
+
1206
+ class TaskPriority(Enum):
1207
+ """Task difficulties."""
1208
+
1209
+ TRIVIAL = 0.1
1210
+ EASY = 1
1211
+ MEDIUM = 1.5
1212
+ HARD = 2
@@ -0,0 +1,98 @@
1
+ Metadata-Version: 2.3
2
+ Name: Habiticalib
3
+ Version: 0.1.0a2
4
+ Summary: Asynchronous Python client library for the Habitica API
5
+ Project-URL: Documentation, https://tr4nt0r.github.io/habiticalib/
6
+ Project-URL: Source, https://github.com/tr4nt0r/habiticalib
7
+ Author-email: Manfred Dennerlein Rodelo <manfred@dennerlein.name>
8
+ License: MIT License
9
+ License-File: LICENSE
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3 :: Only
13
+ Requires-Python: >=3.12
14
+ Requires-Dist: aiohttp~=3.9
15
+ Requires-Dist: mashumaro~=3.13
16
+ Requires-Dist: orjson~=3.10
17
+ Requires-Dist: pillow~=10.4
18
+ Description-Content-Type: text/markdown
19
+
20
+ # Habiticalib
21
+
22
+ <p align="center">
23
+ <em>Modern asynchronous Python client library for the Habitica API</em>
24
+ </p>
25
+
26
+ [![build](https://github.com/tr4nt0r/habiticalib/workflows/Build/badge.svg)](https://github.com/tr4nt0r/habiticalib/actions)
27
+ [![codecov](https://codecov.io/gh/tr4nt0r/habiticalib/graph/badge.svg?token=iEsZ1Ktj7d)](https://codecov.io/gh/tr4nt0r/habiticalib)
28
+ [![PyPI version](https://badge.fury.io/py/habiticalib.svg)](https://badge.fury.io/py/habiticalib)
29
+
30
+ **Habiticalib** is a Python library for interacting with the [Habitica API](https://habitica.com). It provides an organized, typed interface to work with Habitica’s features, including tasks, user data, and avatars. The goal of this library is to simplify integration with Habitica.
31
+
32
+ ## Key features
33
+
34
+ - **Asynchronous**: The library is fully asynchronous, allowing non-blocking API calls.
35
+ - **Fully typed with Dataclasses**: The library is fully typed using Python `dataclasses`. It handles serialization with `mashumaro` and `orjson` for efficient conversion between Habitica API JSON data and Python objects.
36
+ - **Dynamic avatar image generation**: Habiticalib can fetch all necessary assets (like equipped items, pets, and mounts) and combine them into a single avatar image. This image can be saved to disk or returned as a byte buffer for further processing.
37
+ **Fetch user data**: Retrieve and manage user data such as stats, preferences, and items. User data is structured with dataclasses to make it easy to work with.
38
+ - **Task management**: Support for creating, updating, and retrieving Habitica tasks (to-dos, dailies, habits, rewards) is provided.
39
+ - **Task status updates**: The library allows updates for task statuses, habit scoring, and daily completion.
40
+ - **Tags**: Habiticalib supports the creation, updating and deletion of tags.
41
+ - **Stat allocation, class cystem and sleep**: The library offers methods for stat point allocation and switching between Habitica classes. It also provides the ability to disable the class system and pausing damage(resting in the inn)
42
+
43
+ ## Installation
44
+
45
+ ```bash
46
+ pip install habiticalib
47
+ ```
48
+
49
+ ## Getting started
50
+ Here’s an example to demonstrate basic usage:
51
+
52
+ ```python
53
+ import asyncio
54
+
55
+ from aiohttp import ClientSession
56
+
57
+ from habiticalib import Habitica, TaskType
58
+
59
+
60
+ async def main():
61
+ async with ClientSession() as session:
62
+ habitica = Habitica(session)
63
+
64
+ # Login to Habitica
65
+ habitica.login(username="your_username", password="your_password")
66
+
67
+ # Fetch user data
68
+ user_data = await habitica.user()
69
+ print(f"Your current health: {user_data.stats.hp}")
70
+
71
+ # Fetch all tasks (to-dos, dailies, habits, and rewards)
72
+ tasks = await habitica.get_tasks()
73
+ print("All tasks:")
74
+ for task in tasks:
75
+ print(f"- {task.text} (type: {task.type})")
76
+
77
+ # Fetch only to-dos
78
+ todos = await habitica.get_tasks(task_type=TaskType.TODO)
79
+ print("\nTo-Do tasks:")
80
+ for todo in todos:
81
+ print(f"- {todo.text} (due: {todo.date})")
82
+
83
+ # Fetch only dailies
84
+ dailies = await habitica.tasks(task_type=TaskType.DAILY)
85
+ print("\nDailies:")
86
+ for daily in dailies:
87
+ print(f"- {daily.text}")
88
+
89
+ asyncio.run(main())
90
+ ```
91
+
92
+ ## Documentation
93
+
94
+ For full documentation and detailed usage examples, please visit the [Habiticalib documentation](https://tr4nt0r.github.io/habiticalib/).
95
+
96
+ ## License
97
+
98
+ This project is licensed under the terms of the MIT license.
@@ -0,0 +1,11 @@
1
+ habiticalib/__init__.py,sha256=_RUFLOZSqQWr_j3TnhHhtD5szaf59HR-sS7aOpE4NTg,1491
2
+ habiticalib/const.py,sha256=NsbZeJ3Z_OuZcGzFZESInj9vpyYzjjCpJnVhGmu30vw,609
3
+ habiticalib/exceptions.py,sha256=Db7lDDdT97FsK4S9N45gcusiMMWiqeIcab0H8i7xTtE,1032
4
+ habiticalib/helpers.py,sha256=Y7lAlufK2isnNp7ybcqcWLG9xkWltouCiXaBeLOkobg,3479
5
+ habiticalib/lib.py,sha256=F_tqIULUC8mhYXLak2RYGA_AeaFuAQY6Ie8NImslv_g,54130
6
+ habiticalib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ habiticalib/types.py,sha256=zF9HzSXkuUYwuUv9F8fXfg6sxWy0nlfUo9hFqQG8eGA,32825
8
+ habiticalib-0.1.0a2.dist-info/METADATA,sha256=3hI8OP0ECfHdmYPaZ9zGyX0Nx04kRly2635ll4yfrYY,4178
9
+ habiticalib-0.1.0a2.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
10
+ habiticalib-0.1.0a2.dist-info/licenses/LICENSE,sha256=oIinIOSJ49l1iVIRI3XGXFWt6SF7a83kEFBAY8ORwNI,1084
11
+ habiticalib-0.1.0a2.dist-info/RECORD,,
@@ -1,92 +0,0 @@
1
- Metadata-Version: 2.3
2
- Name: Habiticalib
3
- Version: 0.1.0a1
4
- Summary: Asynchronous Python client library for the Habitica API
5
- Project-URL: Documentation, https://tr4nt0r.github.io/habiticalib/
6
- Project-URL: Source, https://github.com/tr4nt0r/habiticalib
7
- Author-email: Manfred Dennerlein Rodelo <manfred@dennerlein.name>
8
- License: MIT License
9
- License-File: LICENSE
10
- Classifier: License :: OSI Approved :: MIT License
11
- Classifier: Operating System :: OS Independent
12
- Classifier: Programming Language :: Python :: 3 :: Only
13
- Requires-Python: >=3.12
14
- Requires-Dist: aiohttp~=3.9
15
- Requires-Dist: mashumaro~=3.13
16
- Requires-Dist: orjson~=3.10
17
- Requires-Dist: pillow~=10.4
18
- Description-Content-Type: text/markdown
19
-
20
- # Habiticalib
21
-
22
- <p align="center">
23
- <em>Modern asynchronous Python client library for the Habitica API</em>
24
- </p>
25
-
26
- [![build](https://github.com/tr4nt0r/habiticalib/workflows/Build/badge.svg)](https://github.com/tr4nt0r/habiticalib/actions)
27
- [![codecov](https://codecov.io/gh/tr4nt0r/habiticalib/branch/master/graph/badge.svg)](https://codecov.io/gh/tr4nt0r/habiticalib)
28
- [![PyPI version](https://badge.fury.io/py/habiticalib.svg)](https://badge.fury.io/py/habiticalib)
29
-
30
- ---
31
-
32
- **Documentation**: <a href="https://tr4nt0r.github.io/habiticalib/" target="_blank">https://tr4nt0r.github.io/habiticalib/</a>
33
-
34
- **Source Code**: <a href="https://github.com/tr4nt0r/habiticalib" target="_blank">https://github.com/tr4nt0r/habiticalib</a>
35
-
36
- ---
37
-
38
- ## Development
39
-
40
- ### Setup environment
41
-
42
- We use [Hatch](https://hatch.pypa.io/latest/install/) to manage the development environment and production build. Ensure it's installed on your system.
43
-
44
- ### Run unit tests
45
-
46
- You can run all the tests with:
47
-
48
- ```bash
49
- hatch run test
50
- ```
51
-
52
- ### Format the code
53
-
54
- Execute the following command to apply linting and check typing:
55
-
56
- ```bash
57
- hatch run lint
58
- ```
59
-
60
- ### Publish a new version
61
-
62
- You can bump the version, create a commit and associated tag with one command:
63
-
64
- ```bash
65
- hatch version patch
66
- ```
67
-
68
- ```bash
69
- hatch version minor
70
- ```
71
-
72
- ```bash
73
- hatch version major
74
- ```
75
-
76
- Your default Git text editor will open so you can add information about the release.
77
-
78
- When you push the tag on GitHub, the workflow will automatically publish it on PyPi and a GitHub release will be created as draft.
79
-
80
- ## Serve the documentation
81
-
82
- You can serve the Mkdocs documentation with:
83
-
84
- ```bash
85
- hatch run docs-serve
86
- ```
87
-
88
- It'll automatically watch for changes in your code.
89
-
90
- ## License
91
-
92
- This project is licensed under the terms of the MIT license.
@@ -1,11 +0,0 @@
1
- habiticalib/__init__.py,sha256=k4L3Ik4KZ7U_mtIseyqGHG0TdBE7iwxgQfazr2zli5U,301
2
- habiticalib/const.py,sha256=HeIl1dPAeAxt1V-9PkPCt60ThAJJWkUKpCzMEEAR-ik,584
3
- habiticalib/exceptions.py,sha256=V7QAPQM4HbGxq7-BYDSdG9Zi2u9F2w3tX8XwualJbWM,601
4
- habiticalib/helpers.py,sha256=1PEq8tjOgotMnGRUcRcFcLCEa7jFWUORD9ZPHEVH2sU,3527
5
- habiticalib/lib.py,sha256=S0wLsSCSSoEtq-nlx9Wy7TsqI20iLBYUZhrDOkq6Z3o,53766
6
- habiticalib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- habiticalib/types.py,sha256=r_5pCRdfZRv7whryAgVOUnqv4qUGfokgq9GqdkdK_y8,32549
8
- habiticalib-0.1.0a1.dist-info/METADATA,sha256=t7hoV7_9JMYFVUqZgjLN9qh3RFuz7CFaPPL24zB0TlY,2471
9
- habiticalib-0.1.0a1.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
10
- habiticalib-0.1.0a1.dist-info/licenses/LICENSE,sha256=oIinIOSJ49l1iVIRI3XGXFWt6SF7a83kEFBAY8ORwNI,1084
11
- habiticalib-0.1.0a1.dist-info/RECORD,,