Skip to content

Commit

Permalink
Merge branch 'develop' into feature/field-descriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
deeleeramone authored Apr 6, 2024
2 parents 4474022 + 3f4ab6e commit bf3e18b
Show file tree
Hide file tree
Showing 62 changed files with 29,623 additions and 27,079 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/platform-api-integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ name: API Integration Tests

on:
workflow_dispatch:
pull_request:
branches:
- release/*

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
24 changes: 11 additions & 13 deletions examples/usdLiquidityIndex.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,10 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import json\n",
"\n",
"from openbb import obb\n",
"from pandas import DataFrame\n"
]
Expand All @@ -42,23 +40,23 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"OBBject\n",
"\n",
"id: 06580cab-5bdc-7e28-8000-632a5d8dc92f\n",
"results: [{'date': datetime.date(2002, 12, 18), 'WALCL': 719542.0, 'WLRRAL': 21905....\n",
"id: 0660e135-3511-73d7-8000-b792f7e418bb\n",
"results: [{'date': datetime.date(2002, 12, 18), 'provider': 'fred', 'WALCL': 719542...\n",
"provider: fred\n",
"warnings: [{'category': 'UserWarning', 'message': '{\"WALCL\": {\"title\": \"Assets: Tot...\n",
"warnings: None\n",
"chart: None\n",
"extra: {'metadata': {'arguments': {'provider_choices': {'provider': None}, 'standar..."
"extra: {'results_metadata': {'WALCL': {'title': 'Assets: Total Assets: Total Assets..."
]
},
"execution_count": 4,
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -78,7 +76,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 3,
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -110,7 +108,7 @@
}
],
"source": [
"metadata = json.loads(data.warnings[0].message)\n",
"metadata = data.extra[\"results_metadata\"]\n",
"\n",
"display(metadata.keys())\n",
"display(metadata[\"WALCL\"].get(\"title\"))\n",
Expand Down Expand Up @@ -573,7 +571,7 @@
},
{
"cell_type": "code",
"execution_count": 33,
"execution_count": 5,
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -10197,7 +10195,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.4"
"version": "3.11.7"
},
"orig_nbformat": 4
},
Expand Down
18 changes: 18 additions & 0 deletions openbb_platform/core/openbb_core/api/app_loader.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
"""App loader module."""

from typing import List, Optional

from fastapi import APIRouter, FastAPI
from openbb_core.app.router import RouterLoader


class AppLoader:
"""App loader."""

@staticmethod
def get_openapi_tags() -> List[dict]:
"""Get openapi tags."""
main_router = RouterLoader.from_extensions()
openapi_tags = []
# Add tag data for each router in the main router
for r in main_router.routers:
openapi_tags.append(
{
"name": r,
"description": main_router.get_attr(r, "description"),
}
)
return openapi_tags

@staticmethod
def from_routers(
app: FastAPI, routers: List[Optional[APIRouter]], prefix: str
Expand Down
2 changes: 1 addition & 1 deletion openbb_platform/core/openbb_core/api/rest_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,13 @@ async def lifespan(_: FastAPI):
],
lifespan=lifespan,
)

app.add_middleware(
CORSMiddleware,
allow_origins=system.api_settings.cors.allow_origins,
allow_methods=system.api_settings.cors.allow_methods,
allow_headers=system.api_settings.cors.allow_headers,
)
app.openapi_tags = AppLoader.get_openapi_tags()
AppLoader.from_routers(
app=app,
routers=(
Expand Down
13 changes: 6 additions & 7 deletions openbb_platform/core/openbb_core/api/router/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def build_new_signature(path: str, func: Callable) -> Signature:
)


def validate_output(c_out: OBBject) -> OBBject:
def validate_output(c_out: OBBject) -> Dict:
"""
Validate OBBject object.
Expand All @@ -132,8 +132,8 @@ def validate_output(c_out: OBBject) -> OBBject:
Returns
-------
OBBject
Validated OBBject object.
Dict
Serialized OBBject.
"""

def is_model(type_):
Expand Down Expand Up @@ -170,7 +170,7 @@ def exclude_fields_from_api(key: str, value: Any):
for k, v in c_out.model_copy():
exclude_fields_from_api(k, v)

return c_out
return c_out.model_dump()


def build_api_wrapper(
Expand All @@ -188,7 +188,7 @@ def build_api_wrapper(
func.__annotations__ = new_annotations_map

@wraps(wrapped=func)
async def wrapper(*args: Tuple[Any], **kwargs: Dict[str, Any]):
async def wrapper(*args: Tuple[Any], **kwargs: Dict[str, Any]) -> Dict:
user_settings: UserSettings = UserSettings.model_validate(
kwargs.pop(
"__authenticated_user_settings",
Expand All @@ -198,8 +198,7 @@ async def wrapper(*args: Tuple[Any], **kwargs: Dict[str, Any]):
execute = partial(command_runner.run, path, user_settings)
output: OBBject = await execute(*args, **kwargs)

output = validate_output(output)
return output
return validate_output(output)

return wrapper

Expand Down
8 changes: 7 additions & 1 deletion openbb_platform/core/openbb_core/app/model/obbject.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from openbb_core.app.model.abstract.warning import Warning_
from openbb_core.app.model.charts.chart import Chart
from openbb_core.app.utils import basemodel_to_df
from openbb_core.provider.abstract.annotated_result import AnnotatedResult
from openbb_core.provider.abstract.data import Data

if TYPE_CHECKING:
Expand Down Expand Up @@ -330,4 +331,9 @@ async def from_query(cls, query: "Query") -> "OBBject":
OBBject[ResultsType]
OBBject with results.
"""
return cls(results=await query.execute())
results = await query.execute()
if isinstance(results, AnnotatedResult):
return cls(
results=results.result, extra={"results_metadata": results.metadata}
)
return cls(results=results)
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
)
from openbb_core.app.model.abstract.tagged import Tagged
from openbb_core.app.model.fast_api_settings import FastAPISettings
from openbb_core.app.version import VERSION
from openbb_core.app.version import CORE_VERSION, VERSION


class SystemSettings(Tagged):
Expand All @@ -28,6 +28,7 @@ class SystemSettings(Tagged):

# OpenBB section
version: str = VERSION
core: str = CORE_VERSION
home_directory: str = str(HOME_DIRECTORY)
openbb_directory: str = str(OPENBB_DIRECTORY)
user_settings_path: str = str(USER_SETTINGS_PATH)
Expand Down
51 changes: 50 additions & 1 deletion openbb_platform/core/openbb_core/app/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,15 +203,33 @@ def api_router(self) -> APIRouter:
"""API Router."""
return self._api_router

@property
def prefix(self) -> str:
"""Prefix."""
return self._api_router.prefix

@property
def description(self) -> str:
"""Description."""
return self._description

@property
def routers(self) -> Dict[str, "Router"]:
"""Routers nested within the Router, i.e. sub-routers."""
return self._routers

def __init__(
self,
prefix: str = "",
description: str = "",
) -> None:
"""Initialize Router."""
self._api_router = APIRouter(
prefix=prefix,
responses={404: {"description": "Not found"}},
)
self._description = description
self._routers: Dict[str, Router] = {}

@overload
def command(self, func: Optional[Callable[P, OBBject]]) -> Callable[P, OBBject]:
Expand Down Expand Up @@ -290,10 +308,41 @@ def include_router(
prefix: str = "",
):
"""Include router."""
tags = [prefix[1:]] if prefix else None
tags = [prefix.strip("/")] if prefix else None
self._api_router.include_router(
router=router.api_router, prefix=prefix, tags=tags # type: ignore
)
name = prefix if prefix else router.prefix
self._routers[name.strip("/")] = router

def get_attr(self, path: str, attr: str) -> Any:
"""Get router attribute from path.
Parameters
----------
path : str
Path to the router or nested router.
E.g. "/equity" or "/equity/price".
attr : str
Attribute to get.
Returns
-------
Any
Attribute value.
"""
return self._search_attr(self, path, attr)

@staticmethod
def _search_attr(router: "Router", path: str, attr: str) -> Any:
"""Recursively search router attribute from path."""
path = path.strip("/")
first = path.split("/")[0]
if first in router.routers:
return Router._search_attr(
router.routers[first], "/".join(path.split("/")[1:]), attr
)
return getattr(router, attr, None)


class SignatureInspector:
Expand Down
9 changes: 8 additions & 1 deletion openbb_platform/core/openbb_core/app/static/app_factory.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
"""App factory."""

from typing import Optional, Type, TypeVar
from typing import Dict, Optional, Type, TypeVar

from openbb_core.app.command_runner import CommandRunner
from openbb_core.app.model.system_settings import SystemSettings
from openbb_core.app.model.user_settings import UserSettings
from openbb_core.app.static.account import Account
from openbb_core.app.static.container import Container
from openbb_core.app.static.coverage import Coverage
from openbb_core.app.static.reference_loader import ReferenceLoader
from openbb_core.app.version import VERSION

E = TypeVar("E", bound=Type[Container])
Expand All @@ -29,6 +30,7 @@ def __init__(self, command_runner: CommandRunner):
self._command_runner = command_runner
self._account = Account(self)
self._coverage = Coverage(self)
self._reference = ReferenceLoader().reference

@property
def account(self) -> Account:
Expand All @@ -50,6 +52,11 @@ def coverage(self) -> Coverage:
"""Coverage menu."""
return self._coverage

@property
def reference(self) -> Dict[str, Dict]:
"""Return reference data."""
return self._reference


def create_app(extensions: Optional[E] = None) -> Type[BaseApp]:
"""Create the app."""
Expand Down
7 changes: 0 additions & 7 deletions openbb_platform/core/openbb_core/app/static/coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from openbb_core.api.router.helpers.coverage_helpers import get_route_schema_map
from openbb_core.app.provider_interface import ProviderInterface
from openbb_core.app.router import CommandMap
from openbb_core.app.static.reference_loader import ReferenceLoader

if TYPE_CHECKING:
from openbb_core.app.static.app_factory import BaseApp
Expand All @@ -28,7 +27,6 @@ def __init__(self, app: "BaseApp"):
self._app = app
self._command_map = CommandMap(coverage_sep=".")
self._provider_interface = ProviderInterface()
self._reference_loader = ReferenceLoader()

def __repr__(self) -> str:
"""Return docstring."""
Expand All @@ -52,11 +50,6 @@ def command_model(self) -> Dict[str, Dict[str, Dict[str, Dict[str, Any]]]]:
for command, value in self._command_map.commands_model.items()
}

@property
def reference(self) -> Dict[str, Dict]:
"""Return reference data."""
return self._reference_loader.reference

def command_schemas(self, filter_by_provider: Optional[str] = None):
"""Return route schema for a command."""
return get_route_schema_map(
Expand Down
Loading

0 comments on commit bf3e18b

Please sign in to comment.