Skip to content

toggl_api.WorkspaceBody dataclass

Bases: BaseBody

METHOD DESCRIPTION
format

Format the body into a usable format for a request.

ATTRIBUTE DESCRIPTION
name

Name of the workspace. Check TogglWorkspace static method for validation.

TYPE: str | None

admins

List of admins, optional.

TYPE: list[int]

only_admins_may_create_projects

Only admins will be able to create projects, optional,

TYPE: bool

only_admins_may_create_tags

Only admins will be able to create tags, optional,

TYPE: bool

only_admins_see_billable_rates

Whether only admins will be able to see billable rates, premium feature,

TYPE: bool

only_admins_see_team_dashboard

Only admins will be able to see the team dashboard, optional,

TYPE: bool

projects_billable_by_default

Whether projects will be set as billable by default, premium feature,

TYPE: bool

projects_enforce_billable

Whether tracking time to projects will enforce billable setting to be respected.

TYPE: bool

projects_private_by_default

Whether projects will be set to private by default, optional.

TYPE: bool

rate_change_mode

The rate change mode, premium feature, optional, only for existing WS.

TYPE: Literal['start-today', 'override-current', 'override-all'] | None

reports_collapse

Whether reports should be collapsed by default, optional,

TYPE: bool

rounding

Default rounding, premium feature, optional, only for existing WS

TYPE: int | None

rounding_minutes

Default rounding in minutes, premium feature, optional, only for existing WS

TYPE: int | None

Source code in src/toggl_api/_workspace.py
 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
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
@dataclass
class WorkspaceBody(BaseBody):
    name: str | None = field(default=None)
    """Name of the workspace. Check TogglWorkspace static method for validation."""

    admins: list[int] = field(
        default_factory=list,
        metadata={
            "endpoints": frozenset(("add", "edit")),
        },
    )
    """List of admins, optional."""

    only_admins_may_create_projects: bool = field(
        default=False,
        metadata={
            "endpoints": frozenset(("add", "edit")),
        },
    )
    """Only admins will be able to create projects, optional,
    only for existing WS, will be false initially"""

    only_admins_may_create_tags: bool = field(
        default=False,
        metadata={
            "endpoints": frozenset(("add", "edit")),
        },
    )
    """Only admins will be able to create tags, optional,
    only for existing WS, will be false initially"""

    only_admins_see_billable_rates: bool = field(
        default=False,
        metadata={
            "endpoints": frozenset(("add", "edit")),
        },
    )
    """Whether only admins will be able to see billable rates, premium feature,
    optional, only for existing WS. Will be false initially"""

    only_admins_see_team_dashboard: bool = field(
        default=False,
        metadata={
            "endpoints": frozenset(("add", "edit")),
        },
    )
    """Only admins will be able to see the team dashboard, optional,
    only for existing WS, will be false initially"""

    projects_billable_by_default: bool = field(
        default=False,
        metadata={
            "endpoints": frozenset(("add", "edit")),
        },
    )
    """Whether projects will be set as billable by default, premium feature,
    optional, only for existing WS. Will be true initially"""

    projects_enforce_billable: bool = field(
        default=False,
        metadata={
            "endpoints": frozenset(("add", "edit")),
        },
    )
    """Whether tracking time to projects will enforce billable setting to be respected."""

    projects_private_by_default: bool = field(
        default=False,
        metadata={
            "endpoints": frozenset(("add", "edit")),
        },
    )
    """Whether projects will be set to private by default, optional.
    Will be true initially."""

    rate_change_mode: Literal["start-today", "override-current", "override-all"] | None = field(
        default=None,
        metadata={
            "endpoints": frozenset(("add", "edit")),
        },
    )
    """The rate change mode, premium feature, optional, only for existing WS.
    Can be 'start-today', 'override-current', 'override-all'"""

    reports_collapse: bool = field(
        default=False,
        metadata={
            "endpoints": frozenset(("add", "edit")),
        },
    )
    """Whether reports should be collapsed by default, optional,
    only for existing WS, will be true initially"""

    rounding: int | None = field(
        default=None,
        metadata={
            "endpoints": frozenset(("add", "edit")),
        },
    )
    """Default rounding, premium feature, optional, only for existing WS"""

    rounding_minutes: int | None = field(
        default=None,
        metadata={
            "endpoints": frozenset(("add", "edit")),
        },
    )
    """Default rounding in minutes, premium feature, optional, only for existing WS"""

    def __post_init__(self) -> None:
        if self.name:
            try:
                TogglWorkspace.validate_name(self.name)
            except NamingError as err:
                if str(err) != "No spaces allowed in the workspace name!":
                    raise
                log.warning(err)
                self.name = self.name.replace(" ", "-")
                log.warning("Updated to new name: %s!", self.name)

    def format(self, endpoint: str, **body: Any) -> dict[str, Any]:
        """Format the body into a usable format for a request.

        Gets called form within an endpoint method.

        Args:
            endpoint: Which endpoint to target.
            body: Prefilled body with extra arguments.

        Returns:
            A JSON body with the relevant parameters prefilled.
        """
        for fld in fields(self):
            if not self._verify_endpoint_parameter(fld.name, endpoint):
                continue

            value = getattr(self, fld.name)
            if not value:
                continue

            body[fld.name] = value

        return body

name class-attribute instance-attribute

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

Name of the workspace. Check TogglWorkspace static method for validation.

admins class-attribute instance-attribute

admins: list[int] = field(
    default_factory=list, metadata={"endpoints": frozenset(("add", "edit"))}
)

List of admins, optional.

only_admins_may_create_projects class-attribute instance-attribute

only_admins_may_create_projects: bool = field(
    default=False, metadata={"endpoints": frozenset(("add", "edit"))}
)

Only admins will be able to create projects, optional, only for existing WS, will be false initially

only_admins_may_create_tags class-attribute instance-attribute

only_admins_may_create_tags: bool = field(
    default=False, metadata={"endpoints": frozenset(("add", "edit"))}
)

Only admins will be able to create tags, optional, only for existing WS, will be false initially

only_admins_see_billable_rates class-attribute instance-attribute

only_admins_see_billable_rates: bool = field(
    default=False, metadata={"endpoints": frozenset(("add", "edit"))}
)

Whether only admins will be able to see billable rates, premium feature, optional, only for existing WS. Will be false initially

only_admins_see_team_dashboard class-attribute instance-attribute

only_admins_see_team_dashboard: bool = field(
    default=False, metadata={"endpoints": frozenset(("add", "edit"))}
)

Only admins will be able to see the team dashboard, optional, only for existing WS, will be false initially

projects_billable_by_default class-attribute instance-attribute

projects_billable_by_default: bool = field(
    default=False, metadata={"endpoints": frozenset(("add", "edit"))}
)

Whether projects will be set as billable by default, premium feature, optional, only for existing WS. Will be true initially

projects_enforce_billable class-attribute instance-attribute

projects_enforce_billable: bool = field(
    default=False, metadata={"endpoints": frozenset(("add", "edit"))}
)

Whether tracking time to projects will enforce billable setting to be respected.

projects_private_by_default class-attribute instance-attribute

projects_private_by_default: bool = field(
    default=False, metadata={"endpoints": frozenset(("add", "edit"))}
)

Whether projects will be set to private by default, optional. Will be true initially.

rate_change_mode class-attribute instance-attribute

rate_change_mode: (
    Literal["start-today", "override-current", "override-all"] | None
) = field(default=None, metadata={"endpoints": frozenset(("add", "edit"))})

The rate change mode, premium feature, optional, only for existing WS. Can be 'start-today', 'override-current', 'override-all'

reports_collapse class-attribute instance-attribute

reports_collapse: bool = field(
    default=False, metadata={"endpoints": frozenset(("add", "edit"))}
)

Whether reports should be collapsed by default, optional, only for existing WS, will be true initially

rounding class-attribute instance-attribute

rounding: int | None = field(
    default=None, metadata={"endpoints": frozenset(("add", "edit"))}
)

Default rounding, premium feature, optional, only for existing WS

rounding_minutes class-attribute instance-attribute

rounding_minutes: int | None = field(
    default=None, metadata={"endpoints": frozenset(("add", "edit"))}
)

Default rounding in minutes, premium feature, optional, only for existing WS

format

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

Format the body into a usable format for a request.

Gets called form within an endpoint method.

PARAMETER DESCRIPTION
endpoint

Which endpoint to target.

TYPE: str

body

Prefilled body with extra arguments.

TYPE: Any DEFAULT: {}

RETURNS DESCRIPTION
dict[str, Any]

A JSON body with the relevant parameters prefilled.

Source code in src/toggl_api/_workspace.py
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
def format(self, endpoint: str, **body: Any) -> dict[str, Any]:
    """Format the body into a usable format for a request.

    Gets called form within an endpoint method.

    Args:
        endpoint: Which endpoint to target.
        body: Prefilled body with extra arguments.

    Returns:
        A JSON body with the relevant parameters prefilled.
    """
    for fld in fields(self):
        if not self._verify_endpoint_parameter(fld.name, endpoint):
            continue

        value = getattr(self, fld.name)
        if not value:
            continue

        body[fld.name] = value

    return body

toggl_api.WorkspaceEndpoint

Bases: TogglCachedEndpoint[TogglWorkspace]

Specific endpoints for retrieving and modifying workspaces.

Official Documentation

Examples:

>>> org_id = 123213324
>>> workspace_endpoint = WorkspaceEndpoint(org_id, BasicAuth(...), SqliteCache(...))
PARAMETER DESCRIPTION
organization_id

Workspace endpoint takes an organization id instead of a workspace id.

TYPE: int | TogglOrganization

auth

Authentication for the client.

TYPE: BasicAuth

cache

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

TYPE: TogglCache[TogglWorkspace] | 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

METHOD DESCRIPTION
get

Get the current workspace based on an id or model.

add

Create a new workspace.

collect

List workspaces for given user.

edit

Update a specific workspace.

tracker_constraints

Get the time entry constraints for a given workspace.

statistics

Return workspace admins list, members count and groups count.

Source code in src/toggl_api/_workspace.py
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
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
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
class WorkspaceEndpoint(TogglCachedEndpoint[TogglWorkspace]):
    """Specific endpoints for retrieving and modifying workspaces.

    [Official Documentation](https://engineering.toggl.com/docs/api/workspaces)

    Examples:
        >>> org_id = 123213324
        >>> workspace_endpoint = WorkspaceEndpoint(org_id, BasicAuth(...), SqliteCache(...))

    Params:
        organization_id: Workspace endpoint takes an organization id instead of
            a workspace id.
        auth: Authentication for the client.
        cache: Cache object for caching toggl workspace 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.
    """

    MODEL = TogglWorkspace

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

    def get(
        self,
        workspace: TogglWorkspace | int,
        *,
        refresh: bool = False,
    ) -> TogglWorkspace | None:
        """Get the current workspace based on an id or model.

        [Official Documentation](https://engineering.toggl.com/docs/api/workspaces#get-get-single-workspace)

        Args:
            workspace: Workspace id or model.
            refresh: Whether to use cache or not.

        Raises:
            HTTPStatusError: If anything that's not a '2xx' or '404' status_code is returned.

        Returns:
            Model of workspace if found else none.
        """
        if isinstance(workspace, TogglWorkspace):
            workspace = workspace.id

        if self.cache and not refresh:
            return self.cache.find({"id": workspace})

        try:
            response = self.request(f"workspaces/{workspace}", refresh=refresh)
        except HTTPStatusError as err:
            log.exception("%s")
            if not self.re_raise and err.response.status_code == codes.NOT_FOUND:
                return None
            raise

        return cast("TogglWorkspace", response)

    def add(self, body: WorkspaceBody) -> TogglWorkspace:
        """Create a new workspace.

        [Official Documentation](https://engineering.toggl.com/docs/api/workspaces#post-create-a-new-workspace)

        Enterprise plan feature.

        Args:
            body: All settings for the workspace to be attached to as a body.

        Returns:
            A newly created workspace with the supplied params.
        """
        return cast(
            "TogglWorkspace",
            self.request(
                f"organizations/{self.organization_id}/workspaces",
                body=body.format("add", organization_id=self.organization_id),
                method=RequestMethod.POST,
                refresh=True,
            ),
        )

    def _collect_cache(self, since: int | None) -> list[TogglWorkspace]:
        if isinstance(since, int):
            ts = datetime.fromtimestamp(since, timezone.utc)
            return list(self.query(TogglQuery("timestamp", ts, Comparison.GREATER_THEN)))
        return list(self.load_cache())

    def _validate_collect_since(self, since: datetime | int) -> int:
        since = get_timestamp(since)
        now = int(time.mktime(datetime.now(tz=timezone.utc).timetuple()))
        if since > now:
            msg = "The 'since' argument needs to be before the current time!"
            raise DateTimeError(msg)
        return since

    def collect(
        self,
        since: datetime | int | None = None,
        *,
        refresh: bool = False,
    ) -> list[TogglWorkspace]:
        """List workspaces for given user.

        [Official Documentation](https://engineering.toggl.com/docs/api/me#get-workspaces)

        Args:
            since: Optional argument to filter any workspace after the timestamp.
            refresh: Whether to use cache or not.

        Raises:
            DateTimeError: If the since argument is after the current time.

        Returns:
            A list of workspaces or empty if there are None assocciated with the user.
        """
        if since is not None:
            since = self._validate_collect_since(since)

        if self.cache and not refresh:
            return self._collect_cache(since)

        body = {"since": since} if since else None

        return cast(
            "list[TogglWorkspace]",
            self.request("me/workspaces", body=body, refresh=refresh),
        )

    def edit(self, workspace_id: TogglWorkspace | int, body: WorkspaceBody) -> TogglWorkspace:
        """Update a specific workspace.

        [Official Documentation](https://engineering.toggl.com/docs/api/workspaces#put-update-workspace)

        Raises:
            HTTPStatusError: For anything thats not an *ok* status code.

        Returns:
            A workspace model with the supplied edits.
        """
        if isinstance(workspace_id, TogglWorkspace):
            workspace_id = workspace_id.id

        return cast(
            "TogglWorkspace",
            self.request(
                f"workspaces/{workspace_id}",
                body=body.format("edit"),
                method=RequestMethod.PUT,
                refresh=True,
            ),
        )

    def tracker_constraints(self, workspace_id: TogglWorkspace | int) -> dict[str, bool]:
        """Get the time entry constraints for a given workspace.

        [Official Documentation](https://engineering.toggl.com/docs/api/workspaces#get-get-workspace-time-entry-constraints)

        Toggl premium feature.

        Examples:
            >>> workspace_endpoint.get_workspace_constraints(24214214)
            {
                "description_present": True,
                "project_present": False,
                "tag_present": False",
                "task_present": False,
                "time_entry_constraints_enabled": True,
            }

        Args:
            workspace_id: Id of the workspace to retrieve constraints from.

        Returns:
            A dictionary of booleans containing the settings.
        """
        if isinstance(workspace_id, TogglWorkspace):
            workspace_id = workspace_id.id

        return cast(
            "dict[str, bool]",
            cast(
                "Response",
                self.request(
                    f"workspaces/{workspace_id}/time_entry_constraints",
                    raw=True,
                    refresh=True,
                ),
            ).json(),
        )

    def statistics(self, workspace_id: TogglWorkspace | int) -> WorkspaceStatistics:
        """Return workspace admins list, members count and groups count.

        [Official Documentation](https://api.track.toggl.com/api/v9/workspaces/{workspace_id}/statistics)

        Args:
            workspace_id: Id of the workspace to fetch the statistics from.

        Returns:
            A dictionary containing relevant statistics.
                Refer to WorkspaceStatistics typed dict for reference.
        """
        if isinstance(workspace_id, TogglWorkspace):
            workspace_id = workspace_id.id

        return cast(
            "WorkspaceStatistics",
            cast(
                "Response",
                self.request(
                    f"workspaces/{workspace_id}/statistics",
                    refresh=True,
                    raw=True,
                ),
            ).json(),
        )

get

get(
    workspace: TogglWorkspace | int, *, refresh: bool = False
) -> TogglWorkspace | None

Get the current workspace based on an id or model.

Official Documentation

PARAMETER DESCRIPTION
workspace

Workspace id or model.

TYPE: TogglWorkspace | int

refresh

Whether to use cache or not.

TYPE: bool DEFAULT: False

RAISES DESCRIPTION
HTTPStatusError

If anything that's not a '2xx' or '404' status_code is returned.

RETURNS DESCRIPTION
TogglWorkspace | None

Model of workspace if found else none.

Source code in src/toggl_api/_workspace.py
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
def get(
    self,
    workspace: TogglWorkspace | int,
    *,
    refresh: bool = False,
) -> TogglWorkspace | None:
    """Get the current workspace based on an id or model.

    [Official Documentation](https://engineering.toggl.com/docs/api/workspaces#get-get-single-workspace)

    Args:
        workspace: Workspace id or model.
        refresh: Whether to use cache or not.

    Raises:
        HTTPStatusError: If anything that's not a '2xx' or '404' status_code is returned.

    Returns:
        Model of workspace if found else none.
    """
    if isinstance(workspace, TogglWorkspace):
        workspace = workspace.id

    if self.cache and not refresh:
        return self.cache.find({"id": workspace})

    try:
        response = self.request(f"workspaces/{workspace}", refresh=refresh)
    except HTTPStatusError as err:
        log.exception("%s")
        if not self.re_raise and err.response.status_code == codes.NOT_FOUND:
            return None
        raise

    return cast("TogglWorkspace", response)

add

Create a new workspace.

Official Documentation

Enterprise plan feature.

PARAMETER DESCRIPTION
body

All settings for the workspace to be attached to as a body.

TYPE: WorkspaceBody

RETURNS DESCRIPTION
TogglWorkspace

A newly created workspace with the supplied params.

Source code in src/toggl_api/_workspace.py
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
def add(self, body: WorkspaceBody) -> TogglWorkspace:
    """Create a new workspace.

    [Official Documentation](https://engineering.toggl.com/docs/api/workspaces#post-create-a-new-workspace)

    Enterprise plan feature.

    Args:
        body: All settings for the workspace to be attached to as a body.

    Returns:
        A newly created workspace with the supplied params.
    """
    return cast(
        "TogglWorkspace",
        self.request(
            f"organizations/{self.organization_id}/workspaces",
            body=body.format("add", organization_id=self.organization_id),
            method=RequestMethod.POST,
            refresh=True,
        ),
    )

collect

collect(
    since: datetime | int | None = None, *, refresh: bool = False
) -> list[TogglWorkspace]

List workspaces for given user.

Official Documentation

PARAMETER DESCRIPTION
since

Optional argument to filter any workspace after the timestamp.

TYPE: datetime | int | None DEFAULT: None

refresh

Whether to use cache or not.

TYPE: bool DEFAULT: False

RAISES DESCRIPTION
DateTimeError

If the since argument is after the current time.

RETURNS DESCRIPTION
list[TogglWorkspace]

A list of workspaces or empty if there are None assocciated with the user.

Source code in src/toggl_api/_workspace.py
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
def collect(
    self,
    since: datetime | int | None = None,
    *,
    refresh: bool = False,
) -> list[TogglWorkspace]:
    """List workspaces for given user.

    [Official Documentation](https://engineering.toggl.com/docs/api/me#get-workspaces)

    Args:
        since: Optional argument to filter any workspace after the timestamp.
        refresh: Whether to use cache or not.

    Raises:
        DateTimeError: If the since argument is after the current time.

    Returns:
        A list of workspaces or empty if there are None assocciated with the user.
    """
    if since is not None:
        since = self._validate_collect_since(since)

    if self.cache and not refresh:
        return self._collect_cache(since)

    body = {"since": since} if since else None

    return cast(
        "list[TogglWorkspace]",
        self.request("me/workspaces", body=body, refresh=refresh),
    )

edit

edit(
    workspace_id: TogglWorkspace | int, body: WorkspaceBody
) -> TogglWorkspace

Update a specific workspace.

Official Documentation

RAISES DESCRIPTION
HTTPStatusError

For anything thats not an ok status code.

RETURNS DESCRIPTION
TogglWorkspace

A workspace model with the supplied edits.

Source code in src/toggl_api/_workspace.py
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
def edit(self, workspace_id: TogglWorkspace | int, body: WorkspaceBody) -> TogglWorkspace:
    """Update a specific workspace.

    [Official Documentation](https://engineering.toggl.com/docs/api/workspaces#put-update-workspace)

    Raises:
        HTTPStatusError: For anything thats not an *ok* status code.

    Returns:
        A workspace model with the supplied edits.
    """
    if isinstance(workspace_id, TogglWorkspace):
        workspace_id = workspace_id.id

    return cast(
        "TogglWorkspace",
        self.request(
            f"workspaces/{workspace_id}",
            body=body.format("edit"),
            method=RequestMethod.PUT,
            refresh=True,
        ),
    )

tracker_constraints

tracker_constraints(workspace_id: TogglWorkspace | int) -> dict[str, bool]

Get the time entry constraints for a given workspace.

Official Documentation

Toggl premium feature.

Examples:

>>> workspace_endpoint.get_workspace_constraints(24214214)
{
    "description_present": True,
    "project_present": False,
    "tag_present": False",
    "task_present": False,
    "time_entry_constraints_enabled": True,
}
PARAMETER DESCRIPTION
workspace_id

Id of the workspace to retrieve constraints from.

TYPE: TogglWorkspace | int

RETURNS DESCRIPTION
dict[str, bool]

A dictionary of booleans containing the settings.

Source code in src/toggl_api/_workspace.py
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
def tracker_constraints(self, workspace_id: TogglWorkspace | int) -> dict[str, bool]:
    """Get the time entry constraints for a given workspace.

    [Official Documentation](https://engineering.toggl.com/docs/api/workspaces#get-get-workspace-time-entry-constraints)

    Toggl premium feature.

    Examples:
        >>> workspace_endpoint.get_workspace_constraints(24214214)
        {
            "description_present": True,
            "project_present": False,
            "tag_present": False",
            "task_present": False,
            "time_entry_constraints_enabled": True,
        }

    Args:
        workspace_id: Id of the workspace to retrieve constraints from.

    Returns:
        A dictionary of booleans containing the settings.
    """
    if isinstance(workspace_id, TogglWorkspace):
        workspace_id = workspace_id.id

    return cast(
        "dict[str, bool]",
        cast(
            "Response",
            self.request(
                f"workspaces/{workspace_id}/time_entry_constraints",
                raw=True,
                refresh=True,
            ),
        ).json(),
    )

statistics

statistics(workspace_id: TogglWorkspace | int) -> WorkspaceStatistics

Return workspace admins list, members count and groups count.

Official Documentation

PARAMETER DESCRIPTION
workspace_id

Id of the workspace to fetch the statistics from.

TYPE: TogglWorkspace | int

RETURNS DESCRIPTION
WorkspaceStatistics

A dictionary containing relevant statistics. Refer to WorkspaceStatistics typed dict for reference.

Source code in src/toggl_api/_workspace.py
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
def statistics(self, workspace_id: TogglWorkspace | int) -> WorkspaceStatistics:
    """Return workspace admins list, members count and groups count.

    [Official Documentation](https://api.track.toggl.com/api/v9/workspaces/{workspace_id}/statistics)

    Args:
        workspace_id: Id of the workspace to fetch the statistics from.

    Returns:
        A dictionary containing relevant statistics.
            Refer to WorkspaceStatistics typed dict for reference.
    """
    if isinstance(workspace_id, TogglWorkspace):
        workspace_id = workspace_id.id

    return cast(
        "WorkspaceStatistics",
        cast(
            "Response",
            self.request(
                f"workspaces/{workspace_id}/statistics",
                refresh=True,
                raw=True,
            ),
        ).json(),
    )

toggl_api.asyncio.AsyncWorkspaceEndpoint

Bases: TogglAsyncCachedEndpoint[TogglWorkspace]

Specific endpoints for retrieving and modifying workspaces.

Official Documentation

Examples:

>>> org_id = 123213324
>>> workspace_endpoint = AsyncWorkspaceEndpoint(org_id, BasicAuth(...), AsyncSqliteCache(...))
PARAMETER DESCRIPTION
organization_id

Workspace endpoint takes an organization id instead of a workspace id.

TYPE: int | TogglOrganization

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: 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
get

Get the current workspace based on an id or model.

add

Create a new workspace.

collect

List workspaces for given user.

edit

Update a specific workspace.

tracker_constraints

Get the time entry constraints for a given workspace.

statistics

Return workspace admins list, members count and groups count.

get async

get(
    workspace: TogglWorkspace | int, *, refresh: bool = False
) -> TogglWorkspace | None

Get the current workspace based on an id or model.

Official Documentation

PARAMETER DESCRIPTION
workspace

Workspace id or model.

TYPE: TogglWorkspace | int

refresh

Whether to use cache or not.

TYPE: bool DEFAULT: False

RAISES DESCRIPTION
HTTPStatusError

If anything that's not a '2xx' or '404' status_code is returned.

RETURNS DESCRIPTION
TogglWorkspace | None

Model of workspace if found else none.

add async

Create a new workspace.

Official Documentation

Enterprise plan feature.

PARAMETER DESCRIPTION
body

All settings for the workspace to be attached to as a body.

TYPE: WorkspaceBody

RETURNS DESCRIPTION
TogglWorkspace

A newly created workspace with the supplied params.

collect async

collect(
    since: datetime | int | None = None, *, refresh: bool = False
) -> list[TogglWorkspace]

List workspaces for given user.

Official Documentation

PARAMETER DESCRIPTION
since

Optional argument to filter any workspace after the timestamp.

TYPE: datetime | int | None DEFAULT: None

refresh

Whether to use cache or not.

TYPE: bool DEFAULT: False

RAISES DESCRIPTION
DateTimeError

If the since argument is after the current time.

RETURNS DESCRIPTION
list[TogglWorkspace]

A list of workspaces or empty if there are None assocciated with the user.

edit async

edit(
    workspace_id: TogglWorkspace | int, body: WorkspaceBody
) -> TogglWorkspace

Update a specific workspace.

Official Documentation

RAISES DESCRIPTION
HTTPStatusError

For anything thats not an ok status code.

RETURNS DESCRIPTION
TogglWorkspace

A workspace model with the supplied edits.

tracker_constraints async

tracker_constraints(workspace_id: TogglWorkspace | int) -> dict[str, bool]

Get the time entry constraints for a given workspace.

Official Documentation

Toggl premium feature.

Examples:

>>> await workspace_endpoint.get_workspace_constraints(24214214)
{
    "description_present": True,
    "project_present": False,
    "tag_present": False",
    "task_present": False,
    "time_entry_constraints_enabled": True,
}
PARAMETER DESCRIPTION
workspace_id

Id of the workspace to retrieve constraints from.

TYPE: TogglWorkspace | int

RETURNS DESCRIPTION
dict[str, bool]

A dictionary of booleans containing the settings.

statistics async

statistics(workspace_id: TogglWorkspace | int) -> WorkspaceStatistics

Return workspace admins list, members count and groups count.

Official Documentation

PARAMETER DESCRIPTION
workspace_id

Id of the workspace to fetch the statistics from.

TYPE: TogglWorkspace | int

RETURNS DESCRIPTION
WorkspaceStatistics

Dictionary containing relevant statistics. Refer to WorkspaceStatistics typed dict for reference.

Types

toggl_api.User

Bases: TypedDict

Source code in src/toggl_api/_workspace.py
173
174
175
class User(TypedDict):
    user_id: int
    name: str

toggl_api.WorkspaceStatistics

Bases: TypedDict

Source code in src/toggl_api/_workspace.py
178
179
180
181
class WorkspaceStatistics(TypedDict):
    admins: list[User]
    groups_count: int
    members_count: int