@@ -67,31 +67,33 @@ def open(
6767 request_modifier : Callable [[Request ], Request ] | None = None ,
6868 timeout : TimeoutTypes | None = None ,
6969 ) -> "Client" :
70- """Opens a STAPI API client
70+ """Opens a STAPI API client.
7171
7272 Args:
73- url : The URL of a STAPI API.
74- headers : A dictionary of additional headers to use in all requests
75- made to any part of this STAPI API.
73+ url: The URL of a STAPI API
74+ headers: Optional dictionary of additional headers to use in all requests
75+ made to any part of this STAPI API
7676 parameters: Optional dictionary of query string parameters to
77- include in all requests.
78- request_modifier: A callable that either modifies a ` Request` instance or
77+ include in all requests
78+ request_modifier: Optional callable that modifies a Request instance or
7979 returns a new one. This can be useful for injecting Authentication
8080 headers and/or signing fully-formed requests (e.g. signing requests
8181 using AWS SigV4).
82-
8382 The callable should expect a single argument, which will be an instance
84- of :class:`requests.Request`.
85-
86- If the callable returns a `requests.Request`, that will be used.
83+ of :class:`httpx.Request`.
84+ If the callable returns a `httpx.Request`, that will be used.
8785 Alternately, the callable may simply modify the provided request object
88- and return `None`.
89- timeout: Optional float or (float, float) tuple following the semantics
90- defined by `Requests
91- <https://requests.readthedocs.io/en/latest/api/#main-interface>`__.
86+ and return `None`
87+ timeout: Optional timeout configuration. Can be:
88+ - None to disable timeouts
89+ - float for a default timeout
90+ - tuple of (connect, read, write, pool) timeouts, each being float or None
91+ - httpx.Timeout instance for fine-grained control
92+ See `httpx timeouts <https://www.python-httpx.org/advanced/timeouts/>`__
93+ for details
9294
93- Return :
94- client : A :class:`Client` instance for this STAPI API
95+ Returns :
96+ Client : A :class:`Client` instance for this STAPI API
9597 """
9698 stapi_io = StapiIO (
9799 root_url = AnyUrl (url ),
@@ -118,11 +120,11 @@ def get_single_link(
118120 """Get a single :class:`~stapi_pydantic.Link` instance associated with this object.
119121
120122 Args:
121- rel : If set, filter links such that only those
122- matching this relationship are returned .
123- media_type: If set, filter the links such that only
124- those matching media_type are returned. media_type can
125- be a single value or a list of values.
123+ rel: Optional relationship filter. If set, only links matching this
124+ relationship are considered .
125+ media_type: Optional media type filter. If set, only links matching
126+ this media type are considered. Can be a single value or an
127+ iterable of values.
126128
127129 Returns:
128130 :class:`~stapi_pydantic.Link` | None: First link that matches ``rel``
@@ -161,6 +163,15 @@ def read_links(self) -> None:
161163 ]
162164
163165 def read_conformance (self ) -> None :
166+ """Read the API conformance from the root of the STAPI API.
167+
168+ The conformance is stored in `Client.conforms_to`. This method attempts to read
169+ from "/conformance" endpoint first, then falls back to the root endpoint "/".
170+
171+ Note:
172+ This method silently continues if endpoints return APIError, no exceptions
173+ are raised.
174+ """
164175 conformance : list [str ] = []
165176 for endpoint in ["/conformance" , "/" ]:
166177 try :
@@ -173,22 +184,26 @@ def read_conformance(self) -> None:
173184 self .set_conforms_to (conformance )
174185
175186 def has_conforms_to (self ) -> bool :
176- """Whether server contains list of ``"conformsTo"`` URIs"""
187+ """Whether server contains list of ``"conformsTo"`` URIs
188+
189+ Return:
190+ Whether the server contains list of ``"conformsTo"`` URIs
191+ """
177192 return bool (self .conforms_to )
178193
179194 def get_conforms_to (self ) -> list [str ]:
180195 """List of ``"conformsTo"`` URIs
181196
182197 Return:
183- list[str]: List of URIs that the server conforms to
198+ List of URIs that the server conforms to
184199 """
185200 return self .conforms_to .copy ()
186201
187202 def set_conforms_to (self , conformance_uris : list [str ]) -> None :
188203 """Set list of ``"conformsTo"`` URIs
189204
190205 Args:
191- conformance_uris : URIs indicating what the server conforms to
206+ conformance_uris: URIs indicating what the server conforms to
192207 """
193208 self .conforms_to = conformance_uris
194209
@@ -204,7 +219,7 @@ def add_conforms_to(self, name: str) -> None:
204219 """Add ``"conformsTo"`` by name.
205220
206221 Args:
207- name : name of :py:class:`ConformanceClasses` keys to add.
222+ name: Name of :py:class:`ConformanceClasses` keys to add.
208223 """
209224 conformance_class = ConformanceClasses .get_by_name (name )
210225
@@ -215,7 +230,7 @@ def remove_conforms_to(self, name: str) -> None:
215230 """Remove ``"conformsTo"`` by name.
216231
217232 Args:
218- name : name of :py:class:`ConformanceClasses` keys to remove.
233+ name: Name of :py:class:`ConformanceClasses` keys to remove.
219234 """
220235 conformance_class = ConformanceClasses .get_by_name (name )
221236
@@ -230,21 +245,24 @@ def has_conformance(self, conformance_class: ConformanceClasses | str) -> bool:
230245 provides such an endpoint.
231246
232247 Args:
233- name : name of :py:class:`ConformanceClasses` keys to check
234- conformance against.
248+ conformance_class: Either a ConformanceClasses enum member or a
249+ string name of a conformance class to check against
250+
235251
236252 Return:
237- bool: Indicates if the API conforms to the given spec or URI.
253+ Indicates if the API conforms to the given spec or URI.
238254 """
239255 if isinstance (conformance_class , str ):
240256 conformance_class = ConformanceClasses .get_by_name (conformance_class )
241257
242258 return any (re .match (conformance_class .pattern , uri ) for uri in self .get_conforms_to ())
243259
244260 def _supports_opportunities (self ) -> bool :
261+ """Check if the API supports opportunities"""
245262 return self .has_conformance (ConformanceClasses .OPPORTUNITIES )
246263
247264 def _supports_async_opportunities (self ) -> bool :
265+ """Check if the API supports asynchronous opportunities"""
248266 return self .has_conformance (ConformanceClasses .ASYNC_OPPORTUNITIES )
249267
250268 def get_products (self , limit : int | None = None ) -> Iterator [Product ]:
@@ -346,6 +364,17 @@ def create_product_order(self, product_id: str, order_parameters: OrderPayload)
346364 return Order .model_validate (product_order_json )
347365
348366 def _get_products_href (self , product_id : str | None = None , subpath : str | None = None ) -> str :
367+ """Get the href for the products endpoint
368+
369+ Args:
370+ product_id: Optional product ID to get the href for
371+
372+ Returns:
373+ str: The href for the products endpoint
374+
375+ Raises:
376+ ValueError: When no products link is found in the API
377+ """
349378 product_link = self .get_single_link ("products" )
350379 if product_link is None :
351380 raise ValueError ("No products link found" )
@@ -368,6 +397,9 @@ def get_orders(self, limit: int | None = None) -> Iterator[Order]: # type: igno
368397 # TODO Update return type after the pydantic model generic type is fixed
369398 """Get orders from this STAPI API
370399
400+ Args:
401+ limit: Optional limit on the number of orders to return
402+
371403 Returns:
372404 Iterator[Order]: An iterator of STAPI Orders
373405 """
@@ -395,7 +427,7 @@ def get_order(self, order_id: str) -> Order: # type: ignore[type-arg]
395427 Order: A STAPI Order
396428
397429 Raises:
398- ValueError if order_id does not exist.
430+ ValueError: When the specified order_id does not exist
399431 """
400432
401433 order_endpoint = self ._get_orders_href (order_id )
@@ -407,6 +439,18 @@ def get_order(self, order_id: str) -> Order: # type: ignore[type-arg]
407439 return Order .model_validate (order_json )
408440
409441 def _get_orders_href (self , order_id : str | None = None ) -> str :
442+ """Get the href for the orders endpoint
443+
444+ Args:
445+ order_id: Optional order ID to get the href for
446+
447+ Returns:
448+ The href for the orders endpoint
449+
450+ Raises:
451+ ValueError: When no orders link is found in the API
452+ """
453+
410454 order_link = self .get_single_link ("orders" )
411455 if order_link is None :
412456 raise ValueError ("No orders link found" )
0 commit comments