From d49d6fcae093bf85a32aa7b74440db35b4cd2ccc Mon Sep 17 00:00:00 2001 From: thearchitector Date: Fri, 5 Apr 2024 19:02:06 -0400 Subject: [PATCH] add: typed example --- examples/typed_calls.py | 52 ++++++++++++++++++++++++++++++++++++++++ indico/client/request.py | 5 +++- 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 examples/typed_calls.py diff --git a/examples/typed_calls.py b/examples/typed_calls.py new file mode 100644 index 00000000..776a4559 --- /dev/null +++ b/examples/typed_calls.py @@ -0,0 +1,52 @@ +""" +The async client can be used as a replacement for the synchronous +IndicoClient to make concurrent calls to the platform +""" + +import asyncio +from typing import AsyncIterator, List + +from indico import AsyncIndicoClient, IndicoConfig +from indico.queries import CreateDataset +from indico.queries.datasets import GetDataset, ListDatasets +from indico.types.dataset import Dataset +from indico.types.submission import Submission + +""" +Example illustrating how to use the client in typed contexts +""" + +config = IndicoConfig(host="try.indico.io") + + +async def main(): + async with AsyncIndicoClient(config=config) as client: + ipa_version: str = await client.get_ipa_version() + print(ipa_version) + + filename: str = "my_file_for_all_datasets.pdf" + + # CreateDataset is typed to return a Dataset, so multiple concurrent calls + # via asyncio.gather should, and does, return List[Dataset] + datasets: List[Dataset] = await asyncio.gather( + *( + client.call(CreateDataset(name=f"My Dataset {i}", files=[filename])) + for i in range(1, 4) + ) + ) + assert len(datasets) == 3 + + # paginated calls are also properly typed + pages: AsyncIterator[List[Dataset]] = client.paginate(ListDatasets()) + async for datasets in pages: + for d in datasets: + print(d.id) + + # incorrect typing will throw mypy / ide linting errors when using those tools. + # here, Pyright correctly reports '"Dataset" is not the same as "Submission"' + not_a_submission: Submission = await client.call(GetDataset(datasets[0].id)) + + +if __name__ == "__main__": + # How to run a Python script using async + asyncio.run(main()) diff --git a/indico/client/request.py b/indico/client/request.py index 4ff7b8fc..a4bd2775 100644 --- a/indico/client/request.py +++ b/indico/client/request.py @@ -121,7 +121,10 @@ class RequestChain(Generic[ResponseType]): def requests( self, ) -> "Iterator[Union[RequestChain[Any], HTTPRequest[Any], Delay]]": - ... + raise NotImplementedError( + "RequestChains must define an iterator for their requests;" + "otherwise, subclass GraphQLResponse instead." + ) class Delay: