Skip to content

Commit

Permalink
chore(release): version 1.5.1
Browse files Browse the repository at this point in the history
chore(cliff): hide navigation in changelog
  • Loading branch information
ddkasa committed Nov 26, 2024
2 parents 06bdaad + bacab09 commit f16c140
Show file tree
Hide file tree
Showing 19 changed files with 159 additions and 93 deletions.
5 changes: 5 additions & 0 deletions cliff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
[changelog]
# template for the changelog header
header = """
---
hide:
- navigation
---
# Changelog\n
All notable changes to this project will be documented in this file.\n
"""
Expand Down
13 changes: 12 additions & 1 deletion docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
---
hide:
- navigation
- navigation
---

# Changelog

All notable changes to this project will be documented in this file.

## [1.5.1] - 2024-11-26

### 🐛 Bug Fixes

- *(models)* From_kwargs not incorporating organization id

### 📚 Documentation

- *(endpoints)* Correct and improve docstrings
- *(cache, config)* Remove unnecessary type on return value in docstrings

## [1.5.0] - 2024-11-25

### 🚀 Features
Expand Down
5 changes: 2 additions & 3 deletions docs/api-guide/organization.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
> [!NOTE]
> Organization endpoint doesn't require a workspace id.
::: toggl_api.OrganizationEndpoint
options:
show_source: true
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "toggl-api-wrapper"
version = "1.5.0"
version = "1.5.1"
description = "Simple Toggl API wrapper for non-premium features."
authors = ["David Kasakaitis <[email protected]>"]
license = "MIT"
Expand Down
21 changes: 15 additions & 6 deletions toggl_api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ class ClientEndpoint(TogglCachedEndpoint[TogglClient]):
[Official Documentation](https://engineering.toggl.com/docs/api/clients)
Examples:
>>> wid = 123213324
>>> client_endpoint = ClientEndpoint(wid, BasicAuth(...), SqliteCache(...))
>>> client_endpoint.get(214125562)
TogglClient(214125562, "Simplicidentata", workspace=123213324)
Params:
workspace_id: The workspace the clients belong to.
auth: Authentication for the client.
Expand Down Expand Up @@ -109,7 +115,7 @@ def add(self, body: ClientBody) -> TogglClient | None:
NamingError: If no name was set as its required.
Returns:
TogglClient: Newly created client with specified parameters.
Newly created client with specified parameters.
"""

if body.name is None:
Expand All @@ -134,7 +140,7 @@ def get(self, client_id: int | TogglClient, *, refresh: bool = False) -> TogglCl
is not found in cache. Defaults to False.
Returns:
TogglClient | None: If the client was found.
A TogglClient if the client was found else None.
"""
if isinstance(client_id, TogglClient):
client_id = client_id.id
Expand Down Expand Up @@ -167,7 +173,7 @@ def edit(self, client: TogglClient | int, body: ClientBody) -> TogglClient | Non
body: New parameters to use. Ignore client status.
Returns:
TogglClient | None: Newly edited client or None if not found.
Newly edited client or None if not found.
"""
if body.status:
log.warning("Client status not supported by edit endpoint")
Expand All @@ -188,6 +194,10 @@ def delete(self, client: TogglClient | int) -> None:
This endpoint always hit the external API in order to keep clients consistent.
[Official Documentation](https://engineering.toggl.com/docs/api/clients#delete-delete-client)
Raises:
HTTPStatusError: If anything thats not an *ok* or *404* status code
is returned.
"""
client_id = client if isinstance(client, int) else client.id
try:
Expand Down Expand Up @@ -228,12 +238,11 @@ def collect(
[Official Documentation](https://engineering.toggl.com/docs/api/clients#get-list-clients)
Args:
body: Status and name to target. Ignores notes. Ignores status if
using cache.
body: Status and name to target. Ignores notes. Ignores status if using cache.
refresh: Whether to refresh cache.
Returns:
list[TogglClient]: A list of clients. Empty if not found.
A list of clients. Empty if not found.
"""
if not refresh:
return self._collect_cache(body)
Expand Down
8 changes: 4 additions & 4 deletions toggl_api/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def generate_authentication() -> BasicAuth:
AuthenticationError: If credentials are not set or invalid.
Returns:
BasicAuth: BasicAuth object that is used with httpx client.
BasicAuth object that is used with Httpx client.
"""
api_token = os.getenv("TOGGL_API_TOKEN")
if api_token is None:
Expand Down Expand Up @@ -83,7 +83,7 @@ def use_togglrc(config_path: Optional[Path] = None) -> BasicAuth:
AuthenticationError: If credentials are not set or invalid.
Returns:
BasicAuth: BasicAuth object that is used with httpx client.
BasicAuth object that is used with httpx client.
"""
try:
config = _get_togglrc(config_path)
Expand Down Expand Up @@ -138,7 +138,7 @@ def retrieve_workspace_id(default: Optional[int] = None) -> int:
variable or the workspace set is not an integer.
Returns:
int: The id of the workspace.
The id of the workspace.
"""

workspace = os.environ.get("TOGGL_WORKSPACE_ID", default)
Expand All @@ -165,7 +165,7 @@ def retrieve_togglrc_workspace_id(config_path: Optional[Path] = None) -> int:
ValueError: If the workspace value is not an integer.
Returns:
int: The id of the workspace.
The id of the workspace.
"""

config = _get_togglrc(config_path)
Expand Down
5 changes: 4 additions & 1 deletion toggl_api/meta/base_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,11 @@ class property if set to None.
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:
Any: Response data or None if request does not return any data.
Response data or None if request does not return any data.
"""
if retries is None:
retries = self.retries
Expand Down
4 changes: 2 additions & 2 deletions toggl_api/meta/cache/json_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ def delete_entries(self, update: list[T] | T, **kwargs: Any) -> None:
self.delete_entry(entry)
return None

def query(self, *query: TogglQuery, distinct: bool = False) -> list[TogglClass]:
def query(self, *query: TogglQuery, distinct: bool = False) -> list[T]:
"""Query method for filtering Toggl objects from cache.
Filters cached Toggl objects by set of supplied queries.
Expand All @@ -254,7 +254,7 @@ def query(self, *query: TogglQuery, distinct: bool = False) -> list[TogglClass]:
with unhashable fields such as lists.
Returns:
list[TogglClass]: A query object with parameters filtered.
A list of models with the query parameters that matched.
"""

log.debug("Querying cache with %s parameters.", len(query), extra={"query": query})
Expand Down
6 changes: 3 additions & 3 deletions toggl_api/meta/cache/sqlite_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@ def find_entry(self, query: T | dict[str, Any]) -> T | None:
return search.filter_by(**query).first()

def query(self, *query: TogglQuery, distinct: bool = False) -> Query[T]:
"""Query method for filtering Toggl objects from cache.
"""Query method for filtering models from cache.
Filters cached toggl objects by set of supplied queries.
Filters cached model by set of supplied queries.
Supports queries with various comparisons with the [Comparison][toggl_api.Comparison]
enumeration.
Expand All @@ -144,7 +144,7 @@ def query(self, *query: TogglQuery, distinct: bool = False) -> Query[T]:
distinct: Whether to keep equivalent values around.
Returns:
Query[TogglClass]: A SQLAlchemy query object with parameters filtered.
A SQLAlchemy query object with parameters filtered.
"""

search = self.session.query(self.parent.model)
Expand Down
9 changes: 6 additions & 3 deletions toggl_api/meta/cached_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,12 @@ def request( # type: ignore[override]
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:
TogglClass | Iterable[TogglClass] | None: Toggl API response data
processed into TogglClass objects.
Toggl API response data processed into TogglClass objects or not
depending on arguments.
"""

data = self.load_cache() if self.model is not None else None
Expand Down Expand Up @@ -166,7 +169,7 @@ def query(self, *query: TogglQuery, distinct: bool = False) -> list[T]:
distinct: A boolean that remove duplicate values if present.
Returns:
Iterable: An iterable object depending on the cache used.
A list objects depending on the endpoint.
"""
return list(self.cache.query(*query, distinct=distinct))

Expand Down
27 changes: 16 additions & 11 deletions toggl_api/models/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class TogglClass(ABC):
"""Base class for all Toggl dataclasses.
Params:
id: Toggl API / Database ID (Primary Key) of the Toggl project.
id: Toggl API / Database ID (Primary Key) of the Toggl model.
name: Name or description of the Toggl project.
timestamp: Local timestamp of when the Toggl project was last modified.
"""
Expand Down Expand Up @@ -71,7 +71,7 @@ class TogglOrganization(TogglClass):
Params:
id: Toggl API / Database ID (Primary Key) of the Toggl organization.
name: Name or description of the Toggl organization.
name: Name of the Toggl organization. Max 140 characters and min 1 character.
timestamp: Local timestamp of when the Toggl organization was last modified.
"""

Expand Down Expand Up @@ -102,8 +102,8 @@ class TogglWorkspace(TogglClass):
"""Data structure for Toggl workspaces.
Params:
id: Toggl API / Database ID (Primary Key) of the Toggl object.
name: Name or description of the Toggl workspace.
id: Toggl API / Database ID (Primary Key) of the Toggl workspace.
name: Name of the workspace.
timestamp: Local timestamp of when the Toggl workspace was last modified.
organization: Organization id the workspace belongs to.
"""
Expand All @@ -126,7 +126,12 @@ def __post_init__(self) -> None:
@classmethod
def from_kwargs(cls, **kwargs: Any) -> TogglWorkspace:
"""Converts an arbitrary amount of kwargs to a workspace."""
return super().from_kwargs(**kwargs) # type: ignore[return-value]
return cls(
id=kwargs["id"],
name=kwargs["name"],
timestamp=kwargs.get("timestamp") or datetime.now(tz=timezone.utc),
organization=kwargs.get("organization", 0),
)

@staticmethod
def validate_name(name: str, *, max_len: int = 140) -> None:
Expand All @@ -148,9 +153,9 @@ class WorkspaceChild(TogglClass):
Params:
id: Toggl API / Database ID (Primary Key) of the Toggl object.
name: Name or description of the Toggl object.
name: Name of the object.
timestamp: Local timestamp of when the Toggl object was last modified.
workspace: The workspace id the toggl object belongs to.
workspace: The workspace id the Toggl object belongs to.
"""

__tablename__ = "workspace_child"
Expand All @@ -177,7 +182,7 @@ class TogglClient(WorkspaceChild):
Params:
id: Toggl API / Database ID (Primary Key) of the Toggl client.
name: Name or description of the Toggl client.
name: Name of the client.
timestamp: Local timestamp of when the Toggl client was last modified.
workspace: The workspace id the Toggl client belongs to.
"""
Expand All @@ -198,11 +203,11 @@ class TogglProject(WorkspaceChild):
"""Data structure for Toggl projects.
Attributes:
STATUS: An enumeration with all project statuses supported by the API.
Status: An enumeration with all project statuses supported by the API.
Params:
id: Toggl API / Database ID (Primary Key) of the Toggl project.
name: Name or description of the Toggl project.
name: Name of the project.
timestamp: Local timestamp of when the Toggl project was last modified.
workspace: The workspace id the project belongs to.
color: Color of the project. Defaults to blue. Refer to this endpoint
Expand Down Expand Up @@ -369,7 +374,7 @@ class TogglTag(WorkspaceChild):
Params:
id: Toggl API / Database ID (Primary Key) of the Toggl tag.
name:Name or description of the Toggl tag.
name: Name of the tag.
timestamp: Local timestamp of when the Toggl tag was last modified.
workspace: The workspace id the tag belongs to.
"""
Expand Down
17 changes: 12 additions & 5 deletions toggl_api/organization.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ class OrganizationEndpoint(TogglCachedEndpoint[TogglOrganization]):
[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 trackers are stored.
Expand Down Expand Up @@ -72,8 +75,7 @@ def get(
HTTPStatusError: If any error except a '404' was received.
Returns:
TogglOrganization | None: Organization object that was retrieve or
None if not found.
Organization object that was retrieve or None if not found.
"""

if isinstance(organization, TogglOrganization):
Expand Down Expand Up @@ -110,9 +112,10 @@ def add(self, name: str, workspace_name: str = "Default-Workspace") -> TogglOrga
Raises:
NamingError: If any of the names are invalid or the wrong length.
HTTPStatusError: If the request is not a success.
Returns:
TogglOrganization: The newly created organization.
The newly created organization.
"""

TogglOrganization.validate_name(name)
Expand All @@ -136,9 +139,10 @@ def edit(self, organization: TogglOrganization | int, name: str) -> TogglOrganiz
Raises:
NamingError: If the new name is invalid.
HTTPStatusError: If the request is not a success.
Returns:
TogglOrganization: The newly edited organization.
The newly edited organization.
"""

TogglOrganization.validate_name(name)
Expand Down Expand Up @@ -167,8 +171,11 @@ def collect(self, *, refresh: bool = False) -> list[TogglOrganization]:
Args:
refresh: Whether to use cache or not.
Raises:
HTTPStatusError: If the request is not a success.
Returns:
list: A list of organization objects or empty if none found.
A list of organization objects or empty if none found.
"""
return self.request("me/organizations", refresh=refresh)

Expand Down
Loading

0 comments on commit f16c140

Please sign in to comment.