Skip to content

Organization

toggl_api.OrganizationEndpoint

Bases: TogglCachedEndpoint[TogglOrganization]

Endpoint to do with handling organization specific details.

Official Documentation

Examples:

>>> org_endpoint = OrganizationEndpoint(BasicAuth(...), SqliteCache(...))
PARAMETER DESCRIPTION
auth

Authentication for the client.

TYPE: BasicAuth

cache

Cache object where the organization models are stored.

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

Create a new organization with a single workspace and assigns

add

Create a new organization with a single workspace.

edit

Update an existing organization.

collect

Get all organizations a given user is part of.

delete

Leave organization effectively deleting user account in org.

Source code in src/toggl_api/_organization.py
 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
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
class OrganizationEndpoint(TogglCachedEndpoint[TogglOrganization]):
    """Endpoint to do with handling organization specific details.

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

    Examples:
        >>> org_endpoint = OrganizationEndpoint(BasicAuth(...), SqliteCache(...))

    Params:
        auth: Authentication for the client.
        cache: Cache object where the organization models are stored.
        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 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 = TogglOrganization

    def __init__(
        self,
        auth: BasicAuth,
        cache: TogglCache[TogglOrganization] | 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,
        )

    def get(
        self,
        organization: TogglOrganization | int,
        *,
        refresh: bool = False,
    ) -> TogglOrganization | None:
        """Create a new organization with a single workspace and assigns
        current user as the organization owner.

        [Official Documentation](https://engineering.toggl.com/docs/api/organizations#get-organization-data)

        Args:
            organization: Organization to retrieve.
            refresh: Whether to ignore cache completely.

        Raises:
            HTTPStatusError: If any error except a '404' was received.

        Returns:
            Organization object that was retrieve or None if not found.
        """  # noqa: D205
        if isinstance(organization, TogglOrganization):
            organization = organization.id

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

        try:
            response = self.request(
                f"organizations/{organization}",
                refresh=refresh,
            )
        except HTTPStatusError as err:
            if not self.re_raise and err.response.status_code in {
                codes.NOT_FOUND,
                codes.FORBIDDEN,
            }:
                log.warning(err)
                return None
            raise

        return cast("TogglOrganization", response)

    def add(
        self,
        name: str,
        workspace_name: str = "Default-Workspace",
    ) -> TogglOrganization:
        """Create a new organization with a single workspace.

        Assigns current user as the organization owner.

        [Official Documentation](https://engineering.toggl.com/docs/api/organizations#post-creates-a-new-organization)

        Examples:
            >>> org = organization_endpoint.add("New-Workspace")
            >>> org.name
            "New-Workspace"

        Args:
            name: Name of the new orgnization.
            workspace_name: Name of the default workspace in the organization.
                No space characters allowed.

        Raises:
            NamingError: If any of the names are invalid or the wrong length.
            HTTPStatusError: If the request is not a success.

        Returns:
            The newly created organization.
        """
        TogglOrganization.validate_name(name)
        TogglWorkspace.validate_name(workspace_name)

        return cast(
            "TogglOrganization",
            self.request(
                "organizations",
                body={"name": name, "workspace_name": workspace_name},
                method=RequestMethod.POST,
                refresh=True,
            ),
        )

    def edit(
        self,
        organization: TogglOrganization | int,
        name: str,
    ) -> TogglOrganization:
        """Update an existing organization.

        [Official Documentation](https://engineering.toggl.com/docs/api/organizations#put-updates-an-existing-organization)

        Args:
            organization: The id of the organization to edit.
            name: What name to change the org to.

        Raises:
            NamingError: If the new name is invalid.
            HTTPStatusError: If the request is not a success.

        Returns:
            The newly edited organization.
        """
        TogglOrganization.validate_name(name)

        if isinstance(organization, TogglOrganization):
            organization = organization.id

        self.request(
            f"organizations/{organization}",
            body={"name": name},
            refresh=True,
            method=RequestMethod.PUT,
        )

        edit = TogglOrganization(organization, name)
        if self.cache:
            self.cache.update(edit)
            self.cache.commit()

        return edit

    def collect(self, *, refresh: bool = False) -> list[TogglOrganization]:
        """Get all organizations a given user is part of.

        [Official Documentation](https://engineering.toggl.com/docs/api/me#get-organizations-that-a-user-is-part-of)

        Args:
            refresh: Whether to use cache or not.

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

        Returns:
            A list of organization objects or empty if none found.
        """
        return cast(
            "list[TogglOrganization]",
            self.request("me/organizations", refresh=refresh),
        )

    def delete(self, organization: TogglOrganization | int) -> None:
        """Leave organization effectively deleting user account in org.

        Deletes organization if it is last user.

        Deletion might not be instant on the API end and might take a few
        seconds to propogate, so the object might appear in the 'get' or
        'collect' method.

        [Official Documentation](https://engineering.toggl.com/docs/api/organizations#delete-leaves-organization)

        Args:
            organization: Organization to delete.

        Raises:
            HTTPStatusError: If the response status_code is not '200' or '404'.
        """
        org_id = organization if isinstance(organization, int) else organization.id
        try:
            self.request(
                f"organizations/{org_id}/users/leave",
                method=RequestMethod.DELETE,
                refresh=True,
            )
        except HTTPStatusError as err:
            if self.re_raise or err.response.status_code != codes.NOT_FOUND:
                raise
            log.exception("%s")
            log.warning(
                "Organization with id %s was either already deleted or did not exist in the first place!",
                org_id,
            )
        if self.cache is None:
            return

        if isinstance(organization, int):
            org = self.cache.find({"id": organization})
            if not isinstance(org, TogglOrganization):
                return
            organization = org

        self.cache.delete(organization)
        self.cache.commit()

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

get

get(
    organization: TogglOrganization | int, *, refresh: bool = False
) -> TogglOrganization | None

Create a new organization with a single workspace and assigns current user as the organization owner.

Official Documentation

PARAMETER DESCRIPTION
organization

Organization to retrieve.

TYPE: TogglOrganization | int

refresh

Whether to ignore cache completely.

TYPE: bool DEFAULT: False

RAISES DESCRIPTION
HTTPStatusError

If any error except a '404' was received.

RETURNS DESCRIPTION
TogglOrganization | None

Organization object that was retrieve or None if not found.

Source code in src/toggl_api/_organization.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
 98
 99
100
101
102
103
104
105
def get(
    self,
    organization: TogglOrganization | int,
    *,
    refresh: bool = False,
) -> TogglOrganization | None:
    """Create a new organization with a single workspace and assigns
    current user as the organization owner.

    [Official Documentation](https://engineering.toggl.com/docs/api/organizations#get-organization-data)

    Args:
        organization: Organization to retrieve.
        refresh: Whether to ignore cache completely.

    Raises:
        HTTPStatusError: If any error except a '404' was received.

    Returns:
        Organization object that was retrieve or None if not found.
    """  # noqa: D205
    if isinstance(organization, TogglOrganization):
        organization = organization.id

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

    try:
        response = self.request(
            f"organizations/{organization}",
            refresh=refresh,
        )
    except HTTPStatusError as err:
        if not self.re_raise and err.response.status_code in {
            codes.NOT_FOUND,
            codes.FORBIDDEN,
        }:
            log.warning(err)
            return None
        raise

    return cast("TogglOrganization", response)

add

add(name: str, workspace_name: str = 'Default-Workspace') -> TogglOrganization

Create a new organization with a single workspace.

Assigns current user as the organization owner.

Official Documentation

Examples:

>>> org = organization_endpoint.add("New-Workspace")
>>> org.name
"New-Workspace"
PARAMETER DESCRIPTION
name

Name of the new orgnization.

TYPE: str

workspace_name

Name of the default workspace in the organization. No space characters allowed.

TYPE: str DEFAULT: 'Default-Workspace'

RAISES DESCRIPTION
NamingError

If any of the names are invalid or the wrong length.

HTTPStatusError

If the request is not a success.

RETURNS DESCRIPTION
TogglOrganization

The newly created organization.

Source code in src/toggl_api/_organization.py
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
def add(
    self,
    name: str,
    workspace_name: str = "Default-Workspace",
) -> TogglOrganization:
    """Create a new organization with a single workspace.

    Assigns current user as the organization owner.

    [Official Documentation](https://engineering.toggl.com/docs/api/organizations#post-creates-a-new-organization)

    Examples:
        >>> org = organization_endpoint.add("New-Workspace")
        >>> org.name
        "New-Workspace"

    Args:
        name: Name of the new orgnization.
        workspace_name: Name of the default workspace in the organization.
            No space characters allowed.

    Raises:
        NamingError: If any of the names are invalid or the wrong length.
        HTTPStatusError: If the request is not a success.

    Returns:
        The newly created organization.
    """
    TogglOrganization.validate_name(name)
    TogglWorkspace.validate_name(workspace_name)

    return cast(
        "TogglOrganization",
        self.request(
            "organizations",
            body={"name": name, "workspace_name": workspace_name},
            method=RequestMethod.POST,
            refresh=True,
        ),
    )

edit

edit(organization: TogglOrganization | int, name: str) -> TogglOrganization

Update an existing organization.

Official Documentation

PARAMETER DESCRIPTION
organization

The id of the organization to edit.

TYPE: TogglOrganization | int

name

What name to change the org to.

TYPE: str

RAISES DESCRIPTION
NamingError

If the new name is invalid.

HTTPStatusError

If the request is not a success.

RETURNS DESCRIPTION
TogglOrganization

The newly edited organization.

Source code in src/toggl_api/_organization.py
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
def edit(
    self,
    organization: TogglOrganization | int,
    name: str,
) -> TogglOrganization:
    """Update an existing organization.

    [Official Documentation](https://engineering.toggl.com/docs/api/organizations#put-updates-an-existing-organization)

    Args:
        organization: The id of the organization to edit.
        name: What name to change the org to.

    Raises:
        NamingError: If the new name is invalid.
        HTTPStatusError: If the request is not a success.

    Returns:
        The newly edited organization.
    """
    TogglOrganization.validate_name(name)

    if isinstance(organization, TogglOrganization):
        organization = organization.id

    self.request(
        f"organizations/{organization}",
        body={"name": name},
        refresh=True,
        method=RequestMethod.PUT,
    )

    edit = TogglOrganization(organization, name)
    if self.cache:
        self.cache.update(edit)
        self.cache.commit()

    return edit

collect

collect(*, refresh: bool = False) -> list[TogglOrganization]

Get all organizations a given user is part of.

Official Documentation

PARAMETER DESCRIPTION
refresh

Whether to use cache or not.

TYPE: bool DEFAULT: False

RAISES DESCRIPTION
HTTPStatusError

If the request is not a success.

RETURNS DESCRIPTION
list[TogglOrganization]

A list of organization objects or empty if none found.

Source code in src/toggl_api/_organization.py
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
def collect(self, *, refresh: bool = False) -> list[TogglOrganization]:
    """Get all organizations a given user is part of.

    [Official Documentation](https://engineering.toggl.com/docs/api/me#get-organizations-that-a-user-is-part-of)

    Args:
        refresh: Whether to use cache or not.

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

    Returns:
        A list of organization objects or empty if none found.
    """
    return cast(
        "list[TogglOrganization]",
        self.request("me/organizations", refresh=refresh),
    )

delete

delete(organization: TogglOrganization | int) -> None

Leave organization effectively deleting user account in org.

Deletes organization if it is last user.

Deletion might not be instant on the API end and might take a few seconds to propogate, so the object might appear in the 'get' or 'collect' method.

Official Documentation

PARAMETER DESCRIPTION
organization

Organization to delete.

TYPE: TogglOrganization | int

RAISES DESCRIPTION
HTTPStatusError

If the response status_code is not '200' or '404'.

Source code in src/toggl_api/_organization.py
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
def delete(self, organization: TogglOrganization | int) -> None:
    """Leave organization effectively deleting user account in org.

    Deletes organization if it is last user.

    Deletion might not be instant on the API end and might take a few
    seconds to propogate, so the object might appear in the 'get' or
    'collect' method.

    [Official Documentation](https://engineering.toggl.com/docs/api/organizations#delete-leaves-organization)

    Args:
        organization: Organization to delete.

    Raises:
        HTTPStatusError: If the response status_code is not '200' or '404'.
    """
    org_id = organization if isinstance(organization, int) else organization.id
    try:
        self.request(
            f"organizations/{org_id}/users/leave",
            method=RequestMethod.DELETE,
            refresh=True,
        )
    except HTTPStatusError as err:
        if self.re_raise or err.response.status_code != codes.NOT_FOUND:
            raise
        log.exception("%s")
        log.warning(
            "Organization with id %s was either already deleted or did not exist in the first place!",
            org_id,
        )
    if self.cache is None:
        return

    if isinstance(organization, int):
        org = self.cache.find({"id": organization})
        if not isinstance(org, TogglOrganization):
            return
        organization = org

    self.cache.delete(organization)
    self.cache.commit()

toggl_api.asyncio.AsyncOrganizationEndpoint

Bases: TogglAsyncCachedEndpoint[TogglOrganization]

Endpoint to do with handling organization specific details.

Official Documentation

Examples:

>>> org_endpoint = OrganizationEndpoint(BasicAuth(...), AsyncSqliteCache(...))
PARAMETER DESCRIPTION
auth

Authentication for the client.

TYPE: BasicAuth

cache

Cache object where the organization models are stored.

TYPE: AsyncSqliteCache[TogglOrganization] | 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 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

Create a new organization with a single workspace.

add

Create a new organization with a single workspace.

edit

Update an existing organization.

collect

Get all organizations a given user is part of.

delete

Leave organization, effectively delete user account in org.

get async

get(
    organization: TogglOrganization | int, *, refresh: bool = False
) -> TogglOrganization | None

Create a new organization with a single workspace.

Official Documentation

PARAMETER DESCRIPTION
organization

Organization to retrieve.

TYPE: TogglOrganization | int

refresh

Whether to ignore cache completely.

TYPE: bool DEFAULT: False

RAISES DESCRIPTION
HTTPStatusError

If any error except a '404' was received.

RETURNS DESCRIPTION
TogglOrganization | None

Organization object that was retrieve or None if not found.

add async

add(name: str, workspace_name: str = 'Default-Workspace') -> TogglOrganization

Create a new organization with a single workspace.

Official Documentation

Examples:

>>> org = await organization_endpoint.add("New-Workspace")
>>> org.name
"New-Workspace"
PARAMETER DESCRIPTION
name

Name of the new orgnization.

TYPE: str

workspace_name

Name of the default workspace in the organization. No space characters allowed.

TYPE: str DEFAULT: 'Default-Workspace'

RAISES DESCRIPTION
NamingError

If any of the names are invalid or the wrong length.

HTTPStatusError

If the request is not a success.

RETURNS DESCRIPTION
TogglOrganization

The newly created organization.

edit async

edit(organization: TogglOrganization | int, name: str) -> TogglOrganization

Update an existing organization.

Official Documentation

PARAMETER DESCRIPTION
organization

The id of the organization to edit.

TYPE: TogglOrganization | int

name

What name to change the org to.

TYPE: str

RAISES DESCRIPTION
NamingError

If the new name is invalid.

HTTPStatusError

If the request is not a success.

RETURNS DESCRIPTION
TogglOrganization

The newly edited organization.

collect async

collect(*, refresh: bool = False) -> list[TogglOrganization]

Get all organizations a given user is part of.

Official Documentation

PARAMETER DESCRIPTION
refresh

Whether to use cache or not.

TYPE: bool DEFAULT: False

RAISES DESCRIPTION
HTTPStatusError

If the request is not a success.

RETURNS DESCRIPTION
list[TogglOrganization]

A list of organization objects or empty if none found.

delete async

delete(organization: TogglOrganization | int) -> None

Leave organization, effectively delete user account in org.

If another user is in the organization it will remain active.

Deletion might not be instant on the API end and might take a few seconds to propogate, so the object might appear in the 'get' or 'collect' method.

Official Documentation

PARAMETER DESCRIPTION
organization

Organization to delete.

TYPE: TogglOrganization | int

RAISES DESCRIPTION
HTTPStatusError

If the response status_code is not '200' or '404'.