如何在 FastAPI 中声明 pydantic BaseModel 以在其键之一中接收有效的 json 对象

问题描述 投票:0回答:2

客户端应用程序使用 POST 方法向服务器发送数据。数据基本上有 4 个键值对,其中第二个键的值是一个有效的 json 对象,其中包含多个键值对。目前看起来是这样的

{
  "name": "string",
  "content": {{"resolution":"1","symbol_type":"stock","exchange":"NSE","listed_exchange":"","symbol":"NSE:SBIN-EQ","short_name":"SBIN","legs":"[{\"symbol\":\"SBIN\",\"pro_symbol\":\"SBIN\"}]","name":"asdwa","description":"","charts_symbols":"{\"1\":{\"symbol\":\"NSE:SBIN-EQ\"}}","is_realtime":"1","content":"{\"name\":\"asdwa\",\"layout\":\"s\",\"charts\":[{\"panes\":[{\"sources\":[{\"type\":\"MainSeries\",\"id\":\"RGTnHz\",\"state\":{\"style\":1,\"esdShowDividends\":true,\"esdShowSplits\":true,\"esdShowEarnings\":true,\"esdShowBreaks\":false,\"esdFlagSize\":2,\"showCountdown\":false,\"bidAsk\":{\"visible\":false,\"lineStyle\":1,\"lineWidth\":1,\"bidLineColor\":\"#2962FF\",\"askLineColor\":\"#EF5350\"},\"prePostMarket\":{\"visible\":true,\"lineStyle\":1,\"lineWidth\":1,\"preMarketColor\":\"#fb8c00\",\"postMarketColor\":\"#2962FF\"},\"highLowAvgPrice\":{\"highLowPriceLinesVisible\":false,\"highLowPriceLabelsVisible\":false,\"averageClosePriceLineVisible\":false,\"averageClosePriceLabelVisible\":false},\"showInDataWindow\":true,\"visible\":true,\"showPriceLine\":true,\"priceLineWidth\":1,\"priceLineColor\":\"\",\"baseLineColor\":\"#B2B5BE\",\"showPrevClosePriceLine\":false,\"prevClosePriceLineWidth\":1,\"prevClosePriceLineColor\":\"rgba( 85, 85, 85, 1)\",\"minTick\":\"default\",\"dividendsAdjustment\":{},\"sessionId\":\"regular\",\"sessVis\":false,\"statusViewStyle\":{\"fontSize\":16,\"showExchange\":true,\"showInterval\":true,\"symbolTextSource\":\"description\"},\"candleStyle\":{\"upColor\":\"#26a69a\",\"downColor\":\"#ef5350\",\"drawWick\":true,\"drawBorder\":true,\"borderColor\":\"#378658\",\"borderUpColor\":\"#26a69a\",\"borderDownColor\":\"#ef5350\",\"wickColor\":\"#737375\",\"wickUpColor\":\"#26a69a\",\"wickDownColor\":\"#ef5350\",\"barColorsOnPrevClose\":false,\"drawBody\":true},\"hollowCandleStyle\":{\"upColor\":\"#26a69a\",\"downColor\":\"#ef5350\",\"drawWick\":true,\"drawBorder\":true,\"borderColor\":\"rgba( 55, 134, 88, 1)\",\"borderUpColor\":\"#26a69a\",\"borderDownColor\":\"#ef5350\",\"wickColor\":\"rgba( 115, 115, 117, 1)\",\"wickUpColor\":\"#26a69a\",\"wickDownColor\":\"#ef5350\",\"drawBody\":true},\"haStyle\":{\"upColor\":\"#26a69a\",\"downColor\":\"#ef5350\",\"drawWick\":true,\"drawBorder\":true,\"borderColor\":\"rgba( 55, 134, 88, 1)\",\"borderUpColor\":\"#26a69a\",\"borderDownColor\":\"#ef5350\",\"wickColor\":\"rgba( 115, 115, 117, 1)\",\"wickUpColor\":\"#26a69a\",\"wickDownColor\":\"#ef5350\",\"showRealLastPrice\":false,\"barColorsOnPrevClose\":false,\"inputs\":{},\"inputInfo\":{},\"drawBody\":true},\"barStyle\":{\"upColor\":\"#26a69a\",\"downColor\":\"#ef5350\",\"barColorsOnPrevClose\":false,\"dontDrawOpen\":false,\"thinBars\":true},\"hiloStyle\":{\"color\":\"#2962FF\",\"showBorders\":true,\"borderColor\":\"#2962FF\",\"showLabels\":true,\"labelColor\":\"#2962FF\",\"fontSize\":7,\"drawBody\":true},\"lineStyle\":{\"color\":\"#2962FF\",\"linestyle\":0,\"linewidth\":2,\"priceSource\":\"close\",\"styleType\":2},\"areaStyle\":{\"color1\":\"rgba(41, 98, 255, 0.28)\",\"color2\":\"#2962FF\",\"linecolor\":\"#2962FF\",\"linestyle\":0,\"linewidth\":2,\"priceSource\":\"close\",\"transparency\":100},\"renkoStyle\":{\"upColor\":\"#26a69a\",\"downColor\":\"#ef5350\",\"borderUpColor\":\"#26a69a\",\"borderDownColor\":\"#ef5350\",\"upColorProjection\":\"rgba( 169, 220, 195, 1)\",\"downColorProjection\":\"rgba( 245, 166, 174, 1)\",\"borderUpColorProjection\":\"rgba( 169, 220, 195, 1)\",\"borderDownColorProjection\":\"rgba( 245, 166, 174, 1)\",\"wickUpColor\":\"#26a69a\",\"wickDownColor\":\"#ef5350\",\"inputs\":{\"source\":\"close\",\"sources\":\"Close\",\"boxSize\":3,\"style\":\"ATR\",\"atrLength\":14,\"wicks\":true},\"inputInfo\":{\"source\":{\"name\":\"source\"},\"sources\":{\"name\":\"Source\"},\"boxSize\":{\"name\":\"Box size\"},\"style\":{\"name\":\"Style\"},\"atrLength\":{\"name\":\"ATR length\"},\"wicks\":{\"name\":\"Wicks\"}}},\"pbStyle\":{\"upColor\":\"#26a69a\",\"downColor\":\"#ef5350\",\"borderUpColor\":\"#26a69a\",\"borderDownColor\":\"#ef5350\",\"upColorProjection\":\"rgba( 169, 220, 195, 1)\",\"downColorProjection\":\"rgba( 245, 166, 174, 1)\",\"borderUpColorProjection\":\"rgba( 169, 220, 195, 1)\",\"borderDownColorProjection\":\"rgba( 245, 166, 174, 1)\",\"inputs\":{\"source\":\"close\",\"lb\":3},\"inputInfo\":{\"source\":{\"name\":\"Source\"},\"lb\":{\"name\":\"Number of line\"}}},\"kagiStyle\":{\"upColor\":\"#26a69a\",\"downColor\":\"#ef5350\",\"upColorProjection\":\"rgba( 169, 220, 195, 1)\",\"downColorProjection\":\"rgba( 245, 166, 174, 1)\",\"inputs\":{\"source\":\"close\",\"style\":\"ATR\",\"atrLength\":14,\"reversalAmount\":1},\"inputInfo\":{\"source\":{\"name\":\"Source\"},\"style\":{\"name\":\"Style\"},\"atrLength\":{\"name\":\"ATR length\"},\"reversalAmount\":{\"name\":\"Reversal amount\"}}},\"pnfStyle\":{\"upColor\":\"#26a69a\",\"downColor\":\"#ef5350\",\"upColorProjection\":\"rgba( 169, 220, 195, 1)\",\"downColorProjection\":\"rgba( 245, 166, 174, 1)\",\"inputs\":{\"sources\":\"Close\",\"reversalAmount\":3,\"boxSize\":1,\"style\":\"ATR\",\"atrLength\":14,\"oneStepBackBuilding\":false},\"inputInfo\":{\"sources\":{\"name\":\"Source\"},\"boxSize\":{\"name\":\"Box size\"},\"reversalAmount\":{\"name\":\"Reversal amount\"},\"style\":{\"name\":\"Style\"},\"atrLength\":{\"name\":\"ATR length\"},\"oneStepBackBuilding\":{\"name\":\"One step back building\"}}},\"baselineStyle\":{\"baselineColor\":\"rgba( 117, 134, 150, 1)\",\"topFillColor1\":\"rgba( 38, 166, 154, 0.28)\",\"topFillColor2\":\"rgba( 38, 166, 154, 0.05)\",\"bottomFillColor1\":\"rgba( 239, 83, 80, 0.05)\",\"bottomFillColor2\":\"rgba( 239, 83, 80, 0.28)\",\"topLineColor\":\"rgba( 38, 166, 154, 1)\",\"bottomLineColor\":\"rgba( 239, 83, 80, 1)\",\"topLineWidth\":2,\"bottomLineWidth\":2,\"priceSource\":\"close\",\"transparency\":50,\"baseLevelPercentage\":50},\"rangeStyle\":{\"upColor\":\"#26a69a\",\"downColor\":\"#ef5350\",\"thinBars\":true,\"upColorProjection\":\"rgba( 169, 220, 195, 1)\",\"downColorProjection\":\"rgba( 245, 166, 174, 1)\",\"inputs\":{\"range\":10,\"phantomBars\":false},\"inputInfo\":{\"range\":{\"name\":\"Range\"},\"phantomBars\":{\"name\":\"Phantom bars\"}}},\"symbol\":\"NSE:SBIN-EQ\",\"shortName\":\"SBIN\",\"timeframe\":\"\",\"onWidget\":false,\"interval\":\"1\",\"unitId\":null,\"currencyId\":null,\"priceAxisProperties\":{\"autoScale\":true,\"autoScaleDisabled\":false,\"lockScale\":false,\"percentage\":false,\"percentageDisabled\":false,\"log\":false,\"logDisabled\":false,\"alignLabels\":true,\"isInverted\":false,\"indexedTo100\":false}},\"zorder\":0,\"haStyle\":{\"studyId\":\"BarSetHeikenAshi@tv-basicstudies-60\"},\"renkoStyle\":{\"studyId\":\"BarSetRenko@tv-prostudies-40\"},\"pbStyle\":{\"studyId\":\"BarSetPriceBreak@tv-prostudies-34\"},\"kagiStyle\":{\"studyId\":\"BarSetKagi@tv-prostudies-34\"},\"pnfStyle\":{\"studyId\":\"BarSetPnF@tv-prostudies-34\"},\"rangeStyle\":{\"studyId\":\"BarSetRange@tv-basicstudies-72\"}},{\"type\":\"study_Volume\",\"id\":\"bl7jkV\",\"state\":{\"styles\":{\"vol\":{\"linestyle\":0,\"linewidth\":1,\"plottype\":5,\"trackPrice\":false,\"transparency\":50,\"visible\":true,\"color\":\"#000080\",\"histogramBase\":0,\"joinPoints\":false,\"title\":\"Volume\"},\"vol_ma\":{\"linestyle\":0,\"linewidth\":1,\"plottype\":0,\"trackPrice\":false,\"transparency\":0,\"visible\":false,\"color\":\"#2196f3\",\"histogramBase\":0,\"joinPoints\":false,\"title\":\"Volume MA\"}},\"palettes\":{\"volumePalette\":{\"colors\":{\"0\":{\"color\":\"#EF5350\",\"width\":1,\"style\":0,\"name\":\"Falling\"},\"1\":{\"color\":\"#26A69A\",\"width\":1,\"style\":0,\"name\":\"Growing\"}}}},\"inputs\":{\"showMA\":false,\"length\":20,\"col_prev_close\":false},\"precision\":\"default\",\"bands\":{},\"area\":{},\"graphics\":{},\"showInDataWindow\":true,\"visible\":true,\"showStudyArguments\":true,\"intervalsVisibilities\":{\"ticks\":true,\"seconds\":true,\"secondsFrom\":1,\"secondsTo\":59,\"minutes\":true,\"minutesFrom\":1,\"minutesTo\":59,\"hours\":true,\"hoursFrom\":1,\"hoursTo\":24,\"days\":true,\"daysFrom\":1,\"daysTo\":366,\"weeks\":true,\"weeksFrom\":1,\"weeksTo\":52,\"months\":true,\"monthsFrom\":1,\"monthsTo\":12,\"ranges\":true},\"plots\":{\"0\":{\"id\":\"vol\",\"type\":\"line\"},\"1\":{\"id\":\"volumePalette\",\"palette\":\"volumePalette\",\"target\":\"vol\",\"type\":\"colorer\"},\"2\":{\"id\":\"vol_ma\",\"type\":\"line\"}},\"_metainfoVersion\":52,\"isTVScript\":false,\"isTVScriptStub\":false,\"is_hidden_study\":false,\"description\":\"Volume\",\"shortDescription\":\"Volume\",\"is_price_study\":false,\"id\":\"Volume@tv-basicstudies\",\"format\":{\"type\":\"volume\"},\"description_localized\":\"Volume\",\"shortId\":\"Volume\",\"packageId\":\"tv-basicstudies\",\"version\":\"1\",\"fullId\":\"Volume@tv-basicstudies-1\",\"productId\":\"tv-basicstudies\",\"name\":\"Volume@tv-basicstudies\",\"_serverMetaInfoVersion\":52},\"zorder\":-10000,\"ownFirstValue\":null,\"metaInfo\":{\"palettes\":{\"volumePalette\":{\"colors\":{\"0\":{\"name\":\"Falling\"},\"1\":{\"name\":\"Growing\"}}}},\"inputs\":[{\"id\":\"showMA\",\"name\":\"show MA\",\"defval\":false,\"type\":\"bool\",\"isHidden\":true},{\"id\":\"length\",\"name\":\"MA Length\",\"defval\":20,\"type\":\"integer\",\"min\":1,\"max\":2000},{\"defval\":false,\"id\":\"col_prev_close\",\"name\":\"Color based on previous close\",\"type\":\"bool\"}],\"plots\":[{\"id\":\"vol\",\"type\":\"line\"},{\"id\":\"volumePalette\",\"palette\":\"volumePalette\",\"target\":\"vol\",\"type\":\"colorer\"},{\"id\":\"vol_ma\",\"type\":\"line\"}],\"graphics\":{},\"defaults\":{\"styles\":{\"vol\":{\"linestyle\":0,\"linewidth\":1,\"plottype\":5,\"trackPrice\":false,\"transparency\":50,\"visible\":true,\"color\":\"#000080\"},\"vol_ma\":{\"linestyle\":0,\"linewidth\":1,\"plottype\":0,\"trackPrice\":false,\"transparency\":0,\"visible\":false,\"color\":\"#2196F3\"}},\"palettes\":{\"volumePalette\":{\"colors\":{\"0\":{\"color\":\"#EF5350\",\"width\":1,\"style\":0},\"1\":{\"color\":\"#26A69A\",\"width\":1,\"style\":0}}}},\"inputs\":{\"showMA\":false,\"length\":20,\"col_prev_close\":false}},\"_metainfoVersion\":52,\"isTVScript\":false,\"isTVScriptStub\":false,\"is_hidden_study\":false,\"styles\":{\"vol\":{\"title\":\"Volume\",\"histogramBase\":0},\"vol_ma\":{\"title\":\"Volume MA\",\"histogramBase\":0}},\"description\":\"Volume\",\"shortDescription\":\"Volume\",\"is_price_study\":false,\"id\":\"Volume@tv-basicstudies-1\",\"format\":{\"type\":\"volume\"},\"description_localized\":\"Volume\",\"shortId\":\"Volume\",\"packageId\":\"tv-basicstudies\",\"version\":\"1\",\"fullId\":\"Volume@tv-basicstudies-1\",\"productId\":\"tv-basicstudies\",\"name\":\"Volume@tv-basicstudies\",\"_serverMetaInfoVersion\":52}}],\"leftAxisesState\":[],\"rightAxisesState\":[{\"state\":{\"id\":\"AEh8VAL7anFf\",\"m_priceRange\":{\"m_maxValue\":505.6,\"m_minValue\":494},\"m_isAutoScale\":true,\"m_isPercentage\":false,\"m_isIndexedTo100\":false,\"m_isLog\":false,\"m_isLockScale\":false,\"m_isInverted\":false,\"m_height\":641.6,\"m_topMargin\":0.1,\"m_bottomMargin\":0.08,\"alignLabels\":true},\"sources\":[\"RGTnHz\"]}],\"overlayPriceScales\":{\"bl7jkV\":{\"id\":\"aYA6FWoeiTkP\",\"m_priceRange\":{\"m_maxValue\":298353,\"m_minValue\":0},\"m_isAutoScale\":true,\"m_isPercentage\":false,\"m_isIndexedTo100\":false,\"m_isLog\":false,\"m_isLockScale\":false,\"m_isInverted\":false,\"m_height\":641.6,\"m_topMargin\":0.1,\"m_bottomMargin\":0.08,\"alignLabels\":true}},\"stretchFactor\":2000,\"mainSourceId\":\"RGTnHz\",\"priceScaleRatio\":null}],\"timeScale\":{\"m_barSpacing\":6,\"m_rightOffset\":10},\"chartProperties\":{\"paneProperties\":{\"backgroundType\":\"solid\",\"background\":\"#ffffff\",\"backgroundGradientStartColor\":\"#ffffff\",\"backgroundGradientEndColor\":\"#ffffff\",\"vertGridProperties\":{\"color\":\"rgba(42, 46, 57, 0.06)\",\"style\":0},\"horzGridProperties\":{\"color\":\"rgba(42, 46, 57, 0.06)\",\"style\":0},\"crossHairProperties\":{\"color\":\"#9598A1\",\"style\":2,\"transparency\":0,\"width\":1},\"topMargin\":10,\"bottomMargin\":8,\"axisProperties\":{\"autoScale\":true,\"autoScaleDisabled\":false,\"lockScale\":false,\"percentage\":false,\"percentageDisabled\":false,\"indexedTo100\":false,\"log\":false,\"logDisabled\":false,\"alignLabels\":true,\"isInverted\":false},\"legendProperties\":{\"showStudyArguments\":true,\"showStudyTitles\":true,\"showStudyValues\":true,\"showSeriesTitle\":true,\"showSeriesOHLC\":true,\"showLegend\":true,\"showBarChange\":true,\"showBackground\":true,\"backgroundTransparency\":50,\"wrapText\":false}},\"scalesProperties\":{\"backgroundColor\":\"#ffffff\",\"lineColor\":\"rgba(42, 46, 57, 0.14)\",\"textColor\":\"#131722\",\"fontSize\":12,\"scaleSeriesOnly\":false,\"showSeriesLastValue\":true,\"seriesLastValueMode\":1,\"showSeriesPrevCloseValue\":false,\"showStudyLastValue\":false,\"showSymbolLabels\":false,\"showStudyPlotLabels\":false,\"showBidAskLabels\":false,\"showPrePostMarketPriceLabel\":true,\"showFundamentalNameLabel\":false,\"showFundamentalLastValue\":false,\"barSpacing\":6,\"showCurrency\":true,\"showUnit\":true},\"chartEventsSourceProperties\":{\"visible\":true,\"futureOnly\":true,\"breaks\":{\"color\":\"rgba(85, 85, 85, 1)\",\"visible\":false,\"style\":2,\"width\":1}},\"tradingProperties\":{\"showPositions\":true,\"positionPL\":{\"visibility\":true,\"display\":0},\"showOrders\":true,\"showExecutions\":true,\"horizontalAlignment\":0,\"extendLeft\":true,\"lineLength\":5,\"lineWidth\":1,\"lineStyle\":0},\"priceScaleSelectionStrategyName\":\"auto\"},\"lineToolsGroups\":{\"groups\":[]},\"version\":3,\"timezone\":\"Asia/Kolkata\",\"sessions\":{\"properties\":{\"graphics\":{\"backgrounds\":{\"outOfSession\":{\"color\":\"#2962FF\",\"transparency\":92,\"visible\":false},\"preMarket\":{\"color\":\"#FF9800\",\"transparency\":92,\"visible\":false},\"postMarket\":{\"color\":\"#2962FF\",\"transparency\":92,\"visible\":false}},\"vertlines\":{\"sessBreaks\":{\"color\":\"#4985e7\",\"style\":2,\"visible\":false,\"width\":1}}}}},\"shouldBeSavedEvenIfHidden\":false,\"chartId\":\"1\"}]}"}},
  "symbol": "string",
  "resolution": "string"
}

我尝试遵循 BaseModel 声明和异步函数

class Item(BaseModel):
    name: str
    content: dict
    symbol: str
    resolution: str

@app.post("/saveload/v1/charts")
async def create_item(item: Item, q: str | None = None):
    return item

但这会导致

error 422 Unprocessable Entity
,因为正如你所看到的,
dict
将json包裹在大括号中,因此FastAPI抛出了这个错误。那么我应该如何声明 BaseModel 来接收这些数据。预先感谢您。

json python-3.x fastapi pydantic
2个回答
0
投票

感谢@ MatsLindh 和 @BijayRegmi,我在 google 上搜索了他们的建议并找到了解决方案,只需使用 https://jsontopydantic.com/ 上的实用程序即可从最终的

BaseModel
对象构建 pydantic
json
。一切都会很好。


0
投票

正如已经指出的,

{{
...
}}
不是 有效的 JSON 类型。您应该将
content
值的外大括号替换为方括号,即
[{ ... }]
。例如:

{
  "name": "string",
  "content": [{"name": "Bob", "age":25}, {"name": "Alice", "age":24}],
  "symbol": "string",
  "resolution": "string"
}

因此,对应的Pydantic模型应该如下:

from fastapi import FastAPI
from pydantic import BaseModel
from typing import List


class Item(BaseModel):
    name: str
    content: List[dict]
    symbol: str
    resolution: str


app = FastAPI()


@app.post("/create")
async def create(item: Item):
    return item

我强烈建议您查看这个答案,了解有关

422 Unprocessable entity
错误的更多详细信息,以及用于定义需要 JSON 数据的 FastAPI 端点的各种方法的示例。

© www.soinside.com 2019 - 2024. All rights reserved.