Skip to content

Note

Report endpoints are not cached locally.

toggl_api.reports.ReportBody dataclass

Bases: BaseBody

Body for summary endpoint which turns into a JSON body.

METHOD DESCRIPTION
format

Format a body into the correct values types.

ATTRIBUTE DESCRIPTION
start_date

Start date, example time.DateOnly. Should be less than End date.

TYPE: date | None

end_date

End date, example time. DateOnly. Should be greater than Start date.

TYPE: date | None

client_ids

Client IDs, optional, filtering attribute. To filter records with no clients, use [None].

TYPE: list[int | None]

description

Description, optional, filtering attribute.

TYPE: str | None

group_ids

Group IDs, optional, filtering attribute.

TYPE: list[int]

grouping

Grouping option, optional.

TYPE: str | None

grouped

Whether time entries should be grouped, optional, default false.

TYPE: bool

include_time_entry_ids

Whether time entry IDs should be included in the results, optional, default true. Not applicable for export.

TYPE: bool

max_duration_seconds

Max duration seconds, optional, filtering attribute. Time Audit only,

TYPE: int | None

min_duration_seconds

Min duration seconds, optional, filtering attribute. Time Audit only,

TYPE: int | None

project_ids

Project IDs, optional, filtering attribute. To filter records with no projects, use [None].

TYPE: list[int | None]

rounding

Whether time should be rounded, optional, default from user preferences.

TYPE: int | None

rounding_minutes

Rounding minutes value, optional, default from user preferences.

TYPE: Literal[0, 1, 5, 6, 10, 12, 15, 30, 60, 240] | None

sub_grouping

SubGrouping option, optional.

TYPE: str | None

tag_ids

Tag IDs, optional, filtering attribute. To filter records with no tags, use [None].

TYPE: list[int | None]

time_entry_ids

TimeEntryIDs filters by time entries.

TYPE: list[int]

user_ids

User IDs, optional, filtering attribute.

TYPE: list[int]

date_format

Date format, optional, default 'YYYY-MM-DD'.

TYPE: Literal['MM/DD/YYYY', 'DD-MM-YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD', 'DD/MM/YYYY', 'DD.MM.YYYY']

duration_format

Duration format, optional, default "classic". Can be "classic", "decimal" or "improved".

TYPE: Literal['classic', 'decimal', 'improved']

order_by

Order by option, optional, default title. Can be title or duration.

TYPE: Literal['title', 'duration'] | None

order_dir

Order direction, optional. Can be ASC or DESC.

TYPE: Literal['ASC', 'DESC'] | None

resolution

Graph resolution, optional. Allow clients to explicitly request a resolution.

TYPE: str | None

enrich_response

It will force the detailed report to return as much information as possible, as it does for the export.

TYPE: bool

Source code in src/toggl_api/reports.py
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
@dataclass
class ReportBody(BaseBody):
    """Body for summary endpoint which turns into a JSON body."""

    start_date: date | None = field(default=None)
    """Start date, example time.DateOnly. Should be less than End date."""

    end_date: date | None = field(default=None)
    """End date, example time. DateOnly. Should be greater than Start date."""

    client_ids: list[int | None] = field(default_factory=list)
    """Client IDs, optional, filtering attribute. To filter records with no clients, use [None]."""

    description: str | None = field(default=None)
    """Description, optional, filtering attribute."""

    group_ids: list[int] = field(default_factory=list)
    """Group IDs, optional, filtering attribute."""

    grouping: str | None = field(
        default=None,
        metadata={
            "endpoints": frozenset(
                (
                    "summary_time_entries",
                    "summary_report_pdf",
                    "summary_report_csv",
                ),
            ),
        },
    )
    """Grouping option, optional."""

    grouped: bool = field(
        default=False,
        metadata={
            "endpoints": frozenset(
                (
                    "detail_search_time",
                    "detail_report_pdf",
                    "detail_report_csv",
                    "detail_totals",
                ),
            ),
        },
    )
    """Whether time entries should be grouped, optional, default false."""

    include_time_entry_ids: bool = field(
        default=True,  # NOTE: API default is False. Wrapper sets it as True.
        metadata={
            "endpoints": frozenset(
                (
                    "summary_time_entries",
                    "summary_report_pdf",
                    "summary_report_csv",
                ),
            ),
        },
    )
    """Whether time entry IDs should be included in the results, optional, default true. Not applicable for export."""

    max_duration_seconds: int | None = field(default=None)
    """Max duration seconds, optional, filtering attribute. Time Audit only,
    should be greater than min_duration_seconds."""

    min_duration_seconds: int | None = field(default=None)
    """Min duration seconds, optional, filtering attribute. Time Audit only,
    should be less than max_duration_seconds."""

    project_ids: list[int | None] = field(default_factory=list)
    """Project IDs, optional, filtering attribute. To filter records with no projects, use [None]."""

    rounding: int | None = field(default=None)
    """Whether time should be rounded, optional, default from user preferences."""

    rounding_minutes: Literal[0, 1, 5, 6, 10, 12, 15, 30, 60, 240] | None = field(default=None)
    """Rounding minutes value, optional, default from user preferences.
    Should be 0, 1, 5, 6, 10, 12, 15, 30, 60 or 240."""

    sub_grouping: str | None = field(
        default=None,
        metadata={
            "endpoints": frozenset(
                (
                    "summary_time_entries",
                    "summary_report_pdf",
                    "summary_report_csv",
                ),
            ),
        },
    )
    """SubGrouping option, optional."""

    tag_ids: list[int | None] = field(default_factory=list)
    """Tag IDs, optional, filtering attribute. To filter records with no tags, use [None]."""

    time_entry_ids: list[int] = field(default_factory=list)
    """TimeEntryIDs filters by time entries."""

    user_ids: list[int] = field(default_factory=list)
    """User IDs, optional, filtering attribute."""

    date_format: Literal[
        "MM/DD/YYYY",
        "DD-MM-YYYY",
        "MM-DD-YYYY",
        "YYYY-MM-DD",
        "DD/MM/YYYY",
        "DD.MM.YYYY",
    ] = field(
        default="YYYY-MM-DD",  # NOTE: API Default is 'MM/DD/YYYY'
        metadata={
            "endpoints": frozenset(
                (
                    "summary_report_pdf",
                    "detail_report_pdf",
                    "weekly_report_pdf",
                ),
            ),
        },
    )
    """Date format, optional, default 'YYYY-MM-DD'."""

    duration_format: Literal["classic", "decimal", "improved"] = field(
        default="classic",
        metadata={
            "endpoints": frozenset(
                (
                    "summary_report_pdf",
                    "summary_report_csv",
                    "detailed_report_pdf",
                    "detailed_report_csv",
                    "weekly_report_pdf",
                ),
            ),
        },
    )
    """Duration format, optional, default "classic". Can be "classic", "decimal" or "improved"."""

    order_by: Literal["title", "duration"] | None = field(
        default=None,
        metadata={
            "endpoints": frozenset(
                (
                    "summary_report_pdf",
                    "summary_report_csv",
                    "detail_search_time",
                    "detail_report_pdf",
                    "detail_report_csv",
                ),
            ),
        },
    )
    """Order by option, optional, default title. Can be title or duration."""

    order_dir: Literal["ASC", "DESC"] | None = field(
        default=None,
        metadata={
            "endpoints": frozenset(
                (
                    "summary_report_pdf",
                    "summary_report_csv",
                    "detail_search_time",
                    "detail_report_pdf",
                    "detail_report_csv",
                ),
            ),
        },
    )
    """Order direction, optional. Can be ASC or DESC."""

    resolution: str | None = field(
        default=None,
        metadata={
            "endpoints": frozenset(
                (
                    "summary_report_pdf",
                    "detail_totals",
                ),
            ),
        },
    )
    """Graph resolution, optional. Allow clients to explicitly request a resolution."""

    enrich_response: bool = field(
        default=False,
        metadata={
            "endpoints": frozenset(
                (
                    "detail_search_time",
                    "detail_report",
                ),
            ),
        },
    )
    """It will force the detailed report to return as much information as possible, as it does for the export."""

    def format(self, endpoint: str, **body: Any) -> dict[str, Any]:
        """Format a body into the correct values types.

        Args:
            endpoint: The name of the endpoint for filtering.
            body: Body pre-filled with miscellanous values:

        Raises:
            DateTimeError: If the start date is after the end date.

        Returns:
            Dictionary of formatted values.
        """
        body.update(
            {
                "client_ids": self.client_ids,
                "project_ids": self.project_ids,
                "tag_ids": self.tag_ids,
                "time_entry_ids": self.time_entry_ids,
                "user_ids": self.user_ids,
            },
        )

        if self.start_date:
            body["start_date"] = format_iso(self.start_date)
            if self.end_date is not None and self.start_date > self.end_date:
                msg = "Start date needs to be on or before the end date!"
                raise DateTimeError(msg)

        if self.end_date:
            body["end_date"] = format_iso(self.end_date)

        if self._verify_endpoint_parameter("date_format", endpoint):
            body["date_format"] = self.date_format

        if self._verify_endpoint_parameter("duration_format", endpoint):
            body["duration_format"] = self.duration_format

        if self.include_time_entry_ids and self._verify_endpoint_parameter("include_time_entry_ids", endpoint):
            body["include_time_entry_ids"] = self.include_time_entry_ids

        if self.description is not None:
            body["description"] = self.description

        if self.group_ids:
            body["group_ids"] = self.group_ids

        if self.grouping and self._verify_endpoint_parameter("grouping", endpoint):
            body["grouping"] = self.grouping

        if self.grouped and self._verify_endpoint_parameter("grouped", endpoint):
            body["grouped"] = self.grouped

        if isinstance(self.max_duration_seconds, int):
            body["max_duration_seconds"] = self.max_duration_seconds

        if isinstance(self.min_duration_seconds, int):
            body["min_duration_seconds"] = self.min_duration_seconds

        if isinstance(self.rounding, int):
            body["rounding"] = self.rounding

        if isinstance(self.rounding_minutes, int):
            body["rounding_minutes"] = self.rounding_minutes

        if self.sub_grouping is not None and self._verify_endpoint_parameter("sub_grouping", endpoint):
            body["sub_grouping"] = self.sub_grouping

        if self.order_by is not None and self._verify_endpoint_parameter("order_by", endpoint):
            body["order_by"] = self.order_by

        if self.order_dir is not None and self._verify_endpoint_parameter("order_dir", endpoint):
            body["order_dir"] = self.order_dir

        if self.resolution is not None and self._verify_endpoint_parameter("resolution", endpoint):
            body["resolution"] = self.resolution

        if self.enrich_response and self._verify_endpoint_parameter("enrich_response", endpoint):
            body["enrich_response"] = self.enrich_response

        return body

start_date class-attribute instance-attribute

start_date: date | None = field(default=None)

Start date, example time.DateOnly. Should be less than End date.

end_date class-attribute instance-attribute

end_date: date | None = field(default=None)

End date, example time. DateOnly. Should be greater than Start date.

client_ids class-attribute instance-attribute

client_ids: list[int | None] = field(default_factory=list)

Client IDs, optional, filtering attribute. To filter records with no clients, use [None].

description class-attribute instance-attribute

description: str | None = field(default=None)

Description, optional, filtering attribute.

group_ids class-attribute instance-attribute

group_ids: list[int] = field(default_factory=list)

Group IDs, optional, filtering attribute.

grouping class-attribute instance-attribute

grouping: str | None = field(
    default=None,
    metadata={
        "endpoints": frozenset(
            (
                "summary_time_entries",
                "summary_report_pdf",
                "summary_report_csv",
            )
        )
    },
)

Grouping option, optional.

grouped class-attribute instance-attribute

grouped: bool = field(
    default=False,
    metadata={
        "endpoints": frozenset(
            (
                "detail_search_time",
                "detail_report_pdf",
                "detail_report_csv",
                "detail_totals",
            )
        )
    },
)

Whether time entries should be grouped, optional, default false.

include_time_entry_ids class-attribute instance-attribute

include_time_entry_ids: bool = field(
    default=True,
    metadata={
        "endpoints": frozenset(
            (
                "summary_time_entries",
                "summary_report_pdf",
                "summary_report_csv",
            )
        )
    },
)

Whether time entry IDs should be included in the results, optional, default true. Not applicable for export.

max_duration_seconds class-attribute instance-attribute

max_duration_seconds: int | None = field(default=None)

Max duration seconds, optional, filtering attribute. Time Audit only, should be greater than min_duration_seconds.

min_duration_seconds class-attribute instance-attribute

min_duration_seconds: int | None = field(default=None)

Min duration seconds, optional, filtering attribute. Time Audit only, should be less than max_duration_seconds.

project_ids class-attribute instance-attribute

project_ids: list[int | None] = field(default_factory=list)

Project IDs, optional, filtering attribute. To filter records with no projects, use [None].

rounding class-attribute instance-attribute

rounding: int | None = field(default=None)

Whether time should be rounded, optional, default from user preferences.

rounding_minutes class-attribute instance-attribute

rounding_minutes: Literal[0, 1, 5, 6, 10, 12, 15, 30, 60, 240] | None = field(
    default=None
)

Rounding minutes value, optional, default from user preferences. Should be 0, 1, 5, 6, 10, 12, 15, 30, 60 or 240.

sub_grouping class-attribute instance-attribute

sub_grouping: str | None = field(
    default=None,
    metadata={
        "endpoints": frozenset(
            (
                "summary_time_entries",
                "summary_report_pdf",
                "summary_report_csv",
            )
        )
    },
)

SubGrouping option, optional.

tag_ids class-attribute instance-attribute

tag_ids: list[int | None] = field(default_factory=list)

Tag IDs, optional, filtering attribute. To filter records with no tags, use [None].

time_entry_ids class-attribute instance-attribute

time_entry_ids: list[int] = field(default_factory=list)

TimeEntryIDs filters by time entries.

user_ids class-attribute instance-attribute

user_ids: list[int] = field(default_factory=list)

User IDs, optional, filtering attribute.

date_format class-attribute instance-attribute

date_format: Literal[
    "MM/DD/YYYY",
    "DD-MM-YYYY",
    "MM-DD-YYYY",
    "YYYY-MM-DD",
    "DD/MM/YYYY",
    "DD.MM.YYYY",
] = field(
    default="YYYY-MM-DD",
    metadata={
        "endpoints": frozenset(
            ("summary_report_pdf", "detail_report_pdf", "weekly_report_pdf")
        )
    },
)

Date format, optional, default 'YYYY-MM-DD'.

duration_format class-attribute instance-attribute

duration_format: Literal["classic", "decimal", "improved"] = field(
    default="classic",
    metadata={
        "endpoints": frozenset(
            (
                "summary_report_pdf",
                "summary_report_csv",
                "detailed_report_pdf",
                "detailed_report_csv",
                "weekly_report_pdf",
            )
        )
    },
)

Duration format, optional, default "classic". Can be "classic", "decimal" or "improved".

order_by class-attribute instance-attribute

order_by: Literal["title", "duration"] | None = field(
    default=None,
    metadata={
        "endpoints": frozenset(
            (
                "summary_report_pdf",
                "summary_report_csv",
                "detail_search_time",
                "detail_report_pdf",
                "detail_report_csv",
            )
        )
    },
)

Order by option, optional, default title. Can be title or duration.

order_dir class-attribute instance-attribute

order_dir: Literal["ASC", "DESC"] | None = field(
    default=None,
    metadata={
        "endpoints": frozenset(
            (
                "summary_report_pdf",
                "summary_report_csv",
                "detail_search_time",
                "detail_report_pdf",
                "detail_report_csv",
            )
        )
    },
)

Order direction, optional. Can be ASC or DESC.

resolution class-attribute instance-attribute

resolution: str | None = field(
    default=None,
    metadata={"endpoints": frozenset(("summary_report_pdf", "detail_totals"))},
)

Graph resolution, optional. Allow clients to explicitly request a resolution.

enrich_response class-attribute instance-attribute

enrich_response: bool = field(
    default=False,
    metadata={"endpoints": frozenset(("detail_search_time", "detail_report"))},
)

It will force the detailed report to return as much information as possible, as it does for the export.

format

format(endpoint: str, **body: Any) -> dict[str, Any]

Format a body into the correct values types.

PARAMETER DESCRIPTION
endpoint

The name of the endpoint for filtering.

TYPE: str

body

Body pre-filled with miscellanous values:

TYPE: Any DEFAULT: {}

RAISES DESCRIPTION
DateTimeError

If the start date is after the end date.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary of formatted values.

Source code in src/toggl_api/reports.py
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
def format(self, endpoint: str, **body: Any) -> dict[str, Any]:
    """Format a body into the correct values types.

    Args:
        endpoint: The name of the endpoint for filtering.
        body: Body pre-filled with miscellanous values:

    Raises:
        DateTimeError: If the start date is after the end date.

    Returns:
        Dictionary of formatted values.
    """
    body.update(
        {
            "client_ids": self.client_ids,
            "project_ids": self.project_ids,
            "tag_ids": self.tag_ids,
            "time_entry_ids": self.time_entry_ids,
            "user_ids": self.user_ids,
        },
    )

    if self.start_date:
        body["start_date"] = format_iso(self.start_date)
        if self.end_date is not None and self.start_date > self.end_date:
            msg = "Start date needs to be on or before the end date!"
            raise DateTimeError(msg)

    if self.end_date:
        body["end_date"] = format_iso(self.end_date)

    if self._verify_endpoint_parameter("date_format", endpoint):
        body["date_format"] = self.date_format

    if self._verify_endpoint_parameter("duration_format", endpoint):
        body["duration_format"] = self.duration_format

    if self.include_time_entry_ids and self._verify_endpoint_parameter("include_time_entry_ids", endpoint):
        body["include_time_entry_ids"] = self.include_time_entry_ids

    if self.description is not None:
        body["description"] = self.description

    if self.group_ids:
        body["group_ids"] = self.group_ids

    if self.grouping and self._verify_endpoint_parameter("grouping", endpoint):
        body["grouping"] = self.grouping

    if self.grouped and self._verify_endpoint_parameter("grouped", endpoint):
        body["grouped"] = self.grouped

    if isinstance(self.max_duration_seconds, int):
        body["max_duration_seconds"] = self.max_duration_seconds

    if isinstance(self.min_duration_seconds, int):
        body["min_duration_seconds"] = self.min_duration_seconds

    if isinstance(self.rounding, int):
        body["rounding"] = self.rounding

    if isinstance(self.rounding_minutes, int):
        body["rounding_minutes"] = self.rounding_minutes

    if self.sub_grouping is not None and self._verify_endpoint_parameter("sub_grouping", endpoint):
        body["sub_grouping"] = self.sub_grouping

    if self.order_by is not None and self._verify_endpoint_parameter("order_by", endpoint):
        body["order_by"] = self.order_by

    if self.order_dir is not None and self._verify_endpoint_parameter("order_dir", endpoint):
        body["order_dir"] = self.order_dir

    if self.resolution is not None and self._verify_endpoint_parameter("resolution", endpoint):
        body["resolution"] = self.resolution

    if self.enrich_response and self._verify_endpoint_parameter("enrich_response", endpoint):
        body["enrich_response"] = self.enrich_response

    return body

toggl_api.reports.ReportEndpoint

Bases: TogglEndpoint[Any]

Abstract baseclass for the reports endpoint that overrides BASE_ENDPOINT.

METHOD DESCRIPTION
search_time_entries

Search for time entries for the given report endpoint.

export_report

Export a report for the given report endpoint.

search_time_entries abstractmethod

search_time_entries(body: ReportBody, *args: Any, **kwargs: Any) -> Any

Search for time entries for the given report endpoint.

export_report abstractmethod

export_report(body: ReportBody, *args: Any, **kwargs: Any) -> Any

Export a report for the given report endpoint.

toggl_api.asyncio.AsyncReportEndpoint

Bases: TogglAsyncEndpoint[Any]

Abstract baseclass for the async report endpoints that overrides BASE_ENDPOINT.


Summary Reports

toggl_api.reports.SummaryReportEndpoint

Bases: ReportEndpoint

Summary reports endpoints.

Official Documentation

METHOD DESCRIPTION
project_summary

Return a specific projects summary within the parameters provided.

project_summaries

Return a summary of user projects according to parameters provided.

search_time_entries

Return a list of time entries within the parameters specified.

export_report

Download summary report in the specified in the specified format: csv or pdf.

ATTRIBUTE DESCRIPTION
endpoint

Summary report endpoint url parameters.

TYPE: str

Source code in src/toggl_api/reports.py
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
class SummaryReportEndpoint(ReportEndpoint):
    """Summary reports endpoints.

    [Official Documentation](https://engineering.toggl.com/docs/reports/summary_reports)
    """

    def project_summary(
        self,
        project: TogglProject | int,
        start_date: date | str,
        end_date: date | str,
    ) -> dict[str, int]:
        """Return a specific projects summary within the parameters provided.

        [Official Documentation](https://engineering.toggl.com/docs/reports/summary_reports#post-load-project-summary)

        Args:
            project: Project to retrieve summaries about.
            start_date: The date to gather project summary data from.
            end_date: The date to gather project summary data to.

        Returns:
            A list of dictionary with the summary data.
        """
        return cast(
            "dict[str, int]",
            self.request(
                f"{self.endpoint}/projects/{project.id if isinstance(project, TogglProject) else project}/summary",
                method=RequestMethod.POST,
                body={
                    "start_date": format_iso(start_date),
                    "end_date": format_iso(end_date),
                },
            ),
        )

    def project_summaries(
        self,
        start_date: date | str,
        end_date: date | str,
    ) -> list[dict[str, int]]:
        """Return a summary of user projects according to parameters provided.

        [Official Documentation](https://engineering.toggl.com/docs/reports/summary_reports#post-list-project-users)

        Args:
            start_date: The date to gather project summaries from.
            end_date: The date to gather project summaries data to.

        Returns:
            A list of dictionary with the summary data.
        """
        return cast(
            "list[dict[str, int]]",
            self.request(
                f"{self.endpoint}/projects/summary",
                method=RequestMethod.POST,
                body={
                    "start_date": format_iso(start_date),
                    "end_date": format_iso(end_date),
                },
            ),
        )

    def search_time_entries(self, body: ReportBody) -> list[dict[str, int]]:
        """Return a list of time entries within the parameters specified.

        [Official Documentation](https://engineering.toggl.com/docs/reports/summary_reports#post-search-time-entries)

        Args:
            body: Body parameters to filter time entries by.

        Returns:
            A list of dictionaries with the filtered tracker data.
        """
        return cast(
            "list[dict[str, int]]",
            self.request(
                f"{self.endpoint}/summary/time_entries",
                method=RequestMethod.POST,
                body=body.format(
                    "summary_time_entries",
                    workspace_id=self.workspace_id,
                ),
            ),
        )

    def export_report(
        self,
        body: ReportBody,
        extension: ReportFormats,
        *,
        collapse: bool = False,
    ) -> bytes:
        """Download summary report in the specified in the specified format: csv or pdf.

        [Official Documentation](https://engineering.toggl.com/docs/reports/summary_reports#post-export-summary-report)

        Args:
            body: Body parameters to filter the report by.
            extension: What format to use for the report. CSV or PDF.
            collapse: Whether collapse others. Inserted into body.

        Raises:
            InvalidExtensionError: If extension is not pdf or csv.

        Returns:
            A format ready to be saved as a file or used for further processing.
        """
        _validate_extension(extension)

        return cast(
            "Response",
            self.request(
                f"{self.endpoint}/summary/time_entries.{extension}",
                method=RequestMethod.POST,
                body=body.format(
                    f"summary_report_{extension}",
                    workspace_id=self.workspace_id,
                    collapse=collapse,
                ),
                raw=True,
            ),
        ).content

    @property
    def endpoint(self) -> str:
        """Summary report endpoint url parameters."""
        return f"workspace/{self.workspace_id}"

endpoint property

endpoint: str

Summary report endpoint url parameters.

project_summary

project_summary(
    project: TogglProject | int, start_date: date | str, end_date: date | str
) -> dict[str, int]

Return a specific projects summary within the parameters provided.

Official Documentation

PARAMETER DESCRIPTION
project

Project to retrieve summaries about.

TYPE: TogglProject | int

start_date

The date to gather project summary data from.

TYPE: date | str

end_date

The date to gather project summary data to.

TYPE: date | str

RETURNS DESCRIPTION
dict[str, int]

A list of dictionary with the summary data.

Source code in src/toggl_api/reports.py
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
def project_summary(
    self,
    project: TogglProject | int,
    start_date: date | str,
    end_date: date | str,
) -> dict[str, int]:
    """Return a specific projects summary within the parameters provided.

    [Official Documentation](https://engineering.toggl.com/docs/reports/summary_reports#post-load-project-summary)

    Args:
        project: Project to retrieve summaries about.
        start_date: The date to gather project summary data from.
        end_date: The date to gather project summary data to.

    Returns:
        A list of dictionary with the summary data.
    """
    return cast(
        "dict[str, int]",
        self.request(
            f"{self.endpoint}/projects/{project.id if isinstance(project, TogglProject) else project}/summary",
            method=RequestMethod.POST,
            body={
                "start_date": format_iso(start_date),
                "end_date": format_iso(end_date),
            },
        ),
    )

project_summaries

project_summaries(
    start_date: date | str, end_date: date | str
) -> list[dict[str, int]]

Return a summary of user projects according to parameters provided.

Official Documentation

PARAMETER DESCRIPTION
start_date

The date to gather project summaries from.

TYPE: date | str

end_date

The date to gather project summaries data to.

TYPE: date | str

RETURNS DESCRIPTION
list[dict[str, int]]

A list of dictionary with the summary data.

Source code in src/toggl_api/reports.py
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
def project_summaries(
    self,
    start_date: date | str,
    end_date: date | str,
) -> list[dict[str, int]]:
    """Return a summary of user projects according to parameters provided.

    [Official Documentation](https://engineering.toggl.com/docs/reports/summary_reports#post-list-project-users)

    Args:
        start_date: The date to gather project summaries from.
        end_date: The date to gather project summaries data to.

    Returns:
        A list of dictionary with the summary data.
    """
    return cast(
        "list[dict[str, int]]",
        self.request(
            f"{self.endpoint}/projects/summary",
            method=RequestMethod.POST,
            body={
                "start_date": format_iso(start_date),
                "end_date": format_iso(end_date),
            },
        ),
    )

search_time_entries

search_time_entries(body: ReportBody) -> list[dict[str, int]]

Return a list of time entries within the parameters specified.

Official Documentation

PARAMETER DESCRIPTION
body

Body parameters to filter time entries by.

TYPE: ReportBody

RETURNS DESCRIPTION
list[dict[str, int]]

A list of dictionaries with the filtered tracker data.

Source code in src/toggl_api/reports.py
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
def search_time_entries(self, body: ReportBody) -> list[dict[str, int]]:
    """Return a list of time entries within the parameters specified.

    [Official Documentation](https://engineering.toggl.com/docs/reports/summary_reports#post-search-time-entries)

    Args:
        body: Body parameters to filter time entries by.

    Returns:
        A list of dictionaries with the filtered tracker data.
    """
    return cast(
        "list[dict[str, int]]",
        self.request(
            f"{self.endpoint}/summary/time_entries",
            method=RequestMethod.POST,
            body=body.format(
                "summary_time_entries",
                workspace_id=self.workspace_id,
            ),
        ),
    )

export_report

export_report(
    body: ReportBody, extension: ReportFormats, *, collapse: bool = False
) -> bytes

Download summary report in the specified in the specified format: csv or pdf.

Official Documentation

PARAMETER DESCRIPTION
body

Body parameters to filter the report by.

TYPE: ReportBody

extension

What format to use for the report. CSV or PDF.

TYPE: ReportFormats

collapse

Whether collapse others. Inserted into body.

TYPE: bool DEFAULT: False

RAISES DESCRIPTION
InvalidExtensionError

If extension is not pdf or csv.

RETURNS DESCRIPTION
bytes

A format ready to be saved as a file or used for further processing.

Source code in src/toggl_api/reports.py
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
def export_report(
    self,
    body: ReportBody,
    extension: ReportFormats,
    *,
    collapse: bool = False,
) -> bytes:
    """Download summary report in the specified in the specified format: csv or pdf.

    [Official Documentation](https://engineering.toggl.com/docs/reports/summary_reports#post-export-summary-report)

    Args:
        body: Body parameters to filter the report by.
        extension: What format to use for the report. CSV or PDF.
        collapse: Whether collapse others. Inserted into body.

    Raises:
        InvalidExtensionError: If extension is not pdf or csv.

    Returns:
        A format ready to be saved as a file or used for further processing.
    """
    _validate_extension(extension)

    return cast(
        "Response",
        self.request(
            f"{self.endpoint}/summary/time_entries.{extension}",
            method=RequestMethod.POST,
            body=body.format(
                f"summary_report_{extension}",
                workspace_id=self.workspace_id,
                collapse=collapse,
            ),
            raw=True,
        ),
    ).content

toggl_api.asyncio.AsyncSummaryReportEndpoint

Bases: AsyncReportEndpoint

Summary reports endpoints.

Official Documentation

METHOD DESCRIPTION
project_summary

Return a specific projects summary within the parameters provided.

project_summaries

Return a summary of user projects according to parameters provided.

search_time_entries

Return a list of time entries within the parameters specified.

export_report

Download summary report in the specified in the specified format: csv or pdf.

project_summary async

project_summary(
    project: TogglProject | int, start_date: date | str, end_date: date | str
) -> dict[str, int]

Return a specific projects summary within the parameters provided.

Official Documentation

PARAMETER DESCRIPTION
project

Project to retrieve summaries about.

TYPE: TogglProject | int

start_date

The date to gather project summary data from.

TYPE: date | str

end_date

The date to gather project summary data to.

TYPE: date | str

RETURNS DESCRIPTION
dict[str, int]

A list of dictionary with the summary data.

project_summaries async

project_summaries(
    start_date: date | str, end_date: date | str
) -> list[dict[str, int]]

Return a summary of user projects according to parameters provided.

Official Documentation

PARAMETER DESCRIPTION
start_date

The date to gather project summaries from.

TYPE: date | str

end_date

The date to gather project summaries data to.

TYPE: date | str

RETURNS DESCRIPTION
list[dict[str, int]]

A list of dictionary with the summary data.

search_time_entries async

search_time_entries(body: ReportBody) -> list[dict[str, int]]

Return a list of time entries within the parameters specified.

Official Documentation

PARAMETER DESCRIPTION
body

Body parameters to filter time entries by.

TYPE: ReportBody

RETURNS DESCRIPTION
list[dict[str, int]]

A list of dictionaries with the filtered tracker data.

export_report async

export_report(
    body: ReportBody, extension: ReportFormats, *, collapse: bool = False
) -> bytes

Download summary report in the specified in the specified format: csv or pdf.

Official Documentation

PARAMETER DESCRIPTION
body

Body parameters to filter the report by.

TYPE: ReportBody

extension

What format to use for the report. CSV or PDF.

TYPE: ReportFormats

collapse

Whether collapse others. Inserted into body.

TYPE: bool DEFAULT: False

RAISES DESCRIPTION
InvalidExtensionError

If extension is not pdf or csv.

RETURNS DESCRIPTION
bytes

A format ready to be saved as a file or used for further processing.


Detailed Reports

toggl_api.reports.PaginatedResult dataclass

Bases: Generic[T]

Generic dataclass for paginated results.

METHOD DESCRIPTION
__post_init__

Post init method that converts any numeric values to actual ints.

next_options

Create the next options with a newly defined page size.

Source code in src/toggl_api/reports.py
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
@dataclass
class PaginatedResult(Generic[T]):
    """Generic dataclass for paginated results."""

    result: T = field()
    next_id: int | None = field(default=None)
    next_row: int | None = field(default=None)

    def __post_init__(self) -> None:
        """Post init method that converts any numeric values to actual ints."""
        # NOTE: Header types are strings so post init converts to integer.
        if self.next_id:
            self.next_id = int(self.next_id)
        if self.next_row:
            self.next_row = int(self.next_row)

    def next_options(self, page_size: int = 50) -> PaginationOptions:
        """Create the next options with a newly defined page size.

        Args:
            page_size: Override the page size.

        Returns:
            New pagination options for the next request.
        """
        return PaginationOptions(page_size, self.next_id, self.next_row)

__post_init__

__post_init__() -> None

Post init method that converts any numeric values to actual ints.

Source code in src/toggl_api/reports.py
39
40
41
42
43
44
45
def __post_init__(self) -> None:
    """Post init method that converts any numeric values to actual ints."""
    # NOTE: Header types are strings so post init converts to integer.
    if self.next_id:
        self.next_id = int(self.next_id)
    if self.next_row:
        self.next_row = int(self.next_row)

next_options

next_options(page_size: int = 50) -> PaginationOptions

Create the next options with a newly defined page size.

PARAMETER DESCRIPTION
page_size

Override the page size.

TYPE: int DEFAULT: 50

RETURNS DESCRIPTION
PaginationOptions

New pagination options for the next request.

Source code in src/toggl_api/reports.py
47
48
49
50
51
52
53
54
55
56
def next_options(self, page_size: int = 50) -> PaginationOptions:
    """Create the next options with a newly defined page size.

    Args:
        page_size: Override the page size.

    Returns:
        New pagination options for the next request.
    """
    return PaginationOptions(page_size, self.next_id, self.next_row)

toggl_api.reports.PaginationOptions dataclass

Dataclass for paginate endpoints.

Source code in src/toggl_api/reports.py
22
23
24
25
26
27
28
@dataclass(frozen=True)
class PaginationOptions:
    """Dataclass for paginate endpoints."""

    page_size: int = field(default=50)
    next_id: int | None = field(default=None)
    next_row: int | None = field(default=None)

toggl_api.reports.DetailedReportEndpoint

Bases: ReportEndpoint

Detailed reports endpoint.

Official Documentation

METHOD DESCRIPTION
search_time_entries

Return time entries for detailed report according to the given filters.

export_report

Download detailed report in pdf or csv format.

totals_report

Return totals sums for detailed report.

ATTRIBUTE DESCRIPTION
endpoint

Detailed report endpoint url parameters.

TYPE: str

Source code in src/toggl_api/reports.py
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
class DetailedReportEndpoint(ReportEndpoint):
    """Detailed reports endpoint.

    [Official Documentation](https://engineering.toggl.com/docs/reports/detailed_reports)
    """

    @staticmethod
    def _paginate(request: Response, *, raw: bool = False) -> PaginatedResult[Any]:
        return PaginatedResult(
            request.content if raw else request.json(),
            request.headers.get("x-next-id"),
            request.headers.get("x-next-row-number"),
        )

    @staticmethod
    def _paginate_body(
        body: dict[str, Any],
        pagination: PaginationOptions,
    ) -> dict[str, Any]:
        body["page_size"] = pagination.page_size
        if pagination.next_id is not None and pagination.next_row is not None:
            body["first_id"] = pagination.next_id
            body["first_row_number"] = pagination.next_row

        return body

    def search_time_entries(
        self,
        body: ReportBody,
        pagination: PaginationOptions | None = None,
        *,
        hide_amounts: bool = False,
    ) -> PaginatedResult[list[dict[str, Any]]]:
        """Return time entries for detailed report according to the given filters.

        [Official Documentation](https://engineering.toggl.com/docs/reports/detailed_reports#post-search-time-entries)

        Args:
            body: JSON body with filters for time entries.
            pagination: Pagination options containing page size, next_id and next_row.
            hide_amounts: Whether amounts should be hidden.

        Returns:
            Data with pagination information if required.
        """
        pagination = pagination or PaginationOptions()

        request: Response = cast(
            "Response",
            self.request(
                self.endpoint,
                body=self._paginate_body(
                    body.format(
                        "detail_search_time",
                        workspace_id=self.workspace_id,
                        hide_amounts=hide_amounts,
                    ),
                    pagination,
                ),
                method=RequestMethod.POST,
                raw=True,
            ),
        )

        return self._paginate(request)

    def export_report(
        self,
        body: ReportBody,
        extension: ReportFormats,
        pagination: PaginationOptions | None = None,
        *,
        hide_amounts: bool = False,
    ) -> PaginatedResult[bytes]:
        """Download detailed report in pdf or csv format.

        [Official Documentation](https://engineering.toggl.com/docs/reports/detailed_reports#post-export-detailed-report)

        Args:
            body: JSON body for formatting and filtering the report.
            extension: Format of the exported report. PDF or CSV.
            pagination: Pagination options containing page size, next_id and next_row.
            hide_amounts: Whether amounts should be hidden.

        Raises:
            InvalidExtensionError: If extension is not pdf or csv.
            HTTPStatusError: If the request is not a success.

        Returns:
            Report ready to be saved or further processed in python.
        """
        _validate_extension(extension)

        pagination = pagination or PaginationOptions()
        request = cast(
            "Response",
            self.request(
                f"{self.endpoint}.{extension}",
                body=self._paginate_body(
                    body.format(
                        f"detail_report_{extension}",
                        workspace_id=self.workspace_id,
                        hide_amounts=hide_amounts,
                    ),
                    pagination,
                ),
                method=RequestMethod.POST,
                raw=True,
            ),
        )
        return self._paginate(request, raw=True)

    def totals_report(
        self,
        body: ReportBody,
        *,
        granularity: Literal["day", "week", "month"] = "day",
        with_graph: bool = False,
    ) -> dict[str, int]:
        """Return totals sums for detailed report.

        [Official Documentation](https://engineering.toggl.com/docs/reports/detailed_reports#post-load-totals-detailed-report)

        Args:
            body: JSON body for filtering the report.
            granularity: Totals granularity, optional, overrides resolution values.
            with_graph: Whether Graph information should be loaded.

        Returns:
            With the totals relevant to the provided filters.
        """
        return cast(
            "dict[str, int]",
            self.request(
                f"{self.endpoint}/totals",
                body=body.format(
                    "detail_totals",
                    workspace_id=self.workspace_id,
                    granularity=granularity,
                    with_graph=with_graph,
                ),
                method=RequestMethod.POST,
            ),
        )

    @property
    def endpoint(self) -> str:
        """Detailed report endpoint url parameters."""
        return f"workspace/{self.workspace_id}/search/time_entries"

endpoint property

endpoint: str

Detailed report endpoint url parameters.

search_time_entries

search_time_entries(
    body: ReportBody,
    pagination: PaginationOptions | None = None,
    *,
    hide_amounts: bool = False,
) -> PaginatedResult[list[dict[str, Any]]]

Return time entries for detailed report according to the given filters.

Official Documentation

PARAMETER DESCRIPTION
body

JSON body with filters for time entries.

TYPE: ReportBody

pagination

Pagination options containing page size, next_id and next_row.

TYPE: PaginationOptions | None DEFAULT: None

hide_amounts

Whether amounts should be hidden.

TYPE: bool DEFAULT: False

RETURNS DESCRIPTION
PaginatedResult[list[dict[str, Any]]]

Data with pagination information if required.

Source code in src/toggl_api/reports.py
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
def search_time_entries(
    self,
    body: ReportBody,
    pagination: PaginationOptions | None = None,
    *,
    hide_amounts: bool = False,
) -> PaginatedResult[list[dict[str, Any]]]:
    """Return time entries for detailed report according to the given filters.

    [Official Documentation](https://engineering.toggl.com/docs/reports/detailed_reports#post-search-time-entries)

    Args:
        body: JSON body with filters for time entries.
        pagination: Pagination options containing page size, next_id and next_row.
        hide_amounts: Whether amounts should be hidden.

    Returns:
        Data with pagination information if required.
    """
    pagination = pagination or PaginationOptions()

    request: Response = cast(
        "Response",
        self.request(
            self.endpoint,
            body=self._paginate_body(
                body.format(
                    "detail_search_time",
                    workspace_id=self.workspace_id,
                    hide_amounts=hide_amounts,
                ),
                pagination,
            ),
            method=RequestMethod.POST,
            raw=True,
        ),
    )

    return self._paginate(request)

export_report

export_report(
    body: ReportBody,
    extension: ReportFormats,
    pagination: PaginationOptions | None = None,
    *,
    hide_amounts: bool = False,
) -> PaginatedResult[bytes]

Download detailed report in pdf or csv format.

Official Documentation

PARAMETER DESCRIPTION
body

JSON body for formatting and filtering the report.

TYPE: ReportBody

extension

Format of the exported report. PDF or CSV.

TYPE: ReportFormats

pagination

Pagination options containing page size, next_id and next_row.

TYPE: PaginationOptions | None DEFAULT: None

hide_amounts

Whether amounts should be hidden.

TYPE: bool DEFAULT: False

RAISES DESCRIPTION
InvalidExtensionError

If extension is not pdf or csv.

HTTPStatusError

If the request is not a success.

RETURNS DESCRIPTION
PaginatedResult[bytes]

Report ready to be saved or further processed in python.

Source code in src/toggl_api/reports.py
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
def export_report(
    self,
    body: ReportBody,
    extension: ReportFormats,
    pagination: PaginationOptions | None = None,
    *,
    hide_amounts: bool = False,
) -> PaginatedResult[bytes]:
    """Download detailed report in pdf or csv format.

    [Official Documentation](https://engineering.toggl.com/docs/reports/detailed_reports#post-export-detailed-report)

    Args:
        body: JSON body for formatting and filtering the report.
        extension: Format of the exported report. PDF or CSV.
        pagination: Pagination options containing page size, next_id and next_row.
        hide_amounts: Whether amounts should be hidden.

    Raises:
        InvalidExtensionError: If extension is not pdf or csv.
        HTTPStatusError: If the request is not a success.

    Returns:
        Report ready to be saved or further processed in python.
    """
    _validate_extension(extension)

    pagination = pagination or PaginationOptions()
    request = cast(
        "Response",
        self.request(
            f"{self.endpoint}.{extension}",
            body=self._paginate_body(
                body.format(
                    f"detail_report_{extension}",
                    workspace_id=self.workspace_id,
                    hide_amounts=hide_amounts,
                ),
                pagination,
            ),
            method=RequestMethod.POST,
            raw=True,
        ),
    )
    return self._paginate(request, raw=True)

totals_report

totals_report(
    body: ReportBody,
    *,
    granularity: Literal["day", "week", "month"] = "day",
    with_graph: bool = False,
) -> dict[str, int]

Return totals sums for detailed report.

Official Documentation

PARAMETER DESCRIPTION
body

JSON body for filtering the report.

TYPE: ReportBody

granularity

Totals granularity, optional, overrides resolution values.

TYPE: Literal['day', 'week', 'month'] DEFAULT: 'day'

with_graph

Whether Graph information should be loaded.

TYPE: bool DEFAULT: False

RETURNS DESCRIPTION
dict[str, int]

With the totals relevant to the provided filters.

Source code in src/toggl_api/reports.py
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
def totals_report(
    self,
    body: ReportBody,
    *,
    granularity: Literal["day", "week", "month"] = "day",
    with_graph: bool = False,
) -> dict[str, int]:
    """Return totals sums for detailed report.

    [Official Documentation](https://engineering.toggl.com/docs/reports/detailed_reports#post-load-totals-detailed-report)

    Args:
        body: JSON body for filtering the report.
        granularity: Totals granularity, optional, overrides resolution values.
        with_graph: Whether Graph information should be loaded.

    Returns:
        With the totals relevant to the provided filters.
    """
    return cast(
        "dict[str, int]",
        self.request(
            f"{self.endpoint}/totals",
            body=body.format(
                "detail_totals",
                workspace_id=self.workspace_id,
                granularity=granularity,
                with_graph=with_graph,
            ),
            method=RequestMethod.POST,
        ),
    )

toggl_api.asyncio.AsyncDetailedReportEndpoint

Bases: AsyncReportEndpoint

Detailed reports endpoint.

Official Documentation

METHOD DESCRIPTION
search_time_entries

Return time entries for detailed report according to the given filters.

export_report

Download detailed report in pdf or csv format.

totals_report

Return totals sums for detailed report.

search_time_entries async

search_time_entries(
    body: ReportBody,
    pagination: PaginationOptions | None = None,
    *,
    hide_amounts: bool = False,
) -> PaginatedResult[list[dict[str, Any]]]

Return time entries for detailed report according to the given filters.

Official Documentation

PARAMETER DESCRIPTION
body

JSON body with filters for time entries.

TYPE: ReportBody

pagination

Pagination options containing page size, next_id and next_row.

TYPE: PaginationOptions | None DEFAULT: None

hide_amounts

Whether amounts should be hidden.

TYPE: bool DEFAULT: False

RETURNS DESCRIPTION
PaginatedResult[list[dict[str, Any]]]

Data with pagination information if required.

export_report async

export_report(
    body: ReportBody,
    extension: ReportFormats,
    pagination: PaginationOptions | None = None,
    *,
    hide_amounts: bool = False,
) -> PaginatedResult[bytes]

Download detailed report in pdf or csv format.

Official Documentation

PARAMETER DESCRIPTION
body

JSON body for formatting and filtering the report.

TYPE: ReportBody

extension

Format of the exported report. PDF or CSV.

TYPE: ReportFormats

pagination

Pagination options containing page size, next_id and next_row.

TYPE: PaginationOptions | None DEFAULT: None

hide_amounts

Whether amounts should be hidden.

TYPE: bool DEFAULT: False

RAISES DESCRIPTION
InvalidExtensionError

If extension is not pdf or csv.

HTTPStatusError

If the request is not a success.

RETURNS DESCRIPTION
PaginatedResult[bytes]

Report ready to be saved or further processed in python.

totals_report async

totals_report(
    body: ReportBody,
    *,
    granularity: Literal["day", "week", "month"] = "day",
    with_graph: bool = False,
) -> dict[str, int]

Return totals sums for detailed report.

Official Documentation

PARAMETER DESCRIPTION
body

JSON body for filtering the report.

TYPE: ReportBody

granularity

Totals granularity, optional, overrides resolution values.

TYPE: Literal['day', 'week', 'month'] DEFAULT: 'day'

with_graph

Whether Graph information should be loaded.

TYPE: bool DEFAULT: False

RETURNS DESCRIPTION
dict[str, int]

With the totals relevant to the provided filters.


Weekly Reports

toggl_api.reports.WeeklyReportEndpoint

Bases: ReportEndpoint

Weekly reports endpoint.

Official Documentation

METHOD DESCRIPTION
search_time_entries

Return time entries for weekly report according to the given filters.

export_report

Download weekly report in pdf or csv format.

ATTRIBUTE DESCRIPTION
endpoint

Weekly report endpoint url parameters.

TYPE: str

Source code in src/toggl_api/reports.py
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
class WeeklyReportEndpoint(ReportEndpoint):
    """Weekly reports endpoint.

    [Official Documentation](https://engineering.toggl.com/docs/reports/weekly_reports)
    """

    def search_time_entries(self, body: ReportBody) -> list[dict[str, Any]]:
        """Return time entries for weekly report according to the given filters.

        [Official Documentation](https://engineering.toggl.com/docs/reports/detailed_reports#post-search-time-entries)

        Args:
            body: JSON body for filtering time entries.

        Returns:
            A List of time entries filted by the formatted body.
        """
        return cast(
            "list[dict[str, Any]]",
            self.request(
                self.endpoint,
                body=body.format(
                    "weekly_time_entries",
                    workspace_id=self.workspace_id,
                ),
                method=RequestMethod.POST,
            ),
        )

    def export_report(self, body: ReportBody, extension: ReportFormats) -> bytes:
        """Download weekly report in pdf or csv format.

        [Official Documentation](https://engineering.toggl.com/docs/reports/weekly_reports#post-export-weekly-report)

        Args:
            body: JSON body for filtering time entries.
            extension: extension: Format of the exported report. PDF or CSV.

        Raises:
            InvalidExtensionError: If extension is not pdf or csv.

        Returns:
            Report ready to be saved or further processed in python.
        """
        _validate_extension(extension)
        return cast(
            "Response",
            self.request(
                f"{self.endpoint}.{extension}",
                body=body.format(
                    f"weekly_report_{extension}",
                    workspace_id=self.workspace_id,
                ),
                method=RequestMethod.POST,
                raw=True,
            ),
        ).content

    @property
    def endpoint(self) -> str:
        """Weekly report endpoint url parameters."""
        return f"workspace/{self.workspace_id}/weekly/time_entries"

endpoint property

endpoint: str

Weekly report endpoint url parameters.

search_time_entries

search_time_entries(body: ReportBody) -> list[dict[str, Any]]

Return time entries for weekly report according to the given filters.

Official Documentation

PARAMETER DESCRIPTION
body

JSON body for filtering time entries.

TYPE: ReportBody

RETURNS DESCRIPTION
list[dict[str, Any]]

A List of time entries filted by the formatted body.

Source code in src/toggl_api/reports.py
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
def search_time_entries(self, body: ReportBody) -> list[dict[str, Any]]:
    """Return time entries for weekly report according to the given filters.

    [Official Documentation](https://engineering.toggl.com/docs/reports/detailed_reports#post-search-time-entries)

    Args:
        body: JSON body for filtering time entries.

    Returns:
        A List of time entries filted by the formatted body.
    """
    return cast(
        "list[dict[str, Any]]",
        self.request(
            self.endpoint,
            body=body.format(
                "weekly_time_entries",
                workspace_id=self.workspace_id,
            ),
            method=RequestMethod.POST,
        ),
    )

export_report

export_report(body: ReportBody, extension: ReportFormats) -> bytes

Download weekly report in pdf or csv format.

Official Documentation

PARAMETER DESCRIPTION
body

JSON body for filtering time entries.

TYPE: ReportBody

extension

extension: Format of the exported report. PDF or CSV.

TYPE: ReportFormats

RAISES DESCRIPTION
InvalidExtensionError

If extension is not pdf or csv.

RETURNS DESCRIPTION
bytes

Report ready to be saved or further processed in python.

Source code in src/toggl_api/reports.py
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
def export_report(self, body: ReportBody, extension: ReportFormats) -> bytes:
    """Download weekly report in pdf or csv format.

    [Official Documentation](https://engineering.toggl.com/docs/reports/weekly_reports#post-export-weekly-report)

    Args:
        body: JSON body for filtering time entries.
        extension: extension: Format of the exported report. PDF or CSV.

    Raises:
        InvalidExtensionError: If extension is not pdf or csv.

    Returns:
        Report ready to be saved or further processed in python.
    """
    _validate_extension(extension)
    return cast(
        "Response",
        self.request(
            f"{self.endpoint}.{extension}",
            body=body.format(
                f"weekly_report_{extension}",
                workspace_id=self.workspace_id,
            ),
            method=RequestMethod.POST,
            raw=True,
        ),
    ).content

toggl_api.asyncio.AsyncWeeklyReportEndpoint

Bases: AsyncReportEndpoint

Weekly reports endpoint.

Official Documentation

METHOD DESCRIPTION
search_time_entries

Return time entries for weekly report according to the given filters.

export_report

Download weekly report in pdf or csv format.

search_time_entries async

search_time_entries(body: ReportBody) -> list[dict[str, Any]]

Return time entries for weekly report according to the given filters.

Official Documentation

PARAMETER DESCRIPTION
body

JSON body for filtering time entries.

TYPE: ReportBody

RETURNS DESCRIPTION
list[dict[str, Any]]

A List of time entries filted by the formatted body.

export_report async

export_report(body: ReportBody, extension: ReportFormats) -> bytes

Download weekly report in pdf or csv format.

Official Documentation

PARAMETER DESCRIPTION
body

JSON body for filtering time entries.

TYPE: ReportBody

extension

extension: Format of the exported report. PDF or CSV.

TYPE: ReportFormats

RAISES DESCRIPTION
InvalidExtensionError

If extension is not pdf or csv.

RETURNS DESCRIPTION
bytes

Report ready to be saved or further processed in python.