Skip to content

Trackers

toggl_api.modules.tracker.TrackerBody dataclass

JSON body dataclass for PUT, POST & PATCH requests.

format_body(workspace_id: int) -> dict[str, Any]

Formats the body for JSON requests.

Gets called by the endpoint methods before requesting.

Parameters:

  • workspace_id (int) –

    Alternate Workspace ID for the request if the body does not contain a workspace_id.

Returns:

  • dict[str, Any]

    dict[str, Any]: JSON compatible formatted body.

toggl_api.modules.tracker.TrackerEndpoint

Bases: TogglCachedEndpoint

edit_tracker(tracker: TogglTracker | int, body: TrackerBody) -> Optional[TogglTracker]

Edit an existing tracker.

delete_tracker(tracker: TogglTracker | int) -> None

Delete tracker from Toggl.

Parameters:

  • tracker (TogglTracker | int) –

    Tracker object with ID to delete.

Returns:

  • None ( None ) –

    If the tracker was deleted or not found at all.

stop_tracker(tracker: TogglTracker | int) -> Optional[TogglTracker]

Stops a running tracker.

Parameters:

  • tracker (TogglTracker | int) –

    Tracker object with IP to stop.

Returns:

  • TogglTracker ( Optional[TogglTracker] ) –

    If the tracker was stopped or if the tracker wasn't running it will return None.

add_tracker(body: TrackerBody) -> Optional[TogglTracker]

Add a new tracker.

Parameters:

  • body (TrackerBody) –

    Body of the request. Description must be set. If start date is not set it will be set to current time with duration set to -1 for a running tracker.

Raises:

  • ValueError

    Description must be set in order to create a new tracker.

Returns:

  • TogglTracker ( Optional[TogglTracker] ) –

    The tracker that was created.

toggl_api.modules.user.UserEndpoint

Bases: TogglCachedEndpoint

Source code in toggl_api/modules/user.py
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 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
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 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
class UserEndpoint(TogglCachedEndpoint):
    TRACKER_NOT_RUNNING: Final[int] = 405

    def current_tracker(self, *, refresh: bool = True) -> Optional[TogglTracker]:
        """Get current running tracker. Returns None if no tracker is running."""

        try:
            response = self.request("time_entries/current", refresh=refresh)
        except HTTPStatusError as err:
            if err.response.status_code == self.TRACKER_NOT_RUNNING:
                return None
            raise

        return response if isinstance(response, TogglTracker) else None

    def get_trackers(
        self,
        since: Optional[int | datetime] = None,
        before: Optional[date] = None,
        start_date: Optional[date] = None,
        end_date: Optional[date] = None,
        *,
        refresh: bool = False,
    ) -> list[TogglTracker]:
        """Get a set of trackers depending on specified parameters.

        Args:
            since: Get entries modified since this date using UNIX timestamp,
                including deleted ones.
            before: Get entries with start time, before given date (YYYY-MM-DD)
                or with time in RFC3339 format.
            start_date: Get entries with start time, from start_date YYYY-MM-DD
                or with time in RFC3339 format. To be used with end_date.
            end_date: Get entries with start time, until end_date YYYY-MM-DD or
                with time in RFC3339 format. To be used with start_date.
            refresh: Whether to refresh the cache or not.

        Returns:
            list[TogglTracker]: List of TogglTracker objects that are within
                specified parameters. Empty if none matched.
        """

        params = "time_entries"
        if since and before:
            params = f"?since={since}&before={before}"
        elif start_date and end_date:
            params = f"?start_date={start_date}&end_date={end_date}"
        response = self.request(params, refresh=refresh)

        # TODO: Need to filter cached trackers.
        # TODO: Implement sorting of trackers.

        return response if isinstance(response, list) else []  # type: ignore[return-value]

    def get_tracker(
        self,
        tracker_id: int | TogglTracker,
        *,
        refresh: bool = False,
    ) -> Optional[TogglTracker]:
        """Get a single tracker by ID.

        Args:
            tracker_id: ID of the tracker to get.
            refresh: Whether to refresh the cache or not.

        Returns:
            TogglTracker | None: TogglTracker object or None if not found.
        """
        if isinstance(tracker_id, TogglTracker):
            tracker_id = tracker_id.id

        if not refresh:
            tracker = self.cache.find_entry({"id": tracker_id})
            if isinstance(tracker, TogglTracker):
                return tracker
            refresh = True
        try:
            response = self.request(
                f"time_entries/{tracker_id}",
                refresh=refresh,
            )
        except HTTPStatusError as err:
            if err.response.status_code == self.NOT_FOUND:
                return None
            raise

        return response  # type: ignore[return-value]

    def check_authentication(self) -> bool:
        """Check if user is correctly authenticated with the Toggl API."""
        try:
            TogglCachedEndpoint.request(self, "logged")
        except HTTPError:
            return False

        return True

    @property
    def endpoint(self) -> str:
        return "me/"

    @property
    def model(self) -> type[TogglTracker]:
        return TogglTracker

current_tracker(*, refresh: bool = True) -> Optional[TogglTracker]

Get current running tracker. Returns None if no tracker is running.

Source code in toggl_api/modules/user.py
13
14
15
16
17
18
19
20
21
22
23
def current_tracker(self, *, refresh: bool = True) -> Optional[TogglTracker]:
    """Get current running tracker. Returns None if no tracker is running."""

    try:
        response = self.request("time_entries/current", refresh=refresh)
    except HTTPStatusError as err:
        if err.response.status_code == self.TRACKER_NOT_RUNNING:
            return None
        raise

    return response if isinstance(response, TogglTracker) else None

get_trackers(since: Optional[int | datetime] = None, before: Optional[date] = None, start_date: Optional[date] = None, end_date: Optional[date] = None, *, refresh: bool = False) -> list[TogglTracker]

Get a set of trackers depending on specified parameters.

Parameters:

  • since (Optional[int | datetime], default: None ) –

    Get entries modified since this date using UNIX timestamp, including deleted ones.

  • before (Optional[date], default: None ) –

    Get entries with start time, before given date (YYYY-MM-DD) or with time in RFC3339 format.

  • start_date (Optional[date], default: None ) –

    Get entries with start time, from start_date YYYY-MM-DD or with time in RFC3339 format. To be used with end_date.

  • end_date (Optional[date], default: None ) –

    Get entries with start time, until end_date YYYY-MM-DD or with time in RFC3339 format. To be used with start_date.

  • refresh (bool, default: False ) –

    Whether to refresh the cache or not.

Returns:

  • list[TogglTracker]

    list[TogglTracker]: List of TogglTracker objects that are within specified parameters. Empty if none matched.

Source code in toggl_api/modules/user.py
25
26
27
28
29
30
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
57
58
59
60
61
62
def get_trackers(
    self,
    since: Optional[int | datetime] = None,
    before: Optional[date] = None,
    start_date: Optional[date] = None,
    end_date: Optional[date] = None,
    *,
    refresh: bool = False,
) -> list[TogglTracker]:
    """Get a set of trackers depending on specified parameters.

    Args:
        since: Get entries modified since this date using UNIX timestamp,
            including deleted ones.
        before: Get entries with start time, before given date (YYYY-MM-DD)
            or with time in RFC3339 format.
        start_date: Get entries with start time, from start_date YYYY-MM-DD
            or with time in RFC3339 format. To be used with end_date.
        end_date: Get entries with start time, until end_date YYYY-MM-DD or
            with time in RFC3339 format. To be used with start_date.
        refresh: Whether to refresh the cache or not.

    Returns:
        list[TogglTracker]: List of TogglTracker objects that are within
            specified parameters. Empty if none matched.
    """

    params = "time_entries"
    if since and before:
        params = f"?since={since}&before={before}"
    elif start_date and end_date:
        params = f"?start_date={start_date}&end_date={end_date}"
    response = self.request(params, refresh=refresh)

    # TODO: Need to filter cached trackers.
    # TODO: Implement sorting of trackers.

    return response if isinstance(response, list) else []  # type: ignore[return-value]

get_tracker(tracker_id: int | TogglTracker, *, refresh: bool = False) -> Optional[TogglTracker]

Get a single tracker by ID.

Parameters:

  • tracker_id (int | TogglTracker) –

    ID of the tracker to get.

  • refresh (bool, default: False ) –

    Whether to refresh the cache or not.

Returns:

  • Optional[TogglTracker]

    TogglTracker | None: TogglTracker object or None if not found.

Source code in toggl_api/modules/user.py
64
65
66
67
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
def get_tracker(
    self,
    tracker_id: int | TogglTracker,
    *,
    refresh: bool = False,
) -> Optional[TogglTracker]:
    """Get a single tracker by ID.

    Args:
        tracker_id: ID of the tracker to get.
        refresh: Whether to refresh the cache or not.

    Returns:
        TogglTracker | None: TogglTracker object or None if not found.
    """
    if isinstance(tracker_id, TogglTracker):
        tracker_id = tracker_id.id

    if not refresh:
        tracker = self.cache.find_entry({"id": tracker_id})
        if isinstance(tracker, TogglTracker):
            return tracker
        refresh = True
    try:
        response = self.request(
            f"time_entries/{tracker_id}",
            refresh=refresh,
        )
    except HTTPStatusError as err:
        if err.response.status_code == self.NOT_FOUND:
            return None
        raise

    return response  # type: ignore[return-value]

check_authentication() -> bool

Check if user is correctly authenticated with the Toggl API.

Source code in toggl_api/modules/user.py
 99
100
101
102
103
104
105
106
def check_authentication(self) -> bool:
    """Check if user is correctly authenticated with the Toggl API."""
    try:
        TogglCachedEndpoint.request(self, "logged")
    except HTTPError:
        return False

    return True