Skip to content

Commit e5c6727

Browse files
author
Nacho Maiz
authored
Feat-filterable-aretry (#30)
* added retry functionality to handshake * simplified query ensure method to avoid a copy * fix on_errors docstring * fix import order * changed back parameters title to attributes * added test to check exception type handling * changed page names and added automatic color scheme * changed new flag to use minor versions * added links to dependencies * changed title * moved batched behavior section to the end * removed ssl warning and reordered sections * summarized changes for 1.0 * version bump and stable tag * added note about reaching stable * added links to endpoint doc pages * updated release date formats
1 parent 0b950b7 commit e5c6727

21 files changed

+231
-220
lines changed

bavapi/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@
4242
collections,
4343
companies,
4444
countries,
45-
regions,
4645
raw_query,
46+
regions,
4747
sectors,
4848
studies,
4949
years,

bavapi/_fetcher.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import functools
2020
import warnings
2121
from typing import (
22+
Any,
2223
Callable,
2324
Coroutine,
2425
Generic,
@@ -28,6 +29,7 @@
2829
NamedTuple,
2930
Optional,
3031
Protocol,
32+
Type,
3133
TypeVar,
3234
)
3335

@@ -37,7 +39,7 @@
3739
Q = TypeVar("Q", bound="_Query")
3840
P = ParamSpec("P")
3941

40-
AsyncCallable = Callable[P, Coroutine[None, None, T]]
42+
AsyncCallable = Callable[P, Coroutine[Any, Any, T]]
4143

4244

4345
class _Query(Protocol):
@@ -196,7 +198,10 @@ def warn_if_errors(self) -> None:
196198

197199

198200
def aretry(
199-
func: AsyncCallable[P, T], retries: int = 3, delay: float = 0
201+
func: AsyncCallable[P, T],
202+
retries: int = 3,
203+
delay: float = 0,
204+
exc_types: Iterable[Type[Exception]] = (Exception,),
200205
) -> AsyncCallable[P, T]:
201206
"""Retry an asynchronous function upon failure a number of times.
202207
@@ -212,6 +217,9 @@ def aretry(
212217
If the value is 0 or negative, the function will only be tried once
213218
delay : float, optional
214219
Time to wait between retries, default 0
220+
exc_types: Iterable[type[Exception]], optional
221+
Exception types to retry on, default (Exception,)
222+
215223
Returns
216224
-------
217225
AsyncCallable[P, T]
@@ -229,7 +237,7 @@ async def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
229237
for retry_count in range(retries + 1):
230238
try:
231239
return await func(*args, **kwargs)
232-
except Exception as exc:
240+
except exc_types as exc:
233241
if retry_count == retries:
234242
raise exc
235243
await asyncio.sleep(delay)

bavapi/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ def retries(self, value: int) -> None:
270270

271271
@property
272272
def on_errors(self) -> Literal["warn", "raise"]:
273-
"""Number of times to retry a request."""
273+
"""Raise immediately on errors or warn at the end of the request."""
274274
return self._client.on_errors
275275

276276
@on_errors.setter

bavapi/filters.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class FountFilters(BaseModel):
6161
6262
Can be used with `raw_query` endpoints.
6363
64-
Parameters
64+
Attributes
6565
----------
6666
updated_since : str, date or datetime, optional
6767
Request items that have been updated since the specified date, default None
@@ -130,7 +130,7 @@ class AudiencesFilters(FountFilters):
130130
See <https://developer.wppbav.com/docs/2.x/core-resources/audiences>
131131
for more info.
132132
133-
Parameters
133+
Attributes
134134
----------
135135
active : Literal[0, 1], optional
136136
Return active audiences only if set to `1`, default 0
@@ -165,7 +165,7 @@ class BrandsFilters(FountFilters):
165165
See <https://developer.wppbav.com/docs/2.x/core-resources/brands>
166166
for more info.
167167
168-
Parameters
168+
Attributes
169169
----------
170170
country_codes : str or list[str], optional
171171
Two-letter ISO-3166 country code or list of country codes, default None
@@ -208,7 +208,7 @@ class BrandMetricsFilters(FountFilters):
208208
See <https://developer.wppbav.com/docs/2.x/core-resources/brand-metrics>
209209
for more info.
210210
211-
Parameters
211+
Attributes
212212
----------
213213
active : Literal[0, 1], optional
214214
Return active brand metrics when set to `1`, default 0
@@ -252,7 +252,7 @@ class BrandMetricGroupsFilters(FountFilters):
252252
See <https://developer.wppbav.com/docs/2.x/core-resources/brand-metric-groups>
253253
for more info.
254254
255-
Parameters
255+
Attributes
256256
----------
257257
active : Literal[0, 1], optional
258258
Return active brand metrics when set to `1`, default 0
@@ -288,7 +288,7 @@ class BrandscapeFilters(FountFilters):
288288
289289
The `Audiences` class is provided to make it easier to filter audiences.
290290
291-
Parameters
291+
Attributes
292292
----------
293293
country_code : str or list[str], optional
294294
Two-letter ISO-3166 country code or list of country codes, default None
@@ -370,7 +370,7 @@ class CategoriesFilters(FountFilters):
370370
See <https://developer.wppbav.com/docs/2.x/core-resources/categories>
371371
for more info.
372372
373-
Parameters
373+
Attributes
374374
----------
375375
sector : int or list[int], optional
376376
Fount sector ID or list of sector IDs, default None
@@ -390,7 +390,7 @@ class CitiesFilters(FountFilters):
390390
See <https://developer.wppbav.com/docs/2.x/core-resources/cities>
391391
for more info.
392392
393-
Parameters
393+
Attributes
394394
----------
395395
capitals: Literal[0, 1], optional
396396
Return capitals only, default 0
@@ -421,7 +421,7 @@ class CompaniesFilters(FountFilters):
421421
See <https://developer.wppbav.com/docs/2.x/core-resources/companies>
422422
for more info.
423423
424-
Parameters
424+
Attributes
425425
----------
426426
public: Literal[0, 1], optional
427427
Return public (listed) companies only, default 0
@@ -449,7 +449,7 @@ class CountriesFilters(FountFilters):
449449
See <https://developer.wppbav.com/docs/2.x/core-resources/countries>
450450
for more info.
451451
452-
Parameters
452+
Attributes
453453
----------
454454
active: Literal[0, 1], optional
455455
Return active countries only, default 0
@@ -480,7 +480,7 @@ class CollectionsFilters(FountFilters):
480480
See <https://developer.wppbav.com/docs/2.x/core-resources/collections>
481481
for more info.
482482
483-
Parameters
483+
Attributes
484484
----------
485485
public : Literal[0, 1], optional
486486
Return public collections only, default 0
@@ -521,7 +521,7 @@ class SectorsFilters(FountFilters):
521521
See <https://developer.wppbav.com/docs/2.x/core-resources/sectors>
522522
for more info.
523523
524-
Parameters
524+
Attributes
525525
----------
526526
in_most_influential : Literal[0, 1], optional
527527
Sectors that are part of the Most Influential lists, default 0
@@ -546,7 +546,7 @@ class StudiesFilters(FountFilters):
546546
See <https://developer.wppbav.com/docs/2.x/core-resources/studies>
547547
for more info.
548548
549-
Parameters
549+
Attributes
550550
----------
551551
country_codes : str or list[str], optional
552552
Two-letter ISO-3166 country code or list of country codes, default None

bavapi/http.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import asyncio
66
import math
7+
import ssl
78
from json import JSONDecodeError
89
from typing import (
910
TYPE_CHECKING,
@@ -296,7 +297,8 @@ async def query(
296297
"""
297298
per_page = query.per_page or self.per_page
298299
init_per_page = per_page if query.is_single_page() else 1
299-
resp = await self.get(endpoint, query.with_page(per_page=init_per_page))
300+
handshake_func = aretry(self.get, self.retries, 0.25, (ssl.SSLError,))
301+
resp = await handshake_func(endpoint, query.with_page(per_page=init_per_page))
300302

301303
payload: Dict[str, JSONData] = resp.json()
302304
data: JSONData = payload["data"]

bavapi/query.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -242,13 +242,14 @@ def ensure(
242242
Query
243243
`Query` class with additional parameters added if any
244244
"""
245-
params = {k: v for k, v in kwargs.items() if v}
245+
params: MutableMapping[str, QueryParamValues[F]] = {
246+
k: v for k, v in kwargs.items() if v
247+
}
246248

247249
if query is None:
248250
return cls(**params) # type: ignore[arg-type]
249251

250-
new_params = cast(MutableMapping[str, QueryParamValues[F]], params.copy())
251-
new_params.update(query.model_dump(exclude={"filters"}, exclude_defaults=True))
252-
new_params.update({"filters": query.filters}) # type: ignore[arg-type]
252+
params.update(query.model_dump(exclude={"filters"}, exclude_defaults=True))
253+
params.update({"filters": query.filters})
253254

254-
return cls(**new_params) # type: ignore[arg-type]
255+
return cls(**params) # type: ignore[arg-type]

docs/endpoints/cities.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Cities
22

3-
!!! abstract "New in `v1.0.0`"
3+
!!! abstract "New in `v1.0`"
44

55
The `cities` endpoint has full support, including query validation.
66

docs/endpoints/companies.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Companies
22

3-
!!! abstract "New in `v1.0.0`"
3+
!!! abstract "New in `v1.0`"
44

55
The `companies` endpoint has full support, including query validation.
66

docs/endpoints/countries.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Countries
22

3-
!!! abstract "New in `v1.0.0`"
3+
!!! abstract "New in `v1.0`"
44

55
The `countries` endpoint has full support, including query validation.
66

docs/endpoints/regions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Regions
22

3-
!!! abstract "New in `v1.0.0`"
3+
!!! abstract "New in `v1.0`"
44

55
The `regions` endpoint has full support, including query validation.
66

docs/endpoints/years.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Years
22

3-
!!! abstract "New in `v1.0.0`"
3+
!!! abstract "New in `v1.0`"
44

55
The `years` endpoint has full support, including query validation.
66

docs/getting-started/installation.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,18 @@ Once you have installed Python and have acquired your Fount API token, return to
1414

1515
`bavapi` depends on the following excellent libraries:
1616

17-
- `httpx` for communication with the Fount API.
18-
- `pandas` for processing retrieved data into tables.
19-
- `pydantic` to validate query and filter parameters.
20-
- `nest-asyncio` to support Jupyter notebooks.
21-
- `tqdm` to show helpful progress bars.
22-
- `typing-extensions` for type-checking compatibility in Python < 3.12.
17+
- [`httpx`](https://www.python-httpx.org/) for communication with the Fount API.
18+
- [`pandas`](https://pandas.pydata.org/docs/index.html) for processing retrieved data into tables.
19+
- [`pydantic`](https://docs.pydantic.dev/latest/) to validate query and filter parameters.
20+
- [`nest-asyncio`](https://github.com/erdewit/nest_asyncio) to support Jupyter notebooks.
21+
- [`tqdm`](https://tqdm.github.io/) to show helpful progress bars.
22+
- [`typing-extensions`](https://typing-extensions.readthedocs.io/en/latest/) for type-checking compatibility in Python < 3.12.
2323

2424
These libraries will be installed automatically when you install `bavapi`.
2525

2626
## Installing `bavapi`
2727

28-
Once you have your virtual environment activated, you can install `bavapi` with the following command:
28+
Once you have your virtual (or conda) environment activated, you can install `bavapi` with the following command:
2929

3030
```prompt
3131
pip install wpp-bavapi
@@ -34,7 +34,7 @@ pip install wpp-bavapi
3434
!!! tip "Installing with `conda`"
3535
`bavapi` is not currently available from `conda` directly, though it should be possible to install and use it within a `conda` environment.
3636

37-
Use the following commands to maximize compatibility between `conda` and `pip`:
37+
You can use the following commands to maximize compatibility between `conda` and `pip`:
3838

3939
```prompt
4040
conda install httpx, pandas, pydantic, nest-asyncio, tqdm, typing_extensions

docs/getting-started/reference-classes.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Installing `bavapi` *Reference* classes
1+
# Reference classes
22

33
`bavapi` can generate some convenience reference classes which map Fount resource IDs with a more readable name, both for ease of use and for autocompletion in IDEs.
44

@@ -7,7 +7,7 @@ These classes are automatically generated by a console command that becomes avai
77
!!! info "Protected Access"
88
A Fount API token is required to generate reference files. See the [Authentication](authentication.md) section for more information and instructions for using `.env` files.
99

10-
As of `v0.13` the following reference classes will be generated in a folder named `bavapi_refs` (by default, see [below](#specify-destination-folder)):
10+
As of `v1.0` the following reference classes will be generated in a folder named `bavapi_refs` (by default, see [below](#specify-destination-folder)):
1111

1212
- `Audiences`: encodes audience IDs
1313
- `Countries`: encodes country IDs

docs/index.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ See [Installation](getting-started/installation.md) for more detailed instructio
4141
>>> result
4242
```
4343

44-
1. :lock: Replace "TOKEN" with your token.
44+
1. :lock: Replace `"TOKEN"` with your Fount API token.
4545

4646
| | sector_id | sector_name | id | name | ... |
4747
| --: | :-------- | :-------------------- | :--- | :----- | :-- |
@@ -52,20 +52,20 @@ See [Installation](getting-started/installation.md) for more detailed instructio
5252

5353
- Support for all endpoints in the Fount API.
5454
- Extended support for the following endpoints:
55-
- `audiences`
56-
- `brand-metrics`
57-
- `brand-metric-groups`
58-
- `brands`
59-
- `brandscape-data`
60-
- `categories`
61-
- `cities`
62-
- `collections`
63-
- `companies`
64-
- `countries`
65-
- `sectors`
66-
- `studies`
67-
- `years`
68-
- Other endpoints are available via the `raw_query` functions and methods.
55+
- [`audiences`](endpoints/audiences.md)
56+
- [`brand-metrics`](endpoints/brand-metrics.md)
57+
- [`brand-metric-groups`](endpoints/brand-metric-groups.md)
58+
- [`brands`](endpoints/brands.md)
59+
- [`brandscape-data`](endpoints/brandscape-data.md)
60+
- [`categories`](endpoints/categories.md)
61+
- [`cities`](endpoints/cities.md)
62+
- [`collections`](endpoints/collections.md)
63+
- [`companies`](endpoints/companies.md)
64+
- [`countries`](endpoints/countries.md)
65+
- [`sectors`](endpoints/sectors.md)
66+
- [`studies`](endpoints/studies.md)
67+
- [`years`](endpoints/years.md)
68+
- Other endpoints are available via the [`raw_query`](endpoints/index.md#other-endpoints) functions and methods.
6969
- Validates query parameters are of the correct types and provides type hints for better IDE support.
7070
- Retrieve multiple pages of data simultaneously, monitoring and preventing exceeding API rate limit.
7171
- Both synchronous and asynchronous APIs for accessing BAV data.

0 commit comments

Comments
 (0)