mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-11-08 10:22:09 +00:00
Merge branch 'develop' into feature/charting-obbject
This commit is contained in:
14
.github/labeler.yml
vendored
14
.github/labeler.yml
vendored
@@ -9,16 +9,6 @@ labels:
|
||||
files:
|
||||
- "openbb_platform/.*"
|
||||
|
||||
- label: "bug"
|
||||
branch: "^hotfix/.*"
|
||||
files:
|
||||
- "openbb_platform/.*"
|
||||
|
||||
- label: "platform"
|
||||
branch: "^hotfix/.*"
|
||||
files:
|
||||
- "openbb_platform/.*"
|
||||
|
||||
- label: "enhancement"
|
||||
branch: "^feature/.*"
|
||||
|
||||
@@ -27,3 +17,7 @@ labels:
|
||||
|
||||
- label: "docs"
|
||||
branch: "^docs/.*"
|
||||
|
||||
- label: "excel"
|
||||
files:
|
||||
- "website/content/excel/.*"
|
||||
2
.github/workflows/labels-PR.yml
vendored
2
.github/workflows/labels-PR.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: 💡 Pull Request Labels
|
||||
name: Pull Request Labels
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
50
openbb_platform/core/openbb_core/app/assets/parameter_pool.json
vendored
Normal file
50
openbb_platform/core/openbb_core/app/assets/parameter_pool.json
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"crypto": {
|
||||
"symbol": "BTCUSD"
|
||||
},
|
||||
"currency": {
|
||||
"symbol": "EURUSD"
|
||||
},
|
||||
"derivatives": {
|
||||
"symbol": "AAPL"
|
||||
},
|
||||
"economy": {
|
||||
"country": "portugal",
|
||||
"countries": ["portugal", "spain"]
|
||||
},
|
||||
"economy.fred_series": {
|
||||
"symbol": "GFDGDPA188S"
|
||||
},
|
||||
"equity": {
|
||||
"symbol": "AAPL",
|
||||
"symbols": "AAPL,MSFT",
|
||||
"query": "AAPL"
|
||||
},
|
||||
"equity.fundamental.historical_attributes": {
|
||||
"tag": "ebitda"
|
||||
},
|
||||
"equity.fundamental.latest_attributes": {
|
||||
"tag": "ceo"
|
||||
},
|
||||
"equity.fundamental.transcript": {
|
||||
"year": 2020
|
||||
},
|
||||
"etf": {
|
||||
"symbol": "SPY",
|
||||
"query": "Vanguard"
|
||||
},
|
||||
"futures": {
|
||||
"symbol": "ES"
|
||||
},
|
||||
"index": {
|
||||
"symbol": "SPX",
|
||||
"index": "^IBEX"
|
||||
},
|
||||
"news": {
|
||||
"symbols": "AAPL,MSFT"
|
||||
},
|
||||
"regulators": {
|
||||
"symbol": "AAPL",
|
||||
"query": "AAPL"
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
ASSETS_DIRECTORY = Path(__file__).parent / "assets"
|
||||
HOME_DIRECTORY = Path.home()
|
||||
OPENBB_DIRECTORY = Path(HOME_DIRECTORY, ".openbb_platform")
|
||||
USER_SETTINGS_PATH = Path(OPENBB_DIRECTORY, "user_settings.json")
|
||||
|
||||
83
openbb_platform/core/openbb_core/app/example_generator.py
Normal file
83
openbb_platform/core/openbb_core/app/example_generator.py
Normal file
@@ -0,0 +1,83 @@
|
||||
"""OpenBB Platform example generator."""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import (
|
||||
Any,
|
||||
Dict,
|
||||
)
|
||||
|
||||
from pydantic.fields import FieldInfo
|
||||
from pydantic_core import PydanticUndefined
|
||||
|
||||
from openbb_core.app.constants import ASSETS_DIRECTORY
|
||||
from openbb_core.app.provider_interface import ProviderInterface
|
||||
|
||||
try:
|
||||
with Path(ASSETS_DIRECTORY, "parameter_pool.json").open() as f:
|
||||
PARAMETER_POOL = json.load(f)
|
||||
except Exception:
|
||||
PARAMETER_POOL = {}
|
||||
|
||||
|
||||
class ExampleGenerator:
|
||||
"""Generate examples for the API."""
|
||||
|
||||
@staticmethod
|
||||
def _get_value_from_pool(pool: dict, route: str, param: str) -> str:
|
||||
"""Get the value from the pool.
|
||||
|
||||
The example parameters can be defined for:
|
||||
- route: "crypto.historical.price": {"symbol": "CRYPTO_HISTORICAL_PRICE_SYMBOL"}
|
||||
- sub-router: "crypto.historical": {"symbol": "CRYPTO_HISTORICAL_SYMBOL"}
|
||||
- router: "crypto": {"symbol": "CRYPTO_SYMBOL"}
|
||||
|
||||
The search for the 'key' is done in the following order:
|
||||
- route
|
||||
- sub-router
|
||||
- router
|
||||
"""
|
||||
parts = route.split(".")
|
||||
for i in range(len(parts), 0, -1):
|
||||
partial_route = ".".join(parts[:i])
|
||||
if partial_route in pool and param in pool[partial_route]:
|
||||
return pool[partial_route][param]
|
||||
return "VALUE_NOT_FOUND"
|
||||
|
||||
@classmethod
|
||||
def generate(
|
||||
cls,
|
||||
route: str,
|
||||
model: str,
|
||||
) -> str:
|
||||
"""Generate the example for the command."""
|
||||
if not route or not model:
|
||||
return ""
|
||||
|
||||
standard_params: Dict[str, FieldInfo] = (
|
||||
ProviderInterface()
|
||||
.map.get(model, {})
|
||||
.get("openbb", {})
|
||||
.get("QueryParams", {})
|
||||
.get("fields", {})
|
||||
)
|
||||
|
||||
eg_params: Dict[str, Any] = {}
|
||||
for p, v in standard_params.items():
|
||||
if v.default is not None:
|
||||
if v.default is not PydanticUndefined and v.default != "":
|
||||
eg_params[p] = v.default
|
||||
else:
|
||||
eg_params[p] = cls._get_value_from_pool(PARAMETER_POOL, route, p)
|
||||
|
||||
example = f"obb.{route}("
|
||||
for n, v in eg_params.items():
|
||||
if isinstance(v, str):
|
||||
v = f'"{v}"' # noqa: PLW2901
|
||||
example += f"{n}={v}, "
|
||||
if eg_params:
|
||||
example = example[:-2] + ")"
|
||||
else:
|
||||
example += ")"
|
||||
|
||||
return example
|
||||
@@ -24,6 +24,7 @@ from pydantic import BaseModel
|
||||
from pydantic.v1.validators import find_validators
|
||||
from typing_extensions import Annotated, ParamSpec, _AnnotatedAlias
|
||||
|
||||
from openbb_core.app.example_generator import ExampleGenerator
|
||||
from openbb_core.app.extension_loader import ExtensionLoader
|
||||
from openbb_core.app.model.abstract.warning import OpenBBWarning
|
||||
from openbb_core.app.model.command_context import CommandContext
|
||||
@@ -232,16 +233,23 @@ class Router:
|
||||
|
||||
model = kwargs.pop("model", "")
|
||||
deprecation_message = kwargs.pop("deprecation_message", None)
|
||||
examples = kwargs.pop("examples", [])
|
||||
exclude_auto_examples = kwargs.pop("exclude_auto_examples", False)
|
||||
|
||||
if func := SignatureInspector.complete(func, model):
|
||||
if not exclude_auto_examples:
|
||||
examples.insert(
|
||||
0,
|
||||
ExampleGenerator.generate(
|
||||
route=SignatureInspector.get_operation_id(func, sep="."),
|
||||
model=model,
|
||||
),
|
||||
)
|
||||
|
||||
if model:
|
||||
kwargs["response_model_exclude_unset"] = True
|
||||
kwargs["openapi_extra"] = {"model": model}
|
||||
|
||||
func = SignatureInspector.complete_signature(func, model)
|
||||
|
||||
if func:
|
||||
CommandValidator.check(func=func, model=model)
|
||||
|
||||
kwargs["openapi_extra"] = kwargs.get("openapi_extra", {})
|
||||
kwargs["openapi_extra"]["model"] = model
|
||||
kwargs["openapi_extra"]["examples"] = examples
|
||||
kwargs["operation_id"] = kwargs.get(
|
||||
"operation_id", SignatureInspector.get_operation_id(func)
|
||||
)
|
||||
@@ -300,7 +308,7 @@ class SignatureInspector:
|
||||
"""Inspect function signature."""
|
||||
|
||||
@classmethod
|
||||
def complete_signature(
|
||||
def complete(
|
||||
cls, func: Callable[P, OBBject], model: str
|
||||
) -> Optional[Callable[P, OBBject]]:
|
||||
"""Complete function signature."""
|
||||
@@ -321,7 +329,6 @@ class SignatureInspector:
|
||||
category=OpenBBWarning,
|
||||
)
|
||||
return None
|
||||
|
||||
cls.validate_signature(
|
||||
func,
|
||||
{
|
||||
@@ -445,19 +452,20 @@ class SignatureInspector:
|
||||
if doc:
|
||||
description = doc.split(" Parameters\n ----------")[0]
|
||||
description = description.split(" Returns\n -------")[0]
|
||||
description = description.split(" Example\n -------")[0]
|
||||
description = "\n".join([line.strip() for line in description.split("\n")])
|
||||
|
||||
return description
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def get_operation_id(func: Callable) -> str:
|
||||
def get_operation_id(func: Callable, sep: str = "_") -> str:
|
||||
"""Get operation id."""
|
||||
operation_id = [
|
||||
t.replace("_router", "").replace("openbb_", "")
|
||||
for t in func.__module__.split(".") + [func.__name__]
|
||||
]
|
||||
cleaned_id = "_".join({c: "" for c in operation_id if c}.keys())
|
||||
cleaned_id = sep.join({c: "" for c in operation_id if c}.keys())
|
||||
return cleaned_id
|
||||
|
||||
|
||||
|
||||
@@ -9,11 +9,9 @@ from inspect import Parameter, _empty, isclass, signature
|
||||
from json import dumps, load
|
||||
from pathlib import Path
|
||||
from typing import (
|
||||
Any,
|
||||
Callable,
|
||||
Dict,
|
||||
List,
|
||||
Literal,
|
||||
Optional,
|
||||
OrderedDict,
|
||||
Set,
|
||||
@@ -22,7 +20,6 @@ from typing import (
|
||||
TypeVar,
|
||||
Union,
|
||||
get_args,
|
||||
get_origin,
|
||||
get_type_hints,
|
||||
)
|
||||
|
||||
@@ -37,7 +34,7 @@ from typing_extensions import Annotated, _AnnotatedAlias
|
||||
from openbb_core.app.extension_loader import ExtensionLoader, OpenBBGroups
|
||||
from openbb_core.app.model.custom_parameter import OpenBBCustomParameter
|
||||
from openbb_core.app.provider_interface import ProviderInterface
|
||||
from openbb_core.app.router import CommandMap, RouterLoader
|
||||
from openbb_core.app.router import RouterLoader
|
||||
from openbb_core.app.static.utils.console import Console
|
||||
from openbb_core.app.static.utils.linters import Linters
|
||||
from openbb_core.env import Env
|
||||
@@ -395,6 +392,7 @@ class ClassDefinition:
|
||||
if route.openapi_extra
|
||||
else None
|
||||
),
|
||||
examples=route.openapi_extra.get("examples", None),
|
||||
) # type: ignore
|
||||
else:
|
||||
doc += " /" if path else " /"
|
||||
@@ -667,12 +665,16 @@ class MethodDefinition:
|
||||
func: Callable,
|
||||
formatted_params: OrderedDict[str, Parameter],
|
||||
model_name: Optional[str] = None,
|
||||
examples: Optional[List[str]] = None,
|
||||
):
|
||||
"""Build the command method docstring."""
|
||||
doc = func.__doc__
|
||||
if model_name:
|
||||
doc = DocstringGenerator.generate(
|
||||
func=func, formatted_params=formatted_params, model_name=model_name
|
||||
func=func,
|
||||
formatted_params=formatted_params,
|
||||
model_name=model_name,
|
||||
examples=examples,
|
||||
)
|
||||
code = f' """{doc} """ # noqa: E501\n\n' if doc else ""
|
||||
|
||||
@@ -728,7 +730,11 @@ class MethodDefinition:
|
||||
|
||||
@classmethod
|
||||
def build_command_method(
|
||||
cls, path: str, func: Callable, model_name: Optional[str] = None
|
||||
cls,
|
||||
path: str,
|
||||
func: Callable,
|
||||
model_name: Optional[str] = None,
|
||||
examples: Optional[List[str]] = None,
|
||||
) -> str:
|
||||
"""Build the command method."""
|
||||
func_name = func.__name__
|
||||
@@ -745,7 +751,10 @@ class MethodDefinition:
|
||||
model_name=model_name,
|
||||
)
|
||||
code += cls.build_command_method_doc(
|
||||
func=func, formatted_params=formatted_params, model_name=model_name
|
||||
func=func,
|
||||
formatted_params=formatted_params,
|
||||
model_name=model_name,
|
||||
examples=examples,
|
||||
)
|
||||
|
||||
code += cls.build_command_method_body(path=path, func=func)
|
||||
@@ -780,114 +789,6 @@ class DocstringGenerator:
|
||||
|
||||
return obbject_description
|
||||
|
||||
@staticmethod
|
||||
def get_model_standard_params(param_fields: Dict[str, FieldInfo]) -> Dict[str, Any]:
|
||||
"""Get the test params for the fetcher based on the required standard params."""
|
||||
test_params: Dict[str, Any] = {}
|
||||
for field_name, field in param_fields.items():
|
||||
if field.default and field.default is not PydanticUndefined:
|
||||
test_params[field_name] = field.default
|
||||
elif field.default and field.default is PydanticUndefined:
|
||||
example_dict = {
|
||||
"symbol": "AAPL",
|
||||
"symbols": "AAPL,MSFT",
|
||||
"start_date": "2023-01-01",
|
||||
"end_date": "2023-06-06",
|
||||
"country": "Portugal",
|
||||
"date": "2023-01-01",
|
||||
"countries": ["portugal", "spain"],
|
||||
}
|
||||
if field_name in example_dict:
|
||||
test_params[field_name] = example_dict[field_name]
|
||||
elif field.annotation == str:
|
||||
test_params[field_name] = "TEST_STRING"
|
||||
elif field.annotation == int:
|
||||
test_params[field_name] = 1
|
||||
elif field.annotation == float:
|
||||
test_params[field_name] = 1.0
|
||||
elif field.annotation == bool:
|
||||
test_params[field_name] = True
|
||||
elif get_origin(field.annotation) is Literal: # type: ignore
|
||||
option = field.annotation.__args__[0] # type: ignore
|
||||
if isinstance(option, str):
|
||||
test_params[field_name] = f'"{option}"'
|
||||
else:
|
||||
test_params[field_name] = option
|
||||
|
||||
return test_params
|
||||
|
||||
@staticmethod
|
||||
def get_full_command_name(route: str) -> str:
|
||||
"""Get the full command name."""
|
||||
cmd_parts = route.split("/")
|
||||
del cmd_parts[0]
|
||||
|
||||
menu = cmd_parts[0]
|
||||
command = cmd_parts[-1]
|
||||
sub_menus = cmd_parts[1:-1]
|
||||
|
||||
sub_menu_str_cmd = f".{'.'.join(sub_menus)}" if sub_menus else ""
|
||||
|
||||
full_command = f"{menu}{sub_menu_str_cmd}.{command}"
|
||||
|
||||
return full_command
|
||||
|
||||
@classmethod
|
||||
def generate_example(
|
||||
cls,
|
||||
model_name: str,
|
||||
standard_params: Dict[str, FieldInfo],
|
||||
) -> str:
|
||||
"""Generate the example for the command."""
|
||||
# find the model router here
|
||||
cm = CommandMap()
|
||||
commands_model = cm.commands_model
|
||||
route = [k for k, v in commands_model.items() if v == model_name]
|
||||
|
||||
if not route:
|
||||
return ""
|
||||
|
||||
full_command_name = cls.get_full_command_name(route=route[0])
|
||||
example_params = cls.get_model_standard_params(param_fields=standard_params)
|
||||
|
||||
# Edge cases (might find more)
|
||||
if "crypto" in route[0] and "symbol" in example_params:
|
||||
example_params["symbol"] = "BTCUSD"
|
||||
elif "currency" in route[0] and "symbol" in example_params:
|
||||
example_params["symbol"] = "EURUSD"
|
||||
elif (
|
||||
"index" in route[0]
|
||||
and "european" not in route[0]
|
||||
and "symbol" in example_params
|
||||
):
|
||||
example_params["symbol"] = "SPX"
|
||||
elif (
|
||||
"index" in route[0]
|
||||
and "european" in route[0]
|
||||
and "symbol" in example_params
|
||||
):
|
||||
example_params["symbol"] = "BUKBUS"
|
||||
elif (
|
||||
"futures" in route[0] and "curve" in route[0] and "symbol" in example_params
|
||||
):
|
||||
example_params["symbol"] = "VX"
|
||||
elif "futures" in route[0] and "symbol" in example_params:
|
||||
example_params["symbol"] = "ES"
|
||||
|
||||
example = "\n Example\n -------\n"
|
||||
example += " >>> from openbb import obb\n"
|
||||
example += f" >>> obb.{full_command_name}("
|
||||
for param_name, param_value in example_params.items():
|
||||
if isinstance(param_value, str):
|
||||
param_value = f'"{param_value}"' # noqa: PLW2901
|
||||
example += f"{param_name}={param_value}, "
|
||||
if example_params:
|
||||
example = example[:-2] + ")\n"
|
||||
else:
|
||||
example += ")\n"
|
||||
|
||||
return example
|
||||
|
||||
@classmethod
|
||||
def generate_model_docstring(
|
||||
cls,
|
||||
@@ -897,6 +798,7 @@ class DocstringGenerator:
|
||||
params: dict,
|
||||
returns: Dict[str, FieldInfo],
|
||||
results_type: str,
|
||||
examples: Optional[List[str]] = None,
|
||||
) -> str:
|
||||
"""Create the docstring for model."""
|
||||
|
||||
@@ -922,9 +824,11 @@ class DocstringGenerator:
|
||||
"openbb"
|
||||
]["QueryParams"]["fields"]
|
||||
|
||||
example_docstring = cls.generate_example(
|
||||
model_name=model_name, standard_params=obb_query_fields
|
||||
)
|
||||
if examples:
|
||||
example_docstring = "\n Example\n -------\n"
|
||||
example_docstring += " >>> from openbb import obb\n"
|
||||
for example in examples:
|
||||
example_docstring += f" >>> {example}\n"
|
||||
|
||||
docstring = summary
|
||||
docstring += "\n\n"
|
||||
@@ -1014,7 +918,9 @@ class DocstringGenerator:
|
||||
docstring += f" {field.alias or name} : {field_type}\n"
|
||||
docstring += f" {format_description(description)}\n"
|
||||
|
||||
docstring += example_docstring
|
||||
if examples:
|
||||
docstring += example_docstring
|
||||
|
||||
return docstring
|
||||
|
||||
@classmethod
|
||||
@@ -1023,6 +929,7 @@ class DocstringGenerator:
|
||||
func: Callable,
|
||||
formatted_params: OrderedDict[str, Parameter],
|
||||
model_name: Optional[str] = None,
|
||||
examples: Optional[List[str]] = None,
|
||||
) -> Optional[str]:
|
||||
"""Generate the docstring for the function."""
|
||||
doc = func.__doc__
|
||||
@@ -1045,6 +952,7 @@ class DocstringGenerator:
|
||||
params=params,
|
||||
returns=returns,
|
||||
results_type=results_type,
|
||||
examples=examples,
|
||||
)
|
||||
return doc
|
||||
return doc
|
||||
|
||||
@@ -12,7 +12,7 @@ from openbb_core.provider.utils.descriptions import DATA_DESCRIPTIONS
|
||||
class CryptoSearchQueryParams(QueryParams):
|
||||
"""Crypto Search Query."""
|
||||
|
||||
query: Optional[str] = Field(description="Search query.", default="")
|
||||
query: Optional[str] = Field(description="Search query.", default=None)
|
||||
|
||||
|
||||
class CryptoSearchData(Data):
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
"""Test the example_generator.py file."""
|
||||
|
||||
# pylint: disable=redefined-outer-name, protected-access
|
||||
|
||||
|
||||
import pytest
|
||||
from openbb_core.app.example_generator import ExampleGenerator
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def example_generator():
|
||||
"""Return example generator."""
|
||||
return ExampleGenerator()
|
||||
|
||||
|
||||
def test_docstring_generator_init(example_generator):
|
||||
"""Test example generator init."""
|
||||
assert example_generator
|
||||
|
||||
|
||||
TEST_POOL = {
|
||||
"crypto": {"symbol": "CRYPTO_SYMBOL"},
|
||||
"crypto.search": {"symbol": "CRYPTO_SEARCH_SYMBOL"},
|
||||
"crypto.price.historical": {"symbol": "CRYPTO_HISTORICAL_PRICE_SYMBOL"},
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"route, param, expected",
|
||||
[
|
||||
("", "", "VALUE_NOT_FOUND"),
|
||||
("random_route", "", "VALUE_NOT_FOUND"),
|
||||
("crypto", "symbol", "CRYPTO_SYMBOL"),
|
||||
("crypto.search", "symbol", "CRYPTO_SEARCH_SYMBOL"),
|
||||
("crypto.price.historical", "symbol", "CRYPTO_HISTORICAL_PRICE_SYMBOL"),
|
||||
("crypto.price.historical", "random_param", "VALUE_NOT_FOUND"),
|
||||
],
|
||||
)
|
||||
def test_get_value_from_pool(example_generator, route, param, expected):
|
||||
"""Test get value from pool."""
|
||||
assert example_generator._get_value_from_pool(TEST_POOL, route, param) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"route, model, expected",
|
||||
[
|
||||
("", "", ""),
|
||||
("random", "test", "obb.random()"),
|
||||
("crypto.search", "CryptoSearch", "obb.crypto.search()"),
|
||||
(
|
||||
"crypto.price.historical",
|
||||
"CryptoHistorical",
|
||||
'obb.crypto.price.historical(symbol="BTCUSD")',
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_generate(example_generator, route, model, expected):
|
||||
"""Test generate example."""
|
||||
assert example_generator.generate(route, model) == expected
|
||||
@@ -197,7 +197,7 @@ def test_complete_signature(signature_inspector):
|
||||
|
||||
model = "EquityHistorical"
|
||||
|
||||
assert signature_inspector.complete_signature(sample_function, model)
|
||||
assert signature_inspector.complete(sample_function, model)
|
||||
|
||||
|
||||
def test_complete_signature_error(signature_inspector):
|
||||
@@ -206,9 +206,7 @@ def test_complete_signature_error(signature_inspector):
|
||||
async def valid_function() -> OBBject[Optional[List[int]]]:
|
||||
return OBBject(results=[1, 2, 3])
|
||||
|
||||
assert (
|
||||
signature_inspector.complete_signature(valid_function, "invalid_model") is None
|
||||
)
|
||||
assert signature_inspector.complete(valid_function, "invalid_model") is None
|
||||
|
||||
|
||||
def test_validate_signature(signature_inspector):
|
||||
|
||||
@@ -31,7 +31,7 @@ class ROUTER_crypto(Container):
|
||||
self,
|
||||
query: Annotated[
|
||||
Optional[str], OpenBBCustomParameter(description="Search query.")
|
||||
] = "",
|
||||
] = None,
|
||||
provider: Optional[Literal["fmp"]] = None,
|
||||
**kwargs
|
||||
) -> OBBject:
|
||||
|
||||
@@ -277,7 +277,7 @@ class ROUTER_economy(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.economy.cpi(countries=['portugal', 'spain'], units="growth_same", frequency="monthly")
|
||||
>>> obb.economy.cpi(countries=['portugal', 'spain'], units="growth_same", frequency="monthly", harmonized=False)
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
@@ -323,7 +323,7 @@ class ROUTER_economy(Container):
|
||||
no default.
|
||||
is_release : Optional[bool]
|
||||
Is release? If True, other search filter variables are ignored. If no query text or release_id is supplied, this defaults to True. (provider: fred)
|
||||
release_id : Optional[Union[str, int]]
|
||||
release_id : Optional[Union[int, str]]
|
||||
A specific release ID to target. (provider: fred)
|
||||
limit : Optional[int]
|
||||
The number of data entries to return. (1-1000) (provider: fred)
|
||||
@@ -354,7 +354,7 @@ class ROUTER_economy(Container):
|
||||
|
||||
FredSearch
|
||||
----------
|
||||
release_id : Optional[Union[str, int]]
|
||||
release_id : Optional[Union[int, str]]
|
||||
The release ID for queries.
|
||||
series_id : Optional[str]
|
||||
The series ID for the item in the release.
|
||||
@@ -521,7 +521,7 @@ class ROUTER_economy(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.economy.fred_series(symbol="AAPL", limit=100000)
|
||||
>>> obb.economy.fred_series(symbol="GFDGDPA188S", limit=100000)
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
|
||||
@@ -540,7 +540,7 @@ class ROUTER_equity(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.equity.search()
|
||||
>>> obb.equity.search(query="AAPL", is_symbol=False)
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
|
||||
@@ -1333,7 +1333,7 @@ class ROUTER_equity_fundamental(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.equity.fundamental.historical_attributes(symbol="AAPL", tag="TEST_STRING", frequency="yearly", limit=1000, sort="desc")
|
||||
>>> obb.equity.fundamental.historical_attributes(symbol="AAPL", tag="ebitda", frequency="yearly", limit=1000, sort="desc")
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
@@ -2031,7 +2031,7 @@ class ROUTER_equity_fundamental(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.equity.fundamental.latest_attributes(symbol="AAPL", tag="TEST_STRING")
|
||||
>>> obb.equity.fundamental.latest_attributes(symbol="AAPL", tag="ceo")
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
@@ -3240,7 +3240,7 @@ class ROUTER_equity_fundamental(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.equity.fundamental.search_attributes(query="TEST_STRING", limit=1000)
|
||||
>>> obb.equity.fundamental.search_attributes(query="AAPL", limit=1000)
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
@@ -3384,7 +3384,7 @@ class ROUTER_equity_fundamental(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.equity.fundamental.transcript(symbol="AAPL", year=1)
|
||||
>>> obb.equity.fundamental.transcript(symbol="AAPL", year=2020)
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
|
||||
@@ -77,47 +77,47 @@ class ROUTER_equity_ownership(Container):
|
||||
--------------
|
||||
symbol : str
|
||||
Symbol representing the entity requested in the data.
|
||||
company_cik : int
|
||||
Company CIK of the insider trading.
|
||||
filing_date : datetime
|
||||
Filing date of the insider trading.
|
||||
company_cik : Optional[Union[int, str]]
|
||||
CIK number of the company.
|
||||
filing_date : Optional[Union[date, datetime]]
|
||||
Filing date of the trade.
|
||||
transaction_date : Optional[date]
|
||||
Transaction date of the insider trading.
|
||||
owner_cik : int
|
||||
Reporting CIK of the insider trading.
|
||||
owner_name : str
|
||||
Reporting name of the insider trading.
|
||||
Date of the transaction.
|
||||
owner_cik : Optional[Union[int, str]]
|
||||
Reporting individual's CIK.
|
||||
owner_name : Optional[str]
|
||||
Name of the reporting individual.
|
||||
owner_title : Optional[str]
|
||||
Designation of owner of the insider trading.
|
||||
transaction_type : str
|
||||
Transaction type of the insider trading.
|
||||
The title held by the reporting individual.
|
||||
transaction_type : Optional[str]
|
||||
Type of transaction being reported.
|
||||
acquisition_or_disposition : Optional[str]
|
||||
Acquisition or disposition of the insider trading.
|
||||
Acquisition or disposition of the shares.
|
||||
security_type : Optional[str]
|
||||
Security type of the insider trading.
|
||||
The type of security transacted.
|
||||
securities_owned : Optional[float]
|
||||
Number of securities owned in the insider trading.
|
||||
Number of securities owned by the reporting individual.
|
||||
securities_transacted : Optional[float]
|
||||
Securities transacted of the insider trading.
|
||||
Number of securities transacted by the reporting individual.
|
||||
transaction_price : Optional[float]
|
||||
Price of the insider trading.
|
||||
filing_url : str
|
||||
Link of the insider trading.
|
||||
The price of the transaction.
|
||||
filing_url : Optional[str]
|
||||
Link to the filing.
|
||||
form_type : Optional[str]
|
||||
Form type of the insider trading. (provider: fmp)
|
||||
company_name : Optional[str]
|
||||
Name of the company. (provider: intrinio)
|
||||
conversion_exercise_price : Optional[float]
|
||||
Conversion/Exercise price of the insider trading. (provider: intrinio)
|
||||
Conversion/Exercise price of the shares. (provider: intrinio)
|
||||
deemed_execution_date : Optional[date]
|
||||
Deemed execution date of the insider trading. (provider: intrinio)
|
||||
Deemed execution date of the trade. (provider: intrinio)
|
||||
exercise_date : Optional[date]
|
||||
Exercise date of the insider trading. (provider: intrinio)
|
||||
Exercise date of the trade. (provider: intrinio)
|
||||
expiration_date : Optional[date]
|
||||
Expiration date of the insider trading. (provider: intrinio)
|
||||
Expiration date of the derivative. (provider: intrinio)
|
||||
underlying_security_title : Optional[str]
|
||||
Name of the underlying non-derivative security related to this derivative transaction. (provider: intrinio)
|
||||
underlying_shares : Optional[int]
|
||||
underlying_shares : Optional[Union[float, int]]
|
||||
Number of underlying shares related to this derivative transaction. (provider: intrinio)
|
||||
nature_of_ownership : Optional[str]
|
||||
Nature of ownership of the insider trading. (provider: intrinio)
|
||||
@@ -438,7 +438,7 @@ class ROUTER_equity_ownership(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.equity.ownership.major_holders(symbol="AAPL")
|
||||
>>> obb.equity.ownership.major_holders(symbol="AAPL", page=0)
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
|
||||
@@ -70,7 +70,7 @@ class ROUTER_etf(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.etf.countries(symbol="AAPL")
|
||||
>>> obb.etf.countries(symbol="SPY")
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
@@ -157,7 +157,7 @@ class ROUTER_etf(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.etf.historical(symbol="AAPL")
|
||||
>>> obb.etf.historical(symbol="SPY")
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
@@ -379,7 +379,7 @@ class ROUTER_etf(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.etf.holdings(symbol="AAPL")
|
||||
>>> obb.etf.holdings(symbol="SPY")
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
@@ -440,7 +440,7 @@ class ROUTER_etf(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.etf.holdings_date(symbol="AAPL")
|
||||
>>> obb.etf.holdings_date(symbol="SPY")
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
@@ -527,7 +527,7 @@ class ROUTER_etf(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.etf.holdings_performance(symbol="AAPL")
|
||||
>>> obb.etf.holdings_performance(symbol="SPY")
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
@@ -616,7 +616,7 @@ class ROUTER_etf(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.etf.info(symbol="AAPL")
|
||||
>>> obb.etf.info(symbol="SPY")
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
@@ -703,7 +703,7 @@ class ROUTER_etf(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.equity.price.performance(symbol="AAPL")
|
||||
>>> obb.etf.price_performance(symbol="SPY")
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
@@ -792,7 +792,7 @@ class ROUTER_etf(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.etf.search()
|
||||
>>> obb.etf.search(query="Vanguard")
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
@@ -853,7 +853,7 @@ class ROUTER_etf(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.etf.sectors(symbol="AAPL")
|
||||
>>> obb.etf.sectors(symbol="SPY")
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
|
||||
@@ -167,7 +167,7 @@ class ROUTER_fixedincome_government(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.fixedincome.government.us_yield_curve()
|
||||
>>> obb.fixedincome.government.us_yield_curve(inflation_adjusted=False)
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
|
||||
@@ -138,7 +138,7 @@ class ROUTER_index(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.index.constituents(index="TEST_STRING")
|
||||
>>> obb.index.constituents(index="^IBEX")
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
@@ -266,7 +266,7 @@ class ROUTER_index(Container):
|
||||
>>> obb.index.market(symbol="SPX")
|
||||
""" # noqa: E501
|
||||
|
||||
from warnings import warn, simplefilter
|
||||
from warnings import simplefilter, warn
|
||||
|
||||
simplefilter("always", DeprecationWarning)
|
||||
warn(
|
||||
|
||||
@@ -126,7 +126,7 @@ class ROUTER_regulators_sec(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.regulators.sec.institutions_search()
|
||||
>>> obb.regulators.sec.institutions_search(query="AAPL")
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
@@ -241,7 +241,7 @@ class ROUTER_regulators_sec(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.regulators.sec.schema_files()
|
||||
>>> obb.regulators.sec.schema_files(query="AAPL")
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
@@ -303,7 +303,7 @@ class ROUTER_regulators_sec(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.regulators.sec.sic_search()
|
||||
>>> obb.regulators.sec.sic_search(query="AAPL")
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
@@ -359,7 +359,7 @@ class ROUTER_regulators_sec(Container):
|
||||
Example
|
||||
-------
|
||||
>>> from openbb import obb
|
||||
>>> obb.regulators.sec.symbol_map()
|
||||
>>> obb.regulators.sec.symbol_map(query="AAPL")
|
||||
""" # noqa: E501
|
||||
|
||||
return self._run(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""Intrinio Options Chains Model."""
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
from datetime import (
|
||||
date as dateType,
|
||||
datetime,
|
||||
@@ -116,11 +117,15 @@ class IntrinioOptionsChainsFetcher(
|
||||
date = datetime.now().date() if query.date is None else query.date
|
||||
date = get_weekday(date)
|
||||
|
||||
results = await amake_requests(await get_urls(date), callback, **kwargs)
|
||||
results = await amake_requests(
|
||||
await get_urls(date.strftime("%Y-%m-%d")), callback, **kwargs
|
||||
)
|
||||
|
||||
if not results:
|
||||
urls = await get_urls(get_weekday(date - timedelta(days=1)))
|
||||
results = await amake_requests(urls, callback, **kwargs)
|
||||
urls = await get_urls(
|
||||
get_weekday(date - timedelta(days=1)).strftime("%Y-%m-%d")
|
||||
)
|
||||
results = await amake_requests(urls, response_callback=callback, **kwargs)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
@@ -123,11 +123,11 @@ async def get_data_one(url: str, **kwargs: Any) -> Dict[str, Any]:
|
||||
return data
|
||||
|
||||
|
||||
def get_weekday(date: dateType) -> str:
|
||||
def get_weekday(date: dateType) -> dateType:
|
||||
"""Return the weekday date."""
|
||||
if date.weekday() in [5, 6]:
|
||||
return (date - timedelta(days=date.weekday() - 4)).strftime("%Y-%m-%d")
|
||||
return date.strftime("%Y-%m-%d")
|
||||
return date - timedelta(days=date.weekday() - 4)
|
||||
return date
|
||||
|
||||
|
||||
async def async_get_data_one(
|
||||
|
||||
Reference in New Issue
Block a user