Advanced Usage¶
This section is intended for developers who are interested in embedding bavapi
functionality into their APIs and applications.
Async support
bavapi
natively supports asynchronous execution, so it is ready to work with popular async
libraries such as fastapi
.
The Client
interface¶
The Client
class is the backbone of bavapi
, and it is the recommended way to interact with the Fount for more advanced users.
Tip
If you're familiar with the requests
or httpx
python packages, this is similar to using requests.Session()
or httpx.Client()
.
Using the Client
class instead of the top-level endpoint functions (bavapi.brands
, for example), can bring significant performance improvements, especially when performing multiple requests at the same time.
The Client
interface is based on httpx.Client
, so it benefits from all the performance features from httpx
:
Quote from the httpx
docs
- Reduced latency across requests (no handshaking).
- Reduced CPU usage and round-trips.
- Reduced network congestion.
By using Client
, you will also get all these benefits, including in Jupyter Notebooks.
Using the Client
interface¶
It is recommended to use Client
in an async with
block:
Otherwise, it is possible to use Client
methods outside of an async with
block, but it might be slightly less performant.
- Close the connection by awaiting
aclose
after you're done with your requests.
Other endpoints¶
Because of the large number of available endpoints in the Fount and the highly customizable queries, some endpoints won't have extended support from the start.
Open for feedback
If you would like to see new endpoints with full type annotation support, please open an issue on GitHub with the Feature Request template.
bavapi
provides raw_query
functions/methods to access all the available endpoints without existing endpoint functions/methods:
bavapi.raw_query
for synchronous requests.bavapi.Client.raw_query
for asynchronous requests.
These raw_query
methods require the use of bavapi.Query
instances to make the request:
import bavapi
from bavapi import Query
from bavapi.filters import FountFilters
async with bavapi.Client("TOKEN") as bav:
res = await bav.raw_query("companies", Query(filters=FountFilters(name="Apple")))
These functions will return a list of JSON dictionaries, one for each entry retrieved from the Fount:
Tip
These methods are meant to be used for custom processing of data (not resulting in a pandas
DataFrame), but it is also possible to use some of the parsing functions available in bavapi.parsing.responses.
The Query
class¶
bavapi.Query
is a pydantic
-powered class that holds and validates all the common (aside from endpoint-specific filters) query parameters to pass to the Fount API.
The default values for the class are the same as the default values in the Fount API itself, so an empty Query
object can be used to get all entries for a specific endpoint:
query = bavapi.Query()
async with bavapi.Client("TOKEN") as bav:
res = await bav.raw_query("brand-metrics", query) # (1)
- Returns all entries for
brand-metrics
. Similar to making aGET
request with no parameters.
Query
can be used to set limits on the number of pages retrieved, or to request a specific page from a query:
Query
parameters¶
All Fount queries performed with bavapi.Query
support the following parameters:
id
: Return only results for a specific id.page
: The page number of results to return.per_page
: The number of results to return per page. Default is 25 and maximum is 100.max_pages
: The maximum number of pages to request. Defaults to requesting all pages in a query.fields
: The keys for the fields to include in the response. Usually they are the field name in lower case.sort
: The key(s) for the field(s) to order the response results by.include
: Additional linked resources to include in the response.updated_since
: Only return items that have been updated since this timestamp.
For more information on the behavior of each of these parameters, see the Fount API docs.
Raw parameter dictionary¶
The to_params
method can be used to parse the parameters into a dictionary of what will be sent to the Fount API:
>>> bavapi.Query(
... filters=BrandscapeFilters(
... brand_name="Facebook",
... year_numbers=[2012, 2013, 2014, 2015]
... ),
... include=["company"]
... ).to_params(endpoint="brandscape-data") # (1)
{
"include[brandscape-data]": "company", # (2)
"filter[brand_name]": "Facebook",
"year_numbers": "2012,2013,2014,2015",
}
- Needs the endpoint name to format parameters correctly.
- Parses
filters
andinclude
into the correct format for the Fount API, and parses all elements in lists of parameters to their string representation.
Control bavapi
batching behavior¶
New in v0.13
bavapi
will automatically batch paginated requests to the API to improve latency and throughput. Default values are set to maintain around twenty concurrent requests at a time.
In addition, bavapi
will also automatically retry failed requests a number of times (default 2
), which can be defined by the user.
Both top-level functions and the Client
class have the following parameters to control the behavior of the requests:
batch_size
: Number of pages to include in each batch of requests, default10
.n_workers
: Number of worker coroutines that will make batched requests at once, default2
.retries
: Number of times to retry a page request before raising an exception, default3
.on_errors
: Whether to"warn"
about failed requests at the end of the query, or"raise"
immediately upon failure (after retries), default"warn"
.
These parameters can be set in both top-level functions and the async Client
class:
The query from the examples above will result in 25 concurrent API requests (5 batch_size
* 5 n_workers
), and bavapi
will retry each failed request twice (after the initial request). on_errors="raise"
will ensure that an exception is raised if all retries for any page result in exceptions.
Warning
In order to avoid SSL and timeout issues, it is recommended to set batch_size
and n_workers
so bavapi
will perform at most 20-30 concurrent requests. The default is 20 concurrent requests (10 batch_size
* 2 n_workers
).
User Agent¶
New in v0.8
It is possible to set the User Agent
parameter for HTTP requests.
The default user agent is "BAVAPI SDK Python"
.
If you want to change the user agent for your application, you can set it when instantiating a Client
: