@@ -78,6 +78,7 @@ def create(
7878 notes : Optional [str ] = None ,
7979 billable : Optional [bool ] = None ,
8080 is_running : Optional [bool ] = None ,
81+ replace_running : Optional [bool ] = None ,
8182 started_time : Optional [str ] = None ,
8283 ended_time : Optional [str ] = None ,
8384 source : Optional [Source ] = None ,
@@ -93,6 +94,7 @@ def create(
9394 notes = notes ,
9495 billable = billable ,
9596 is_running = is_running ,
97+ replace_running = replace_running ,
9698 started_time = started_time ,
9799 ended_time = ended_time ,
98100 source = source ,
@@ -106,6 +108,42 @@ def create(
106108 )
107109 return TimeEntry .model_validate (response .json ())
108110
111+ def start_timer (
112+ self ,
113+ * ,
114+ project_id : str ,
115+ task_id : str ,
116+ spent_date : str ,
117+ user_id : Optional [str ] = None ,
118+ notes : Optional [str ] = None ,
119+ billable : Optional [bool ] = None ,
120+ started_time : Optional [str ] = None ,
121+ source : Optional [Source ] = None ,
122+ metadata : Optional [dict [str , Any ]] = None ,
123+ replace_running : Optional [bool ] = None ,
124+ request_options : Optional [RequestOptions ] = None ,
125+ ) -> TimeEntry :
126+ body = TimeEntryCreate (
127+ project_id = project_id ,
128+ task_id = task_id ,
129+ spent_date = spent_date ,
130+ user_id = user_id ,
131+ notes = notes ,
132+ billable = billable ,
133+ is_running = True ,
134+ replace_running = replace_running ,
135+ started_time = started_time ,
136+ source = source ,
137+ metadata = metadata ,
138+ )
139+ response = self ._http .request (
140+ "POST" ,
141+ _PATH ,
142+ json = body .model_dump (exclude_none = True ),
143+ request_options = request_options ,
144+ )
145+ return TimeEntry .model_validate (response .json ())
146+
109147 def update (
110148 self ,
111149 id : str ,
@@ -140,6 +178,32 @@ def update(
140178 )
141179 return TimeEntry .model_validate (response .json ())
142180
181+ def stop_timer (
182+ self ,
183+ id : str ,
184+ * ,
185+ notes : Optional [str ] = None ,
186+ request_options : Optional [RequestOptions ] = None ,
187+ ) -> TimeEntry :
188+ body : dict [str , Any ] = {}
189+ if notes is not None :
190+ body ["notes" ] = notes
191+ response = self ._http .request ("PATCH" , f"{ _PATH } /{ id } /stop" , json = body , request_options = request_options )
192+ return TimeEntry .model_validate (response .json ())
193+
194+ def restart_timer (
195+ self ,
196+ id : str ,
197+ * ,
198+ replace_running : Optional [bool ] = None ,
199+ request_options : Optional [RequestOptions ] = None ,
200+ ) -> TimeEntry :
201+ body : dict [str , Any ] = {}
202+ if replace_running is not None :
203+ body ["replace_running" ] = replace_running
204+ response = self ._http .request ("PATCH" , f"{ _PATH } /{ id } /restart" , json = body , request_options = request_options )
205+ return TimeEntry .model_validate (response .json ())
206+
143207 def delete (
144208 self ,
145209 id : str ,
@@ -215,6 +279,7 @@ async def create(
215279 notes : Optional [str ] = None ,
216280 billable : Optional [bool ] = None ,
217281 is_running : Optional [bool ] = None ,
282+ replace_running : Optional [bool ] = None ,
218283 started_time : Optional [str ] = None ,
219284 ended_time : Optional [str ] = None ,
220285 source : Optional [Source ] = None ,
@@ -230,6 +295,7 @@ async def create(
230295 notes = notes ,
231296 billable = billable ,
232297 is_running = is_running ,
298+ replace_running = replace_running ,
233299 started_time = started_time ,
234300 ended_time = ended_time ,
235301 source = source ,
@@ -243,6 +309,42 @@ async def create(
243309 )
244310 return TimeEntry .model_validate (response .json ())
245311
312+ async def start_timer (
313+ self ,
314+ * ,
315+ project_id : str ,
316+ task_id : str ,
317+ spent_date : str ,
318+ user_id : Optional [str ] = None ,
319+ notes : Optional [str ] = None ,
320+ billable : Optional [bool ] = None ,
321+ started_time : Optional [str ] = None ,
322+ source : Optional [Source ] = None ,
323+ metadata : Optional [dict [str , Any ]] = None ,
324+ replace_running : Optional [bool ] = None ,
325+ request_options : Optional [RequestOptions ] = None ,
326+ ) -> TimeEntry :
327+ body = TimeEntryCreate (
328+ project_id = project_id ,
329+ task_id = task_id ,
330+ spent_date = spent_date ,
331+ user_id = user_id ,
332+ notes = notes ,
333+ billable = billable ,
334+ is_running = True ,
335+ replace_running = replace_running ,
336+ started_time = started_time ,
337+ source = source ,
338+ metadata = metadata ,
339+ )
340+ response = await self ._http .request (
341+ "POST" ,
342+ _PATH ,
343+ json = body .model_dump (exclude_none = True ),
344+ request_options = request_options ,
345+ )
346+ return TimeEntry .model_validate (response .json ())
347+
246348 async def update (
247349 self ,
248350 id : str ,
@@ -277,6 +379,37 @@ async def update(
277379 )
278380 return TimeEntry .model_validate (response .json ())
279381
382+ async def stop_timer (
383+ self ,
384+ id : str ,
385+ * ,
386+ notes : Optional [str ] = None ,
387+ request_options : Optional [RequestOptions ] = None ,
388+ ) -> TimeEntry :
389+ body : dict [str , Any ] = {}
390+ if notes is not None :
391+ body ["notes" ] = notes
392+ response = await self ._http .request ("PATCH" , f"{ _PATH } /{ id } /stop" , json = body , request_options = request_options )
393+ return TimeEntry .model_validate (response .json ())
394+
395+ async def restart_timer (
396+ self ,
397+ id : str ,
398+ * ,
399+ replace_running : Optional [bool ] = None ,
400+ request_options : Optional [RequestOptions ] = None ,
401+ ) -> TimeEntry :
402+ body : dict [str , Any ] = {}
403+ if replace_running is not None :
404+ body ["replace_running" ] = replace_running
405+ response = await self ._http .request (
406+ "PATCH" ,
407+ f"{ _PATH } /{ id } /restart" ,
408+ json = body ,
409+ request_options = request_options ,
410+ )
411+ return TimeEntry .model_validate (response .json ())
412+
280413 async def delete (
281414 self ,
282415 id : str ,
0 commit comments