”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > How to Handle Both Form and JSON Data in a Single FastAPI Endpoint?

How to Handle Both Form and JSON Data in a Single FastAPI Endpoint?

发布于2024-11-08
浏览:652

How to Handle Both Form and JSON Data in a Single FastAPI Endpoint?

How to create a FastAPI endpoint that can accept either Form or JSON body?

In FastAPI, you can create an endpoint that can accept either a form or JSON body using different methods. Here are a few options:

Option 1: Using a dependency function

This option involves creating a dependency function that checks the value of the Content-Type request header and parses the body using Starlette's methods, accordingly.

from fastapi import FastAPI, Depends, Request
from starlette.datastructures import FormData

app = FastAPI()

async def get_body(request: Request):
    content_type = request.headers.get('Content-Type')
    if content_type is None:
        raise HTTPException(status_code=400, detail='No Content-Type provided!')
    elif content_type == 'application/json':
        return await request.json()
    elif (content_type == 'application/x-www-form-urlencoded' or
          content_type.startswith('multipart/form-data')):
        try:
            return await request.form()
        except Exception:
            raise HTTPException(status_code=400, detail='Invalid Form data')
    else:
        raise HTTPException(status_code=400, detail='Content-Type not supported!')

@app.post('/')
def main(body = Depends(get_body)):
    if isinstance(body, dict):  # if JSON data received
        return body
    elif isinstance(body, FormData):  # if Form/File data received
        msg = body.get('msg')
        items = body.getlist('items')
        return msg

Option 2: Defining separate endpoints

Another option is to have a single endpoint, and define your File(s) and/or Form data parameters as Optional. If any of the parameters have values passed to them, it means that the request was either application/x-www-form-urlencoded or multipart/form-data. Otherwise, it was likely a JSON request.

from fastapi import FastAPI, UploadFile, File, Form
from typing import Optional, List

app = FastAPI()

@app.post('/')
async def submit(items: Optional[List[str]] = Form(None),
                    files: Optional[List[UploadFile]] = File(None)):
    # if File(s) and/or form-data were received
    if items or files:
        filenames = None
        if files:
            filenames = [f.filename for f in files]
        return {'File(s)/form-data': {'items': items, 'filenames': filenames}}
    else:  # check if JSON data were received
        data = await request.json()
        return {'JSON': data}

Option 3: Using a middleware

You can also use a middleware to check the incoming request and reroute it to either /submitJSON or /submitForm endpoint, depending on the Content-Type of the request.

from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse

app = FastAPI()

@app.middleware("http")
async def some_middleware(request: Request, call_next):
    if request.url.path == '/':
        content_type = request.headers.get('Content-Type')
        if content_type is None:
            return JSONResponse(
                content={'detail': 'No Content-Type provided!'}, status_code=400)
        elif content_type == 'application/json':
            request.scope['path'] = '/submitJSON'
        elif (content_type == 'application/x-www-form-urlencoded' or
              content_type.startswith('multipart/form-data')):
            request.scope['path'] = '/submitForm'
        else:
            return JSONResponse(
                content={'detail': 'Content-Type not supported!'}, status_code=400)

    return await call_next(request)

@app.post('/')
def main():
    return

@app.post('/submitJSON')
def submit_json(item: Item):
    return item

@app.post('/submitForm')
def submit_form(msg: str = Form(...), items: List[str] = Form(...),
                    files: Optional[List[UploadFile]] = File(None)):
    return msg

Testing the Options

You can test the above options using Python's requests library:

import requests

url = 'http://127.0.0.1:8000/'
files = [('files', open('a.txt', 'rb')), ('files', open('b.txt', 'rb'))]
payload ={'items': ['foo', 'bar'], 'msg': 'Hello!'}
 
# Send Form data and files
r = requests.post(url, data=payload, files=files)  
print(r.text)

# Send Form data only
r = requests.post(url, data=payload)              
print(r.text)

# Send JSON data
r = requests.post(url, json=payload)              
print(r.text)
最新教程 更多>
  • JavaScript 能否为不可预测的属性实现动态 Getter 和 Setter?
    JavaScript 能否为不可预测的属性实现动态 Getter 和 Setter?
    JavaScript 可以实现动态 Getters/Setters 吗?动态 getters 和 setters 允许 JavaScript 对象处理超出预定义属性的属性访问和修改。虽然早期的 JavaScript 技术对已知属性使用特定的 getter 和 setter,但本文探讨了为任何未定义的...
    编程 发布于2024-11-08
  • 我的第一个使用 Python 构建的开源项目,通过 CLI 快速检查数据库
    我的第一个使用 Python 构建的开源项目,通过 CLI 快速检查数据库
    我的问题是: 在处理其他项目时,我发现自己总是必须连接并使用 SELECT * 来查看虚拟条目或新用户。我更喜欢使用 CLI 来监视我的数据库条目,特别是因为我正在测试并只是将虚拟用户添加为项目中的第一个普通用户。因此,总是需要连接到 postgres、mysql 并从 CLI 进行 select ...
    编程 发布于2024-11-08
  • PHP,永不倒下的大象!
    PHP,永不倒下的大象!
    照片由 Ben Griffiths 在 Unsplash 上拍摄 PHP是一种广受好评的语言,同时也受到其他人的批评,有人说它正在消亡,但真的是这样吗,值得花时间学习PHP吗? PHP PHP 是 Rasmus Lerdorf 在 90 年代开发的一种编程语言,最初它被开发为一种服务...
    编程 发布于2024-11-08
  • 如何从 Android 应用程序安全访问远程 MySQL 数据库?
    如何从 Android 应用程序安全访问远程 MySQL 数据库?
    使用 JDBC 在 Android 中访问远程 MySQL 数据库:综合分析使用 JDBC API 从 Android 应用程序远程连接到 MySQL 数据库是一种常见的操作移动开发者之间的问题。虽然建立直接连接在技术上是可行的,但它带来了重大的安全和性能问题。安全影响允许 Android 应用程序...
    编程 发布于2024-11-08
  • 使用 CSS 创建自定义鼠标光标
    使用 CSS 创建自定义鼠标光标
    Written by Samson Omojola✏️ Editor’s note: This article was last updated by Njong Emy on 5 August 2024 to update content and code blocks, as well as t...
    编程 发布于2024-11-08
  • 如何修复 Chrome 扩展程序中孤立内容脚本导致的“扩展程序上下文无效”错误?
    如何修复 Chrome 扩展程序中孤立内容脚本导致的“扩展程序上下文无效”错误?
    如何在 Chrome 扩展程序更新后删除孤立脚本问题无意中重新加载 Chrome 扩展程序,尤其是处于开发者模式的扩展程序,可能会创建孤立内容脚本。这些脚本仍然在后台运行,但与扩展的其余部分失去了通信,从而导致诸如“扩展上下文无效”和“未检查的运行时.lastError”之类的错误。解决方案孤立的内...
    编程 发布于2024-11-08
  • 为什么需要设置$GOPATH以及如何有效使用它?
    为什么需要设置$GOPATH以及如何有效使用它?
    在 $GOPATH 的迷宫中导航作为一个初露头角的 Go 开发者,在错综复杂的 $GOPATH 中导航可能会令人畏惧。为了阐明其目的和用法,让我们深入研究有关此环境变量的一些常见问题。为什么在项目根目录设置 $GOPATH?传统上, $GOPATH 对于设置安装 Go 包的工作区至关重要。默认情况下...
    编程 发布于2024-11-08
  • 如何构建数据输入系统(快速简单指南)
    如何构建数据输入系统(快速简单指南)
    三步构建数据输入系统 在本指南中,我们详细介绍了使用 Five 的快速应用程序开发环境构建和部署数据输入系统所需的步骤。 什么是数据输入系统? 数据输入系统是一个旨在捕获、存储、管理和分析数据的平台。这些系统有助于收集用于决策、研究、分析和报告的重要信息。数据输入系统范围从基本的在线表格到与数据库和...
    编程 发布于2024-11-08
  • 使用内联 SVG 时如何确保剪辑路径的响应式对齐?
    使用内联 SVG 时如何确保剪辑路径的响应式对齐?
    具有内联 SVG 的响应式剪辑路径将剪辑路径应用于具有背景的元素时,通常会嵌入 SVG 内联。但是,您可能会遇到响应能力或对齐问题,如下例所示:<header id="block-header"> <svg width="100%" he...
    编程 发布于2024-11-08
  • 使用 PHP 安全地传送电子邮件:使用 SMTP 发送无垃圾邮件的指南
    使用 PHP 安全地传送电子邮件:使用 SMTP 发送无垃圾邮件的指南
    这是如何使用 PHP SMTP 发送电子邮件而不进入垃圾邮件文件夹的分步示例。 我们将使用 PHPMailer 库,它简化了通过 SMTP 发送电子邮件的过程,并有助于提高送达率。按照以下步骤,您将了解如何正确配置 SMTP 以避免电子邮件进入垃圾邮件文件夹。 第1步:安装PHPMa...
    编程 发布于2024-11-08
  • 如何使用 Python 的“locale”模块来格式化货币值?
    如何使用 Python 的“locale”模块来格式化货币值?
    Python 中的货币格式:综合指南将数字格式化为货币是编程中的一项常见任务,尤其是在处理财务数据时。在 Python 中,locale 模块提供了方便的函数来格式化货币值。如何使用 Python 的 locale 模块格式化货币值导入 locale模块:import locale设置区域设置:为了...
    编程 发布于2024-11-08
  • 您可能不知道的关于类型转换的有趣事实
    您可能不知道的关于类型转换的有趣事实
    介绍 类型转换不仅仅是技术上的需要;它有着丰富的历史和许多程序员可能不知道的迷人的细微差别。了解这些可以为编程和软件开发提供更深入的见解。 类型转换的历史视角 多年来,类型转换的概念已经发生了显着的演变。 编程语言中类型转换的演变: 在编程的早期,类型转换是一个手动...
    编程 发布于2024-11-08
  • 将数据提取到 CSV 文件时,为什么我的 PDO 准备语句返回双结果?
    将数据提取到 CSV 文件时,为什么我的 PDO 准备语句返回双结果?
    PDO 准备语句获取双结果用户遇到了一个问题,即在将数据输出到CSV 文件。相关代码利用 $result_get_rows->fetch() 函数从数据库中检索行。理解 Fetch() 方法The fetch() PDOStatement 对象的方法用于从结果集中检索行。默认情况下,它以索引数组(按...
    编程 发布于2024-11-08
  • 鸭子类型遇到类型提示:在 Python 中使用协议
    鸭子类型遇到类型提示:在 Python 中使用协议
    Python 的动态特性和对鸭子类型的支持长期以来因其灵活性而受到称赞。然而,随着代码库变得越来越大、越来越复杂,静态类型检查的好处变得越来越明显。但是我们如何协调鸭子类型的灵活性和静态类型检查的安全性呢?进入Python的Protocol类。 在本教程中,您将学习: 什么是鸭子类型以及 Pytho...
    编程 发布于2024-11-08
  • 如何在 PHP 中将时间戳向下舍入到最近的刻钟?
    如何在 PHP 中将时间戳向下舍入到最近的刻钟?
    将时间向下舍入到最近的刻钟许多应用程序需要操作时间戳并根据时间执行计算。一个常见的要求是将时间四舍五入到最接近的一刻钟。 PHP 提供了几个可以帮助完成此任务的函数。这是一个 PHP 脚本,演示如何将 MySQL 日期时间字段四舍五入到最近的刻钟:<?php // Get the curren...
    编程 发布于2024-11-08

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3