channel3-sdk 0.2.1__tar.gz → 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of channel3-sdk might be problematic. Click here for more details.

Files changed (42) hide show
  1. channel3_sdk-0.2.1/README.md → channel3_sdk-1.0.0/PKG-INFO +99 -17
  2. channel3_sdk-0.2.1/PKG-INFO → channel3_sdk-1.0.0/README.md +70 -42
  3. channel3_sdk-1.0.0/channel3_sdk/__init__.py +52 -0
  4. channel3_sdk-1.0.0/channel3_sdk/_gen/.gitignore +23 -0
  5. channel3_sdk-1.0.0/channel3_sdk/_gen/README.md +124 -0
  6. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/__init__.py +8 -0
  7. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/api/__init__.py +1 -0
  8. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/api/channel3_api/__init__.py +1 -0
  9. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/api/channel3_api/get_brand_detail_v0_brands_brand_id_get.py +179 -0
  10. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/api/channel3_api/get_brands_v0_brands_get.py +218 -0
  11. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/api/channel3_api/get_product_detail_v0_products_product_id_get.py +179 -0
  12. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/api/channel3_api/search_v0_search_post.py +193 -0
  13. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/api/default/__init__.py +1 -0
  14. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/api/default/root_get.py +79 -0
  15. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/client.py +268 -0
  16. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/errors.py +16 -0
  17. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/models/__init__.py +35 -0
  18. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/models/availability_status.py +15 -0
  19. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/models/brand.py +109 -0
  20. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/models/error_response.py +59 -0
  21. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/models/paginated_response_brand.py +83 -0
  22. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/models/pagination_meta.py +84 -0
  23. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/models/price.py +89 -0
  24. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/models/product.py +166 -0
  25. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/models/product_detail.py +306 -0
  26. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/models/product_detail_gender_type_0.py +10 -0
  27. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/models/search_config.py +69 -0
  28. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/models/search_filter_price.py +92 -0
  29. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/models/search_filters.py +191 -0
  30. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/models/search_filters_gender_type_0.py +10 -0
  31. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/models/search_request.py +191 -0
  32. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/models/variant.py +75 -0
  33. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/py.typed +1 -0
  34. channel3_sdk-1.0.0/channel3_sdk/_gen/fast_api_client/types.py +54 -0
  35. channel3_sdk-1.0.0/channel3_sdk/_gen/pyproject.toml +26 -0
  36. channel3_sdk-1.0.0/channel3_sdk/client.py +361 -0
  37. channel3_sdk-1.0.0/pyproject.toml +55 -0
  38. channel3_sdk-0.2.1/channel3_sdk/__init__.py +0 -46
  39. channel3_sdk-0.2.1/channel3_sdk/client.py +0 -574
  40. channel3_sdk-0.2.1/channel3_sdk/models.py +0 -135
  41. channel3_sdk-0.2.1/pyproject.toml +0 -40
  42. {channel3_sdk-0.2.1 → channel3_sdk-1.0.0}/channel3_sdk/exceptions.py +0 -0
@@ -1,3 +1,31 @@
1
+ Metadata-Version: 2.1
2
+ Name: channel3-sdk
3
+ Version: 1.0.0
4
+ Summary: The official Python SDK for Channel3
5
+ Home-page: https://github.com/channel3-ai/sdk-python
6
+ License: MIT
7
+ Keywords: ai,shopping,ecommerce,search,api
8
+ Author: Channel3
9
+ Author-email: alex@trychannel3.com
10
+ Requires-Python: >=3.9,<4.0
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Libraries
21
+ Classifier: Typing :: Typed
22
+ Requires-Dist: attrs (>=22.2.0)
23
+ Requires-Dist: httpx (>=0.23.0,<0.29.0)
24
+ Requires-Dist: python-dateutil (>=2.8.0,<3.0.0)
25
+ Requires-Dist: requests (>=2.31.0,<3.0.0)
26
+ Project-URL: Repository, https://github.com/channel3-ai/sdk-python
27
+ Description-Content-Type: text/markdown
28
+
1
29
  # Channel3 Python SDK
2
30
 
3
31
  The official Python SDK for the [Channel3](https://trychannel3.com) AI Shopping API.
@@ -39,10 +67,7 @@ if product_detail.key_features:
39
67
 
40
68
  # Get all brands
41
69
  brands = client.get_brands()
42
- for brand in brands:
43
- print(f"Brand: {brand.name}")
44
- if brand.description:
45
- print(f"Description: {brand.description}")
70
+ print(f"Found {len(brands.items)} brands")
46
71
 
47
72
  # Get specific brand details
48
73
  brand = client.get_brand("brand_123")
@@ -58,23 +83,23 @@ from channel3_sdk import AsyncChannel3Client
58
83
  async def main():
59
84
  # Initialize the async client
60
85
  client = AsyncChannel3Client(api_key="your_api_key_here")
61
-
86
+
62
87
  # Search for products
63
88
  products = await client.search(query="running shoes")
64
-
89
+
65
90
  for product in products:
66
91
  print(f"Product: {product.title}")
67
92
  print(f"Score: {product.score}")
68
93
  print(f"Price: {product.price.currency} {product.price.price}")
69
-
94
+
70
95
  # Get detailed product information
71
96
  if products:
72
97
  product_detail = await client.get_product(products[0].id)
73
98
  print(f"Availability: {product_detail.availability}")
74
-
99
+
75
100
  # Get brands
76
101
  brands = await client.get_brands()
77
- print(f"Found {len(brands)} brands")
102
+ print(f"Found {len(brands.items)} brands")
78
103
 
79
104
  # Run the async function
80
105
  asyncio.run(main())
@@ -126,11 +151,39 @@ products = client.search(
126
151
  )
127
152
  ```
128
153
 
154
+ ### Search configuration and context
155
+
156
+ You can control how search behaves using `SearchConfig`, and add optional `context` to guide results.
157
+
158
+ ```python
159
+ from channel3_sdk import SearchConfig
160
+
161
+ config = SearchConfig(enrich_query=True, semantic_search=False)
162
+
163
+ products = client.search(
164
+ query="running shoes",
165
+ limit=5,
166
+ config=config, # or a dict: {"enrich_query": True, "semantic_search": False}
167
+ context="Marathon training on road surfaces"
168
+ )
169
+ ```
170
+
171
+ Async usage is identical:
172
+
173
+ ```python
174
+ products = await async_client.search(
175
+ query="hiking boots",
176
+ config={"enrich_query": False, "semantic_search": True},
177
+ context="Waterproof boots for alpine conditions"
178
+ )
179
+ ```
180
+
129
181
  ### Brand Management
130
182
 
131
183
  ```python
132
184
  # Get all brands with pagination
133
185
  brands = client.get_brands(page=1, size=50)
186
+ print(brands.pagination.total_count)
134
187
 
135
188
  # Search for specific brands
136
189
  nike_brands = client.get_brands(query="nike")
@@ -146,26 +199,31 @@ print(f"Logo: {brand_detail.logo_url}")
146
199
  ### Client Classes
147
200
 
148
201
  #### `Channel3Client`
202
+
149
203
  Synchronous client for the Channel3 API.
150
204
 
151
205
  **Methods:**
152
- - `search(query=None, image_url=None, base64_image=None, filters=None, limit=20)` → `List[Product]`
206
+
207
+ - `search(query=None, image_url=None, base64_image=None, filters=None, limit=20, config=None, context=None)` → `List[Product]`
153
208
  - `get_product(product_id)` → `ProductDetail`
154
- - `get_brands(query=None, page=1, size=100)` → `List[Brand]`
209
+ - `get_brands(query=None, page=1, size=100)` → `PaginatedResponseBrand`
155
210
  - `get_brand(brand_id)` → `Brand`
156
211
 
157
- #### `AsyncChannel3Client`
212
+ #### `AsyncChannel3Client`
213
+
158
214
  Asynchronous client for the Channel3 API.
159
215
 
160
216
  **Methods:**
161
- - `async search(query=None, image_url=None, base64_image=None, filters=None, limit=20)` → `List[Product]`
217
+
218
+ - `async search(query=None, image_url=None, base64_image=None, filters=None, limit=20, config=None, context=None)` → `List[Product]`
162
219
  - `async get_product(product_id)` → `ProductDetail`
163
- - `async get_brands(query=None, page=1, size=100)` → `List[Brand]`
220
+ - `async get_brands(query=None, page=1, size=100)` → `PaginatedResponseBrand`
164
221
  - `async get_brand(brand_id)` → `Brand`
165
222
 
166
223
  ### Models
167
224
 
168
225
  #### `Product`
226
+
169
227
  - `id: str` - Unique product identifier
170
228
  - `score: float` - Search relevance score
171
229
  - `title: str` - Product title
@@ -177,6 +235,7 @@ Asynchronous client for the Channel3 API.
177
235
  - `variants: List[Variant]` - Product variants
178
236
 
179
237
  #### `ProductDetail`
238
+
180
239
  - `title: str` - Product title
181
240
  - `description: Optional[str]` - Product description
182
241
  - `brand_id: Optional[str]` - Brand identifier
@@ -188,34 +247,57 @@ Asynchronous client for the Channel3 API.
188
247
  - `variants: List[Variant]` - Product variants
189
248
 
190
249
  #### `Brand`
250
+
191
251
  - `id: str` - Unique brand identifier
192
252
  - `name: str` - Brand name
193
253
  - `logo_url: Optional[str]` - Brand logo URL
194
254
  - `description: Optional[str]` - Brand description
195
255
 
196
256
  #### `Variant`
257
+
197
258
  - `product_id: str` - Associated product identifier
198
259
  - `title: str` - Variant title
199
260
  - `image_url: str` - Variant image URL
200
261
 
201
262
  #### `SearchFilters`
263
+
202
264
  - `brand_ids: Optional[List[str]]` - Brand ID filters
203
265
  - `gender: Optional[Literal["male", "female", "unisex"]]` - Gender filter
204
266
  - `price: Optional[SearchFilterPrice]` - Price range filter
205
267
  - `availability: Optional[List[AvailabilityStatus]]` - Availability filters
206
268
 
207
269
  #### `SearchFilterPrice`
270
+
208
271
  - `min_price: Optional[float]` - Minimum price
209
272
  - `max_price: Optional[float]` - Maximum price
210
273
 
274
+ #### `SearchConfig`
275
+
276
+ - `enrich_query: bool = True` — enable query rewriting/enrichment
277
+ - `semantic_search: bool = True` — enable semantic ranking
278
+
211
279
  #### `Price`
280
+
212
281
  - `price: float` - Current price
213
282
  - `compare_at_price: Optional[float]` - Original price (if discounted)
214
283
  - `currency: str` - Currency code
215
284
 
216
285
  #### `AvailabilityStatus`
286
+
217
287
  Enum with values: `IN_STOCK`, `OUT_OF_STOCK`, `PRE_ORDER`, `LIMITED_AVAILABILITY`, `BACK_ORDER`, `DISCONTINUED`, `SOLD_OUT`, `UNKNOWN`
218
288
 
289
+ #### `PaginatedResponseBrand`
290
+
291
+ - `items: List[Brand]` — page of brands
292
+ - `pagination: PaginationMeta` — pagination info
293
+
294
+ #### `PaginationMeta`
295
+
296
+ - `current_page: int`
297
+ - `page_size: int`
298
+ - `total_count: int`
299
+ - `total_pages: int`
300
+
219
301
  ## Error Handling
220
302
 
221
303
  The SDK provides specific exception types for different error conditions:
@@ -249,11 +331,11 @@ except Channel3ConnectionError:
249
331
 
250
332
  ## Requirements
251
333
 
252
- - Python 3.8+
334
+ - Python 3.9+
253
335
  - requests
254
- - aiohttp
255
- - pydantic
336
+ - httpx
256
337
 
257
338
  ## License
258
339
 
259
340
  MIT License
341
+
@@ -1,27 +1,3 @@
1
- Metadata-Version: 2.1
2
- Name: channel3-sdk
3
- Version: 0.2.1
4
- Summary: The official Python SDK for Channel3 AI Shopping API
5
- Home-page: https://github.com/channel3/sdk-python
6
- License: MIT
7
- Keywords: ai,shopping,ecommerce,search,api
8
- Author: Channel3
9
- Author-email: alex@trychannel3.com
10
- Requires-Python: >=3.8,<4.0
11
- Classifier: License :: OSI Approved :: MIT License
12
- Classifier: Programming Language :: Python :: 3
13
- Classifier: Programming Language :: Python :: 3.8
14
- Classifier: Programming Language :: Python :: 3.9
15
- Classifier: Programming Language :: Python :: 3.10
16
- Classifier: Programming Language :: Python :: 3.11
17
- Classifier: Programming Language :: Python :: 3.12
18
- Classifier: Programming Language :: Python :: 3.13
19
- Requires-Dist: aiohttp (>=3.9.0,<4.0.0)
20
- Requires-Dist: pydantic (>=2.5.0,<3.0.0)
21
- Requires-Dist: requests (>=2.31.0,<3.0.0)
22
- Project-URL: Repository, https://github.com/channel3/sdk-python
23
- Description-Content-Type: text/markdown
24
-
25
1
  # Channel3 Python SDK
26
2
 
27
3
  The official Python SDK for the [Channel3](https://trychannel3.com) AI Shopping API.
@@ -63,10 +39,7 @@ if product_detail.key_features:
63
39
 
64
40
  # Get all brands
65
41
  brands = client.get_brands()
66
- for brand in brands:
67
- print(f"Brand: {brand.name}")
68
- if brand.description:
69
- print(f"Description: {brand.description}")
42
+ print(f"Found {len(brands.items)} brands")
70
43
 
71
44
  # Get specific brand details
72
45
  brand = client.get_brand("brand_123")
@@ -82,23 +55,23 @@ from channel3_sdk import AsyncChannel3Client
82
55
  async def main():
83
56
  # Initialize the async client
84
57
  client = AsyncChannel3Client(api_key="your_api_key_here")
85
-
58
+
86
59
  # Search for products
87
60
  products = await client.search(query="running shoes")
88
-
61
+
89
62
  for product in products:
90
63
  print(f"Product: {product.title}")
91
64
  print(f"Score: {product.score}")
92
65
  print(f"Price: {product.price.currency} {product.price.price}")
93
-
66
+
94
67
  # Get detailed product information
95
68
  if products:
96
69
  product_detail = await client.get_product(products[0].id)
97
70
  print(f"Availability: {product_detail.availability}")
98
-
71
+
99
72
  # Get brands
100
73
  brands = await client.get_brands()
101
- print(f"Found {len(brands)} brands")
74
+ print(f"Found {len(brands.items)} brands")
102
75
 
103
76
  # Run the async function
104
77
  asyncio.run(main())
@@ -150,11 +123,39 @@ products = client.search(
150
123
  )
151
124
  ```
152
125
 
126
+ ### Search configuration and context
127
+
128
+ You can control how search behaves using `SearchConfig`, and add optional `context` to guide results.
129
+
130
+ ```python
131
+ from channel3_sdk import SearchConfig
132
+
133
+ config = SearchConfig(enrich_query=True, semantic_search=False)
134
+
135
+ products = client.search(
136
+ query="running shoes",
137
+ limit=5,
138
+ config=config, # or a dict: {"enrich_query": True, "semantic_search": False}
139
+ context="Marathon training on road surfaces"
140
+ )
141
+ ```
142
+
143
+ Async usage is identical:
144
+
145
+ ```python
146
+ products = await async_client.search(
147
+ query="hiking boots",
148
+ config={"enrich_query": False, "semantic_search": True},
149
+ context="Waterproof boots for alpine conditions"
150
+ )
151
+ ```
152
+
153
153
  ### Brand Management
154
154
 
155
155
  ```python
156
156
  # Get all brands with pagination
157
157
  brands = client.get_brands(page=1, size=50)
158
+ print(brands.pagination.total_count)
158
159
 
159
160
  # Search for specific brands
160
161
  nike_brands = client.get_brands(query="nike")
@@ -170,26 +171,31 @@ print(f"Logo: {brand_detail.logo_url}")
170
171
  ### Client Classes
171
172
 
172
173
  #### `Channel3Client`
174
+
173
175
  Synchronous client for the Channel3 API.
174
176
 
175
177
  **Methods:**
176
- - `search(query=None, image_url=None, base64_image=None, filters=None, limit=20)` → `List[Product]`
178
+
179
+ - `search(query=None, image_url=None, base64_image=None, filters=None, limit=20, config=None, context=None)` → `List[Product]`
177
180
  - `get_product(product_id)` → `ProductDetail`
178
- - `get_brands(query=None, page=1, size=100)` → `List[Brand]`
181
+ - `get_brands(query=None, page=1, size=100)` → `PaginatedResponseBrand`
179
182
  - `get_brand(brand_id)` → `Brand`
180
183
 
181
- #### `AsyncChannel3Client`
184
+ #### `AsyncChannel3Client`
185
+
182
186
  Asynchronous client for the Channel3 API.
183
187
 
184
188
  **Methods:**
185
- - `async search(query=None, image_url=None, base64_image=None, filters=None, limit=20)` → `List[Product]`
189
+
190
+ - `async search(query=None, image_url=None, base64_image=None, filters=None, limit=20, config=None, context=None)` → `List[Product]`
186
191
  - `async get_product(product_id)` → `ProductDetail`
187
- - `async get_brands(query=None, page=1, size=100)` → `List[Brand]`
192
+ - `async get_brands(query=None, page=1, size=100)` → `PaginatedResponseBrand`
188
193
  - `async get_brand(brand_id)` → `Brand`
189
194
 
190
195
  ### Models
191
196
 
192
197
  #### `Product`
198
+
193
199
  - `id: str` - Unique product identifier
194
200
  - `score: float` - Search relevance score
195
201
  - `title: str` - Product title
@@ -201,6 +207,7 @@ Asynchronous client for the Channel3 API.
201
207
  - `variants: List[Variant]` - Product variants
202
208
 
203
209
  #### `ProductDetail`
210
+
204
211
  - `title: str` - Product title
205
212
  - `description: Optional[str]` - Product description
206
213
  - `brand_id: Optional[str]` - Brand identifier
@@ -212,34 +219,57 @@ Asynchronous client for the Channel3 API.
212
219
  - `variants: List[Variant]` - Product variants
213
220
 
214
221
  #### `Brand`
222
+
215
223
  - `id: str` - Unique brand identifier
216
224
  - `name: str` - Brand name
217
225
  - `logo_url: Optional[str]` - Brand logo URL
218
226
  - `description: Optional[str]` - Brand description
219
227
 
220
228
  #### `Variant`
229
+
221
230
  - `product_id: str` - Associated product identifier
222
231
  - `title: str` - Variant title
223
232
  - `image_url: str` - Variant image URL
224
233
 
225
234
  #### `SearchFilters`
235
+
226
236
  - `brand_ids: Optional[List[str]]` - Brand ID filters
227
237
  - `gender: Optional[Literal["male", "female", "unisex"]]` - Gender filter
228
238
  - `price: Optional[SearchFilterPrice]` - Price range filter
229
239
  - `availability: Optional[List[AvailabilityStatus]]` - Availability filters
230
240
 
231
241
  #### `SearchFilterPrice`
242
+
232
243
  - `min_price: Optional[float]` - Minimum price
233
244
  - `max_price: Optional[float]` - Maximum price
234
245
 
246
+ #### `SearchConfig`
247
+
248
+ - `enrich_query: bool = True` — enable query rewriting/enrichment
249
+ - `semantic_search: bool = True` — enable semantic ranking
250
+
235
251
  #### `Price`
252
+
236
253
  - `price: float` - Current price
237
254
  - `compare_at_price: Optional[float]` - Original price (if discounted)
238
255
  - `currency: str` - Currency code
239
256
 
240
257
  #### `AvailabilityStatus`
258
+
241
259
  Enum with values: `IN_STOCK`, `OUT_OF_STOCK`, `PRE_ORDER`, `LIMITED_AVAILABILITY`, `BACK_ORDER`, `DISCONTINUED`, `SOLD_OUT`, `UNKNOWN`
242
260
 
261
+ #### `PaginatedResponseBrand`
262
+
263
+ - `items: List[Brand]` — page of brands
264
+ - `pagination: PaginationMeta` — pagination info
265
+
266
+ #### `PaginationMeta`
267
+
268
+ - `current_page: int`
269
+ - `page_size: int`
270
+ - `total_count: int`
271
+ - `total_pages: int`
272
+
243
273
  ## Error Handling
244
274
 
245
275
  The SDK provides specific exception types for different error conditions:
@@ -273,12 +303,10 @@ except Channel3ConnectionError:
273
303
 
274
304
  ## Requirements
275
305
 
276
- - Python 3.8+
306
+ - Python 3.9+
277
307
  - requests
278
- - aiohttp
279
- - pydantic
308
+ - httpx
280
309
 
281
310
  ## License
282
311
 
283
312
  MIT License
284
-
@@ -0,0 +1,52 @@
1
+ """Channel3 SDK for Python - Official SDK for the Channel3 AI Shopping API."""
2
+
3
+ from ._gen.fast_api_client.models.availability_status import AvailabilityStatus
4
+ from ._gen.fast_api_client.models.brand import Brand
5
+ from ._gen.fast_api_client.models.paginated_response_brand import (
6
+ PaginatedResponseBrand,
7
+ )
8
+
9
+ # Re-export generated models so the public API returns exactly what the OpenAPI returns
10
+ from ._gen.fast_api_client.models.pagination_meta import PaginationMeta
11
+ from ._gen.fast_api_client.models.price import Price
12
+ from ._gen.fast_api_client.models.product import Product
13
+ from ._gen.fast_api_client.models.product_detail import ProductDetail
14
+ from ._gen.fast_api_client.models.search_config import SearchConfig
15
+ from ._gen.fast_api_client.models.search_filters import SearchFilters
16
+ from ._gen.fast_api_client.models.search_request import SearchRequest
17
+ from ._gen.fast_api_client.models.variant import Variant
18
+ from .client import AsyncChannel3Client, Channel3Client
19
+ from .exceptions import (
20
+ Channel3AuthenticationError,
21
+ Channel3ConnectionError,
22
+ Channel3Error,
23
+ Channel3NotFoundError,
24
+ Channel3ServerError,
25
+ Channel3ValidationError,
26
+ )
27
+
28
+ __version__ = "1.0.0"
29
+ __all__ = [
30
+ # Clients
31
+ "Channel3Client",
32
+ "AsyncChannel3Client",
33
+ # Models (generated)
34
+ "Product",
35
+ "ProductDetail",
36
+ "SearchFilters",
37
+ "SearchConfig",
38
+ "SearchRequest",
39
+ "Brand",
40
+ "Variant",
41
+ "Price",
42
+ "AvailabilityStatus",
43
+ "PaginatedResponseBrand",
44
+ "PaginationMeta",
45
+ # Exceptions
46
+ "Channel3Error",
47
+ "Channel3AuthenticationError",
48
+ "Channel3ValidationError",
49
+ "Channel3NotFoundError",
50
+ "Channel3ServerError",
51
+ "Channel3ConnectionError",
52
+ ]
@@ -0,0 +1,23 @@
1
+ __pycache__/
2
+ build/
3
+ dist/
4
+ *.egg-info/
5
+ .pytest_cache/
6
+
7
+ # pyenv
8
+ .python-version
9
+
10
+ # Environments
11
+ .env
12
+ .venv
13
+
14
+ # mypy
15
+ .mypy_cache/
16
+ .dmypy.json
17
+ dmypy.json
18
+
19
+ # JetBrains
20
+ .idea/
21
+
22
+ /coverage.xml
23
+ /.coverage
@@ -0,0 +1,124 @@
1
+ # fast-api-client
2
+ A client library for accessing FastAPI
3
+
4
+ ## Usage
5
+ First, create a client:
6
+
7
+ ```python
8
+ from fast_api_client import Client
9
+
10
+ client = Client(base_url="https://api.example.com")
11
+ ```
12
+
13
+ If the endpoints you're going to hit require authentication, use `AuthenticatedClient` instead:
14
+
15
+ ```python
16
+ from fast_api_client import AuthenticatedClient
17
+
18
+ client = AuthenticatedClient(base_url="https://api.example.com", token="SuperSecretToken")
19
+ ```
20
+
21
+ Now call your endpoint and use your models:
22
+
23
+ ```python
24
+ from fast_api_client.models import MyDataModel
25
+ from fast_api_client.api.my_tag import get_my_data_model
26
+ from fast_api_client.types import Response
27
+
28
+ with client as client:
29
+ my_data: MyDataModel = get_my_data_model.sync(client=client)
30
+ # or if you need more info (e.g. status_code)
31
+ response: Response[MyDataModel] = get_my_data_model.sync_detailed(client=client)
32
+ ```
33
+
34
+ Or do the same thing with an async version:
35
+
36
+ ```python
37
+ from fast_api_client.models import MyDataModel
38
+ from fast_api_client.api.my_tag import get_my_data_model
39
+ from fast_api_client.types import Response
40
+
41
+ async with client as client:
42
+ my_data: MyDataModel = await get_my_data_model.asyncio(client=client)
43
+ response: Response[MyDataModel] = await get_my_data_model.asyncio_detailed(client=client)
44
+ ```
45
+
46
+ By default, when you're calling an HTTPS API it will attempt to verify that SSL is working correctly. Using certificate verification is highly recommended most of the time, but sometimes you may need to authenticate to a server (especially an internal server) using a custom certificate bundle.
47
+
48
+ ```python
49
+ client = AuthenticatedClient(
50
+ base_url="https://internal_api.example.com",
51
+ token="SuperSecretToken",
52
+ verify_ssl="/path/to/certificate_bundle.pem",
53
+ )
54
+ ```
55
+
56
+ You can also disable certificate validation altogether, but beware that **this is a security risk**.
57
+
58
+ ```python
59
+ client = AuthenticatedClient(
60
+ base_url="https://internal_api.example.com",
61
+ token="SuperSecretToken",
62
+ verify_ssl=False
63
+ )
64
+ ```
65
+
66
+ Things to know:
67
+ 1. Every path/method combo becomes a Python module with four functions:
68
+ 1. `sync`: Blocking request that returns parsed data (if successful) or `None`
69
+ 1. `sync_detailed`: Blocking request that always returns a `Request`, optionally with `parsed` set if the request was successful.
70
+ 1. `asyncio`: Like `sync` but async instead of blocking
71
+ 1. `asyncio_detailed`: Like `sync_detailed` but async instead of blocking
72
+
73
+ 1. All path/query params, and bodies become method arguments.
74
+ 1. If your endpoint had any tags on it, the first tag will be used as a module name for the function (my_tag above)
75
+ 1. Any endpoint which did not have a tag will be in `fast_api_client.api.default`
76
+
77
+ ## Advanced customizations
78
+
79
+ There are more settings on the generated `Client` class which let you control more runtime behavior, check out the docstring on that class for more info. You can also customize the underlying `httpx.Client` or `httpx.AsyncClient` (depending on your use-case):
80
+
81
+ ```python
82
+ from fast_api_client import Client
83
+
84
+ def log_request(request):
85
+ print(f"Request event hook: {request.method} {request.url} - Waiting for response")
86
+
87
+ def log_response(response):
88
+ request = response.request
89
+ print(f"Response event hook: {request.method} {request.url} - Status {response.status_code}")
90
+
91
+ client = Client(
92
+ base_url="https://api.example.com",
93
+ httpx_args={"event_hooks": {"request": [log_request], "response": [log_response]}},
94
+ )
95
+
96
+ # Or get the underlying httpx client to modify directly with client.get_httpx_client() or client.get_async_httpx_client()
97
+ ```
98
+
99
+ You can even set the httpx client directly, but beware that this will override any existing settings (e.g., base_url):
100
+
101
+ ```python
102
+ import httpx
103
+ from fast_api_client import Client
104
+
105
+ client = Client(
106
+ base_url="https://api.example.com",
107
+ )
108
+ # Note that base_url needs to be re-set, as would any shared cookies, headers, etc.
109
+ client.set_httpx_client(httpx.Client(base_url="https://api.example.com", proxies="http://localhost:8030"))
110
+ ```
111
+
112
+ ## Building / publishing this package
113
+ This project uses [Poetry](https://python-poetry.org/) to manage dependencies and packaging. Here are the basics:
114
+ 1. Update the metadata in pyproject.toml (e.g. authors, version)
115
+ 1. If you're using a private repository, configure it with Poetry
116
+ 1. `poetry config repositories.<your-repository-name> <url-to-your-repository>`
117
+ 1. `poetry config http-basic.<your-repository-name> <username> <password>`
118
+ 1. Publish the client with `poetry publish --build -r <your-repository-name>` or, if for public PyPI, just `poetry publish --build`
119
+
120
+ If you want to install this client into another project without publishing it (e.g. for development) then:
121
+ 1. If that project **is using Poetry**, you can simply do `poetry add <path-to-this-client>` from that project
122
+ 1. If that project is not using Poetry:
123
+ 1. Build a wheel with `poetry build -f wheel`
124
+ 1. Install that wheel from the other project `pip install <path-to-wheel>`
@@ -0,0 +1,8 @@
1
+ """A client library for accessing FastAPI"""
2
+
3
+ from .client import AuthenticatedClient, Client
4
+
5
+ __all__ = (
6
+ "AuthenticatedClient",
7
+ "Client",
8
+ )
@@ -0,0 +1 @@
1
+ """Contains methods for accessing the API"""
@@ -0,0 +1 @@
1
+ """Contains endpoint functions for accessing the API"""