Skip to content

Commit fd5c01a

Browse files
author
Georgy Aleksahin
committed
[ERP-1140]: updated toggle API version v8->v9
* updated entities * updated poetry dependencies * updated python version
1 parent b2a7247 commit fd5c01a

File tree

7 files changed

+860
-793
lines changed

7 files changed

+860
-793
lines changed

docs/conf.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
import datetime
22
from pathlib import Path
3+
34
from sphinx.ext import apidoc
45

6+
57
copyright = f"{datetime.datetime.now().year}, Evrone"
68

79
# Auto generate documentation
810
if False:
9-
apidoc.main([
10-
'-f', # force overwrite
11-
'-T', # no modules.rst toc
12-
'-e', # Each module on it's own page
13-
'-o', str(Path(__file__).parent), # Output dir relative to "Sphinx root"
14-
str(Path(__file__).parent.parent / 'toggl_python') # Source code root
15-
])
11+
apidoc.main(
12+
[
13+
"-f", # force overwrite
14+
"-T", # no modules.rst toc
15+
"-e", # Each module on it's own page
16+
"-o",
17+
str(Path(__file__).parent), # Output dir relative to "Sphinx root"
18+
str(Path(__file__).parent.parent / "toggl_python"), # Source code root
19+
]
20+
)

poetry.lock

Lines changed: 786 additions & 725 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "toggl_python"
3-
version = "0.2.7"
3+
version = "0.2.8"
44
description = "Python wrapper for Toggl API."
55
authors = ["Ivlev Denis <[email protected]>"]
66
readme = "README.md"
@@ -15,23 +15,24 @@ classifiers = [
1515
"Programming Language :: Python :: 3",
1616
"Programming Language :: Python :: 3.8",
1717
"Programming Language :: Python :: 3.9",
18+
"Programming Language :: Python :: 3.11",
1819
]
1920

2021
[tool.poetry.dependencies]
21-
python = "^3.8"
22-
httpx = {extras=["http2"], version="^0.17.1"}
23-
pydantic = {extras = ["email"], version = "^1.7.2"}
22+
python = "3.11"
23+
httpx = {extras=["http2"], version="^0.25.0"}
24+
pydantic = {extras = ["email"], version = "^2.4.2"}
2425

2526
[tool.poetry.dev-dependencies]
26-
pytest = "^6.2"
27-
respx = "^0.16"
28-
black = "^20.8b1"
29-
ipython = "^7.21.0"
30-
mypy = "^0.812"
31-
coverage = "^5.5"
32-
flake8 = "^3.9.0"
33-
isort = "^5.8.0"
34-
pre-commit = "^2.11.1"
27+
pytest = "^7.4.2"
28+
respx = "^0.20.2"
29+
black = "^23.9"
30+
ipython = "^8.16.1"
31+
mypy = "^1.6.0"
32+
coverage = "^7.3"
33+
flake8 = "^6.0"
34+
isort = "^5.12.0"
35+
pre-commit = "3.5.0"
3536

3637
[tool.black]
3738
line-length = 100
@@ -62,5 +63,5 @@ src_paths = "toggl_python"
6263
lines_after_imports = 2
6364

6465
[build-system]
65-
requires = ["poetry>=0.12"]
66+
requires = ["poetry=^1.6"]
6667
build-backend = "poetry.masonry.api"

tests/test_entities.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ def test_client_entity():
2828

2929

3030
def test_group_entity():
31-
Group(name="foo", wid=1)
32-
Group(name="foo", wid=1, notes="some string")
31+
Group(name="foo", workspace_id=1)
32+
Group(name="foo", workspace_id=1, notes="some string")
3333

3434
with pytest.raises(pydantic.ValidationError):
3535
Group(name="foo")
3636
with pytest.raises(pydantic.ValidationError):
37-
Group(wid=1)
37+
Group(workspace_id=1)
3838
with pytest.raises(pydantic.ValidationError):
3939
Group(name=1, wid=None)
4040

@@ -65,23 +65,23 @@ def test_project_user_entity():
6565

6666

6767
def test_tag_entity():
68-
Tag(name="foo", wid=1)
68+
Tag(name="foo", workspace_id=1)
6969

7070
with pytest.raises(pydantic.ValidationError):
7171
Tag(name="foo")
7272
with pytest.raises(pydantic.ValidationError):
73-
Tag(wid=1)
73+
Tag(workspace_id=1)
7474

7575

7676
def test_task_entity():
77-
Task(name="foo", pid=1, wid=1)
77+
Task(name="foo", project_id=1, workspace_id=1)
7878

7979
with pytest.raises(pydantic.ValidationError):
80-
Task(name="foo", pid=1)
80+
Task(name="foo", project_id=1)
8181
with pytest.raises(pydantic.ValidationError):
82-
Task(name="foo", wid=1)
82+
Task(name="foo", workspace_id=1)
8383
with pytest.raises(pydantic.ValidationError):
84-
Task(pid=1, wid=1)
84+
Task(project_id=1, workspace_id=1)
8585

8686

8787
def test_time_entry_entity():

toggl_python/api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class Api:
1616
Allow to interact with official Toggl API via httpx.
1717
"""
1818

19-
BASE_URL: httpx.URL = httpx.URL("https://api.track.toggl.com/api/v8/")
19+
BASE_URL: httpx.URL = httpx.URL("https://api.track.toggl.com/api/v9/")
2020
HEADERS = {
2121
"content-type": "application/json",
2222
"user_agent": "toggl-python",

toggl_python/entities.py

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from datetime import datetime
2-
from typing import Any, Callable, Dict, List, Optional, Union
2+
from typing import Callable, List, Optional, Union
33

4-
from pydantic import BaseModel, EmailStr, HttpUrl
4+
from pydantic import BaseModel, EmailStr, Field, HttpUrl
55

66

77
class BaseEntity(BaseModel):
@@ -17,7 +17,7 @@ class Client(BaseEntity):
1717

1818
class Group(BaseEntity):
1919
name: str
20-
wid: int
20+
wid: int = Field(alias="workspace_id")
2121

2222

2323
class Project(BaseEntity):
@@ -48,15 +48,16 @@ class ProjectUser(BaseEntity):
4848

4949
class Tag(BaseEntity):
5050
name: str
51-
wid: int
51+
wid: int = Field(alias="workspace_id")
5252

5353

5454
class Task(BaseEntity):
5555
name: str
56-
pid: int
57-
wid: int
58-
uid: Optional[int] = None
56+
pid: int = Field(alias="project_id")
57+
wid: int = Field(alias="workspace_id")
58+
uid: Optional[int] = Field(alias="user_id", default=None)
5959
estimated_seconds: Optional[int] = None
60+
tracked_seconds: Optional[int] = None
6061
active: Optional[bool] = True
6162

6263

@@ -69,7 +70,7 @@ class TimeEntry(BaseEntity):
6970
start: Union[datetime, Callable[[], datetime]] = datetime.now
7071
stop: Optional[Union[datetime, Callable[[], datetime]]] = None
7172
duration: int
72-
created_with: Optional[str]
73+
created_with: Optional[str] = None
7374
tags: List[str] = []
7475
duronly: Optional[bool] = None
7576

@@ -89,33 +90,11 @@ class ReportTimeEntry(BaseEntity):
8990
tags: List[str] = []
9091

9192

92-
class User(BaseEntity):
93-
api_token: Optional[str] = None
94-
default_wid: Optional[int] = None
95-
email: EmailStr
96-
fullname: str
97-
jquery_timeofday_format: str
98-
jquery_date_format: str
99-
timeofday_format: str
100-
date_format: str
101-
store_start_and_stop_time: bool
102-
beginning_of_week: int = 0
103-
language: str
104-
image_url: HttpUrl
105-
sidebar_piechart: bool
106-
new_blog_post: Optional[Dict[str, Any]] = None
107-
send_product_emails: bool
108-
send_weekly_report: bool
109-
send_timer_notifications: bool
110-
openid_enabled: bool
111-
timezone: str
112-
113-
11493
class Workspace(BaseEntity):
11594
name: str
11695
premium: bool
11796
admin: bool
118-
default_hourly_rate: float
97+
default_hourly_rate: Optional[float] = None
11998
default_currency: str
12099
only_admins_may_create_projects: bool
121100
only_admins_see_billable_rates: bool
@@ -124,6 +103,24 @@ class Workspace(BaseEntity):
124103
logo_url: Optional[HttpUrl] = None
125104

126105

106+
class User(BaseEntity):
107+
api_token: Optional[str] = None
108+
default_wid: Optional[int] = Field(alias="default_workspace_id", default=None)
109+
email: EmailStr
110+
fullname: str
111+
beginning_of_week: int = 0
112+
image_url: Optional[HttpUrl] = None
113+
openid_enabled: Optional[bool] = None
114+
timezone: Optional[str] = None
115+
country_id: Optional[int] = None
116+
projects: Optional[Project] = None
117+
tags: Optional[Tag] = None
118+
tasks: Optional[Task] = None
119+
time_entries: Optional[TimeEntry] = None
120+
updated_at: str
121+
workspaces: Optional[Workspace] = None
122+
123+
127124
class WorkspaceUser(BaseEntity):
128125
uid: int
129126
wid: int

toggl_python/repository.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,15 @@ def additionat_method(
106106
if not self.DETAIL_URL:
107107
raise AttributeError("Not defined DETAIL_URL")
108108
_url = (self.DETAIL_URL + "/" + url).format(id=_id)
109-
return self._list(_url, entity, headers=self.HEADERS, param=params)
109+
print("___url", _url)
110+
return self._list(_url, entity, headers=self.HEADERS, param=params, data_key=data_key)
110111
elif single_item:
111-
_url = str(self.BASE_URL) + "/" + url
112+
_url = str(self.BASE_URL) + f"{url}"
112113
return self._retrieve(
113114
_url,
114115
entity,
115116
headers=self.HEADERS,
116117
params=params,
117-
data_key="data",
118118
)
119119
else:
120120
raise NotSupported
@@ -123,7 +123,7 @@ def _retrieve(
123123
self,
124124
_url: Union[str, httpx.URL],
125125
entity_class: Any,
126-
data_key: Optional[str] = "data",
126+
data_key: Optional[str] = None,
127127
**kwargs: Any,
128128
) -> Any:
129129
params = kwargs
@@ -153,8 +153,11 @@ def _list(
153153
params = kwargs
154154
params.update(self.ADDITIONAL_PARAMS.get("list", {}))
155155

156+
print("_url", _url)
157+
156158
response = self.get(_url, params=params)
157159
response_body = response.json()
160+
print("response_body", response_body)
158161

159162
data = response_body
160163
data_key = data_key or self.DATA_CONTAINER.get("list", None)
@@ -229,7 +232,7 @@ class Tasks(BaseRepository):
229232

230233

231234
class TimeEntries(BaseRepository):
232-
LIST_URL = "time_entries"
235+
LIST_URL = "me/time_entries"
233236
ENTITY_CLASS = TimeEntry
234237

235238

@@ -259,7 +262,7 @@ class Workspaces(BaseRepository):
259262
"users": {"url": "users", "entity": User, "detail": False},
260263
"clients": {"url": "clients", "entity": Client, "detail": False},
261264
"groups": {"url": "groups", "entity": Group, "detail": False},
262-
"tasks": {"url": "tasks", "entity": Task, "detail": False},
265+
"tasks": {"url": "tasks", "entity": Task, "data_key": "data", "detail": False},
263266
"tags": {"url": "tags", "entity": Tag, "detail": False},
264267
"workspace_users": {
265268
"url": "workspace_users",

0 commit comments

Comments
 (0)