首页 > 解决方案 > Python FastAPI“发布无法处理的实体”错误

问题描述

提交按钮时出错

主文件

from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates
from pydantic import BaseModel
from googletrans import Translator

import uvicorn

#from googletrans import Translator
#init
app = FastAPI(debug=True)

templates = Jinja2Templates(directory="template")


#route
@app.get('/')
async def home(request: Request):
        data = {'request': request}
        return templates.TemplateResponse('translates.html', data)


class variable(BaseModel):
    Input_text: str
    trans: str

#def translator(request):
@app.post('/',response_model=variable)
async def trans(request: Request,  form: variable ):

    text = request.get('Input_text')
    lang = request.get('trans')
    # print('text:',text,'lang:',lang)

    # connect the translator
    translator = Translator(service_urls=['translate.googleapis.com'])

    # detect langguage
    dt = translator.detect(text)
    dt2 = dt.lang

    # translate the text
    translated = translator.translate(text, lang)
    tr = translated.text
    data = {
        'request': request,
        'translated': tr
        , 'u_lang': dt2
        , 't_lang': lang}

    return templates.TemplateResponse(data, "translates.html",)


if __name__=="__main__":
   uvicorn.run(app,host="127.0.0.1",port=8000)

然后是HTML代码

翻译.html

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Translate</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css">
    <script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.js"></script>

</head>
<body>
<div class="ui container">
    <h2>Translation</h2>

<form action="" method="post">
    <br>

<div class="form-input">
    <center><label for="TextareaInput">Enter Text </label></center>
    <center><textarea class="form-control" name="Input_text" id="TextareaInput" rows="3"></textarea></center>
</div>
<div class="ui divider"></div>

<div class="selection list">
  <center><label for="languages">Choose Langguage:</label></center>
  <center><select name="trans" id="languages">
    <option value="en">English</option>
    <option value="ms">Malay</option>
    <option value="zh-cn">Mandarin</option>
    <option value="ko">Korean</option>
      <option value="ja">Japanese</option>
      <option value="vi">Vietnamese</option>
      <option value="th">Thailand</option>
  </select></center>
</div>
<div class="ui divider"></div>

<div>
   <center> <button type="Submit" class="button">Translate</button></center>
</div>
<div class="ui divider"></div>

<div class="form-output">
    <!---<center><textarea class="form-control" id="TextareaOutput" rows="3" value={{translated}} placeholder="Translate..."></textarea></center>-->

    <div class="Output Translation">

        <br><br>
        <h1>Text translated {{u_lang}} from {{t_lang}}</h1>
        <center>
            <h1>{{translated}}</h1>
        </center>
    </div>
</div>
</form>

</div>

</body>
</html>

当我尝试按钮提交时,这些会发生->

{
  "detail": [
    {
      "loc": [
        "body",
        0
      ],
      "msg": "Expecting value: line 1 column 1 (char 0)",
      "type": "value_error.jsondecode",
      "ctx": {
        "msg": "Expecting value",
        "doc": "Input_text=hi&trans=zh-cn",
        "pos": 0,
        "lineno": 1,
        "colno": 1
      }
    }
  ]
}

很确定错误发生在我的 BaseModel 参数上,但我似乎无法纠正,已经在互联网上搜索。

标签: pythonhtmlfastapi

解决方案


您可以使用Pydantic模型,但您需要创建一个像这样的解决方法,它默认需要一个Body,因此我们通过包装 Pydantic 模型来更改字段的签名。

from fastapi import Form, Depends


def form_body(cls):
    cls.__signature__ = cls.__signature__.replace(
        parameters=[
            arg.replace(default=Form(...))
            for arg in cls.__signature__.parameters.values()
        ]
    )
    return cls


@form_body
class variable(BaseModel):
    Input_text: str
    trans: str

然后你就可以像这样开始使用它了

from fastapi import FastAPI, Form, Depends
from pydantic import BaseModel


app = FastAPI(debug=True)


def form_body(cls):
    cls.__signature__ = cls.__signature__.replace(
        parameters=[
            arg.replace(default=Form(...))
            for arg in cls.__signature__.parameters.values()
        ]
    )
    return cls


@form_body
class variable(BaseModel):
    Input_text: str
    trans: str


@app.post("/", response_model=variable)
async def trans(form: variable = Depends(variable)):

    return form

推荐阅读