Files
OpenBB/website/content/platform/development/developer-guidelines/validators.md
Danglewood c047cfeddd docs/new-working-docs: New working docs branch (#5768)
* move old example notebooks to v3 folder, update loadHistoricalPriceData and add findSymbols

* Create README.md

* Update README.md

* Update README.md

* Update README.md

* Vertical diagram instead

* important classes

* core dependencies

* folder structure

* devtools

* swap order

* fix github pages deploy issue

* development index

* delete expectations for developers

* devtools

* obbject stuff

* add

* installation

* hub sync

* idk if i committed already

* add usage page for financial statements

* add link to reference page

* syntax

* numbers

* nearly --> more than

* easier to read code blocks

* codespell

* removing mention to provider

* add 'orientation' for to_dict

* info card for output user preference

* put it in a code block

* correct user_settings.json example

* syntax corrections

* fix sentence

* get rid of floating point mathc

* get rid of other floating point math

* add companion example notebook for financial statements, and new section

* historical prices usage page

* codespell

* add commitment of traders section to usage

* add a note

* codespell

* get rid of equals sign

* Cleanup docs. with @the-praxs

* install

* obbject extend

* spell

* HeadTitle thingies

* Update obbject_extensions.md

* Update obbject_extensions.md

* typo

* Update architectural_considerations.md

* point to the TET pattern

* optional vs required

* reviewing the  patterns. removed the --pre flag under the assumption this will be the final docs for the release cc @deeleeramone

* add a walkthrough

* spelling

* Add more in the introduction

* validator examples

* update Copper-to-Gold notebook example for V4

* Update README.md

* QA Caveats w @the-praxs

* info on class outputs

* merge add data sources and add data points

* disclaimer on cookiecutter

* add missing import to example

* slight syntax change

* missing code block

* missing import

* update intrinio example syntax

* intrinio syntax update

* urls

* core and provider merged

* example syntax

* grammar

* Update API banner link

* quick-fix-docs cc @minhhoang1023

* Update pip install command for v3

* remove --pre note block

* update landing image

---------

Co-authored-by: Henrique Joaquim <h.joaquim@campus.fct.unl.pt>
Co-authored-by: Luqman <luqazino@gmail.com>
Co-authored-by: James Maslek <jmaslek11@gmail.com>
Co-authored-by: Igor Radovanovic <74266147+IgorWounds@users.noreply.github.com>
Co-authored-by: montezdesousa <79287829+montezdesousa@users.noreply.github.com>
Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com>
Co-authored-by: Pratyush Shukla <ps4534@nyu.edu>
2023-12-01 01:09:25 +00:00

4.4 KiB
Vendored

title, sidebar_position, description, keywords
title sidebar_position description keywords
Validators 4 This guide provides detailed instructions on how and where validators should be used.
OpenBB Platform
Data point addition
Provider creation
Query parameters
Data output models
Fetcher class
validator
field
param
Fast API

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

Both QueryParams and Data models can benefit from the tactical use of Pydantic validators. This page will outline some of the key scenarios where they are deployed. Overall, they assist with enforcing Fast API compliance for both inputs and outputs.

Why Use Validators?

Some situations where they are used include:

  • A query parameter accepts a List.
  • A query parameter is a date.
  • A query parameter requires a dynamic default state.
  • A data field is a date.
  • A data field is a number but the source values contain string elements.

Examples

String or List of Strings

To enforce compliance with Fast API, a list needs to be converted to a comma-separated string. This type of validator works on the input of the model, and it ensures that both the Python interface and the Rest API are able to accept a list of symbols, or just one.

from typing import List, Optional, Set, Union
from datetime import (
    date as dateType,
    datetime,
    timedelta,
)
from dateutil import parser
from openbb_core.provider.abstract.query_params import QueryParams
from openbb_core.provider.utils.descriptions import QUERY_DESCRIPTIONS
from pydantic import Field, field_validator, model_validator

class EquityHistoricalQueryParams(QueryParams):
    """Equity Historical Price Query."""

    symbol: str = Field(description=QUERY_DESCRIPTIONS.get("symbol", ""))
    interval: Optional[str] = Field(
        default="1d",
        description=QUERY_DESCRIPTIONS.get("interval", ""),
    )
    start_date: Optional[dateType] = Field(
        default=None,
        description=QUERY_DESCRIPTIONS.get("start_date", ""),
    )
    end_date: Optional[dateType] = Field(
        default=None,
        description=QUERY_DESCRIPTIONS.get("end_date", ""),
    )

    @field_validator("symbol", mode="before", check_fields=False)
    @classmethod
    def upper_symbol(cls, v: Union[str, List[str], Set[str]]):
        """Convert symbol to uppercase."""
        if isinstance(v, str):
            return v.upper()
        return ",".join([symbol.upper() for symbol in list(v)])

symbols = ["AAPL", "MSFT", "GOOG"]
params = EquityHistoricalQueryParams(symbol=symbols)

params.model_dump()
{'symbol': 'AAPL,MSFT,GOOG',
 'interval': '1d',
 'start_date': None,
 'end_date': None}

The list of symbols can also be entered as a comma-separated string:

symbols = "AAPL,MSFT,GOOG"
params = EquityHistoricalQueryParams(symbol=symbols)
params.model_dump()
{'symbol': 'AAPL,MSFT,GOOG',
 'interval': '1d',
 'start_date': None,
 'end_date': None}

Dynamic Default Date

It might be desirable to have a default date parameter that is not static. To allow this, we must set the default as None, and use the model_validator. The block below is added to the class defined above.

    @model_validator(mode="before")
    @classmethod
    def validate_dates(cls, values) -> dict:
        """Validate the query parameters."""
        if values.get("start_date") is None:
            values["start_date"] = (datetime.now() - timedelta(days=90)).strftime(
                "%Y-%m-%d"
            )
        if values.get("end_date") is None:
            values["end_date"] = datetime.now().strftime("%Y-%m-%d")
        return values
params = EquityHistoricalQueryParams(symbol=symbols)
params.model_dump()
{'symbol': 'AAPL,MSFT,GOOG',
 'interval': '1d',
 'start_date': datetime.date(2023, 8, 30),
 'end_date': datetime.date(2023, 11, 28)}

Formatting Dates

Providers will format dates in a number of ways. OpenBB uses YYYY-MM-DD as the standard convention. Validators are setup to parse the date from the source format to the desired one. The validator below is used in some data models to convert date values to a datetime object.

    @field_validator("date", mode="before", check_fields=False)
    def date_validate(cls, v):  # pylint: disable=E0213
        """Return formatted datetime."""
        return parser.isoparse(str(v))