Skip to content

Commit

Permalink
Merge pull request #5497 from OpenBB-finance/feature/improved-docs
Browse files Browse the repository at this point in the history
Improve docs
  • Loading branch information
IgorWounds committed Oct 4, 2023
2 parents 26e940b + 53c4441 commit 48b0221
Show file tree
Hide file tree
Showing 34 changed files with 1,513 additions and 537 deletions.
717 changes: 410 additions & 307 deletions openbb_platform/CONTRIBUTING.md

Large diffs are not rendered by default.

46 changes: 43 additions & 3 deletions openbb_platform/extensions/charting/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# OpenBB Charting extension

This extension provides a charting library for OpenBB SDK.
This extension provides a charting library for OpenBB Platform.

The library includes:

- a charting infrastructure based on Plotly
- a set of charting components
- prebuilt charts for a set of commands that are built-in OpenBB SDK extensions
- prebuilt charts for a set of commands that are built-in OpenBB extensions

## Installation

Expand Down Expand Up @@ -34,7 +34,7 @@ When using Linux distributions, the PyWry dependency requires certain dependenci

## Usage

To use the extension, run any of the OpenBB SDK endpoints with the `chart` argument set to `True`.
To use the extension, run any of the OpenBB Platform endpoints with the `chart` argument set to `True`.

Here's an example how it would look like in a python interface:

Expand All @@ -52,3 +52,43 @@ stock_data.show()
```

> Note: The `show()` method currently works either in a Jupyter Notebook or in a standalone python script with a PyWry based backend properly initialized.
## Add a visualization to an existing Platform command

One should first ensure that the already implemented endpoint is available in the [charting router](/openbb_platform/extensions/charting/openbb_charting/charting_router.py).

To do so, you can run:
`python openbb_platform/extensions/charting/openbb_charting/builder.py` - which will read all the available endpoints and add them to the charting router.

Afterwards, you'll need to add the visualization to the [charting router](/openbb_platform/extensions/charting/openbb_charting/charting_router.py). The convention to match the endpoint with the respective charting function is the following:

- `/stocks/load` -> `stocks_load`
- `/ta/ema` -> `ta_ema`

When you spot the charting function on the charting router file, you can add the visualization to it.

The implementation should leverage the already existing classes and methods to do so, namely:

- `OpenBBFigure`
- `OpenBBFigureTable`
- `PlotlyTA`

Note that the return of each charting function should respect the already defined return types: `Tuple[OpenBBFigure, Dict[str, Any]]`.

The returned tuple contains a `OpenBBFigure` that is an interactive plotly figure which can be used in a Python interpreter, and a `Dict[str, Any]` that contains the raw data leveraged by the API.

After you're done implementing the charting function, you can use either the Python interface or the API to get the chart. To do so, you'll only need to set the already available `chart` argument to `True`.

### Using the `to_chart` OBBject method

The `OBBject` is the custom OpenBB object that is returned by the Platform commands.
It implements a set of `to_<something>` functions that enable the user to easily transform the data into a different format.

The `to_chart` function should be taken as an advanced feature, as it requires the user to have a good understanding of the charting extension and the `OpenBBFigure` class.

The user can use any number of `**kwargs` that will be passed to the `PlotlyTA` class in order to build custom visualizations with custom indicators and similar.

Refer to the [`to_chart` implementation](openbb_charting/core/to_chart.py) for further details.

> Note that, this method will only work to some limited extent with data that is not standardized.
> Also, it is currently designed only to handle time series data.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import os
from platform.core.openbb_core.app.provider_interface import ProviderInterface
from platform.core.openbb_core.app.router import CommandMap
from typing import Dict, List, Type, get_type_hints

import requests
from extensions.tests.utils.integration_tests_generator import get_test_params
from openbb_core.app.provider_interface import ProviderInterface
from openbb_core.app.router import CommandMap


def get_http_method(api_paths: Dict[str, dict], route: str):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
"""Integration test generator."""
from pathlib import Path, PosixPath
from platform.core.openbb_core.app.provider_interface import ProviderInterface
from platform.core.openbb_core.app.router import CommandMap
from typing import Any, Dict, List, Literal, get_origin

from openbb_core.app.provider_interface import ProviderInterface
from openbb_core.app.router import CommandMap
from pydantic.fields import FieldInfo
from pydantic_core import PydanticUndefined

Expand Down Expand Up @@ -189,4 +189,5 @@ def write_integration_test() -> None:
add_test_commands_to_file(extensions)


write_integration_test()
if __name__ == "__main__":
write_integration_test()
2 changes: 1 addition & 1 deletion openbb_terminal/forecast/trans_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def get_trans_data(
activation: str
The activation function of encoder/decoder intermediate layer, ‘relu’ or ‘gelu’. Defaults to 'relu'.
dropout: float
Fraction of neurons afected by Dropout. Defaults to 0.0.
Fraction of neurons affected by Dropout. Defaults to 0.0.
batch_size: int
Number of time series (input and output sequences) used in each training pass. Defaults to 32.
n_epochs: int
Expand Down
6 changes: 3 additions & 3 deletions openbb_terminal/stocks/options/options_chains_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ def calculate_strangle(

strangle: dict[str, Any] = {}

# Includees the as-of date if it is historical EOD data.
# Includes the as-of date if it is historical EOD data.
if (
options.source == "Intrinio"
and options.date != ""
Expand Down Expand Up @@ -892,7 +892,7 @@ def calculate_vertical_call_spread(
max_profit = sold - bought - spread_cost[0]
call_spread_: dict[str, Any] = {}
if sold != bought and spread_cost[0] != 0:
# Includees the as-of date if it is historical EOD data.
# Includes the as-of date if it is historical EOD data.
if (
options.source == "Intrinio"
and options.date != ""
Expand Down Expand Up @@ -1036,7 +1036,7 @@ def calculate_vertical_put_spread(
max_loss = (sold - bought - max_profit) * -1
put_spread_: dict[str, Any] = {}
if sold != bought and max_loss != 0:
# Includees the as-of date if it is historical EOD data.
# Includes the as-of date if it is historical EOD data.
if (
options.source == "Intrinio"
and options.date != ""
Expand Down
2 changes: 1 addition & 1 deletion website/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ website/content/_index.md
/...
```

Note that the `common` folder holds features that are common across contexts, e.g. `technical analysis` can be performed on both `stocks` or `crytpo`.
Note that the `common` folder holds features that are common across contexts, e.g. `technical analysis` can be performed on both `stocks` or `crypto`.

### New Feature

Expand Down
4 changes: 4 additions & 0 deletions website/content/platform/contributing/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"label": "Contributing",
"position": 2
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"label": "Extension Development",
"position": 2
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
title: Add a custom data source
sidebar_position: 2
description: Add a custom data source to the OpenBB Platform.
keywords: [openbb platform, extension, custom data source, contributing, documentation]
---

import HeadTitle from '@site/src/components/General/HeadTitle.tsx';

<HeadTitle title="Add a custom data source - Platform | OpenBB Docs" />

You will get your data either from a CSV file, local database or from an API endpoint.

If you don't want or don't need to partake in the data standardization framework, you have the option to add all the logic straight inside the router file. This is usually the case when you are returning custom data from your local CSV file, or similar. Keep in mind that we also serve the REST API and that you shouldn't send non-serializable objects as a response (e.g. a pandas dataframe).

Saying that, we highly recommend following the standardization framework, as it will make your life easier in the long run and unlock a set of features that are only available to standardized data.

When standardizing, all data is defined using two different pydantic models:

1. Define the [query parameters](https://github.com/OpenBB-finance/OpenBBTerminal/tree/feature/openbb-sdk-v4/openbb_platform/platform/provider/openbb_provider/abstract/query_params.py) model.
2. Define the resulting [data schema](https://github.com/OpenBB-finance/OpenBBTerminal/tree/feature/openbb-sdk-v4/openbb_platform/platform/provider/openbb_provider/abstract/data.py) model.

> The models can be entirely custom, or inherit from the OpenBB standardized models.
> They enforce a safe and consistent data structure, validation and type checking.
We call this the ***Know-Your-Data*** principle.

After you've defined both models, you'll need to define a `Fetcher` class which contains three methods:

1. `transform_query` - transforms the query parameters to the format of the API endpoint.
2. `extract_data` - makes the request to the API endpoint and returns the raw data.
3. `transform_data` - transforms the raw data into the defined data model.

> Note that the `Fetcher` should inherit from the [`Fetcher`](https://github.com/OpenBB-finance/OpenBBTerminal/tree/feature/openbb-sdk-v4/openbb_platform/platform/provider/openbb_provider/abstract/fetcher.py) class, which is a generic class that receives the query parameters and the data model as type parameters.
After finalizing your models, you need to make them visible to the Openbb Platform. This is done by adding the `Fetcher` to the `__init__.py` file of the `<your_package_name>/<your_module_name>` folder as part of the [`Provider`](https://github.com/OpenBB-finance/OpenBBTerminal/tree/feature/openbb-sdk-v4/openbb_platform/platform/provider/openbb_provider/abstract/provider.py).

Any command, that uses the `Fetcher` class you've just defined, will be calling the `transform_query`, `extract_data` and `transform_data` methods under the hood in order to get the data and output it do the end user.

If you're not sure what's a command and why is it even using the `Fetcher` class, follow along!

## OpenBB Platform commands

The OpenBB Platform will enable you to query and output your data in a very simple way.

> Any Platform endpoint will be available both from a Python interface and the API.
The command definition on the Platform follows [FastAPI](https://fastapi.tiangolo.com/) conventions, meaning that you'll be creating **endpoints**.

The Cookiecutter template generates for you a `router.py` file with a set of examples that you can follow, namely:

- Perform a simple `GET` and `POST` request - without worrying on any custom data definition.
- Using a custom data definition so you get your data the exact way you want it.

You can expect the following endpoint structure when using a `Fetcher` to serve the data:

```python
@router.command(model="Example")
def model_example(
cc: CommandContext,
provider_choices: ProviderChoices,
standard_params: StandardParams,
extra_params: ExtraParams,
) -> OBBject[BaseModel]:
"""Example Data."""
return OBBject(results=Query(**locals()).execute())
```

Let's break it down:

- `@router.command(...)` - this tells the OpenBB Platform that this is a command.
- `model="Example"` - this is the name of the `Fetcher` dictionary key that you've defined in the `__init__.py` file of the `<your_package_name>/<your_module_name>` folder.
- `cc: CommandContext` - this contains a set of user and system settings that is useful during the execution of the command - eg. api keys.
- `provider_choices: ProviderChoices` - all the providers that implement the `Example` `Fetcher`.
- `standard_params: StandardParams` - standardized parameters that are common to all providers that implement the `Example` `Fetcher`.
- `extra_params: ExtraParams` - it contains the provider specific arguments that are not standardized.

You only need to change the `model` parameter to the name of the `Fetcher` dictionary key and everything else will be handled by the OpenBB Platform.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
title: Extension Development
sidebar_position: 1
description: Learn how to develop Extensions inside the OpenBB Platform.
keywords: [openbb platform, introduction, extensions, contributing, documentation]
---

import HeadTitle from '@site/src/components/General/HeadTitle.tsx';

<HeadTitle title="Extension Development - Platform | OpenBB Docs" />

We have a Cookiecutter template that will help you get started. It serves as a jumpstart for your extensions development, so you can focus on the data and not on the boilerplate.

Please refer to the [Cookiecutter template](https://github.com/OpenBB-finance/openbb-cookiecutter) and follow the instructions there.

This section will walk you through the steps of adding a new extension to the OpenBB Platform.

The high level steps are:

- Generate the extension structure
- Install your dependencies
- Install your new package
- Use your extension (either from Python or the API interface)
- QA your extension
- Share your extension with the community
91 changes: 91 additions & 0 deletions website/content/platform/contributing/extension-development/qa.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
title: Extension QA
sidebar_position: 3
description: Learn how to QA your extension.
keywords: [openbb platform, introduction, qa, contributing, extension, documentation]
---

import HeadTitle from '@site/src/components/General/HeadTitle.tsx';

<HeadTitle title="How to QA your extension - Platform | OpenBB Docs" />

We are strong believers in the QA process and we want to make sure that all the extensions that are added to the OpenBB Platform are of high quality. To ensure this, we have a set of QA tools that you can use to test your extension.

Primarily, we have tools that semi-automate the creation of unit and integration tests.

> The QA tools are still in development and we are constantly improving them.
## Unit tests

Each `Fetcher` comes equipped with a `test` method that will ensure that it is implemented correctly and that it is returning the expected data. It also ensures that all types are correct and that the data is valid.

To create unit tests for your Fetchers, you can run the following command:

```bash
python openbb_platform/providers/tests/utils/unit_test_generator.py
```

> Note that you should be running this file from the root of the repository.
The automatic unit test generation will add unit tests for all the fetchers available in a given provider.

> Note that sometimes manual intervention is needed. For example, adjusting out-of-top level imports or adding specific arguments for a given fetcher.
## Integration tests

The integration tests are a bit more complex than the unit tests, as we want to test both the Python interface and the API interface. For this, we have two scripts that will help you generate the integration tests.

To generate the integration tests for the Python interface, you can run the following command:

```bash
python openbb_platform/extensions/tests/utils/integration_tests_generator.py
```

To generate the integration tests for the API interface, you can run the following command:

```bash
python openbb_platform/extensions/tests/utils/integration_tests_api_generator.py
```

When testing the API interface, you'll need to run the OpenBB Platform locally before running the tests. To do so, you can run the following command:

```bash
uvicorn openbb_platform.platform.core.openbb_core.api.rest_api:app --host 0.0.0.0 --port 8000 --reload
```

These automated tests are a great way to reduce the amount of code you need to write, but they are not a replacement for manual testing and might require tweaking. That's why we have unit tests that test the generated integration tests to ensure they cover all providers and parameters.

To run the tests we can do:

- Unit tests only:

```bash
pytest openbb_platform -m "not integration"
```

- Integration tests only:

```bash
pytest openbb_platform -m integration
```

- Both integration and unit tests:

```bash
pytest openbb_platform
```

## Import time

We aim to have a short import time for the package. To measure that we use `tuna`.

- <https://pypi.org/project/tuna/>

To visualize the import time breakdown by module and find potential bottlenecks, run the
following commands from `openbb_platform` directory:

```bash
pip install tuna
python -X importtime openbb/__init__.py 2> import.log
tuna import.log
```
Loading

0 comments on commit 48b0221

Please sign in to comment.