Storage multipart upload with custom metadata not adding metadata - file-upload

I'm constructing a multipart/related upload request, as described here, with some custom object metadata in the request body. The upload is successful but the custom metadata fields are not being set.
The request body looks like:
--===============5679188666781658153==
Content-Type: application/json; -charset="utf-8"
MIME-Version: 1.0
{"x-goog-meta-local-path": "./images/02-05-2017/2017-02-05T14:33:30.364112.jpg", "x-goog-meta-capture-ds": "2017-02-05T14:33:30.364112", "name": "0/02-05-2017/2017-02-05T14:33:30.364112.jpg"}
--===============5679188666781658153==
Content-Type: image/jpeg
MIME-Version: 1.0
Content-Transfer-Encoding: base64
<Image Data>
--===============5679188666781658153==--
From my understanding I should be able to arbitrarily set metadata key:value pairs as long as the keys are prefixed with x-goog-meta-*.
Am I missing something? How can I persist the custom metadata to the object using a multipart upload?

I found the answer in this related question: Google Storage API custom header on node.js
As jterrace points out:
Take a look at the JSON request builder here: https://developers.google.com/storage/docs/json_api/v1/objects/insert
You'll notice that metadata is a separate key in the body. So you'll want something like:
var metadata = {
name: "name"
contentLanguage: "en",
metadata: {
"something": "completely different",
},
acl: [...]
};

Related

OpenAPI spec - requirement of filename in multipart/form-data

I'm reverse-engineering an API with an endpoint /submit, that accepts the type multipart/form-data content. On the webpage of the service, there is a form to upload plaintext files, so the body of the request should look (and according to devtools it actually looks) like this:
-----------------------------16987925643278910326523687321
Content-Disposition: form-data; name="output"; filename="aaa.txt"
Content-Type: text/plain
some text
-----------------------------16987925643278910326523687321--
My OpenAPI specification of the request body is as follows:
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
output:
type: string
This works almost perfectly, but the code generated from the specification doesn't include the filename="something.txt" in its requests, which the API for some reason needs.
OK: Content-Disposition: form-data; name="output"; filename="aaa.txt"
Error: Content-Disposition: form-data; name="output"
How can I specify in the OpenAPI specification, that the part must always be provided with the filename?
As correctly pointed out by #Helen, the solution is to add format: binary after type: string in the specification:
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
output:
type: string
format: binary # <- THIS

Getting error in file upload using karate api

Could anyone please assist me to file upload functionality using Karate API? I have tried many ways, but getting error message as
"[{"title":"QUERY.BIZ.004","status":500,"detail":"Error in uploading document","timestamp":"2021-12-01T09:04:01.033+01:00"}]"
PAYLOAD DETAILS
metadata: {"key":"FILE_NAME","value":"karate-logo"}
metadata: {"key":"FILE_EXTENSION","value":"jpg"}
metadata: {"key":"TAG","value":"REQUEST"}
metadata: {"key":"DOC_TYP","value":"00008"}
file: (binary)
REQUEST HEADERS
Accept: application/json
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Length: 2368
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary9A1eYQihw4rdVq9f
Below mentioned karate API code which I used in the framework
Given url posturl
And path 'document'
And header id = '1608672'
And header Content-Type = 'multipart/form-data'
And multipart file file = { read: 'classpath:dataDrivenPayload/karate-logo.jpg', filename: 'karate-logo.jpg', contentType: 'image/jpg' }
And multipart field metadata = {"key":"FILE_NAME","value":"karate-logo"}, {"key":"FILE_EXTENSION","value":"jpg"}, {"key":"TAG","value":"REQUEST"}, {"key":"DOC_TYP","value":"00008"}
When method POST
Then status 200
I think the metadata needs to be sent as multiple "parts".
Try something like this:
* url 'https://httpbin.org/anything'
* multipart file metadata = { value: '{"key":"FILE_NAME","value":"karate-logo"}' }
* multipart file metadata = { value: '{"key":"FILE_EXTENSION","value":"jpg"}' }
* method post
* status 200
Otherwise, please use these instructions to troubleshoot, and work with your server-side team if possible: github.com/karatelabs/karate/issues/1645#issuecomment-862502881

Creating multipart/mixed request

I have a very specific case I'm trying to test with Karate.
PUT https://test-api.com/endpoint
Content-Type: multipart/mixed; boundary=BOUNDARY
--BOUNDARY
Content-Type: application/vnd.api+json
{"type": "json-api-object"}
--BOUNDARY
Content-Disposition: attachment; name="fieldname"; filename="filename.jpg"
Content-Type: image/jpeg
Content-Encoding: base64
<binary data>
--BOUNDARY--
Examples show multipart/mixed requests, but they don't show how to set the content-type header on each part. I tried using And multipart header... but that didn't parse correctly.
https://github.com/intuit/karate/blob/master/karate-demo/src/test/java/demo/upload/upload.feature
If I can get this figured out with your help, I'll make a PR against the examples to hopefully help someone in the future.
Yeah this is the first time I'm seeing a need for a custom content-type for each part. This will need a change in the code, so yes an example will expedite a fix.
Meanwhile you can customize the content-type for normal requests.
I had success using mulipart files
* configure headers = {"Content-Type": 'multipart/mixed'}
* configure charset = null
* def mFiles = {}
* set mFiles.jsondata = { value: {'type': 'json-api-object'}, contentType: 'application/vnd.api+json' }
* set mFiles.fieldname = { read: 'classpath:path/to/somePhoto.jpg', filename: 'filename.jpg', contentType: 'image/jpeg' }
Given url "https://my-api.com/put"
And multipart files mFiles
When method PUT
According to this comment, multipart file is preferred for anything other than a string in a multipart field.

How to utilize API call to overwrite/update Google Sheet?

My current API request will post a new Google Sheet every time it runs, but I just want it to either overwrite the existing sheet or just update it with new data.
I've tried using different request methods, but it's not doing what I am looking to do.
Request URL: https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart
Request Method: POST
Content Type: multipart/related; boundary="foo_bar_baz"
Request Body:
--foo_bar_baz
Content-Type: application/json; charset=UTF-8
{
"name": "<var_my_google_sheet_name>",
"mimeType": "application/vnd.google-apps.spreadsheet"
}
--foo_bar_baz
Content-Type: text/csv; charset=UTF-8
<var_query_results>
--foo_bar_baz--
Hoping to have it either overwrite the existing table over and over with updated data, or to just append new data to the existing table.

How to describe a `multipart/form-data` request in blueprint documentation standard?

i'm trying to document an API and one of these endpoints works as multipart/form-data content-type recipient to catch user uploads, and the whole other endpoints works as application/json content-type recipients.
In my documentation i have documented all json requests as properly json objects, but in the multipart/form-data idk how to describe it.
EX 1 - JSON Endpoint:
{
"data": {
"name": "username",
"email": "email#example.com"
}
}
Now i dont know how to describe this object as multipart/form-data object, using de Blueprint API Docs standard.
Can someone help me?