Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upload File with Payload #1272

Closed
michaelh659 opened this issue Apr 15, 2020 · 3 comments
Closed

Upload File with Payload #1272

michaelh659 opened this issue Apr 15, 2020 · 3 comments

Comments

@michaelh659
Copy link

I am looking for an example of how to upload a file with, what I am referring to as a payload. Similar to a curl command I found:
curl -i -X POST -H "Content-Type: multipart/mixed" -F "file=@/some/path/to/file.txt" -F "metadata={"edipi":123456789,"firstName":"John","lastName":"Smith","email":"john.smith@gmail.com"};type=application/json" http://localhost:5000/uploadfile/

@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile = File(...)):
return { "filename": file.filename)

What seems to puzzle me is how to declare the parameters and ultimately unit testing.

Any example would be good. The json/dict in that curl example is a bit wordy, it can be stripped to "foo": "bar", for example, if that helps?

Does anyone have any suggestions?

Thanks.

@michaelh659 michaelh659 added the question Question or problem label Apr 15, 2020
@michaelh659
Copy link
Author

Ok, I think I got it.
The curl for this example could look like this:
curl -X POST "http://localhost:5000/uploadfile/" -H "accept: application/json" -H "Content-Type: multipart/form-data" -F "f=@i.txt;type=text/plain" -F "params={"edipi":123456789,"firstName":"John"};type=application/json"

the signature would be something like:
async def create_upload_file(f: UploadFile = File(...),params: str = Form(...)):
return { 'params' : params, 'filename', f.filename }

Result would be:
{"params":"{"edipi":123456789,"firstName":"John"}","filename":"i.txt"}

Quick recap. That curl command uploads a file (i.txt) and some form data specified by the second -F params=...

I will try to post the unit test for it later. This should be enough to get me going.

If there are improvements to this approach, I would love to learn.

@michaelh659
Copy link
Author

To complete the circle, I do have an example of what the test for the above scenario might look like. Working with the assumption that the tests are making use of the TestClient..

#this is untested but should be pretty close.
import json
def test_upload_file(self):
f = {"file":("junkfile.txt", BytesIO(b"abcdef"), "multipart/form-data")}
d = {"edipi":123456789,"firstName":"John"}
params = ({"params":(json.dumps(d))}) #pretty liberal use of parenthesis ?
#assuming that self.app = TestClient({app_name_here})
response = self.app.put('/uploadfile/',files=f, data=params)
self.assertEqual(response.status_code==200,True)

I am unsure if this will help anyone. I find it somewhat helpful.

Note that on the 'upload file' I do something like:
async def create_upload_file(f: UploadFile = File(...),params: str = Form(...)):
inputs = json.loads(params)
# if that works..
inputs['firstName'] == 'John' # True

Perhaps the more robust way would be to make some type of model out of the 'params' and declare the params as something like : params:params_model=Form(...) or some variation of that.
No clue if that would work.

@neokeld
Copy link

neokeld commented Jun 5, 2020

Some good threads :

Repository owner locked and limited conversation to collaborators Feb 28, 2023
@tiangolo tiangolo converted this issue into discussion #9047 Feb 28, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Projects
None yet
Development

No branches or pull requests

3 participants