summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Aptekarev <aptekarev@gmail.com>2024-02-07 17:00:30 +0100
committerGitHub <noreply@github.com>2024-02-07 16:00:30 +0000
commitc41f43c412dd0f36d35f40604ce0cef59b878e5d (patch)
tree9f1daebd88fbe17dcc0cabd684797ee50917de69
parent3805e9b2534629db7026b6e24c12175733a21568 (diff)
Feature/platform standardization notebook (#6049)
* Add platform standardization overview notebook to examples * Add py.typed marker to openbb-fred
-rw-r--r--examples/platform_standardization.ipynb825
-rw-r--r--openbb_platform/providers/fred/py.typed0
2 files changed, 825 insertions, 0 deletions
diff --git a/examples/platform_standardization.ipynb b/examples/platform_standardization.ipynb
new file mode 100644
index 00000000000..76720c52fdb
--- /dev/null
+++ b/examples/platform_standardization.ipynb
@@ -0,0 +1,825 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## How platform works"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from openbb import obb"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "OpenBB Platform v4.1.3dev\n",
+ "\n",
+ "Utilities:\n",
+ " /account\n",
+ " /user\n",
+ " /system\n",
+ " /coverage\n",
+ "\n",
+ "Routers:\n",
+ " /crypto\n",
+ " /currency\n",
+ " /derivatives\n",
+ " /economy\n",
+ " /equity\n",
+ " /etf\n",
+ " /fixedincome\n",
+ " /index\n",
+ " /news\n",
+ " /regulators\n",
+ "\n",
+ "Extensions:\n",
+ " - crypto@1.1.1\n",
+ " - currency@1.1.1\n",
+ " - derivatives@1.1.1\n",
+ " - economy@1.1.1\n",
+ " - equity@1.1.1\n",
+ " - etf@1.1.1\n",
+ " - fixedincome@1.1.1\n",
+ " - index@1.1.1\n",
+ " - news@1.1.1\n",
+ " - openbb_charting@1.1.1\n",
+ " - regulators@1.1.1\n",
+ "\n",
+ " - benzinga@1.1.1\n",
+ " - federal_reserve@1.1.1\n",
+ " - fmp@1.1.1\n",
+ " - fred@1.1.1\n",
+ " - intrinio@1.1.1\n",
+ " - oecd@1.1.1\n",
+ " - polygon@1.1.1\n",
+ " - sec@1.1.1\n",
+ " - tiingo@1.1.1\n",
+ " - tradingeconomics@1.1.1\n",
+ " - yfinance@1.1.1 "
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "obb"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "/news\n",
+ " company\n",
+ " world\n",
+ " "
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "obb.news"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Help on method world in module openbb.package.news:\n",
+ "\n",
+ "world(limit: typing.Annotated[int, OpenBBCustomParameter(description='The number of data entries to return. Here its the no. of articles to return.')] = 20, provider: Optional[Literal['benzinga', 'fmp', 'intrinio', 'tiingo']] = None, **kwargs) -> openbb_core.app.model.obbject.OBBject method of openbb.package.news.ROUTER_news instance\n",
+ " World News. Global news data.\n",
+ " \n",
+ " Parameters\n",
+ " ----------\n",
+ " limit : int\n",
+ " The number of data entries to return. Here its the no. of articles to return.\n",
+ " provider : Optional[Literal['benzinga', 'fmp', 'intrinio', 'tiingo']]\n",
+ " The provider to use for the query, by default None.\n",
+ " If None, the provider specified in defaults is selected or 'benzinga' if there is\n",
+ " no default.\n",
+ " display : Literal['headline', 'abstract', 'full']\n",
+ " Specify headline only (headline), headline + teaser (abstract), or headline + full body (full). (provider: benzinga)\n",
+ " date : Optional[str]\n",
+ " Date of the news to retrieve. (provider: benzinga)\n",
+ " start_date : Optional[str]\n",
+ " Start date of the news to retrieve. (provider: benzinga)\n",
+ " end_date : Optional[str]\n",
+ " End date of the news to retrieve. (provider: benzinga)\n",
+ " updated_since : Optional[int]\n",
+ " Number of seconds since the news was updated. (provider: benzinga)\n",
+ " published_since : Optional[int]\n",
+ " Number of seconds since the news was published. (provider: benzinga)\n",
+ " sort : Literal['id', 'created', 'updated']\n",
+ " Key to sort the news by. (provider: benzinga)\n",
+ " order : Literal['asc', 'desc']\n",
+ " Order to sort the news by. (provider: benzinga)\n",
+ " isin : Optional[str]\n",
+ " The ISIN of the news to retrieve. (provider: benzinga)\n",
+ " cusip : Optional[str]\n",
+ " The CUSIP of the news to retrieve. (provider: benzinga)\n",
+ " channels : Optional[str]\n",
+ " Channels of the news to retrieve. (provider: benzinga)\n",
+ " topics : Optional[str]\n",
+ " Topics of the news to retrieve. (provider: benzinga)\n",
+ " authors : Optional[str]\n",
+ " Authors of the news to retrieve. (provider: benzinga)\n",
+ " content_types : Optional[str]\n",
+ " Content types of the news to retrieve. (provider: benzinga)\n",
+ " source : Optional[str]\n",
+ " A comma-separated list of the domains requested. (provider: tiingo)\n",
+ " \n",
+ " Returns\n",
+ " -------\n",
+ " OBBject\n",
+ " results : List[WorldNews]\n",
+ " Serializable results.\n",
+ " provider : Optional[Literal['benzinga', 'fmp', 'intrinio', 'tiingo']]\n",
+ " Provider name.\n",
+ " warnings : Optional[List[Warning_]]\n",
+ " List of warnings.\n",
+ " chart : Optional[Chart]\n",
+ " Chart object.\n",
+ " extra: Dict[str, Any]\n",
+ " Extra info.\n",
+ " \n",
+ " WorldNews\n",
+ " ---------\n",
+ " date : datetime\n",
+ " The date of the data. Here it is the published date of the news.\n",
+ " title : str\n",
+ " Title of the news.\n",
+ " images : Optional[List[Dict[str, str]]]\n",
+ " Images associated with the news.\n",
+ " text : Optional[str]\n",
+ " Text/body of the news.\n",
+ " url : Optional[str]\n",
+ " URL of the news.\n",
+ " id : Optional[str]\n",
+ " Article ID. (provider: benzinga, intrinio)\n",
+ " author : Optional[str]\n",
+ " Author of the news. (provider: benzinga)\n",
+ " teaser : Optional[str]\n",
+ " Teaser of the news. (provider: benzinga)\n",
+ " channels : Optional[str]\n",
+ " Channels associated with the news. (provider: benzinga)\n",
+ " stocks : Optional[str]\n",
+ " Stocks associated with the news. (provider: benzinga)\n",
+ " tags : Optional[str]\n",
+ " Tags associated with the news. (provider: benzinga, tiingo)\n",
+ " updated : Optional[datetime]\n",
+ " Updated date of the news. (provider: benzinga)\n",
+ " site : Optional[str]\n",
+ " News source. (provider: fmp, tiingo)\n",
+ " company : Optional[Dict[str, Any]]\n",
+ " Company details related to the news article. (provider: intrinio)\n",
+ " symbols : Optional[str]\n",
+ " Ticker tagged in the fetched news. (provider: tiingo)\n",
+ " article_id : Optional[int]\n",
+ " Unique ID of the news article. (provider: tiingo)\n",
+ " crawl_date : Optional[datetime]\n",
+ " Date the news article was crawled. (provider: tiingo)\n",
+ " \n",
+ " Example\n",
+ " -------\n",
+ " >>> from openbb import obb\n",
+ " >>> obb.news.world(limit=20)\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "help(obb.news.world)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Uniform interface allows switching between providers"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "<div>\n",
+ "<style scoped>\n",
+ " .dataframe tbody tr th:only-of-type {\n",
+ " vertical-align: middle;\n",
+ " }\n",
+ "\n",
+ " .dataframe tbody tr th {\n",
+ " vertical-align: top;\n",
+ " }\n",
+ "\n",
+ " .dataframe thead th {\n",
+ " text-align: right;\n",
+ " }\n",
+ "</style>\n",
+ "<table border=\"1\" class=\"dataframe\">\n",
+ " <thead>\n",
+ " <tr style=\"text-align: right;\">\n",
+ " <th>date</th>\n",
+ " <th>2024-02-07 09:58:35+00:00</th>\n",
+ " </tr>\n",
+ " </thead>\n",
+ " <tbody>\n",
+ " <tr>\n",
+ " <th>title</th>\n",
+ " <td>Should You be Bullish on Chart Industries’ (GT...</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>text</th>\n",
+ " <td>Baron Funds, an investment management company,...</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>url</th>\n",
+ " <td>https://finance.yahoo.com/news/bullish-chart-i...</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>id</th>\n",
+ " <td>nws_AGnVkk</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>company</th>\n",
+ " <td>{'id': 'com_0yb6by', 'ticker': 'GTLS', 'name':...</td>\n",
+ " </tr>\n",
+ " </tbody>\n",
+ "</table>\n",
+ "</div>"
+ ],
+ "text/plain": [
+ "date 2024-02-07 09:58:35+00:00\n",
+ "title Should You be Bullish on Chart Industries’ (GT...\n",
+ "text Baron Funds, an investment management company,...\n",
+ "url https://finance.yahoo.com/news/bullish-chart-i...\n",
+ "id nws_AGnVkk\n",
+ "company {'id': 'com_0yb6by', 'ticker': 'GTLS', 'name':..."
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "obb.news.world(limit=1, provider=\"intrinio\").to_df().T"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "<div>\n",
+ "<style scoped>\n",
+ " .dataframe tbody tr th:only-of-type {\n",
+ " vertical-align: middle;\n",
+ " }\n",
+ "\n",
+ " .dataframe tbody tr th {\n",
+ " vertical-align: top;\n",
+ " }\n",
+ "\n",
+ " .dataframe thead th {\n",
+ " text-align: right;\n",
+ " }\n",
+ "</style>\n",
+ "<table border=\"1\" class=\"dataframe\">\n",
+ " <thead>\n",
+ " <tr style=\"text-align: right;\">\n",
+ " <th>date</th>\n",
+ " <th>2024-02-07 06:14:10-04:00</th>\n",
+ " </tr>\n",
+ " </thead>\n",
+ " <tbody>\n",
+ " <tr>\n",
+ " <th>title</th>\n",
+ " <td>Keybanc Maintains Overweight on FMC, Lowers Pr...</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>images</th>\n",
+ " <td>[]</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>text</th>\n",
+ " <td>Keybanc analyst Aleksey Yefremov maintains ...</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>url</th>\n",
+ " <td>https://www.benzinga.com/news/24/02/36974882/k...</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>id</th>\n",
+ " <td>36974882</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>author</th>\n",
+ " <td>Benzinga Newsdesk</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>teaser</th>\n",
+ " <td>Keybanc analyst Aleksey Yefremov maintains ...</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>channels</th>\n",
+ " <td>News,Price Target,Analyst Ratings</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>stocks</th>\n",
+ " <td>FMC</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>tags</th>\n",
+ " <td></td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>updated</th>\n",
+ " <td>2024-02-07 06:14:11-04:00</td>\n",
+ " </tr>\n",
+ " </tbody>\n",
+ "</table>\n",
+ "</div>"
+ ],
+ "text/plain": [
+ "date 2024-02-07 06:14:10-04:00\n",
+ "title Keybanc Maintains Overweight on FMC, Lowers Pr...\n",
+ "images []\n",
+ "text Keybanc analyst Aleksey Yefremov maintains ...\n",
+ "url https://www.benzinga.com/news/24/02/36974882/k...\n",
+ "id 36974882\n",
+ "author Benzinga Newsdesk\n",
+ "teaser Keybanc analyst Aleksey Yefremov maintains ...\n",
+ "channels News,Price Target,Analyst Ratings\n",
+ "stocks FMC\n",
+ "tags \n",
+ "updated 2024-02-07 06:14:11-04:00"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "obb.news.world(limit=1, provider=\"benzinga\").to_df().T"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "\n",
+ "---\n",
+ "\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Standardization of input and output schemas is done with Pydantic models"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### This is a standard model"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'date': FieldInfo(annotation=datetime, required=True, alias='date', alias_priority=1, description='The date of the data. Here it is the published date of the news.'),\n",
+ " 'title': FieldInfo(annotation=str, required=True, alias='title', alias_priority=1, description='Title of the news.'),\n",
+ " 'images': FieldInfo(annotation=Union[List[Dict[str, str]], NoneType], required=False, alias='images', alias_priority=1, description='Images associated with the news.'),\n",
+ " 'text': FieldInfo(annotation=Union[str, NoneType], required=False, alias='text', alias_priority=1, description='Text/body of the news.'),\n",
+ " 'url': FieldInfo(annotation=Union[str, NoneType], required=False, alias='url', alias_priority=1, description='URL of the news.')}"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "from openbb_core.provider.standard_models.world_news import WorldNewsData\n",
+ "WorldNewsData.__fields__"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### These are provider models"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from openbb_intrinio.models.world_news import IntrinioWorldNewsData\n",
+ "from openbb_benzinga.models.world_news import BenzingaWorldNewsData"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'date': FieldInfo(annotation=datetime, required=True, alias='date', alias_priority=1, description='The date of the data. Here it is the published date of the news.'),\n",
+ " 'title': FieldInfo(annotation=str, required=True, alias='title', alias_priority=1, description='Title of the news.'),\n",
+ " 'images': FieldInfo(annotation=Union[List[Dict[str, str]], NoneType], required=False, alias='images', alias_priority=1, description='Images associated with the news.'),\n",
+ " 'text': FieldInfo(annotation=Union[str, NoneType], required=False, alias='text', alias_priority=1, description='Text/body of the news.'),\n",
+ " 'url': FieldInfo(annotation=Union[str, NoneType], required=False, alias='url', alias_priority=1, description='URL of the news.'),\n",
+ " 'id': FieldInfo(annotation=str, required=True, alias='id', alias_priority=1, description='Article ID.'),\n",
+ " 'company': FieldInfo(annotation=Dict[str, Any], required=True, alias='company', alias_priority=1, description='Company details related to the news article.')}"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "IntrinioWorldNewsData.__fields__"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'date': FieldInfo(annotation=datetime, required=True, alias='date', alias_priority=1, description='The date of the data. Here it is the published date of the news.'),\n",
+ " 'title': FieldInfo(annotation=str, required=True, alias='title', alias_priority=1, description='Title of the news.'),\n",
+ " 'images': FieldInfo(annotation=Union[List[Dict[str, str]], NoneType], required=False, alias='images', alias_priority=1, description='Images associated with the news.'),\n",
+ " 'text': FieldInfo(annotation=Union[str, NoneType], required=False, alias='text', alias_priority=1, description='Text/body of the news.'),\n",
+ " 'url': FieldInfo(annotation=Union[str, NoneType], required=False, alias='url', alias_priority=1, description='URL of the news.'),\n",
+ " 'id': FieldInfo(annotation=str, required=True, alias='id', alias_priority=1, description='Article ID.'),\n",
+ " 'author': FieldInfo(annotation=Union[str, NoneType], required=False, alias='author', alias_priority=1, description='Author of the news.'),\n",
+ " 'teaser': FieldInfo(annotation=Union[str, NoneType], required=False, alias='teaser', alias_priority=1, description='Teaser of the news.'),\n",
+ " 'channels': FieldInfo(annotation=Union[str, NoneType], required=False, alias='channels', alias_priority=1, description='Channels associated with the news.'),\n",
+ " 'stocks': FieldInfo(annotation=Union[str, NoneType], required=False, alias='stocks', alias_priority=1, description='Stocks associated with the news.'),\n",
+ " 'tags': FieldInfo(annotation=Union[str, NoneType], required=False, alias='tags', alias_priority=1, description='Tags associated with the news.'),\n",
+ " 'updated': FieldInfo(annotation=Union[datetime, NoneType], required=False, alias='updated', alias_priority=1, description='Updated date of the news.')}"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "BenzingaWorldNewsData.__fields__"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Inheritance, field mapping and quality assurance"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Provider models inherit from Standard Models"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "issubclass(BenzingaWorldNewsData, WorldNewsData)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Provider models use aliases to map to standard fields"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'date': 'created', 'text': 'body', 'images': 'image'}"
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "BenzingaWorldNewsData.__alias_dict__"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Provider models implement field validation"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'date_validate': Decorator(cls_ref='openbb_intrinio.models.world_news.IntrinioWorldNewsData:5617792448', cls_var_name='date_validate', func=<bound method IntrinioWorldNewsData.date_validate of <class 'openbb_intrinio.models.world_news.IntrinioWorldNewsData'>>, shim=None, info=FieldValidatorDecoratorInfo(fields=('publication_date',), mode='before', check_fields=False))}"
+ ]
+ },
+ "execution_count": 13,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "IntrinioWorldNewsData.__dict__[\"__pydantic_decorators__\"].field_validators"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'date_validate': Decorator(cls_ref='openbb_benzinga.models.world_news.BenzingaWorldNewsData:5091361632', cls_var_name='date_validate', func=<bound method BenzingaWorldNewsData.date_validate of <class 'openbb_benzinga.models.world_news.BenzingaWorldNewsData'>>, shim=None, info=FieldValidatorDecoratorInfo(fields=('date', 'updated'), mode='before', check_fields=False)),\n",
+ " 'list_validate': Decorator(cls_ref='openbb_benzinga.models.world_news.BenzingaWorldNewsData:5091361632', cls_var_name='list_validate', func=<bound method BenzingaWorldNewsData.list_validate of <class 'openbb_benzinga.models.world_news.BenzingaWorldNewsData'>>, shim=None, info=FieldValidatorDecoratorInfo(fields=('stocks', 'channels', 'tags'), mode='before', check_fields=False)),\n",
+ " 'id_validate': Decorator(cls_ref='openbb_benzinga.models.world_news.BenzingaWorldNewsData:5091361632', cls_var_name='id_validate', func=<bound method BenzingaWorldNewsData.id_validate of <class 'openbb_benzinga.models.world_news.BenzingaWorldNewsData'>>, shim=None, info=FieldValidatorDecoratorInfo(fields=('id',), mode='before', check_fields=False))}"
+ ]
+ },
+ "execution_count": 14,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "BenzingaWorldNewsData.__dict__[\"__pydantic_decorators__\"].field_validators"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Example:\n",
+ "\n",
+ "```python\n",
+ "@field_validator(\"date\")\n",
+ "def date_validate(cls, v):\n",
+ " \"\"\"Return the date as a datetime object.\"\"\"\n",
+ " return datetime.strptime(v, \"%a, %d %b %Y %H:%M:%S %z\")\n",
+ "```\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "---"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Modularity"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "OpenBB Platform v4.1.3dev\n",
+ "\n",
+ "Utilities:\n",
+ " /account\n",
+ " /user\n",
+ " /system\n",
+ " /coverage\n",
+ "\n",
+ "Routers:\n",
+ " /crypto\n",
+ " /currency\n",
+ " /derivatives\n",
+ " /economy\n",
+ " /equity\n",
+ " /etf\n",
+ " /fixedincome\n",
+ " /index\n",
+ " /news\n",
+ " /regulators\n",
+ "\n",
+ "Extensions:\n",
+ " - crypto@1.1.1\n",
+ " - currency@1.1.1\n",
+ " - derivatives@1.1.1\n",
+ " - economy@1.1.1\n",
+ " - equity@1.1.1\n",
+ " - etf@1.1.1\n",
+ " - fixedincome@1.1.1\n",
+ " - index@1.1.1\n",
+ " - news@1.1.1\n",
+ " - openbb_charting@1.1.1\n",
+ " - regulators@1.1.1\n",
+ "\n",
+ " - benzinga@1.1.1\n",
+ " - federal_reserve@1.1.1\n",
+ " - fmp@1.1.1\n",
+ " - fred@1.1.1\n",
+ " - intrinio@1.1.1\n",
+ " - oecd@1.1.1\n",
+ " - polygon@1.1.1\n",
+ " - sec@1.1.1\n",
+ " - tiingo@1.1.1\n",
+ " - tradingeconomics@1.1.1\n",
+ " - yfinance@1.1.1 "
+ ]
+ },
+ "execution_count": 15,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "obb"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Each extension and provider integration is a separate python package"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "openbb 4.1.3\n",
+ "openbb-benzinga 1.1.1\n",
+ "openbb-charting 1.1.1\n",
+ "openbb-core 1.1.1\n",
+ "openbb-crypto 1.1.1\n",
+ "openbb-currency 1.1.1\n",
+ "openbb-derivatives 1.1.1\n",
+ "openbb-economy 1.1.1\n",
+ "openbb-equity 1.1.1\n",
+ "openbb-etf 1.1.1\n",
+ "openbb-federal-reserve 1.1.1\n",
+ "openbb-fixedincome 1.1.1\n",
+ "openbb-fmp 1.1.1\n",
+ "openbb-fred 1.1.1\n",
+ "openbb-index 1.1.1\n",
+ "openbb-intrinio 1.1.1\n",
+ "openbb-news 1.1.1\n",
+ "openbb-oecd 1.1.1\n",
+ "openbb-polygon 1.1.1\n",
+ "openbb-regulators 1.1.1\n",
+ "openbb-sec 1.1.1\n",
+ "openbb-tiingo 1.1.1\n",
+ "openbb-tradingeconomics 1.1.1\n",
+ "openbb-yfinance 1.1.1\n"
+ ]
+ }
+ ],
+ "source": [
+ "!pip list | grep openbb"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Install/Uninstall a provider as python packages"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "!pip uninstall openbb-yfinance"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "To learn more about how it works, here are a few links to the [documentation](https://docs.openbb.co/platform):\n",
+ "\n",
+ "- [Architecture. Data, Query Parameters and Fetchers.](https://docs.openbb.co/platform/development/developer-guidelines/architectural_considerations)\n",
+ "- [Integrating a new provider.](https://docs.openbb.co/platform/development/developer-guidelines/add_data_point)\n",
+ "- [Building standalone extensions.](https://docs.openbb.co/platform/development/developer-guidelines/build_openbb_extensions)\n",
+ "- and more in the [Development](https://docs.openbb.co/platform/development) section of the docs...\n"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "venv",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.11.6"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/openbb_platform/providers/fred/py.typed b/openbb_platform/providers/fred/py.typed
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/