Макет базы данных для работы с FastAPI и Pydantic

Я работаю над проектом, в котором использую FastAPI и pydantic. Об этом упоминалось в репозитории github, из которого я беру задачи: We do expect you to mock a database interaction layer in any way you see fit and generate data (which can be randomized) for the purposes of this test. The implementation of this database layer is left up to you. Ссылка на репозиторий Github: https://github.com/steeleye/recruitment-ext/wiki/API-Developer-Assessment

Я впервые работаю с fastapi и никогда раньше не слышал о насмешках. У меня есть следующий код:

from fastapi import FastAPI, Path
from typing import Optional
from pydantic import BaseModel, Field
import datetime as dt

class TradeDetails(BaseModel):
    buySellIndicator: str = Field(description = "A value of BUY for buys, SELL for sells.")

    price: float = Field(description = "The price of the Trade.")

    quantity: int = Field(description = "The amount of units traded.")


class Trade(BaseModel):
    asset_class: Optional[str] = Field(alias = "assetClass", default=None, description = "The asset class of the instrument traded. E.g. Bond, Equity, FX...etc")

    counterparty: Optional[str] = Field(default=None, description = "The counterparty the trade was executed with. May not always be available")

    instrument_id: str = Field(alias = "instrumentId", description = "The ISIN/ID of the instrument traded. E.g. TSLA, AAPL, AMZN...etc")

    instrument_name: str = Field(alias = "instrumentName", description = "The name of the instrument traded.")

    trade_date_time: dt.datetime = Field(alias = "tradeDateTime", description = "The date-time the Trade was executed")

    trade_details: TradeDetails = Field(alias = "tradeDetails", description = "The details of the trade, i.e. price, quantity")

    trade_id: str = Field(alias = "tradeId", default=None, description = "The unique ID of the trade")

    trader: str = Field(description = "The name of the Trader")
     
app = FastAPI()

# data = {
#     'asset_class': 'Bond',
#     'conterparty': 'delio',
#     'instrument_id': 'AAPL',
#     'instrument_name': 'Guitar',
#     'trade_date_time':'2023-06-6 12:22',
#     'trade_details':{'buySellIndicator':'BUY', 'price':100.0, 'quantity': 10},
#     'trade_id': '11',
#     'trader':'john'
# }

trade = Trade(assetClass='asset',
    counterparty='count',
    instrumentId='AAPL',
    instrumentName='Guitar',
    tradeDateTime='2023-06-6 12:22',
    tradeDetails = {'buySellIndicator':'BUY', 'price':100.0, 'quantity': 10},
    tradeId='11',
    trader='john')

@app.get("/")
def index():
    return {"name": "API Developer Assessment"}

@app.get("/get-trade/{tradeId}")
def get_trade(tradeId:int=Path(description = "The Id of the trade you want to view")):
    return trade.tradeId

@app.get("/Trade")
def get_trade_list():
    return trade.dict()

# @app.get('/get-by-query')
# def get_trade()

Как мне издеваться над базой данных?

почему бы не использовать объект dict из Trade с id в качестве ключа и вставить в него кучу объектов (может быть случайным) и получить от него при вызове API.

Abhishek 06.06.2023 17:21
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Скажем, у вас есть эти упрощенные модели:

from typing import Optional

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field


class TradeDetails(BaseModel):
    price: float
    quantity: int


class Trade(BaseModel):
    asset_class: Optional[str] = Field(alias = "assetClass", default=None)
    trade_details: TradeDetails = Field(alias = "tradeDetails")
    trade_id: str = Field(alias = "tradeId", default=None)
    trader: str

...

Точно так же, как @Abhishek предложил в комментарии, вы можете просто настроить очень простой словарь с идентификаторами сделок в качестве ключей и соответствующими объектами Trade в качестве значений, например:

TRADE_1 = Trade(
    assetClass = "foo",
    tradeDetails=TradeDetails(price=100.0, quantity=10),
    tradeId = "1",
    trader = "john",
)
TRADE_2 = Trade(
    assetClass = "bar",
    tradeDetails=TradeDetails(price=200.0, quantity=1),
    tradeId = "2",
    trader = "alice",
)
TRADE_3 = Trade(
    assetClass = "baz",
    tradeDetails=TradeDetails(price=3.14, quantity=5),
    tradeId = "3",
    trader = "dan",
)

MOCK_TRADE_DATABASE = {
    "1": TRADE_1,
    "2": TRADE_2,
    "3": TRADE_3,
}

Затем вы можете настроить свои конечные точки примерно так:

...

app = FastAPI()


@app.get("/trades/{trade_id}")
def get_trade_by_id(trade_id: str) -> Trade:
    if trade_id not in MOCK_TRADE_DATABASE:
        raise HTTPException(status_code=404)
    return MOCK_TRADE_DATABASE[trade_id]


@app.get("/trades/")
def get_trade_list(search: Optional[str] = None) -> list[Trade]:
    if search is None:
        return list(MOCK_TRADE_DATABASE.values())
    # Search only for matching `trader` values:
    return [
        trade for trade in MOCK_TRADE_DATABASE.values()
        if search in trade.trader
    ]

Если вы попробуете это, вы увидите, что вы можете запросить, например, конкретную сделку 2 через /trades/2, и вы можете получить массив всех сделок, где trader имеет a в своем имени через /trades/?search=a.

Если вы хотите немного пофантазировать, вы можете вместо этого настроить простую базу данных SQLite и даже разрешить пользователям добавлять в нее новые Trade.

Но поскольку в задании четко сказано «издеваться» над базой данных, я не думаю, что настоящая база данных (даже такая минимальная, как SQLite) ожидается.

Могу ли я искать что-нибудь? с помощью второй конечной точки?

Karthik Bhandary 07.06.2023 07:21

@KarthikBhandary Хочешь, я решу за тебя все задание?

Daniil Fajnberg 07.06.2023 09:20

Нет, я разобрался! Я просто не увидел комментарий, прежде чем спросить

Karthik Bhandary 07.06.2023 09:25

Я тоже выполнил задание. Спасибо вам за помощь!

Karthik Bhandary 07.06.2023 09:26

Другие вопросы по теме