Skip to content

Endpoint

toggl_api.meta.RequestMethod

Bases: Enum

Describing the different request types primarily for selecting request methods.

Source code in src/toggl_api/meta/_enums.py
 4
 5
 6
 7
 8
 9
10
11
class RequestMethod(enum.Enum):
    """Describing the different request types primarily for selecting request methods."""

    GET = enum.auto()
    POST = enum.auto()
    PUT = enum.auto()
    DELETE = enum.auto()
    PATCH = enum.auto()

toggl_api.meta.TogglEndpoint

Bases: ABC, Generic[T]

Base class with basic functionality for all API requests.

ATTRIBUTE DESCRIPTION
BASE_ENDPOINT

Base URL of the Toggl API.

TYPE: str

HEADERS

Default headers that the API requires for most endpoints.

TYPE: Final[Headers]

client

Httpx client that is used for making requests to the API.

PARAMETER DESCRIPTION
auth

Authentication for the client.

TYPE: BasicAuth

client

Optional client to be passed to be used for requests. Useful when a global client is used and needs to be recycled.

TYPE: Client | None DEFAULT: None

timeout

How long it takes for the client to timeout. Keyword Only. Defaults to 10 seconds.

TYPE: Timeout | int DEFAULT: 10

re_raise

Whether to raise all HTTPStatusError errors and not handle them internally. Keyword Only.

TYPE: bool DEFAULT: False

retries

Max retries to attempt if the server returns a 5xx status_code. Has no effect if re_raise is True. Keyword Only.

TYPE: int DEFAULT: 3

METHOD DESCRIPTION
request

Request & handle data from the Toggl API.

process_models
api_status

Verify that the Toggl API is up.

Source code in src/toggl_api/meta/_base_endpoint.py
 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
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
class TogglEndpoint(ABC, Generic[T]):
    """Base class with basic functionality for all API requests.

    Attributes:
        BASE_ENDPOINT: Base URL of the Toggl API.
        HEADERS: Default headers that the API requires for most endpoints.
        client: Httpx client that is used for making requests to the API.

    Params:
        auth: Authentication for the client.
        client: Optional client to be passed to be used for requests. Useful
            when a global client is used and needs to be recycled.
        timeout: How long it takes for the client to timeout. Keyword Only.
            Defaults to 10 seconds.
        re_raise: Whether to raise all HTTPStatusError errors and not handle them
            internally. Keyword Only.
        retries: Max retries to attempt if the server returns a *5xx* status_code.
            Has no effect if re_raise is `True`. Keyword Only.
    """

    BASE_ENDPOINT: ClassVar[str] = "https://api.track.toggl.com/api/v9/"
    HEADERS: Final[Headers] = Headers({"content-type": "application/json"})
    MODEL: type[T] | None = None

    __slots__ = ("client", "re_raise", "retries", "workspace_id")

    def __init__(
        self,
        auth: BasicAuth,
        *,
        client: Client | None = None,
        timeout: Timeout | int = 10,
        re_raise: bool = False,
        retries: int = 3,
    ) -> None:
        self.re_raise = re_raise
        self.retries = max(0, retries)

        # NOTE: USES BASE_ENDPOINT instead of endpoint property for base_url
        # as current httpx concatenation is causing appended slashes.
        self.client = client = client or Client()
        client.auth = auth
        client.base_url = self.BASE_ENDPOINT  # type: ignore[assignment] # NOTE: Setter accepts strings.
        client.timeout = timeout if isinstance(timeout, Timeout) else Timeout(timeout)

        atexit.register(self.client.close)

    def _request_handle_error(
        self,
        response: Response,
        body: dict[str, Any] | list[dict[str, Any]] | None,
        headers: Headers | None,
        method: RequestMethod,
        parameters: str,
        *,
        raw: bool,
        retries: int,
    ) -> T | list[T] | Response | None:
        msg = "Request failed with status code %s: %s"
        log.error(msg, response.status_code, response.text)

        if not self.re_raise and codes.is_server_error(response.status_code) and retries:
            delay = random.randint(1, 5)
            retries -= 1
            log.error(
                ("Status code %s is a server error. Retrying request in %s seconds. There are %s retries left."),
                response.status_code,
                delay,
                retries,
            )
            # NOTE: According to https://engineering.toggl.com/docs/#generic-responses
            time.sleep(delay)
            return TogglEndpoint.request(
                self,
                parameters,
                headers,
                body,
                method,
                raw=raw,
                retries=retries,
            )

        return response.raise_for_status()

    def _process_response(
        self,
        response: Response,
        *,
        raw: bool,
    ) -> T | list[T] | Response | None:
        try:
            data = response if raw else response.json()
        except ValueError:
            return None

        if self.MODEL is None or raw:
            return data

        if isinstance(data, list):
            data = self.process_models(data)
        elif isinstance(data, dict):
            data = self.MODEL.from_kwargs(**data)

        return data

    def _build_request(
        self,
        parameters: str,
        headers: Headers | None,
        body: dict[str, Any] | list[dict[str, Any]] | None,
        method: RequestMethod,
    ) -> Request:
        url = self.BASE_ENDPOINT + parameters
        headers = headers or self.HEADERS

        requires_body = method not in {RequestMethod.DELETE, RequestMethod.GET}
        return self.client.build_request(
            method.name.lower(),
            url,
            headers=headers,
            json=body if requires_body else None,
        )

    def request(
        self,
        parameters: str,
        headers: Headers | None = None,
        body: dict[str, Any] | list[dict[str, Any]] | None = None,
        method: RequestMethod = RequestMethod.GET,
        *,
        raw: bool = False,
        retries: int | None = None,
    ) -> T | list[T] | Response | None:
        """Request & handle data from the Toggl API.

        Args:
            parameters (str): Request parameters with the endpoint excluded.
                Will concate with the endpoint property.
            headers (dict, optional): Custom request headers. Defaults to
                class property if set to None.
            body (dict | list, optional): Request body JSON data for specifying info.
                Defaults to None. Only used with none-GET or DELETE requests.
            method (RequestMethod): Request method to select. Defaults to GET.
            raw (bool): Whether to use the raw data. Defaults to False.
            retries (int): For recursive calls if the server fails multiple times.

        Raises:
            HTTPStatusError: If the request is not a success.

        Returns:
            Response data or None if request does not return any data.
        """
        if retries is None:
            retries = self.retries

        request = self._build_request(parameters, headers, body, method)
        response = self.client.send(request)

        if codes.is_error(response.status_code):
            return self._request_handle_error(
                response,
                body,
                headers,
                method,
                parameters,
                raw=raw,
                retries=retries,
            )

        return self._process_response(response, raw=raw)

    @classmethod
    def process_models(cls, data: list[dict[str, Any]]) -> list[T]:
        from_kwargs = cast("type[T]", cls.MODEL).from_kwargs
        return [from_kwargs(**mdl) for mdl in data]

    @staticmethod
    def api_status() -> bool:
        """Verify that the Toggl API is up.

        Returns:
            True if the API is up.
        """
        try:
            result = httpx.get(
                "https://api.track.toggl.com/api/v9/status",
            ).json()
        except (HTTPStatusError, JSONDecodeError):
            log.critical("Failed to get a response from the Toggl API!")
            log.exception("%s")
            return False

        return bool(result) and result.get("status") == "OK"

request

request(
    parameters: str,
    headers: Headers | None = None,
    body: dict[str, Any] | list[dict[str, Any]] | None = None,
    method: RequestMethod = GET,
    *,
    raw: bool = False,
    retries: int | None = None,
) -> T | list[T] | Response | None

Request & handle data from the Toggl API.

PARAMETER DESCRIPTION
parameters

Request parameters with the endpoint excluded. Will concate with the endpoint property.

TYPE: str

headers

Custom request headers. Defaults to class property if set to None.

TYPE: dict DEFAULT: None

body

Request body JSON data for specifying info. Defaults to None. Only used with none-GET or DELETE requests.

TYPE: dict | list DEFAULT: None

method

Request method to select. Defaults to GET.

TYPE: RequestMethod DEFAULT: GET

raw

Whether to use the raw data. Defaults to False.

TYPE: bool DEFAULT: False

retries

For recursive calls if the server fails multiple times.

TYPE: int DEFAULT: None

RAISES DESCRIPTION
HTTPStatusError

If the request is not a success.

RETURNS DESCRIPTION
T | list[T] | Response | None

Response data or None if request does not return any data.

Source code in src/toggl_api/meta/_base_endpoint.py
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
def request(
    self,
    parameters: str,
    headers: Headers | None = None,
    body: dict[str, Any] | list[dict[str, Any]] | None = None,
    method: RequestMethod = RequestMethod.GET,
    *,
    raw: bool = False,
    retries: int | None = None,
) -> T | list[T] | Response | None:
    """Request & handle data from the Toggl API.

    Args:
        parameters (str): Request parameters with the endpoint excluded.
            Will concate with the endpoint property.
        headers (dict, optional): Custom request headers. Defaults to
            class property if set to None.
        body (dict | list, optional): Request body JSON data for specifying info.
            Defaults to None. Only used with none-GET or DELETE requests.
        method (RequestMethod): Request method to select. Defaults to GET.
        raw (bool): Whether to use the raw data. Defaults to False.
        retries (int): For recursive calls if the server fails multiple times.

    Raises:
        HTTPStatusError: If the request is not a success.

    Returns:
        Response data or None if request does not return any data.
    """
    if retries is None:
        retries = self.retries

    request = self._build_request(parameters, headers, body, method)
    response = self.client.send(request)

    if codes.is_error(response.status_code):
        return self._request_handle_error(
            response,
            body,
            headers,
            method,
            parameters,
            raw=raw,
            retries=retries,
        )

    return self._process_response(response, raw=raw)

process_models classmethod

process_models(data: list[dict[str, Any]]) -> list[T]
Source code in src/toggl_api/meta/_base_endpoint.py
217
218
219
220
@classmethod
def process_models(cls, data: list[dict[str, Any]]) -> list[T]:
    from_kwargs = cast("type[T]", cls.MODEL).from_kwargs
    return [from_kwargs(**mdl) for mdl in data]

api_status staticmethod

api_status() -> bool

Verify that the Toggl API is up.

RETURNS DESCRIPTION
bool

True if the API is up.

Source code in src/toggl_api/meta/_base_endpoint.py
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
@staticmethod
def api_status() -> bool:
    """Verify that the Toggl API is up.

    Returns:
        True if the API is up.
    """
    try:
        result = httpx.get(
            "https://api.track.toggl.com/api/v9/status",
        ).json()
    except (HTTPStatusError, JSONDecodeError):
        log.critical("Failed to get a response from the Toggl API!")
        log.exception("%s")
        return False

    return bool(result) and result.get("status") == "OK"

toggl_api.asyncio.TogglAsyncEndpoint

Bases: ABC, Generic[T]

Base class with basic functionality for all async API requests.

ATTRIBUTE DESCRIPTION
BASE_ENDPOINT

Base URL of the Toggl API.

TYPE: URL

HEADERS

Default headers that the API requires for most endpoints.

TYPE: Final[Headers]

client

Async httpx client that is used for making requests to the API.

PARAMETER DESCRIPTION
auth

Authentication for the client.

TYPE: BasicAuth

client

Optional async client to be passed to be used for requests.

TYPE: AsyncClient | None DEFAULT: None

timeout

How long it takes for the client to timeout. Keyword Only. Defaults to 10 seconds.

TYPE: Timeout | int DEFAULT: 10

re_raise

Whether to raise all HTTPStatusError errors and not handle them internally. Keyword Only.

TYPE: bool DEFAULT: False

retries

Max retries to attempt if the server returns a 5xx status_code. Has no effect if re_raise is True. Keyword Only.

TYPE: int DEFAULT: 3

METHOD DESCRIPTION
api_status

Verify that the Toggl API is up.

api_status async staticmethod

api_status() -> bool

Verify that the Toggl API is up.

RETURNS DESCRIPTION
bool

True if the API is up.


toggl_api.meta.TogglCachedEndpoint

Bases: TogglEndpoint[T]

Abstract cached endpoint for requesting toggl API data to disk.

See parent endpoint for more details.

PARAMETER DESCRIPTION
auth

Authentication for the client.

TYPE: BasicAuth

cache

Cache object for caching toggl API data to disk. Builtin cache types are JSONCache and SqliteCache.

TYPE: TogglCache[T] | None DEFAULT: None

client

Optional client to be passed to be used for requests. Useful when a global client is used and needs to be recycled.

TYPE: Client | None DEFAULT: None

timeout

How long it takes for the client to timeout. Keyword Only. Defaults to 10 seconds.

TYPE: Timeout | int DEFAULT: 10

re_raise

Whether to raise all HTTPStatusError errors and not handle them internally. Keyword Only.

TYPE: bool DEFAULT: False

retries

Max retries to attempt if the server returns a 5xx status_code. Has no effect if re_raise is True. Keyword Only.

TYPE: int DEFAULT: 3

ATTRIBUTE DESCRIPTION
cache

Cache object the endpoint will use for storing models. Assigns itself as the parent automatically.

TYPE: TogglCache[T] | None

METHOD DESCRIPTION
request

Overriden method that implements the cache into the request chain.

load_cache

Method for loading cache into memory.

save_cache

Method for saving cache to disk. Ignored if expiry is set to 0 seconds.

query

Wrapper method for accessing querying capabilities within the assigned cache.

Source code in src/toggl_api/meta/_cached_endpoint.py
 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
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
class TogglCachedEndpoint(TogglEndpoint[T]):
    """Abstract cached endpoint for requesting toggl API data to disk.

    See parent endpoint for more details.

    Params:
        auth: Authentication for the client.
        cache: Cache object for caching toggl API data to disk. Builtin cache
            types are JSONCache and SqliteCache.
        client: Optional client to be passed to be used for requests. Useful
            when a global client is used and needs to be recycled.
        timeout: How long it takes for the client to timeout. Keyword Only.
            Defaults to 10 seconds.
        re_raise: Whether to raise all HTTPStatusError errors and not handle them
            internally. Keyword Only.
        retries: Max retries to attempt if the server returns a *5xx* status_code.
            Has no effect if re_raise is `True`. Keyword Only.

    Attributes:
        cache: Cache object the endpoint will use for storing models. Assigns
            itself as the parent automatically.

    Methods:
        request: Overriden method that implements the cache into the request chain.
        load_cache: Method for loading cache into memory.
        save_cache: Method for saving cache to disk. Ignored if expiry is set
            to 0 seconds.
        query: Wrapper method for accessing querying capabilities within the
            assigned cache.
    """

    __slots__ = ("_cache",)

    def __init__(
        self,
        auth: BasicAuth,
        cache: TogglCache[T] | None = None,
        *,
        client: Client | None = None,
        timeout: Timeout | int = 10,
        re_raise: bool = False,
        retries: int = 3,
    ) -> None:
        super().__init__(
            auth=auth,
            client=client,
            timeout=timeout,
            re_raise=re_raise,
            retries=retries,
        )
        self.cache = cache

    def request(  # type: ignore[override]
        self,
        parameters: str,
        headers: Headers | None = None,
        body: dict[str, Any] | list[Any] | None = None,
        method: RequestMethod = RequestMethod.GET,
        *,
        refresh: bool = False,
        raw: bool = False,
    ) -> T | list[T] | Response | None:
        """Overridden request method with builtin cache.

        Args:
            parameters: Request parameters with the endpoint excluded.
            headers: Request headers. Custom headers can be added here.
            body: Request body for GET, POST, PUT, PATCH requests.
                Defaults to None.
            method: Request method. Defaults to GET.
            refresh: Whether to refresh the cache or not. Defaults to False.
            raw (bool): Whether to use the raw data. Defaults to False.

        Raises:
            HTTPStatusError: If the request is not a success.

        Returns:
            Toggl API response data processed into TogglClass objects or not
                depending on arguments.
        """
        data = self.load_cache() if self.cache and self.MODEL is not None else None
        if data and not refresh:
            log.info(
                "Loading request %s%s data from cache.",
                self.BASE_ENDPOINT,
                parameters,
                extra={"body": body, "headers": headers, "method": method},
            )
            return cast("list[T]", data)

        response = super().request(
            parameters,
            method=method,
            headers=headers,
            body=body,
            raw=raw,
        )
        if raw:
            return response

        if response is None or method == RequestMethod.DELETE:
            return None

        if self.cache and self.MODEL is not None:
            self.save_cache(response, method)  # type: ignore[arg-type]

        return response

    def load_cache(self) -> Iterable[T]:
        """Direct loading method for retrieving all models from cache.

        Raises:
            NoCacheAssignedError: If no cache is assigned to the endpoint.

        Returns:
            An iterable of models that have been previously saved.
        """
        if self.cache is None:
            raise NoCacheAssignedError

        return self.cache.load()

    def save_cache(
        self,
        response: list[T] | T,
        method: RequestMethod,
    ) -> None:
        """Direct saving method for retrieving all models from cache.

        Args:
            response: A list of values or single value to save.
            method: To method to use when updating the cache.

        Raises:
            NoCacheAssignedError: If no cache is assigned to the endpoint.
        """
        if self.cache is None:
            raise NoCacheAssignedError
        if isinstance(self.cache.expire_after, timedelta) and not self.cache.expire_after.total_seconds():
            log.debug(
                "Cache is set to immediately expire!",
                extra={"expiry": self.cache.expire_after},
            )
            return None
        return self.cache.save(response, method)

    def query(
        self,
        *query: TogglQuery[Any],
        distinct: bool = False,
    ) -> list[T]:
        """Query wrapper for the cache method.

        If the original data structure is required use the query on the
        *.cache* attribute instead.

        Args:
            *query: An arbitary amount of queries to match the models to.
            distinct: A boolean that remove duplicate values if present.

        Raises:
            NoCacheAssignedError: If the current cache is set to None.

        Returns:
            A list objects depending on the endpoint.
        """
        if self.cache is None:
            raise NoCacheAssignedError
        return list(self.cache.query(*query, distinct=distinct))

    @property
    def cache(self) -> TogglCache[T] | None:
        return self._cache

    @cache.setter
    def cache(self, value: TogglCache[T] | None) -> None:
        self._cache = value
        if self.cache and self.cache._parent is not self:  # noqa: SLF001
            self.cache.parent = self

cache property writable

cache: TogglCache[T] | None

request

request(
    parameters: str,
    headers: Headers | None = None,
    body: dict[str, Any] | list[Any] | None = None,
    method: RequestMethod = GET,
    *,
    refresh: bool = False,
    raw: bool = False,
) -> T | list[T] | Response | None

Overridden request method with builtin cache.

PARAMETER DESCRIPTION
parameters

Request parameters with the endpoint excluded.

TYPE: str

headers

Request headers. Custom headers can be added here.

TYPE: Headers | None DEFAULT: None

body

Request body for GET, POST, PUT, PATCH requests. Defaults to None.

TYPE: dict[str, Any] | list[Any] | None DEFAULT: None

method

Request method. Defaults to GET.

TYPE: RequestMethod DEFAULT: GET

refresh

Whether to refresh the cache or not. Defaults to False.

TYPE: bool DEFAULT: False

raw

Whether to use the raw data. Defaults to False.

TYPE: bool DEFAULT: False

RAISES DESCRIPTION
HTTPStatusError

If the request is not a success.

RETURNS DESCRIPTION
T | list[T] | Response | None

Toggl API response data processed into TogglClass objects or not depending on arguments.

Source code in src/toggl_api/meta/_cached_endpoint.py
 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
def request(  # type: ignore[override]
    self,
    parameters: str,
    headers: Headers | None = None,
    body: dict[str, Any] | list[Any] | None = None,
    method: RequestMethod = RequestMethod.GET,
    *,
    refresh: bool = False,
    raw: bool = False,
) -> T | list[T] | Response | None:
    """Overridden request method with builtin cache.

    Args:
        parameters: Request parameters with the endpoint excluded.
        headers: Request headers. Custom headers can be added here.
        body: Request body for GET, POST, PUT, PATCH requests.
            Defaults to None.
        method: Request method. Defaults to GET.
        refresh: Whether to refresh the cache or not. Defaults to False.
        raw (bool): Whether to use the raw data. Defaults to False.

    Raises:
        HTTPStatusError: If the request is not a success.

    Returns:
        Toggl API response data processed into TogglClass objects or not
            depending on arguments.
    """
    data = self.load_cache() if self.cache and self.MODEL is not None else None
    if data and not refresh:
        log.info(
            "Loading request %s%s data from cache.",
            self.BASE_ENDPOINT,
            parameters,
            extra={"body": body, "headers": headers, "method": method},
        )
        return cast("list[T]", data)

    response = super().request(
        parameters,
        method=method,
        headers=headers,
        body=body,
        raw=raw,
    )
    if raw:
        return response

    if response is None or method == RequestMethod.DELETE:
        return None

    if self.cache and self.MODEL is not None:
        self.save_cache(response, method)  # type: ignore[arg-type]

    return response

load_cache

load_cache() -> Iterable[T]

Direct loading method for retrieving all models from cache.

RAISES DESCRIPTION
NoCacheAssignedError

If no cache is assigned to the endpoint.

RETURNS DESCRIPTION
Iterable[T]

An iterable of models that have been previously saved.

Source code in src/toggl_api/meta/_cached_endpoint.py
146
147
148
149
150
151
152
153
154
155
156
157
158
def load_cache(self) -> Iterable[T]:
    """Direct loading method for retrieving all models from cache.

    Raises:
        NoCacheAssignedError: If no cache is assigned to the endpoint.

    Returns:
        An iterable of models that have been previously saved.
    """
    if self.cache is None:
        raise NoCacheAssignedError

    return self.cache.load()

save_cache

save_cache(response: list[T] | T, method: RequestMethod) -> None

Direct saving method for retrieving all models from cache.

PARAMETER DESCRIPTION
response

A list of values or single value to save.

TYPE: list[T] | T

method

To method to use when updating the cache.

TYPE: RequestMethod

RAISES DESCRIPTION
NoCacheAssignedError

If no cache is assigned to the endpoint.

Source code in src/toggl_api/meta/_cached_endpoint.py
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
def save_cache(
    self,
    response: list[T] | T,
    method: RequestMethod,
) -> None:
    """Direct saving method for retrieving all models from cache.

    Args:
        response: A list of values or single value to save.
        method: To method to use when updating the cache.

    Raises:
        NoCacheAssignedError: If no cache is assigned to the endpoint.
    """
    if self.cache is None:
        raise NoCacheAssignedError
    if isinstance(self.cache.expire_after, timedelta) and not self.cache.expire_after.total_seconds():
        log.debug(
            "Cache is set to immediately expire!",
            extra={"expiry": self.cache.expire_after},
        )
        return None
    return self.cache.save(response, method)

query

query(*query: TogglQuery[Any], distinct: bool = False) -> list[T]

Query wrapper for the cache method.

If the original data structure is required use the query on the .cache attribute instead.

PARAMETER DESCRIPTION
*query

An arbitary amount of queries to match the models to.

TYPE: TogglQuery[Any] DEFAULT: ()

distinct

A boolean that remove duplicate values if present.

TYPE: bool DEFAULT: False

RAISES DESCRIPTION
NoCacheAssignedError

If the current cache is set to None.

RETURNS DESCRIPTION
list[T]

A list objects depending on the endpoint.

Source code in src/toggl_api/meta/_cached_endpoint.py
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
def query(
    self,
    *query: TogglQuery[Any],
    distinct: bool = False,
) -> list[T]:
    """Query wrapper for the cache method.

    If the original data structure is required use the query on the
    *.cache* attribute instead.

    Args:
        *query: An arbitary amount of queries to match the models to.
        distinct: A boolean that remove duplicate values if present.

    Raises:
        NoCacheAssignedError: If the current cache is set to None.

    Returns:
        A list objects depending on the endpoint.
    """
    if self.cache is None:
        raise NoCacheAssignedError
    return list(self.cache.query(*query, distinct=distinct))

toggl_api.asyncio.TogglAsyncCachedEndpoint

Bases: TogglAsyncEndpoint[T]

Abstract cached endpoint for requesting toggl API data to disk.

See parent endpoint for more details.

PARAMETER DESCRIPTION
auth

Authentication for the client.

TYPE: BasicAuth

cache

Cache object for caching toggl API data to disk. AsyncSqlitecache only available for now.

TYPE: AsyncSqliteCache[T] | None DEFAULT: None

client

Optional async client to be passed to be used for requests.

TYPE: AsyncClient | None DEFAULT: None

timeout

How long it takes for the client to timeout. Keyword Only. Defaults to 10 seconds.

TYPE: int DEFAULT: 10

re_raise

Whether to raise all HTTPStatusError errors and not handle them internally. Keyword Only.

TYPE: bool DEFAULT: False

retries

Max retries to attempt if the server returns a 5xx status_code. Has no effect if re_raise is True. Keyword Only.

TYPE: int DEFAULT: 3

ATTRIBUTE DESCRIPTION
cache

Cache object the endpoint will use for storing models. Assigns itself as the parent automatically.

TYPE: AsyncSqliteCache[T] | None

client

Async httpx client that is used for making requests to the API.

METHOD DESCRIPTION
request

Overriden method that implements the cache into the request chain.

load_cache

Method for loading cache into memory.

save_cache

Method for saving cache to disk. Ignored if expiry is set to 0 seconds.

request async

request(
    parameters: str,
    headers: Headers | None = None,
    body: dict[str, Any] | list[Any] | None = None,
    method: RequestMethod = GET,
    *,
    refresh: bool = False,
    raw: bool = False,
) -> T | list[T] | Response | None

Overridden request method with builtin cache.

PARAMETER DESCRIPTION
parameters

Request parameters with the endpoint excluded.

TYPE: str

headers

Request headers. Custom headers can be added here.

TYPE: Headers | None DEFAULT: None

body

Request body for GET, POST, PUT, PATCH requests. Defaults to None.

TYPE: dict[str, Any] | list[Any] | None DEFAULT: None

method

Request method. Defaults to GET.

TYPE: RequestMethod DEFAULT: GET

refresh

Whether to refresh the cache or not. Defaults to False.

TYPE: bool DEFAULT: False

raw

Whether to use the raw data. Defaults to False.

TYPE: bool DEFAULT: False

RAISES DESCRIPTION
HTTPStatusError

If the request is not a success.

RETURNS DESCRIPTION
T | list[T] | Response | None

Toggl API response data processed into TogglClass objects or not depending on arguments.

load_cache async

load_cache() -> Iterable[T]

Direct loading method for retrieving all models from cache.

RAISES DESCRIPTION
NoCacheAssignedError

If no cache is assigned to the endpoint.

RETURNS DESCRIPTION
Iterable[T]

Previously cached objects.

save_cache async

save_cache(response: list[T] | T, method: RequestMethod) -> None

Save all provided models to cache.

PARAMETER DESCRIPTION
response

A list of values or single value to save.

TYPE: list[T] | T

method

To method to use when updating the cache.

TYPE: RequestMethod

RAISES DESCRIPTION
NoCacheAssignedError

If no cache is assigned to the endpoint.