From f2fda8643e1a0d56569b995dd4665e0b624f147d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaros=C5=82aw=20Skrzypek?= Date: Sat, 24 Aug 2019 18:09:42 +0200 Subject: [PATCH] allow using multipart/form-data to upload files with graphql --- starlette/graphql.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/starlette/graphql.py b/starlette/graphql.py index 2063c0789..a16c558b9 100644 --- a/starlette/graphql.py +++ b/starlette/graphql.py @@ -7,6 +7,7 @@ from starlette.requests import Request from starlette.responses import HTMLResponse, JSONResponse, PlainTextResponse, Response from starlette.types import Receive, Scope, Send +from starlette.datastructures import UploadFile, MultiDict try: import graphene @@ -54,6 +55,7 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: await response(scope, receive, send) async def handle_graphql(self, request: Request) -> Response: + files = MultiDict() if request.method in ("GET", "HEAD"): if "text/html" in request.headers.get("Accept", ""): if not self.graphiql: @@ -75,6 +77,20 @@ async def handle_graphql(self, request: Request) -> Response: data = {"query": text} elif "query" in request.query_params: data = request.query_params + elif "multipart/form-data" in content_type: + form = await request.form() + data = { + "query": form.get('query'), + "variables": json.loads(form.get('variables')), + } + + for (key, value) in form.items(): + if type(value) is UploadFile: + files.append(key, { + "filename": value.filename, + "content_type": value.content_type, + "content": await form[key].read() + }) else: return PlainTextResponse( "Unsupported Media Type", @@ -97,7 +113,7 @@ async def handle_graphql(self, request: Request) -> Response: ) background = BackgroundTasks() - context = {"request": request, "background": background} + context = {"request": request, "background": background, "files": files } result = await self.execute( query, variables=variables, context=context, operation_name=operation_name