1818 Search ,
1919 SearchData ,
2020)
21- from bookshop .client .runtime import ExecutionError , UnexpectedNullError
22- from bookshop .client .schema import Address , BookFilter , OrderStatus
2321from bookshop .get_order_graphql import GetOrder , GetOrderData
22+ from bookshop .graphql .runtime import ExecutionError , UnexpectedNullError , merge
23+ from bookshop .graphql .schema import Address , BookFilter , OrderStatus
2424from bookshop .scalar import ISBN
25- from bookshop .transport import Client , SubscriptionClient
25+ from bookshop .transport import send , subscribe
2626
2727
28- def describe (isbn : ISBN , / , * , client : Client ) -> str :
28+ def describe (isbn : ISBN , / ) -> str :
2929 variables : GetBookVariables = {"lookup" : {"isbn" : isbn }}
3030
31+ # Caught only to show what the error carries.
32+ # You would usually let the error propagate since a null here is a bug.
3133 try :
32- data = client (GetBook (variables ))
34+ data = send (GetBook (variables ))
3335 except UnexpectedNullError as error :
3436 assert error .path == ["book" ]
3537 assert error .__notes__ == [f"Raised by `GetBook` with variables { variables !r} ." ]
@@ -46,15 +48,10 @@ def describe(isbn: ISBN, /, *, client: Client) -> str:
4648 return f"{ book ['title' ]} , { by } , costs { book ['price' ]:.2f} ."
4749
4850
49- def book_and_similar (
50- isbn : ISBN , text : str , / , * , client : Client
51- ) -> tuple [str , list [str ]]:
52- # Two queries in one call to the transport.
53- book_data , search_data = client (
54- (
55- GetBook ({"lookup" : {"isbn" : isbn }}),
56- Search ({"text" : text }),
57- )
51+ def book_and_similar (isbn : ISBN , text : str , / ) -> tuple [str , list [str ]]:
52+ # Two queries in one request.
53+ book_data , search_data = send (
54+ merge (GetBook ({"lookup" : {"isbn" : isbn }}), Search ({"text" : text }))
5855 )
5956 assert_type (book_data , GetBookData )
6057 assert_type (search_data , SearchData )
@@ -67,19 +64,21 @@ def book_and_similar(
6764
6865
6966def look_up (
70- isbns : Sequence [ISBN ], publication_ids : Sequence [str ], / , * , client : Client
67+ isbns : Sequence [ISBN ], publication_ids : Sequence [str ], /
7168) -> tuple [GetBookData | GetPublicationData , ...]:
72- # Any number of queries in one call to the transport.
73- return client ( # ty: ignore[unsound-return-statement] # Pyright and Pyrefly already infer this.
74- [
75- * (GetBook ({"lookup" : {"isbn" : isbn }}) for isbn in isbns ),
76- * (GetPublication ({"id" : id_ }) for id_ in publication_ids ),
77- ]
69+ # Any number of queries in one request.
70+ return send ( # ty: ignore[unsound-return-statement] # Pyright and Pyrefly already infer this.
71+ merge (
72+ [
73+ * (GetBook ({"lookup" : {"isbn" : isbn }}) for isbn in isbns ),
74+ * (GetPublication ({"id" : id_ }) for id_ in publication_ids ),
75+ ]
76+ )
7877 )
7978
8079
81- def run_saved_search (name : str , / , * , client : Client ) -> list [str ]:
82- data = client (GetSavedSearch ({"name" : name }))
80+ def run_saved_search (name : str , / ) -> list [str ]:
81+ data = send (GetSavedSearch ({"name" : name }))
8382 search = data ["savedSearch" ]
8483
8584 if search is None :
@@ -88,12 +87,12 @@ def run_saved_search(name: str, /, *, client: Client) -> list[str]:
8887 book_filter = search ["value" ]
8988 assert_type (book_filter , BookFilter | None )
9089 # Sent back as is.
91- books = client (ListBooks ({"filter" : book_filter }))
90+ books = send (ListBooks ({"filter" : book_filter }))
9291 return [book ["title" ] for book in books ["books" ]]
9392
9493
95- def length (publication_id : str , / , * , client : Client ) -> str :
96- data = client (GetPublication ({"id" : publication_id }))
94+ def length (publication_id : str , / ) -> str :
95+ data = send (GetPublication ({"id" : publication_id }))
9796 publication = data ["publication" ]
9897
9998 if publication is None :
@@ -120,12 +119,12 @@ def status_label(status: OrderStatus, /) -> str:
120119 case "CANCELED" :
121120 return "Canceled"
122121 case _:
123- # A member added after this client was generated .
122+ # A member added after codegen .
124123 return status .replace ("_" , " " ).capitalize ()
125124
126125
127- def cheaper_than (limit : Decimal , / , * , client : Client ) -> list [str ]:
128- data = client (ListBooks ({"filter" : {"priceBelow" : limit }}))
126+ def cheaper_than (limit : Decimal , / ) -> list [str ]:
127+ data = send (ListBooks ({"filter" : {"priceBelow" : limit }}))
129128 labels : list [str ] = []
130129
131130 for book in data ["books" ]:
@@ -136,8 +135,8 @@ def cheaper_than(limit: Decimal, /, *, client: Client) -> list[str]:
136135 return labels
137136
138137
139- def order (book_id : str , address : Address , / , * , client : Client ) -> str :
140- data = client (
138+ def order (book_id : str , address : Address , / ) -> str :
139+ data = send (
141140 PlaceOrder (
142141 {"input" : {"lines" : [{"book" : book_id }], "shippingAddress" : address }}
143142 )
@@ -148,24 +147,8 @@ def order(book_id: str, address: Address, /, *, client: Client) -> str:
148147 return f"Order { order ['id' ]} : { order ['total' ]:.2f} at { order ['placedAt' ]:%H:%M} ."
149148
150149
151- def cancel (order_ids : list [str ], / , * , client : Client ) -> list [str ]:
152- """Cancel the orders in one call to the transport, and explain each failure."""
153- results = client (
154- [
155- CancelOrder ({"input" : {"order" : order_id }}).returning_error ()
156- for order_id in order_ids
157- ]
158- )
159- # Each error has a note naming its operation and the variables sent.
160- return [
161- f"{ error .__notes__ [0 ]} { error !s} "
162- for error in results
163- if isinstance (error , ExecutionError )
164- ]
165-
166-
167- def track (order_id : str , / , * , client : Client ) -> str :
168- result = client (GetOrder ({"id" : order_id }).returning_error ())
150+ def track (order_id : str , / ) -> str :
151+ result = send (GetOrder ({"id" : order_id }).returning_error ())
169152
170153 if isinstance (result , ExecutionError ):
171154 data = result .parse_data ()
@@ -180,12 +163,27 @@ def track(order_id: str, /, *, client: Client) -> str:
180163 )
181164
182165
183- def watch (order_id : str , / , * , client : SubscriptionClient ) -> list [OrderStatus ]:
184- """Follow the order until it is delivered, and return its statuses."""
166+ def cancel (order_ids : list [str ], / ) -> list [str ]:
167+ results = send (
168+ merge (
169+ [
170+ CancelOrder ({"input" : {"order" : order_id }}).returning_error ()
171+ for order_id in order_ids
172+ ]
173+ )
174+ )
175+ # Each error has a note naming its operation and the variables sent.
176+ return [
177+ f"{ error .__notes__ [0 ]} { error !s} "
178+ for error in results
179+ if isinstance (error , ExecutionError )
180+ ]
181+
182+
183+ def watch (order_id : str , / ) -> list [OrderStatus ]:
185184 statuses : list [OrderStatus ] = []
186- events = client (OnOrderStatusChanged ({"orderId" : order_id }))
185+ events = subscribe (OnOrderStatusChanged ({"orderId" : order_id }))
187186
188- # Closing the stream, however the loop ends, unsubscribes.
189187 with closing (events ):
190188 for event in events :
191189 statuses .append (event ["orderStatusChanged" ]["status" ])
0 commit comments