Question: I am developing a webhook in which a third-party service will hit my URL and will provide some files, now I can not use FastAPI's UploadFile = File (...) because it throws an error of the required field File I want to read the payload and files from the request object as we can do in Flask by simply doing this from flask import request files = request.files  How can I achieve the same in FastAPI?

Answer: The proper approach would be to define File/UploadFile and Form type parameters in your endpoint, as demonstrated in Method 1 of this answer, as well as here, here and here (for a faster file and data uploading approach, see this answer and this answer as well). For instance: @app.post("/submit") async def register(name: str = Form(...), files: List[UploadFile] = File(...)): pass  However, since you are looking for an approach using the Request object (which could be useful when dealing with arbitrary data), you could use FastAPI/Starlette's await request.form() method to parse the body, which would return a FormData object, containing all the File(s) and Form data submitted by the user. Simple Working Example from fastapi import FastAPI, Request app = FastAPI() @app.post("/submit") async def submit(request: Request): return await request.form()  A more complete example is given below, which also demonstrates how to obtain every File and Form input in the FormData object returned by Starlette. For more details and references, please have a look at this answer, which the following example is based on. Also, if, for any reason, you would like to use a def instead of async def endpoint, please have a look at this answer on how to read the file contents inside a def endpoint. You might find this answer helpful as well. Complete Working Example app.py from fastapi import FastAPI, Request, Depends, HTTPException from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates from starlette.datastructures import FormData, UploadFile app = FastAPI() templates = Jinja2Templates(directory='templates') 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/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!') # Use this approach, if keys (names) of Form/File data are unknown to the backend beforehand @app.post('/submit') async def submit(body=Depends(get_body)): if isinstance(body, FormData): # if Form/File data received for k in body: entries = body.getlist(k) if isinstance(body.getlist(k)[0], UploadFile): # check if it is an UploadFile object for file in entries: print(f'Filename: {file.filename}. Content (first 15 bytes): {await file.read(15)}') else: data = entries if len(entries) > 1 else entries[0] print(f"{k}={data}") return 'OK' # Use this approach, if keys (names) of Form/File data are known to the backend beforehand @app.post('/other') async def other(body=Depends(get_body)): if isinstance(body, FormData): # if Form/File data received items = body.getlist('items') print(f"items={items}") msg = body.get('msg') print(f"msg={msg}") files = body.getlist('files') # returns a list of UploadFile objects if files: for file in files: print(f'Filename: {file.filename}. Content (first 15 bytes): {await file.read(15)}') return 'OK' @app.get('/', response_class=HTMLResponse) async def main(request: Request): return templates.TemplateResponse('index.html', {'request': request})  Test using HTML <form> Please make sure that each <input> element, for both form and file inputs, includes a name attribute, as shown below; otherwise, it won't be included in Starlette's FormData object. templates/index.html <!DOCTYPE html> <html> <body> <form method="post" action="/submit" enctype="multipart/form-data"> msg : <input type="text" name="msg" value="test"><br> item 2 : <input type="text" name="items" value="1"><br> item 2 : <input type="text" name="items" value="2"><br> <label for="fileInput">Choose file(s) to upload</label> <input type="file" id="fileInput" name="files" multiple> <input type="submit" value="submit"> </form> </body> </html>  Test using JavaScript's Fetch API templates/index.html <!DOCTYPE html> <html> <body> <form id="myForm" > msg : <input type="text" name="msg" value="test"><br> item 1 : <input type="text" name="items" value="1"><br> item 2 : <input type="text" name="items" value="2"><br> </form> <label for="fileInput">Choose file(s) to upload</label> <input type="file" id="fileInput" name="files" multiple><br> <input type="button" value="Submit" onclick="submitUsingFetch()"> <p id="resp"></p> <script> function submitUsingFetch() { const resp = document.getElementById("resp"); const fileInput = document.getElementById('fileInput'); const myForm = document.getElementById('myForm'); var formData = new FormData(myForm); for (const file of fileInput.files) formData.append('files', file); fetch('/submit', { method: 'POST', body: formData, }) .then(response => response.json()) .then(data => { resp.innerHTML = JSON.stringify(data); // data is a JSON object }) .catch(error => { console.error(error); }); } </script> </body> </html>  Test using Python requests test.py import requests url = 'http://127.0.0.1:8000/submit' data = {'items': ['foo', 'bar'], 'msg': 'Hello!'} files = [('files', open('a.txt', 'rb')), ('files', open('b.txt', 'rb'))] # Send Form data and files r = requests.post(url, data=data, files=files) print(r.text) # Send Form data only r = requests.post(url, data=data) print(r.text)