diff options
Diffstat (limited to 'website/content/platform/getting_started/map_a_provider_to_a_route.mdx')
-rw-r--r-- | website/content/platform/getting_started/map_a_provider_to_a_route.mdx | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/website/content/platform/getting_started/map_a_provider_to_a_route.mdx b/website/content/platform/getting_started/map_a_provider_to_a_route.mdx new file mode 100644 index 00000000000..8ef9df71d89 --- /dev/null +++ b/website/content/platform/getting_started/map_a_provider_to_a_route.mdx @@ -0,0 +1,240 @@ +--- +title: Fetch Data From a New Provider +sidebar_position: 10 +description: This page demonstrates how to get started mapping Provider extension models to the Provider Interface and Router. By the end, you will have mapped a new Provider extension to World News standard model. +keywords: + - OpenBB Platform + - Open source + - community + - code + - provider + - openbb-provider + - data + - extension + - how-to + - new + - template + - quick start + - quickstart + - provider interface +--- + +import HeadTitle from "@site/src/components/General/HeadTitle.tsx"; + +<HeadTitle title="Quick Start - Fetch Data From a New Provider - How-To - Development | OpenBB Platform Docs" /> + +This page demonstrates how to get started mapping Provider extension models to the Provider Interface and Router. + +It continues the example provided [here](create_new_provider_extension). By the end, you will have mapped a new Provider extension to the World News standard model. This will connect it to the existing command and make it accessible through the `provider` parameter. + +All Provider models are made of three elements: + +- QueryParams +- Data +- Fetcher + +## Start Mapping + +### Create Model File + +- In the `/models` folder of the extension - `/Users/username/path_to_created_folder/empty_provider/openbb_empty_provider/models` - create a new file called, "world_news.py". +- Start the file with a docstring, then a new line. + +```python +"""Empty World News Model.""" + +``` + +### Import Statements + +The import schema will follow a pattern similar to this, depending on the specific requirements of the function. + +```python +from typing import Any, Dict, List, Literal, Optional + +from openbb_core.provider.abstract.fetcher import Fetcher +from openbb_core.provider.standard_models.world_news import WorldNewsQueryParams, WorldNewsData + +from pydantic import Field +``` + +### Create a QueryParams Model + +- Create a class that inherits from the standard model. + +```python +class EmptyWorldNewsQueryParams(WorldNewsQueryParams): + """Empty World News Query Params.""" + + some_param: Optional[str] = Field( + default=None, + description="Some Empty Parameter.", + ) +``` + +Field and model validators are added here, if required. + +### Create a Data Model + +- Create a class that inherits from the standard model. + +```python +class EmptyWorldNewsData(WorldNewsData): + """Empty World News Data""" + + some_param: Optional[str] = Field( + default=None, + description="Some Empty Data Field." + ) +``` + +Field and model validators are added here, if required. + +### Build Fetcher + +The Fetcher consists of three stages: + +- Transform Query +- Extract Data +- Transform Data + +Each stage is a static method within the Fetcher class that inherits the QueryParams and Data models. + +The structure of the methods within should always be the same, and input/output types should match throughout. + +```python +class EmptyWorldNewsFetcher( + Fetcher[ + EmptyWorldNewsQueryParams, + List[EmptyWorldNewsData], + ] +): + """Empty World News Fetcher.""" + + @staticmethod + def transform_query(params: Dict[str, Any]) -> EmptyWorldNewsQueryParams: + """Transform query params.""" + new_params = params + if params.get("some_param"): + new_params["some_param"] = "do_something" + return EmptyWorldNewsQueryParams(**new_params) + + @staticmethod + async def aextract_data( # The function does not have to be asynchronous. If not, remove the leading 'a', 'extract_data'. + query: EmptyWorldNewsQueryParams, + credentials: Optional[Dict[str, str]], + **kwargs: Any, + ) -> List[Dict]: + """Extract data. Put HTTP Requests here. This should return the closest form of raw data possible.""" + results = { + "date": datetime.now().date(), + "title": "Hello from the Empty Provider extension!", + "some_param": query.some_param, + } + return [results] + + @staticmethod + def transform_data( + query: EmptyWorldNewsQueryParams, + data: List[Dict], + **kwargs: Any, + ) -> List[EmptyWorldNewsData]: + """Transform data. Put parsing logic here, if required. This should return validated data models.""" + return [EmptyWorldNewsData.model_validate(d) for d in data] +``` + +## 2. Map Model To Provider Interface + +- In the `__init__.py` where the Provider class was defined, import the Fetcher from the model file and map it to the router. + +```python +# /Users/username/path_to_created_folder/empty_provider/openbb_empty_provider/__init__.py +"""Empty Provider Module.""" + +from openbb_empty_provider.models.world_news import EmptyWorldNewsFetcher +from openbb_core.provider.abstract.provider import Provider + +empty_provider = Provider( + name="empty", + website="http://empty.io", + description="""The empty provider is a supplier of promises.""", + # credentials=["api_key"], + fetcher_dict={ + "WorldNews": EmptyWorldNewsFetcher + }, +) +``` + +## 3. Rebuild Static Assets + +- The Python Interface and static assets need to be rebuilt after these changes. + +```bash +python -c "import openbb; openbb.build()" +``` + +## 4. Smoke Test + +The function's docstring should list the new provider, and the command should return an `OBBject` instance. + +```console + Parameters + ---------- + limit : int + The number of data entries to return. The number of articles to return. + start_date : Union[datetime.date, None, str] + Start date of the data, in YYYY-MM-DD format. + end_date : Union[datetime.date, None, str] + End date of the data, in YYYY-MM-DD format. + provider : Optional[Literal['benzinga', 'empty', 'fmp', 'intrinio', 'tiingo'... + The provider to use for the query, by default None. +``` + +```python +from openbb import obb +obb.news.world(provider="empty") +``` + +```console +OBBject + +id: 066356fc-9661-7448-8000-5885e5120efb +results: [{'date': datetime.datetime(2024, 5, 3, 0, 0), 'title': 'Hello from the Em... +provider: empty +warnings: None +chart: None +extra: {'metadata': {'arguments': {'provider_choices': {'provider': 'empty'}, 'stan... +``` + +The parameters supplied are captured under `results.extra["metadata"].arguments`. + +```python +response = obb.news.world(provider="empty", some_param="adjustment") +response.extra["metadata"].arguments +``` + +```console +{ + 'provider_choices': {'provider': 'empty'}, 'standard_params': {'limit': 2500, 'start_date': None, 'end_date': None}, + 'extra_params': {'some_param': 'adjustment'} +} +``` + +The transformed parameters are passed through to the function. + +```python +response.results +``` + +```console +>>> response.results +[EmptyWorldNewsData(date=2024-05-03 00:00:00, title=Hello from the Empty Provider extension!, images=None, text=None, url=None, some_param=do_something)] +``` + +## Conclusion + +This process created, built, and mapped a new OpenBB Platform Provider model to an existing router endpoint and standard model. + +The output was validated and returned as an instance of `OBBject`. + +Create a new model for each endpoint needing to be mapped. |