[arvados] created: 2.7.0-5360-g44f7408d23
git repository hosting
git at public.arvados.org
Sat Nov 18 21:45:29 UTC 2023
at 44f7408d23ccfbb51dbc06522302af5e4aa53da7 (commit)
commit 44f7408d23ccfbb51dbc06522302af5e4aa53da7
Author: Brett Smith <brett.smith at curii.com>
Date: Sat Nov 18 16:41:04 2023 -0500
21132: Annotate API methods as returning a request object
This is a factual correction. Before this, it looked like the API
methods communicated with the API server and returned a response
directly, which is not true.
Unfortunately pdoc doesn't render the documentation for the
ArvadosAPIRequest.execute override. That's frustrating. I looked for
ways to coerce this but didn't find any. Hopefully the class docstring
gives users enough information about what they need to do. pydoc renders
it as expected, so I still think it's worth keeping.
Arvados-DCO-1.1-Signed-off-by: Brett Smith <brett.smith at curii.com>
diff --git a/sdk/python/discovery2pydoc.py b/sdk/python/discovery2pydoc.py
index e37784e06d..4fe050baf0 100755
--- a/sdk/python/discovery2pydoc.py
+++ b/sdk/python/discovery2pydoc.py
@@ -96,15 +96,51 @@ to list the specific keys you need. Refer to the API documentation for details.
_MODULE_PRELUDE = '''
import googleapiclient.discovery
+import googleapiclient.http
+import httplib2
import sys
-from typing import Any, Dict, List
+from typing import Any, Dict, Generic, List, Optional, TypeVar
if sys.version_info < (3, 8):
from typing_extensions import TypedDict
else:
from typing import TypedDict
+
+# ST represents an API response type
+ST = TypeVar('ST', bound=TypedDict)
+'''
+_REQUEST_CLASS = '''
+class ArvadosAPIRequest(googleapiclient.http.HttpRequest, Generic[ST]):
+ """Generic API request object
+
+ When you call an API method in the Arvados Python SDK, it returns a
+ request object. You usually call `execute()` on this object to submit the
+ request to your Arvados API server and retrieve the response. `execute()`
+ will return the type of object annotated in the subscript of
+ `ArvadosAPIRequest`.
+ """
+
+ def execute(self, http: Optional[httplib2.Http]=None, num_retries: int=0) -> ST:
+ """Execute this request and return the response
+
+ Arguments:
+
+ * http: httplib2.Http | None --- The HTTP client object to use to
+ execute the request. If not specified, uses the HTTP client object
+ created with the API client object.
+
+ * num_retries: int --- The maximum number of times to retry this
+ request if the server returns a retryable failure. The API client
+ object also has a maximum number of retries specified when it is
+ instantiated (see `arvados.api.api_client`). This request is run
+ with the larger of that number and this argument. Default 0.
+ """
+
'''
-_TYPE_MAP = {
+# Annotation represents a valid Python type annotation. Future development
+# could expand this to include other valid types like `type`.
+Annotation = str
+_TYPE_MAP: Mapping[str, Annotation] = {
# Map the API's JavaScript-based type names to Python annotations.
# Some of these may disappear after Arvados issue #19795 is fixed.
'Array': 'List',
@@ -198,9 +234,15 @@ class Parameter(inspect.Parameter):
class Method:
- def __init__(self, name: str, spec: Mapping[str, Any]) -> None:
+ def __init__(
+ self,
+ name: str,
+ spec: Mapping[str, Any],
+ annotate: Callable[[Annotation], Annotation]=str,
+ ) -> None:
self.name = name
self._spec = spec
+ self._annotate = annotate
self._required_params = []
self._optional_params = []
for param_name, param_spec in spec['parameters'].items():
@@ -223,6 +265,7 @@ class Method:
returns = get_type_annotation(self._spec['response']['$ref'])
except KeyError:
returns = 'Dict[str, Any]'
+ returns = self._annotate(returns)
return inspect.Signature(parameters, return_annotation=returns)
def doc(self, doc_slice: slice=slice(None)) -> str:
@@ -286,7 +329,7 @@ def document_resource(name: str, spec: Mapping[str, Any]) -> str:
if class_name in _DEPRECATED_RESOURCES:
docstring += _DEPRECATED_NOTICE
methods = [
- Method(key, meth_spec)
+ Method(key, meth_spec, 'ArvadosAPIRequest[{}]'.format)
for key, meth_spec in spec['methods'].items()
if key not in _ALIASED_METHODS
]
@@ -355,7 +398,11 @@ def main(arglist: Optional[Sequence[str]]=None) -> int:
for name, resource_spec in resources:
print(document_resource(name, resource_spec), file=args.out_file)
- print('''class ArvadosAPIClient(googleapiclient.discovery.Resource):''', file=args.out_file)
+ print(
+ _REQUEST_CLASS,
+ '''class ArvadosAPIClient(googleapiclient.discovery.Resource):''',
+ sep='\n', file=args.out_file,
+ )
for name, _ in resources:
class_name = classify_name(name)
docstring = f"Return an instance of `{class_name}` to call methods via this client"
commit 4571ee1ebc16366997b28561e85e07717da62be9
Author: Brett Smith <brett.smith at curii.com>
Date: Sat Nov 18 12:22:54 2023 -0500
21132: Note ArvadosAPIClient is a Resource
The real impact of this change is marginal, but it establishes a pattern
for documenting request objects, which will be more substantial.
Arvados-DCO-1.1-Signed-off-by: Brett Smith <brett.smith at curii.com>
diff --git a/sdk/python/discovery2pydoc.py b/sdk/python/discovery2pydoc.py
index d2f206c80f..e37784e06d 100755
--- a/sdk/python/discovery2pydoc.py
+++ b/sdk/python/discovery2pydoc.py
@@ -95,6 +95,7 @@ to list the specific keys you need. Refer to the API documentation for details.
'''
_MODULE_PRELUDE = '''
+import googleapiclient.discovery
import sys
from typing import Any, Dict, List
if sys.version_info < (3, 8):
@@ -354,7 +355,7 @@ def main(arglist: Optional[Sequence[str]]=None) -> int:
for name, resource_spec in resources:
print(document_resource(name, resource_spec), file=args.out_file)
- print('''class ArvadosAPIClient:''', file=args.out_file)
+ print('''class ArvadosAPIClient(googleapiclient.discovery.Resource):''', file=args.out_file)
for name, _ in resources:
class_name = classify_name(name)
docstring = f"Return an instance of `{class_name}` to call methods via this client"
commit 6f481c9e2379cc470d2fb392b6fd495fc7cc8f21
Author: Brett Smith <brett.smith at curii.com>
Date: Sat Nov 18 10:18:22 2023 -0500
21136: Use typing generics for builtins in api_resources
The immediate problem this solves is that using `list` unqualified as an
annotation causes pdoc to resolve it as the current class' `list`
method, which is not correct.
We could also specify `builtins.list`, but since it doesn't support
subscripting in Python 3.8, that generates a lot of noisy warnings right
now. So this solution is better for now, and we'll probably migrate to
`builtins.list` in the future.
Arvados-DCO-1.1-Signed-off-by: Brett Smith <brett.smith at curii.com>
diff --git a/sdk/python/discovery2pydoc.py b/sdk/python/discovery2pydoc.py
index 6ca3aafeb6..d2f206c80f 100755
--- a/sdk/python/discovery2pydoc.py
+++ b/sdk/python/discovery2pydoc.py
@@ -96,24 +96,24 @@ to list the specific keys you need. Refer to the API documentation for details.
_MODULE_PRELUDE = '''
import sys
+from typing import Any, Dict, List
if sys.version_info < (3, 8):
- from typing import Any
from typing_extensions import TypedDict
else:
- from typing import Any, TypedDict
+ from typing import TypedDict
'''
_TYPE_MAP = {
# Map the API's JavaScript-based type names to Python annotations.
# Some of these may disappear after Arvados issue #19795 is fixed.
- 'Array': 'list',
- 'array': 'list',
+ 'Array': 'List',
+ 'array': 'List',
'boolean': 'bool',
# datetime fields are strings in ISO 8601 format.
'datetime': 'str',
- 'Hash': 'dict[str, Any]',
+ 'Hash': 'Dict[str, Any]',
'integer': 'int',
- 'object': 'dict[str, Any]',
+ 'object': 'Dict[str, Any]',
'string': 'str',
'text': 'str',
}
@@ -221,7 +221,7 @@ class Method:
try:
returns = get_type_annotation(self._spec['response']['$ref'])
except KeyError:
- returns = 'dict[str, Any]'
+ returns = 'Dict[str, Any]'
return inspect.Signature(parameters, return_annotation=returns)
def doc(self, doc_slice: slice=slice(None)) -> str:
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list