8000 chore(typing): endpoint decorators · tableau/server-client-python@ffa0601 · GitHub
[go: up one dir, main page]

Skip to content

Commit ffa0601

Browse files
committed
chore(typing): endpoint decorators
1 parent 8b728a5 commit ffa0601

File tree

4 files changed

+49
-21
lines changed

4 files changed

+49
-21
lines changed

tableauserverclient/server/endpoint/datasources_endpoint.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def download(
126126
datasource_id: str,
127127
filepath: Optional[PathOrFileW] = None,
128128
include_extract: bool = True,
129-
) -> str:
129+
) -> PathOrFileW:
130130
return self.download_revision(
131131
datasource_id,
132132
None,
@@ -405,7 +405,7 @@ def _get_datasource_revisions(
405405
def download_revision(
406406
self,
407407
datasource_id: str,
408-
revision_number: str,
408+
revision_number: Optional[str],
409409
filepath: Optional[PathOrFileW] = None,
410410
include_extract: bool = True,
411411
) -> PathOrFileW:

tableauserverclient/server/endpoint/endpoint.py

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,42 @@
1+
from typing_extensions import Concatenate
12
from tableauserverclient import datetime_helpers as datetime
23

34
import abc
45
from packaging.version import Version
56
from functools import wraps
67
from xml.etree.ElementTree import ParseError
7-
from typing import Any, Callable, Dict, Generic, List, Optional, TYPE_CHECKING, Tuple, TypeVar, Union
8+
from typing import (
9+
Any,
10+
Callable,
11+
Dict,
12+
Generic,
13+
List,
14+
Optional,
15+
TYPE_CHECKING,
16+
ParamSpec,
17+
Tuple,
18+
TypeVar,
19+
Union,
20+
)
821

922
from tableauserverclient.models.pagination_item import PaginationItem
1023
from tableauserverclient.server.request_options import RequestOptions
1124

12-
from .exceptions import (
25+
from tableauserverclient.server.endpoint.exceptions import (
1326
ServerResponseError,
1427
InternalServerError,
1528
NonXMLResponseError,
1629
E864 NotSignedInError,
1730
)
18-
from ..exceptions import EndpointUnavailableError
31+
from tableauserverclient.server.exceptions import EndpointUnavailableError
1932

2033
from tableauserverclient.server.query import QuerySet
2134
from tableauserverclient import helpers, get_versions
2235

2336
from tableauserverclient.helpers.logging import logger
24-
from tableauserverclient.config import DELAY_SLEEP_SECONDS
2537

2638
if TYPE_CHECKING:
27-
from ..server import Server
39+
from tableauserverclient.server.server import Server
2840
from requests import Response
2941

3042

@@ -38,7 +50,7 @@
3850
USER_AGENT_HEADER = "User-Agent"
3951

4052

41-
class Endpoint(object):
53+
class Endpoint:
4254
def __init__(self, parent_srv: "Server"):
4355
self.parent_srv = parent_srv
4456

@@ -232,7 +244,12 @@ def patch_request(self, url, xml_request, content_type=XML_CONTENT_TYPE, paramet
232244
)
233245

234246

235-
def api(version):
247+
E = TypeVar("E", bound="Endpoint")
248+
P = ParamSpec("P")
249+
R = TypeVar("R")
250+
251+
252+
def api(version: str) -> Callable[[Callable[Concatenate[E, P], R]], Callable[Concatenate[E, P], R]]:
236253
"""Annotate the minimum supported version for an endpoint.
237254
238255
Checks the version on the server object and compares normalized versions.
@@ -251,9 +268,9 @@ def api(version):
251268
>>> ...
252269
"""
253270

254-
def _decorator(func):
271+
def _decorator(func: Callable[Concatenate[E, P], R]) -> Callable[Concatenate[E, P], R]:
255272
@wraps(func)
256-
def wrapper(self, *args, **kwargs):
273+
def wrapper(self: E, *args: P.args, **kwargs: P.kwargs) -> R:
257274
self.parent_srv.assert_at_least_version(version, self.__class__.__name__)
258275
return func(self, *args, **kwargs)
259276

@@ -262,7 +279,7 @@ def wrapper(self, *args, **kwargs):
262279
return _decorator
263280

264281

265-
def parameter_added_in(**params):
282+
def parameter_added_in(**params: str) -> Callable[[Callable[Concatenate[E, P], R]], Callable[Concatenate[E, P], R]]:
266283
"""Annotate minimum versions for new parameters or request options on an endpoint.
267284
268285
The api decorator documents when an endpoint was added, this decorator annotates
@@ -285,9 +302,9 @@ def parameter_added_in(**params):
285302
>>> ...
286303
"""
287304

288-
def _decorator(func):
305+
def _decorator(func: Callable[Concatenate[E, P], R]) -> Callable[Concatenate[E, P], R]:
289306
@wraps(func)
290-
def wrapper(self, *args, **kwargs):
307+
def wrapper(self: E, *args: P.args, **kwargs: P.kwargs) -> R:
291308
import warnings
292309

293310
server_ver = Version(self.parent_srv.version or "0.0")
@@ -335,5 +352,5 @@ def paginate(self, **kwargs) -> QuerySet[T]:
335352
return queryset
336353

337354
@abc.abstractmethod
338-
def get(self, request_options: RequestOptions) -> Tuple[List[T], PaginationItem]:
355+
def get(self, request_options: Optional[RequestOptions] = None) -> Tuple[List[T], PaginationItem]:
339356
raise NotImplementedError(f".get has not been implemented for {self.__class__.__qualname__}")

tableauserverclient/server/endpoint/jobs_endpoint.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import logging
2+
from typing_extensions import Self, overload
23

34
from tableauserverclient.server.query import QuerySet
45

@@ -13,15 +14,25 @@
1314
from typing import List, Optional, Tuple, Union
1415

1516

16-
class Jobs(QuerysetEndpoint[JobItem]):
17+
class Jobs(QuerysetEndpoint[BackgroundJobItem]):
1718
@property
1819
def baseurl(self):
1920
return "{0}/sites/{1}/jobs".format(self.parent_srv.baseurl, self.parent_srv.site_id)
2021

22+
@overload # type: ignore[override]
23+
def get(self: Self, job_id: str, req_options: Optional[RequestOptionsBase] = None) -> JobItem: # type: ignore[override]
24+
...
25+
26+
@overload # type: ignore[override]
27+
def get(self: Self, job_id: RequestOptionsBase, req_options: None) -> Tuple[List[BackgroundJobItem], PaginationItem]: # type: ignore[override]
28+
...
29+
30+
@overload # type: ignore[override]
31+
def get(self: Self, job_id: None, req_options: Optional[RequestOptionsBase]) -> Tuple[List[BackgroundJobItem], PaginationItem]: # type: ignore[override]
32+
...
33+
2134
@api(version="2.6")
22-
def get(
23-
self, job_id: Optional[str] = None, req_options: Optional[RequestOptionsBase] = None
24-
) -> Tuple[List[BackgroundJobItem], PaginationItem]:
35+
def get(self, job_id=None, req_options=None):
2536
# Backwards Compatibility fix until we rev the major version
2637
if job_id is not None and isinstance(job_id, str):
2738
import warnings
@@ -77,7 +88,7 @@ def wait_for_job(self, job_id: Union[str, JobItem], *, timeout: Optional[float]
7788
else:
7889
raise AssertionError("Unexpected finish_code in job", job)
7990

80-
def filter(self, *invalid, page_size: Optional[int] = None, **kwargs) -> QuerySet[JobItem]:
91+
def filter(self, *invalid, page_size: Optional[int] = None, **kwargs) -> QuerySet[BackgroundJobItem]:
8192
"""
8293
Queries the Tableau Server for items using the specified filters. Page
8394
size can be specified to limit the number of items returned in a single

tableauserverclient/server/endpoint/workbooks_endpoint.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ def download(
184184
workbook_id: str,
185185
filepath: Optional[PathOrFileW] = None,
186186
include_extract: bool = True,
187-
) -> str:
187+
) -> PathOrFileW:
188188
return self.download_revision(
189189
workbook_id,
190190
None,

0 commit comments

Comments
 (0)
0