Skip to content

Pydantic models aren't used even though it's hinted as a return type #101

@lov3b

Description

@lov3b

Well, the pydantic models which are defined and hinted as returntypes aren't actually instanciated. Instead most endpoints simply return the result of self__call which is either of dict or list. We can redefine the call-function to something like the following to serialize to a model. A problem which arises is that the test won't work with it's caching out of the box. Another problem, which arises are that some models aren't correctly implemented. For example the SearchResults model.

new __call method

P = TypeVar('P', bound=BaseModel)

   def __call(
            self, method: HttpMethod, path: str, options=None, return_content: bool = False,
            pydantic_model: Optional[Type[P]] = None
    ) -> Union[P, list, dict, bytes, None]:
        method_call = {
            HttpMethod.GET: self._session.get,
            HttpMethod.POST: self._session.post,
            HttpMethod.PUT: self._session.put,
            HttpMethod.DELETE: self._session.delete,
        }.get(method)

        if method_call is None:
            raise ValueError(f"Unknown method type {method}")

        data = {}
        if method == HttpMethod.GET:
            data["params"] = options
        else:
            data["json"] = options

        response = method_call(
            f"{BASE_URL}{path}",
            headers={
                "X-AuthenticationSession": self._authentication_session,
                "X-SecurityToken": self._security_token,
            },
            **data,
        )

        response.raise_for_status()

        # Some routes like add/remove instrument from a watch list
        # only returns 200 OK with no further data about if the operation succeeded
        if len(response.content) == 0:
            return None

        if return_content:
            return response.content

        if pydantic_model is None:
            return response.json()
        return pydantic_model.model_validate_json(response.content)

Broken SearchResults

class SearchHit(BaseModel):
    changePercent: float
    currency: str
    """ ISO 4217 """
    lastPrice: float
    flagCode: str
    """ ISO 3166-1 alpha-2 """
    tradable: bool
    tickerSymbol: str
    name: str
    id: str


class SearchResult(BaseModel):
    instrumentType: str
    numberOfHits: int
    topHits: List[SearchHit]


class SearchResults(BaseModel):
    totalNumberOfHits: int

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions