mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-27 12:40:35 +00:00
[Feature] Store defaults in hub account (#6491)
* feat: store defaults in hub account * fix: rename var * feat: v3Credentials -> deprecatedCredentials * feat: allow unmapped deprecations * fix: account.save() * fix: unit tests * fix: update fallback message
This commit is contained in:
48
assets/extensions/provider.json
vendored
48
assets/extensions/provider.json
vendored
@@ -7,9 +7,9 @@
|
||||
"credentials": [
|
||||
"alpha_vantage_api_key"
|
||||
],
|
||||
"v3Credentials": [
|
||||
"API_KEY_ALPHAVANTAGE"
|
||||
],
|
||||
"deprecatedCredentials": {
|
||||
"API_KEY_ALPHAVANTAGE": "alpha_vantage_api_key"
|
||||
},
|
||||
"website": "https://www.alphavantage.co",
|
||||
"instructions": "Go to: https://www.alphavantage.co/support/#api-key\n\n\n\nFill out the form, pass Captcha, and click on, \"GET FREE API KEY\"."
|
||||
},
|
||||
@@ -31,9 +31,9 @@
|
||||
"credentials": [
|
||||
"biztoc_api_key"
|
||||
],
|
||||
"v3Credentials": [
|
||||
"API_BIZTOC_TOKEN"
|
||||
],
|
||||
"deprecatedCredentials": {
|
||||
"API_BIZTOC_TOKEN": "biztoc_api_key"
|
||||
},
|
||||
"website": "https://api.biztoc.com",
|
||||
"instructions": "The BizToc API is hosted on RapidAPI. To set up, go to: https://rapidapi.com/thma/api/biztoc.\n\n\n\nIn the top right, select 'Sign Up'. After answering some questions, you will be prompted to select one of their plans.\n\n\n\nAfter signing up, navigate back to https://rapidapi.com/thma/api/biztoc. If you are logged in, you will see a header called X-RapidAPI-Key.\n\n"
|
||||
},
|
||||
@@ -95,9 +95,9 @@
|
||||
"credentials": [
|
||||
"fmp_api_key"
|
||||
],
|
||||
"v3Credentials": [
|
||||
"API_KEY_FINANCIALMODELINGPREP"
|
||||
],
|
||||
"deprecatedCredentials": {
|
||||
"API_KEY_FINANCIALMODELINGPREP": "fmp_api_key"
|
||||
},
|
||||
"website": "https://financialmodelingprep.com",
|
||||
"instructions": "Go to: https://site.financialmodelingprep.com/developer/docs\n\n\n\nClick on, \"Get my API KEY here\", and sign up for a free account.\n\n\n\nWith an account created, sign in and navigate to the Dashboard, which shows the assigned token. by pressing the \"Dashboard\" button which will show the API key.\n\n"
|
||||
},
|
||||
@@ -109,9 +109,9 @@
|
||||
"credentials": [
|
||||
"fred_api_key"
|
||||
],
|
||||
"v3Credentials": [
|
||||
"API_FRED_KEY"
|
||||
],
|
||||
"deprecatedCredentials": {
|
||||
"API_FRED_KEY": "fred_api_key"
|
||||
},
|
||||
"website": "https://fred.stlouisfed.org",
|
||||
"instructions": "Go to: https://fred.stlouisfed.org\n\n\n\nClick on, \"My Account\", create a new account or sign in with Google:\n\n\n\nAfter completing the sign-up, go to \"My Account\", and select \"API Keys\". Then, click on, \"Request API Key\".\n\n\n\nFill in the box for information about the use-case for FRED, and by clicking, \"Request API key\", at the bottom of the page, the API key will be issued.\n\n"
|
||||
},
|
||||
@@ -131,9 +131,9 @@
|
||||
"credentials": [
|
||||
"intrinio_api_key"
|
||||
],
|
||||
"v3Credentials": [
|
||||
"API_INTRINIO_KEY"
|
||||
],
|
||||
"deprecatedCredentials": {
|
||||
"API_INTRINIO_KEY": "intrinio_api_key"
|
||||
},
|
||||
"website": "https://intrinio.com",
|
||||
"instructions": "Go to: https://intrinio.com/starter-plan\n\n\n\nAn API key will be issued with a subscription. Find the token value within the account dashboard."
|
||||
},
|
||||
@@ -145,9 +145,9 @@
|
||||
"credentials": [
|
||||
"nasdaq_api_key"
|
||||
],
|
||||
"v3Credentials": [
|
||||
"API_KEY_QUANDL"
|
||||
],
|
||||
"deprecatedCredentials": {
|
||||
"API_KEY_QUANDL": "nasdaq_api_key"
|
||||
},
|
||||
"website": "https://data.nasdaq.com",
|
||||
"instructions": "Go to: https://www.quandl.com\n\n\n\nClick on, \"Sign Up\", and register a new account.\n\n\n\nFollow the sign-up instructions, and upon completion the API key will be assigned.\n\n"
|
||||
},
|
||||
@@ -167,9 +167,9 @@
|
||||
"credentials": [
|
||||
"polygon_api_key"
|
||||
],
|
||||
"v3Credentials": [
|
||||
"API_POLYGON_KEY"
|
||||
],
|
||||
"deprecatedCredentials": {
|
||||
"API_POLYGON_KEY": "polygon_api_key"
|
||||
},
|
||||
"website": "https://polygon.io",
|
||||
"instructions": "Go to: https://polygon.io\n\n\n\nClick on, \"Get your Free API Key\".\n\n\n\nAfter signing up, the API Key is found at the bottom of the account dashboard page.\n\n"
|
||||
},
|
||||
@@ -224,9 +224,9 @@
|
||||
"tradier_api_key",
|
||||
"tradier_account_type"
|
||||
],
|
||||
"v3Credentials": [
|
||||
"API_TRADIER_TOKEN"
|
||||
],
|
||||
"deprecatedCredentials": {
|
||||
"API_TRADIER_TOKEN": "tradier_api_key"
|
||||
},
|
||||
"website": "https://tradier.com",
|
||||
"instructions": "Go to: https://documentation.tradier.com\n\n\n\nClick on, \"Open Account\", to start the sign-up process. After the account has been setup, navigate to [Tradier Broker Dash](https://dash.tradier.com/login?redirect=settings.api) and create the application. Request a sandbox access token."
|
||||
},
|
||||
|
||||
@@ -47,7 +47,7 @@ def to_camel(string: str):
|
||||
return components[0] + "".join(x.title() for x in components[1:])
|
||||
|
||||
|
||||
def createItem(package_name: str, obj: object, obj_attrs: List[str]) -> Dict[str, Any]:
|
||||
def create_item(package_name: str, obj: object, obj_attrs: List[str]) -> Dict[str, Any]:
|
||||
"""Create dictionary item from object attributes."""
|
||||
pkg_spec = OPENBB_PLATFORM_TOML.data["tool"]["poetry"]["dependencies"].get(
|
||||
package_name
|
||||
@@ -68,7 +68,7 @@ def generate_provider_extensions() -> None:
|
||||
"repr_name",
|
||||
"description",
|
||||
"credentials",
|
||||
"v3_credentials",
|
||||
"deprecated_credentials",
|
||||
"website",
|
||||
"instructions",
|
||||
]
|
||||
@@ -80,7 +80,7 @@ def generate_provider_extensions() -> None:
|
||||
file, obj = file_obj[0], file_obj[1]
|
||||
module = import_module(file)
|
||||
provider_obj = getattr(module, obj)
|
||||
data.append(createItem(pkg_name, provider_obj, obj_attrs))
|
||||
data.append(create_item(pkg_name, provider_obj, obj_attrs))
|
||||
write("provider", data)
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ def generate_router_extensions() -> None:
|
||||
file, obj = file_obj[0], file_obj[1]
|
||||
module = import_module(file)
|
||||
router_obj = getattr(module, obj)
|
||||
data.append(createItem(pkg_name, router_obj, obj_attrs))
|
||||
data.append(create_item(pkg_name, router_obj, obj_attrs))
|
||||
write("router", data)
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ def generate_obbject_extensions() -> None:
|
||||
file, obj = file_obj[0], file_obj[1]
|
||||
module = import_module(file)
|
||||
ext_obj = getattr(module, obj)
|
||||
data.append(createItem(pkg_name, ext_obj, obj_attrs))
|
||||
data.append(create_item(pkg_name, ext_obj, obj_attrs))
|
||||
write("obbject", data)
|
||||
|
||||
|
||||
|
||||
@@ -44,3 +44,8 @@ class Defaults(BaseModel):
|
||||
v["provider"] = [provider]
|
||||
new_values["commands"][clean_k] = v
|
||||
return new_values
|
||||
|
||||
def update(self, incoming: "Defaults"):
|
||||
"""Update current defaults."""
|
||||
incoming_commands = incoming.model_dump(exclude_none=True).get("commands", {})
|
||||
self.__dict__["commands"].update(incoming_commands)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Hub user settings model."""
|
||||
|
||||
from typing import Dict, Optional
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
@@ -8,9 +8,9 @@ from pydantic import BaseModel, ConfigDict, Field
|
||||
class HubUserSettings(BaseModel):
|
||||
"""Hub user settings model."""
|
||||
|
||||
# features_settings: Dict[str, str]
|
||||
features_settings: Dict[str, Any] = Field(default_factory=dict)
|
||||
features_keys: Dict[str, Optional[str]] = Field(default_factory=dict)
|
||||
# features_sources: Dict[str, List[str]]
|
||||
# features_sources: Dict[str, Any]
|
||||
# features_terminal_style: Dict[str, Union[str, Dict[str, str]]]
|
||||
|
||||
model_config = ConfigDict(validate_assignment=True)
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
"""Hub manager class."""
|
||||
|
||||
from typing import Optional
|
||||
from typing import Optional, Tuple
|
||||
from warnings import warn
|
||||
|
||||
from fastapi import HTTPException
|
||||
from jwt import ExpiredSignatureError, PyJWTError, decode, get_unverified_header
|
||||
from openbb_core.app.model.abstract.error import OpenBBError
|
||||
from openbb_core.app.model.credentials import Credentials
|
||||
from openbb_core.app.model.defaults import Defaults
|
||||
from openbb_core.app.model.hub.hub_session import HubSession
|
||||
from openbb_core.app.model.hub.hub_user_settings import HubUserSettings
|
||||
from openbb_core.app.model.profile import Profile
|
||||
@@ -81,7 +82,9 @@ class HubService:
|
||||
"""Push user settings to Hub."""
|
||||
if self._session:
|
||||
if user_settings.credentials:
|
||||
hub_user_settings = self.platform2hub(user_settings.credentials)
|
||||
hub_user_settings = self.platform2hub(
|
||||
user_settings.credentials, user_settings.defaults
|
||||
)
|
||||
return self._put_user_settings(self._session, hub_user_settings)
|
||||
return False
|
||||
raise OpenBBError(
|
||||
@@ -93,8 +96,10 @@ class HubService:
|
||||
if self._session:
|
||||
self._hub_user_settings = self._get_user_settings(self._session)
|
||||
profile = Profile(hub_session=self._session)
|
||||
credentials = self.hub2platform(self._hub_user_settings)
|
||||
return UserSettings(profile=profile, credentials=credentials)
|
||||
credentials, defaults = self.hub2platform(self._hub_user_settings)
|
||||
return UserSettings(
|
||||
profile=profile, credentials=credentials, defaults=defaults
|
||||
)
|
||||
raise OpenBBError(
|
||||
"No session found. Login or provide a 'HubSession' on initialization."
|
||||
)
|
||||
@@ -223,7 +228,7 @@ class HubService:
|
||||
detail = response.json().get("detail", None)
|
||||
raise HTTPException(status_code, detail)
|
||||
|
||||
def hub2platform(self, settings: HubUserSettings) -> Credentials:
|
||||
def hub2platform(self, settings: HubUserSettings) -> Tuple[Credentials, Defaults]:
|
||||
"""Convert Hub user settings to Platform models."""
|
||||
if any(k in settings.features_keys for k in self.V3TOV4):
|
||||
deprecated = {
|
||||
@@ -242,9 +247,12 @@ class HubService:
|
||||
self.V3TOV4.get(k, k): settings.features_keys.get(self.V3TOV4.get(k, k), v)
|
||||
for k, v in settings.features_keys.items()
|
||||
}
|
||||
return Credentials(**hub_credentials)
|
||||
defaults = settings.features_settings.get("defaults", {})
|
||||
return Credentials(**hub_credentials), Defaults(**defaults)
|
||||
|
||||
def platform2hub(self, credentials: Credentials) -> HubUserSettings:
|
||||
def platform2hub(
|
||||
self, credentials: Credentials, defaults: Defaults
|
||||
) -> HubUserSettings:
|
||||
"""Convert Platform models to Hub user settings."""
|
||||
# Dump mode json ensures SecretStr values are serialized as strings
|
||||
credentials = credentials.model_dump(mode="json", exclude_none=True)
|
||||
@@ -254,6 +262,8 @@ class HubService:
|
||||
# If v3 key was in the hub already, we keep it
|
||||
k = v3_k if v3_k in settings.features_keys else v4_k
|
||||
settings.features_keys[k] = v
|
||||
defaults_ = defaults.model_dump(mode="json", exclude_none=True)
|
||||
settings.features_settings.update({"defaults": defaults_})
|
||||
return settings
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -125,6 +125,7 @@ class Account: # noqa: D205, D400
|
||||
incoming = self._hub_service.pull()
|
||||
self._base_app.user.profile = incoming.profile
|
||||
self._base_app.user.credentials.update(incoming.credentials)
|
||||
self._base_app.user.defaults.update(incoming.defaults)
|
||||
if remember_me:
|
||||
Path(self._openbb_directory).mkdir(parents=False, exist_ok=True)
|
||||
session_file = Path(self._openbb_directory, self.SESSION_FILE)
|
||||
@@ -187,6 +188,7 @@ class Account: # noqa: D205, D400
|
||||
incoming = self._hub_service.pull()
|
||||
self._base_app.user.profile = incoming.profile
|
||||
self._base_app.user.credentials.update(incoming.credentials)
|
||||
self._base_app.user.defaults.update(incoming.defaults)
|
||||
if return_settings:
|
||||
return self._base_app._command_runner.user_settings
|
||||
return None
|
||||
|
||||
@@ -69,14 +69,14 @@ class Container:
|
||||
result = self._check_credentials(p)
|
||||
if result:
|
||||
return p
|
||||
elif result is False:
|
||||
if result is False:
|
||||
tries.append((p, "missing credentials"))
|
||||
else:
|
||||
tries.append((p, "not found"))
|
||||
|
||||
msg = "\n ".join([f"* '{pair[0]}' -> {pair[1]}" for pair in tries])
|
||||
raise OpenBBError(
|
||||
f"Provider fallback failed, please specify the provider or update credentials.\n"
|
||||
f"Provider fallback failed, please specify one of the available providers or update credentials.\n"
|
||||
f"[Providers]\n {msg}"
|
||||
)
|
||||
return choice
|
||||
|
||||
@@ -17,7 +17,7 @@ class Provider:
|
||||
credentials: Optional[List[str]] = None,
|
||||
fetcher_dict: Optional[Dict[str, Type[Fetcher]]] = None,
|
||||
repr_name: Optional[str] = None,
|
||||
v3_credentials: Optional[List[str]] = None,
|
||||
deprecated_credentials: Optional[Dict[str, Optional[str]]] = None,
|
||||
instructions: Optional[str] = None,
|
||||
) -> None:
|
||||
"""Initialize the provider.
|
||||
@@ -36,8 +36,8 @@ class Provider:
|
||||
Dictionary of fetchers, by default None.
|
||||
repr_name: Optional[str]
|
||||
Full name of the provider, by default None.
|
||||
v3_credentials: Optional[List[str]]
|
||||
List of corresponding v3 credentials, by default None.
|
||||
deprecated_credentials: Optional[Dict[str, Optional[str]]]
|
||||
Map of deprecated credentials to its current name, by default None.
|
||||
instructions: Optional[str]
|
||||
Instructions on how to setup the provider. For example, how to get an API key.
|
||||
"""
|
||||
@@ -52,5 +52,5 @@ class Provider:
|
||||
for c in credentials:
|
||||
self.credentials.append(f"{self.name.lower()}_{c}")
|
||||
self.repr_name = repr_name
|
||||
self.v3_credentials = v3_credentials
|
||||
self.deprecated_credentials = deprecated_credentials
|
||||
self.instructions = instructions
|
||||
|
||||
@@ -10,6 +10,7 @@ from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from jwt import encode
|
||||
from openbb_core.app.model.defaults import Defaults
|
||||
from openbb_core.app.service.hub_service import (
|
||||
Credentials,
|
||||
HubService,
|
||||
@@ -242,8 +243,9 @@ def test_hub2platform_v4_only():
|
||||
"polygon_api_key": "def",
|
||||
"fred_api_key": "ghi",
|
||||
}
|
||||
mock_user_settings.features_settings = {}
|
||||
|
||||
credentials = HubService().hub2platform(mock_user_settings)
|
||||
credentials, _ = HubService().hub2platform(mock_user_settings)
|
||||
assert isinstance(credentials, Credentials)
|
||||
assert credentials.fmp_api_key.get_secret_value() == "abc"
|
||||
assert credentials.polygon_api_key.get_secret_value() == "def"
|
||||
@@ -258,8 +260,9 @@ def test_hub2platform_v3_only():
|
||||
"API_POLYGON_KEY": "def",
|
||||
"API_FRED_KEY": "ghi",
|
||||
}
|
||||
mock_user_settings.features_settings = {}
|
||||
|
||||
credentials = HubService().hub2platform(mock_user_settings)
|
||||
credentials, _ = HubService().hub2platform(mock_user_settings)
|
||||
assert isinstance(credentials, Credentials)
|
||||
assert credentials.fmp_api_key.get_secret_value() == "abc"
|
||||
assert credentials.polygon_api_key.get_secret_value() == "def"
|
||||
@@ -275,8 +278,9 @@ def test_hub2platform_v3v4():
|
||||
"API_POLYGON_KEY": "def",
|
||||
"API_FRED_KEY": "ghi",
|
||||
}
|
||||
mock_user_settings.features_settings = {}
|
||||
|
||||
credentials = HubService().hub2platform(mock_user_settings)
|
||||
credentials, _ = HubService().hub2platform(mock_user_settings)
|
||||
assert isinstance(credentials, Credentials)
|
||||
assert credentials.fmp_api_key.get_secret_value() == "other_key"
|
||||
assert credentials.polygon_api_key.get_secret_value() == "def"
|
||||
@@ -291,6 +295,7 @@ def test_platform2hub():
|
||||
"fmp_api_key": "other_key",
|
||||
"API_FRED_KEY": "ghi",
|
||||
}
|
||||
mock_user_settings.features_settings = {}
|
||||
mock_hub_service = HubService()
|
||||
mock_hub_service._hub_user_settings = mock_user_settings
|
||||
mock_credentials = Credentials( # Current credentials
|
||||
@@ -300,7 +305,8 @@ def test_platform2hub():
|
||||
benzinga_api_key=SecretStr("benzinga"),
|
||||
some_api_key=SecretStr("some"),
|
||||
)
|
||||
user_settings = mock_hub_service.platform2hub(mock_credentials)
|
||||
mock_defaults = Defaults()
|
||||
user_settings = mock_hub_service.platform2hub(mock_credentials, mock_defaults)
|
||||
|
||||
assert isinstance(user_settings, HubUserSettings)
|
||||
assert user_settings.features_keys["API_KEY_FINANCIALMODELINGPREP"] == "fmp"
|
||||
@@ -309,6 +315,7 @@ def test_platform2hub():
|
||||
assert user_settings.features_keys["API_FRED_KEY"] == "fred"
|
||||
assert user_settings.features_keys["benzinga_api_key"] == "benzinga"
|
||||
assert "some_api_key" not in user_settings.features_keys
|
||||
assert "defaults" in user_settings.features_settings
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -88,7 +88,7 @@ def test_container__check_credentials(container):
|
||||
("provider_1", "provider_2"),
|
||||
OpenBBError,
|
||||
escape(
|
||||
"Provider fallback failed, please specify the provider or update credentials."
|
||||
"Provider fallback failed, please specify one of the available providers or update credentials."
|
||||
"\n[Providers]\n * 'x' -> not found\n * 'y' -> not found\n * 'z' -> not found"
|
||||
),
|
||||
),
|
||||
|
||||
@@ -21,6 +21,6 @@ cloud-based APIs, Excel, and Google Sheets. """,
|
||||
"EtfHistorical": AVEquityHistoricalFetcher,
|
||||
},
|
||||
repr_name="Alpha Vantage",
|
||||
v3_credentials=["API_KEY_ALPHAVANTAGE"],
|
||||
deprecated_credentials={"API_KEY_ALPHAVANTAGE": "alpha_vantage_api_key"},
|
||||
instructions='Go to: https://www.alphavantage.co/support/#api-key\n\n\n\nFill out the form, pass Captcha, and click on, "GET FREE API KEY".', # noqa: E501 pylint: disable=line-too-long
|
||||
)
|
||||
|
||||
@@ -20,6 +20,6 @@ we've partnered with OpenBB, allowing you to pull in BizToc's news stream in the
|
||||
"WorldNews": BiztocWorldNewsFetcher,
|
||||
},
|
||||
repr_name="BizToc",
|
||||
v3_credentials=["API_BIZTOC_TOKEN"],
|
||||
deprecated_credentials={"API_BIZTOC_TOKEN": "biztoc_api_key"},
|
||||
instructions="The BizToc API is hosted on RapidAPI. To set up, go to: https://rapidapi.com/thma/api/biztoc.\n\n\n\nIn the top right, select 'Sign Up'. After answering some questions, you will be prompted to select one of their plans.\n\n\n\nAfter signing up, navigate back to https://rapidapi.com/thma/api/biztoc. If you are logged in, you will see a header called X-RapidAPI-Key.\n\n", # noqa: E501 pylint: disable=line-too-long
|
||||
)
|
||||
|
||||
@@ -138,6 +138,6 @@ stock market information (news, currencies, and stock prices).""",
|
||||
"YieldCurve": FMPYieldCurveFetcher,
|
||||
},
|
||||
repr_name="Financial Modeling Prep (FMP)",
|
||||
v3_credentials=["API_KEY_FINANCIALMODELINGPREP"],
|
||||
deprecated_credentials={"API_KEY_FINANCIALMODELINGPREP": "fmp_api_key"},
|
||||
instructions='Go to: https://site.financialmodelingprep.com/developer/docs\n\n\n\nClick on, "Get my API KEY here", and sign up for a free account.\n\n\n\nWith an account created, sign in and navigate to the Dashboard, which shows the assigned token. by pressing the "Dashboard" button which will show the API key.\n\n', # noqa: E501 pylint: disable=line-too-long
|
||||
)
|
||||
|
||||
@@ -86,6 +86,6 @@ Research division of the Federal Reserve Bank of St. Louis that has more than
|
||||
"YieldCurve": FREDYieldCurveFetcher,
|
||||
},
|
||||
repr_name="Federal Reserve Economic Data | St. Louis FED (FRED)",
|
||||
v3_credentials=["API_FRED_KEY"],
|
||||
deprecated_credentials={"API_FRED_KEY": "fred_api_key"},
|
||||
instructions='Go to: https://fred.stlouisfed.org\n\n\n\nClick on, "My Account", create a new account or sign in with Google:\n\n\n\nAfter completing the sign-up, go to "My Account", and select "API Keys". Then, click on, "Request API Key".\n\n\n\nFill in the box for information about the use-case for FRED, and by clicking, "Request API key", at the bottom of the page, the API key will be issued.\n\n', # noqa: E501 pylint: disable=line-too-long
|
||||
)
|
||||
|
||||
@@ -108,6 +108,6 @@ historical financial market data to businesses and developers through an API."""
|
||||
"WorldNews": IntrinioWorldNewsFetcher,
|
||||
},
|
||||
repr_name="Intrinio",
|
||||
v3_credentials=["API_INTRINIO_KEY"],
|
||||
deprecated_credentials={"API_INTRINIO_KEY": "intrinio_api_key"},
|
||||
instructions="Go to: https://intrinio.com/starter-plan\n\n\n\nAn API key will be issued with a subscription. Find the token value within the account dashboard.", # noqa: E501 pylint: disable=line-too-long
|
||||
)
|
||||
|
||||
@@ -34,6 +34,6 @@ unmatched technology, insights and markets expertise.""",
|
||||
"TopRetail": NasdaqTopRetailFetcher,
|
||||
},
|
||||
repr_name="NASDAQ",
|
||||
v3_credentials=["API_KEY_QUANDL"],
|
||||
deprecated_credentials={"API_KEY_QUANDL": "nasdaq_api_key"},
|
||||
instructions='Go to: https://www.quandl.com\n\n\n\nClick on, "Sign Up", and register a new account.\n\n\n\nFollow the sign-up instructions, and upon completion the API key will be assigned.\n\n', # noqa: E501 pylint: disable=line-too-long
|
||||
)
|
||||
|
||||
@@ -40,6 +40,6 @@ company financials, stock market holidays, corporate actions, and more.""",
|
||||
"MarketSnapshots": PolygonMarketSnapshotsFetcher,
|
||||
},
|
||||
repr_name="Polygon.io",
|
||||
v3_credentials=["API_POLYGON_KEY"],
|
||||
deprecated_credentials={"API_POLYGON_KEY": "polygon_api_key"},
|
||||
instructions='Go to: https://polygon.io\n\n\n\nClick on, "Get your Free API Key".\n\n\n\nAfter signing up, the API Key is found at the bottom of the account dashboard page.\n\n', # noqa: E501 pylint: disable=line-too-long
|
||||
)
|
||||
|
||||
@@ -26,6 +26,6 @@ Tradier Brokerage accounts through our APIs.""",
|
||||
"OptionsChains": TradierOptionsChainsFetcher,
|
||||
},
|
||||
repr_name="Tradier",
|
||||
v3_credentials=["API_TRADIER_TOKEN"],
|
||||
deprecated_credentials={"API_TRADIER_TOKEN": "tradier_api_key"},
|
||||
instructions='Go to: https://documentation.tradier.com\n\n\n\nClick on, "Open Account", to start the sign-up process. After the account has been setup, navigate to [Tradier Broker Dash](https://dash.tradier.com/login?redirect=settings.api) and create the application. Request a sandbox access token.', # noqa: E501 pylint: disable=line-too-long
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user