dart-tools 0.8.4__py3-none-any.whl → 0.8.8__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.
Files changed (29) hide show
  1. dart/dart.py +12 -96
  2. dart/generated/api/__init__.py +1 -1
  3. dart/generated/api/doc/list_docs.py +30 -0
  4. dart/generated/api/task/add_task_time_tracking.py +190 -0
  5. dart/generated/api/task/list_tasks.py +206 -0
  6. dart/generated/api/task/move_task.py +190 -0
  7. dart/generated/models/__init__.py +24 -0
  8. dart/generated/models/concise_task.py +58 -0
  9. dart/generated/models/custom_properties.py +8 -8
  10. dart/generated/models/list_docs_o_item.py +6 -4
  11. dart/generated/models/list_tasks_o_item.py +17 -0
  12. dart/generated/models/paginated_comment_list.py +42 -0
  13. dart/generated/models/paginated_comment_list_meta_type_0.py +109 -0
  14. dart/generated/models/paginated_comment_list_meta_type_0_applied_default_filters.py +44 -0
  15. dart/generated/models/paginated_concise_doc_list.py +42 -0
  16. dart/generated/models/paginated_concise_doc_list_meta_type_0.py +109 -0
  17. dart/generated/models/paginated_concise_doc_list_meta_type_0_applied_default_filters.py +44 -0
  18. dart/generated/models/paginated_concise_task_list.py +42 -0
  19. dart/generated/models/paginated_concise_task_list_meta_type_0.py +109 -0
  20. dart/generated/models/paginated_concise_task_list_meta_type_0_applied_default_filters.py +44 -0
  21. dart/generated/models/task.py +58 -0
  22. dart/generated/models/task_move.py +94 -0
  23. dart/generated/models/task_time_tracking_create.py +84 -0
  24. {dart_tools-0.8.4.dist-info → dart_tools-0.8.8.dist-info}/METADATA +2 -46
  25. {dart_tools-0.8.4.dist-info → dart_tools-0.8.8.dist-info}/RECORD +29 -18
  26. {dart_tools-0.8.4.dist-info → dart_tools-0.8.8.dist-info}/WHEEL +0 -0
  27. {dart_tools-0.8.4.dist-info → dart_tools-0.8.8.dist-info}/entry_points.txt +0 -0
  28. {dart_tools-0.8.4.dist-info → dart_tools-0.8.8.dist-info}/licenses/LICENSE +0 -0
  29. {dart_tools-0.8.4.dist-info → dart_tools-0.8.8.dist-info}/top_level.txt +0 -0
dart/dart.py CHANGED
@@ -60,7 +60,7 @@ _PROG = "dart"
60
60
 
61
61
  _PROD_HOST = "https://app.dartai.com"
62
62
  _STAG_HOST = "https://stag.dartai.com"
63
- _DEV_HOST = "http://localhost:5173"
63
+ _DEV_HOST = "http://localhost:5100"
64
64
  _HOST_MAP = {"prod": _PROD_HOST, "stag": _STAG_HOST, "dev": _DEV_HOST}
65
65
 
66
66
  # Service commands
@@ -85,6 +85,7 @@ _ROOT_PUBLIC_API_URL_FRAG = f"{_ROOT_PRIVATE_API_URL_FRAG}/public"
85
85
  _COPY_BRANCH_URL_FRAG = "/vcs/copy-branch-link"
86
86
 
87
87
  _AUTH_TOKEN_ENVVAR_KEY = "DART_TOKEN"
88
+ _HOST_ENVVAR_KEY = "DART_HOST"
88
89
  _CONFIG_FPATH = platformdirs.user_config_path(_APP)
89
90
  _CLIENT_ID_KEY = "clientId"
90
91
  _HOST_KEY = "host"
@@ -105,6 +106,8 @@ _DEFAULT_DARTBOARD = "General/Active"
105
106
 
106
107
  _VERSION = version(_APP)
107
108
  _AUTH_TOKEN_ENVVAR = os.environ.get(_AUTH_TOKEN_ENVVAR_KEY)
109
+ _HOST_ENVVAR = os.environ.get(_HOST_ENVVAR_KEY)
110
+ _DEFAULT_HOST = _HOST_ENVVAR or _PROD_HOST
108
111
 
109
112
 
110
113
  def _get_help_text(fn: Callable) -> str:
@@ -221,7 +224,7 @@ class _Config:
221
224
  pass
222
225
  self._content = {
223
226
  _CLIENT_ID_KEY: _make_id(),
224
- _HOST_KEY: _PROD_HOST,
227
+ _HOST_KEY: _DEFAULT_HOST,
225
228
  _HOSTS_KEY: {},
226
229
  } | self._content
227
230
  self._content[_HOSTS_KEY] = defaultdict(dict, self._content[_HOSTS_KEY])
@@ -371,70 +374,10 @@ class Dart:
371
374
  self._private_api.get_httpx_client().post(_COPY_BRANCH_URL_FRAG, json={"duid": id})
372
375
 
373
376
 
374
- class _Git:
375
- @staticmethod
376
- def _cmd_succeeds(cmd: str) -> bool:
377
- try:
378
- _run_cmd(f"{cmd} 2>&1")
379
- except subprocess.CalledProcessError as ex:
380
- if "128" in str(ex):
381
- return False
382
- raise ex
383
- return True
384
-
385
- @staticmethod
386
- def make_task_name(email: str, task: ConciseTask | Task) -> str:
387
- username = slugify_str(email.split("@")[0], lower=True)
388
- title = slugify_str(task.title, lower=True)
389
- return trim_slug_str(f"{username}/{task.id}-{title}", length=60)
390
-
391
- @staticmethod
392
- def get_current_branch() -> str:
393
- return _run_cmd("git rev-parse --abbrev-ref HEAD").strip()
394
-
395
- @staticmethod
396
- def ensure_in_repo() -> None:
397
- if _Git._cmd_succeeds("git rev-parse --is-inside-work-tree"):
398
- return
399
- _dart_exit("You are not in a git repo.")
400
-
401
- @staticmethod
402
- def ensure_no_unstaged_changes() -> None:
403
- if _run_cmd("git status --porcelain") == "":
404
- return
405
- _dart_exit("You have uncommitted changes. Please commit or stash them.")
406
-
407
- @staticmethod
408
- def ensure_on_main_or_intended() -> None:
409
- branch = _Git.get_current_branch()
410
- if branch == "main":
411
- return
412
- if (
413
- pick(
414
- ["Yes", "No"],
415
- "You're not on the 'main' branch. Is this intentional?",
416
- "→",
417
- )[0]
418
- == "Yes"
419
- ):
420
- return
421
- _run_cmd("git checkout main")
422
-
423
- @staticmethod
424
- def branch_exists(branch: str) -> bool:
425
- return _Git._cmd_succeeds(f"git rev-parse --verify {branch}")
426
-
427
- @staticmethod
428
- def checkout_branch(branch: str) -> None:
429
- if _Git.branch_exists(branch):
430
- _run_cmd(f"git checkout {branch}")
431
- return
432
-
433
- if _Git.branch_exists(f"origin/{branch}"):
434
- _run_cmd(f"git checkout --track origin/{branch}")
435
- return
436
-
437
- _run_cmd(f"git checkout -b {branch}")
377
+ def make_task_branch_name(email: str, task: ConciseTask | Task) -> str:
378
+ username = slugify_str(email.split("@")[0], lower=True)
379
+ title = slugify_str(task.title, lower=True)
380
+ return trim_slug_str(f"{username}/{task.id}-{title}", length=60)
438
381
 
439
382
 
440
383
  def get_host() -> str:
@@ -527,26 +470,11 @@ def login(token: str | None = None) -> bool:
527
470
  return True
528
471
 
529
472
 
530
- def _begin_task(dart: Dart, email: str, task: ConciseTask | Task) -> bool:
531
- _Git.ensure_in_repo()
532
- _Git.ensure_no_unstaged_changes()
533
- _Git.ensure_on_main_or_intended()
534
-
535
- dart = Dart()
536
- dart.copy_branch_link(task.id)
537
-
538
- branch_name = _Git.make_task_name(email, task)
539
- _Git.checkout_branch(branch_name)
540
-
541
- _log(f"Started work on\n\n {task.title}\n {task.html_url}\n")
542
- return True
543
-
544
473
 
545
474
  def begin_task() -> bool:
546
475
  dart = Dart()
547
476
  config = dart.get_config()
548
477
  user = config.user
549
- print(config.dartboards)
550
478
  dartboard_maybe = {"dartboard": _DEFAULT_DARTBOARD} if _DEFAULT_DARTBOARD in config.dartboards else {}
551
479
  filtered_tasks = dart.list_tasks(assignee=user.email, is_completed=False, **dartboard_maybe).results
552
480
 
@@ -560,9 +488,10 @@ def begin_task() -> bool:
560
488
  )[1]
561
489
  assert isinstance(picked_idx, int)
562
490
 
563
- _begin_task(dart, user.email, filtered_tasks[picked_idx])
491
+ task = filtered_tasks[picked_idx]
492
+ branch_name = make_task_branch_name(user.email, task)
564
493
 
565
- _log("Done.")
494
+ _log(json.dumps({"title": task.title, "branch": branch_name, "id": task.id}))
566
495
  return True
567
496
 
568
497
 
@@ -598,7 +527,6 @@ def create_task(
598
527
  priority_int: Union[int, None, Unset] = UNSET,
599
528
  size_int: Union[int, None, Unset] = UNSET,
600
529
  due_at_str: Union[str, None, Unset] = UNSET,
601
- should_begin: bool = False,
602
530
  ) -> Task:
603
531
  dart = Dart()
604
532
  task_create = WrappedTaskCreate(
@@ -616,11 +544,6 @@ def create_task(
616
544
  task = dart.create_task(task_create).item
617
545
  _log(f"Created task\n\n {task.title}\n {task.html_url}\n ID: {task.id}\n")
618
546
 
619
- if should_begin:
620
- user = dart.get_config().user
621
- _begin_task(dart, user.email, task)
622
-
623
- _log("Done.")
624
547
  return task
625
548
 
626
549
 
@@ -816,13 +739,6 @@ def cli() -> None:
816
739
  _CREATE_TASK_CMD, aliases=["tc"], help=_HELP_TEXT_TO_COMMAND[_CREATE_TASK_CMD]
817
740
  )
818
741
  create_task_parser.add_argument("title", help="title of the task")
819
- create_task_parser.add_argument(
820
- "-b",
821
- "--begin",
822
- dest="should_begin",
823
- action="store_true",
824
- help="begin work on the task after creation",
825
- )
826
742
  _add_standard_task_arguments(create_task_parser)
827
743
  create_task_parser.set_defaults(func=create_task)
828
744
 
@@ -8,5 +8,5 @@ from .doc import create_doc, delete_doc, get_doc, list_docs, update_doc
8
8
  from .folder import get_folder
9
9
  from .help_center_article import list_help_center_articles
10
10
  from .skill import retrieve_skill_by_title
11
- from .task import create_task, delete_task, get_task, list_tasks, update_task
11
+ from .task import add_task_time_tracking, create_task, delete_task, get_task, list_tasks, move_task, update_task
12
12
  from .view import get_view
@@ -12,11 +12,13 @@ from ...types import UNSET, Response, Unset
12
12
 
13
13
  def _get_kwargs(
14
14
  *,
15
+ editor: Union[Unset, str] = UNSET,
15
16
  folder: Union[Unset, str] = UNSET,
16
17
  folder_id: Union[Unset, str] = UNSET,
17
18
  ids: Union[Unset, str] = UNSET,
18
19
  in_trash: Union[Unset, bool] = UNSET,
19
20
  limit: Union[Unset, int] = UNSET,
21
+ no_defaults: Union[Unset, bool] = False,
20
22
  o: Union[Unset, list[ListDocsOItem]] = UNSET,
21
23
  offset: Union[Unset, int] = UNSET,
22
24
  s: Union[Unset, str] = UNSET,
@@ -25,6 +27,8 @@ def _get_kwargs(
25
27
  ) -> dict[str, Any]:
26
28
  params: dict[str, Any] = {}
27
29
 
30
+ params["editor"] = editor
31
+
28
32
  params["folder"] = folder
29
33
 
30
34
  params["folder_id"] = folder_id
@@ -35,6 +39,8 @@ def _get_kwargs(
35
39
 
36
40
  params["limit"] = limit
37
41
 
42
+ params["no_defaults"] = no_defaults
43
+
38
44
  json_o: Union[Unset, list[str]] = UNSET
39
45
  if not isinstance(o, Unset):
40
46
  json_o = []
@@ -90,11 +96,13 @@ def _build_response(
90
96
  def sync_detailed(
91
97
  *,
92
98
  client: Union[AuthenticatedClient, Client],
99
+ editor: Union[Unset, str] = UNSET,
93
100
  folder: Union[Unset, str] = UNSET,
94
101
  folder_id: Union[Unset, str] = UNSET,
95
102
  ids: Union[Unset, str] = UNSET,
96
103
  in_trash: Union[Unset, bool] = UNSET,
97
104
  limit: Union[Unset, int] = UNSET,
105
+ no_defaults: Union[Unset, bool] = False,
98
106
  o: Union[Unset, list[ListDocsOItem]] = UNSET,
99
107
  offset: Union[Unset, int] = UNSET,
100
108
  s: Union[Unset, str] = UNSET,
@@ -105,11 +113,13 @@ def sync_detailed(
105
113
  full-text search. Sort by creation/update date or title. Supports pagination.
106
114
 
107
115
  Args:
116
+ editor (Union[Unset, str]):
108
117
  folder (Union[Unset, str]):
109
118
  folder_id (Union[Unset, str]):
110
119
  ids (Union[Unset, str]):
111
120
  in_trash (Union[Unset, bool]):
112
121
  limit (Union[Unset, int]):
122
+ no_defaults (Union[Unset, bool]): Default: False.
113
123
  o (Union[Unset, list[ListDocsOItem]]):
114
124
  offset (Union[Unset, int]):
115
125
  s (Union[Unset, str]):
@@ -125,11 +135,13 @@ def sync_detailed(
125
135
  """
126
136
 
127
137
  kwargs = _get_kwargs(
138
+ editor=editor,
128
139
  folder=folder,
129
140
  folder_id=folder_id,
130
141
  ids=ids,
131
142
  in_trash=in_trash,
132
143
  limit=limit,
144
+ no_defaults=no_defaults,
133
145
  o=o,
134
146
  offset=offset,
135
147
  s=s,
@@ -147,11 +159,13 @@ def sync_detailed(
147
159
  def sync(
148
160
  *,
149
161
  client: Union[AuthenticatedClient, Client],
162
+ editor: Union[Unset, str] = UNSET,
150
163
  folder: Union[Unset, str] = UNSET,
151
164
  folder_id: Union[Unset, str] = UNSET,
152
165
  ids: Union[Unset, str] = UNSET,
153
166
  in_trash: Union[Unset, bool] = UNSET,
154
167
  limit: Union[Unset, int] = UNSET,
168
+ no_defaults: Union[Unset, bool] = False,
155
169
  o: Union[Unset, list[ListDocsOItem]] = UNSET,
156
170
  offset: Union[Unset, int] = UNSET,
157
171
  s: Union[Unset, str] = UNSET,
@@ -162,11 +176,13 @@ def sync(
162
176
  full-text search. Sort by creation/update date or title. Supports pagination.
163
177
 
164
178
  Args:
179
+ editor (Union[Unset, str]):
165
180
  folder (Union[Unset, str]):
166
181
  folder_id (Union[Unset, str]):
167
182
  ids (Union[Unset, str]):
168
183
  in_trash (Union[Unset, bool]):
169
184
  limit (Union[Unset, int]):
185
+ no_defaults (Union[Unset, bool]): Default: False.
170
186
  o (Union[Unset, list[ListDocsOItem]]):
171
187
  offset (Union[Unset, int]):
172
188
  s (Union[Unset, str]):
@@ -183,11 +199,13 @@ def sync(
183
199
 
184
200
  return sync_detailed(
185
201
  client=client,
202
+ editor=editor,
186
203
  folder=folder,
187
204
  folder_id=folder_id,
188
205
  ids=ids,
189
206
  in_trash=in_trash,
190
207
  limit=limit,
208
+ no_defaults=no_defaults,
191
209
  o=o,
192
210
  offset=offset,
193
211
  s=s,
@@ -199,11 +217,13 @@ def sync(
199
217
  async def asyncio_detailed(
200
218
  *,
201
219
  client: Union[AuthenticatedClient, Client],
220
+ editor: Union[Unset, str] = UNSET,
202
221
  folder: Union[Unset, str] = UNSET,
203
222
  folder_id: Union[Unset, str] = UNSET,
204
223
  ids: Union[Unset, str] = UNSET,
205
224
  in_trash: Union[Unset, bool] = UNSET,
206
225
  limit: Union[Unset, int] = UNSET,
226
+ no_defaults: Union[Unset, bool] = False,
207
227
  o: Union[Unset, list[ListDocsOItem]] = UNSET,
208
228
  offset: Union[Unset, int] = UNSET,
209
229
  s: Union[Unset, str] = UNSET,
@@ -214,11 +234,13 @@ async def asyncio_detailed(
214
234
  full-text search. Sort by creation/update date or title. Supports pagination.
215
235
 
216
236
  Args:
237
+ editor (Union[Unset, str]):
217
238
  folder (Union[Unset, str]):
218
239
  folder_id (Union[Unset, str]):
219
240
  ids (Union[Unset, str]):
220
241
  in_trash (Union[Unset, bool]):
221
242
  limit (Union[Unset, int]):
243
+ no_defaults (Union[Unset, bool]): Default: False.
222
244
  o (Union[Unset, list[ListDocsOItem]]):
223
245
  offset (Union[Unset, int]):
224
246
  s (Union[Unset, str]):
@@ -234,11 +256,13 @@ async def asyncio_detailed(
234
256
  """
235
257
 
236
258
  kwargs = _get_kwargs(
259
+ editor=editor,
237
260
  folder=folder,
238
261
  folder_id=folder_id,
239
262
  ids=ids,
240
263
  in_trash=in_trash,
241
264
  limit=limit,
265
+ no_defaults=no_defaults,
242
266
  o=o,
243
267
  offset=offset,
244
268
  s=s,
@@ -254,11 +278,13 @@ async def asyncio_detailed(
254
278
  async def asyncio(
255
279
  *,
256
280
  client: Union[AuthenticatedClient, Client],
281
+ editor: Union[Unset, str] = UNSET,
257
282
  folder: Union[Unset, str] = UNSET,
258
283
  folder_id: Union[Unset, str] = UNSET,
259
284
  ids: Union[Unset, str] = UNSET,
260
285
  in_trash: Union[Unset, bool] = UNSET,
261
286
  limit: Union[Unset, int] = UNSET,
287
+ no_defaults: Union[Unset, bool] = False,
262
288
  o: Union[Unset, list[ListDocsOItem]] = UNSET,
263
289
  offset: Union[Unset, int] = UNSET,
264
290
  s: Union[Unset, str] = UNSET,
@@ -269,11 +295,13 @@ async def asyncio(
269
295
  full-text search. Sort by creation/update date or title. Supports pagination.
270
296
 
271
297
  Args:
298
+ editor (Union[Unset, str]):
272
299
  folder (Union[Unset, str]):
273
300
  folder_id (Union[Unset, str]):
274
301
  ids (Union[Unset, str]):
275
302
  in_trash (Union[Unset, bool]):
276
303
  limit (Union[Unset, int]):
304
+ no_defaults (Union[Unset, bool]): Default: False.
277
305
  o (Union[Unset, list[ListDocsOItem]]):
278
306
  offset (Union[Unset, int]):
279
307
  s (Union[Unset, str]):
@@ -291,11 +319,13 @@ async def asyncio(
291
319
  return (
292
320
  await asyncio_detailed(
293
321
  client=client,
322
+ editor=editor,
294
323
  folder=folder,
295
324
  folder_id=folder_id,
296
325
  ids=ids,
297
326
  in_trash=in_trash,
298
327
  limit=limit,
328
+ no_defaults=no_defaults,
299
329
  o=o,
300
330
  offset=offset,
301
331
  s=s,
@@ -0,0 +1,190 @@
1
+ from http import HTTPStatus
2
+ from typing import Any, Optional, Union, cast
3
+
4
+ import httpx
5
+
6
+ from ... import errors
7
+ from ...client import AuthenticatedClient, Client
8
+ from ...models.task_time_tracking_create import TaskTimeTrackingCreate
9
+ from ...models.wrapped_task import WrappedTask
10
+ from ...types import Response
11
+
12
+
13
+ def _get_kwargs(
14
+ id: str,
15
+ *,
16
+ body: TaskTimeTrackingCreate,
17
+ ) -> dict[str, Any]:
18
+ headers: dict[str, Any] = {}
19
+
20
+ _kwargs: dict[str, Any] = {
21
+ "method": "post",
22
+ "url": "/tasks/{id}/time-tracking".format(
23
+ id=id,
24
+ ),
25
+ }
26
+
27
+ _body = body.to_dict()
28
+
29
+ _kwargs["json"] = _body
30
+ headers["Content-Type"] = "application/json"
31
+
32
+ _kwargs["headers"] = headers
33
+ return _kwargs
34
+
35
+
36
+ def _parse_response(
37
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
38
+ ) -> Optional[Union[Any, WrappedTask]]:
39
+ if response.status_code == 200:
40
+ response_200 = WrappedTask.from_dict(response.json())
41
+
42
+ return response_200
43
+ if response.status_code == 400:
44
+ response_400 = cast(Any, None)
45
+ return response_400
46
+ if client.raise_on_unexpected_status:
47
+ raise errors.UnexpectedStatus(response.status_code, response.content)
48
+ else:
49
+ return None
50
+
51
+
52
+ def _build_response(
53
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
54
+ ) -> Response[Union[Any, WrappedTask]]:
55
+ return Response(
56
+ status_code=HTTPStatus(response.status_code),
57
+ content=response.content,
58
+ headers=response.headers,
59
+ parsed=_parse_response(client=client, response=response),
60
+ )
61
+
62
+
63
+ def sync_detailed(
64
+ id: str,
65
+ *,
66
+ client: Union[AuthenticatedClient, Client],
67
+ body: TaskTimeTrackingCreate,
68
+ ) -> Response[Union[Any, WrappedTask]]:
69
+ """Add a time tracking entry to a task
70
+
71
+ Record an additional time tracking entry on a task and return the updated task with refreshed time
72
+ tracking.
73
+
74
+ Args:
75
+ id (str):
76
+ body (TaskTimeTrackingCreate):
77
+
78
+ Raises:
79
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
80
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
81
+
82
+ Returns:
83
+ Response[Union[Any, WrappedTask]]
84
+ """
85
+
86
+ kwargs = _get_kwargs(
87
+ id=id,
88
+ body=body,
89
+ )
90
+
91
+ response = client.get_httpx_client().request(
92
+ **kwargs,
93
+ )
94
+
95
+ return _build_response(client=client, response=response)
96
+
97
+
98
+ def sync(
99
+ id: str,
100
+ *,
101
+ client: Union[AuthenticatedClient, Client],
102
+ body: TaskTimeTrackingCreate,
103
+ ) -> Optional[Union[Any, WrappedTask]]:
104
+ """Add a time tracking entry to a task
105
+
106
+ Record an additional time tracking entry on a task and return the updated task with refreshed time
107
+ tracking.
108
+
109
+ Args:
110
+ id (str):
111
+ body (TaskTimeTrackingCreate):
112
+
113
+ Raises:
114
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
115
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
116
+
117
+ Returns:
118
+ Union[Any, WrappedTask]
119
+ """
120
+
121
+ return sync_detailed(
122
+ id=id,
123
+ client=client,
124
+ body=body,
125
+ ).parsed
126
+
127
+
128
+ async def asyncio_detailed(
129
+ id: str,
130
+ *,
131
+ client: Union[AuthenticatedClient, Client],
132
+ body: TaskTimeTrackingCreate,
133
+ ) -> Response[Union[Any, WrappedTask]]:
134
+ """Add a time tracking entry to a task
135
+
136
+ Record an additional time tracking entry on a task and return the updated task with refreshed time
137
+ tracking.
138
+
139
+ Args:
140
+ id (str):
141
+ body (TaskTimeTrackingCreate):
142
+
143
+ Raises:
144
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
145
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
146
+
147
+ Returns:
148
+ Response[Union[Any, WrappedTask]]
149
+ """
150
+
151
+ kwargs = _get_kwargs(
152
+ id=id,
153
+ body=body,
154
+ )
155
+
156
+ response = await client.get_async_httpx_client().request(**kwargs)
157
+
158
+ return _build_response(client=client, response=response)
159
+
160
+
161
+ async def asyncio(
162
+ id: str,
163
+ *,
164
+ client: Union[AuthenticatedClient, Client],
165
+ body: TaskTimeTrackingCreate,
166
+ ) -> Optional[Union[Any, WrappedTask]]:
167
+ """Add a time tracking entry to a task
168
+
169
+ Record an additional time tracking entry on a task and return the updated task with refreshed time
170
+ tracking.
171
+
172
+ Args:
173
+ id (str):
174
+ body (TaskTimeTrackingCreate):
175
+
176
+ Raises:
177
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
178
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
179
+
180
+ Returns:
181
+ Union[Any, WrappedTask]
182
+ """
183
+
184
+ return (
185
+ await asyncio_detailed(
186
+ id=id,
187
+ client=client,
188
+ body=body,
189
+ )
190
+ ).parsed