How to convert json to csv with Pandas/ python3? - json

I try to convert a JSON file to a csv file. I have checked most of the delivered solutions on iterative blogs and here at stackoverflow. But the things I tried, did not work out...
I am collecting requests and response headers from different websites and I am using 'json' to save the incoming data.
For analyzing purposes, I would like to convert those data into either csv or excel, optionally SQLite.
Collecting data in this case means, that the headers are not known and may change over time.
I tried some with pandas, but without any success.
My Json data looks like:
[
{
"request_headers": {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.71 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Cookie": "NID=189=rWuM7h_22U5ed7lJX9ewHyxOHJbRB0pgrlemwaGWLZtxDxweyi6e97D6kJ8ONYTz7OwtTl7SWj7qKED8Sspu7VfOnm9uZztJenCp68GjWIsMqOXrueIByIFgi-sLWjzLoDr7UnR1svQFa9tgHPDguKxVoV9-5uRpJsWQIJ30iZs; 1P_JAR=2019-10-13-16; CONSENT=WP.27f3c1",
"DNT": "1",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "it-IT,de;q=0.9,en-US;q=0.8,en;q=0.7"
},
"status_code": 200,
"url": "https://www.google.com/?gws_rd=ssl",
"headers": {
"Set-Cookie": "1P_JAR=2019-10-13-16; expires=Tue, 12-Nov-2019 16:11:15 GMT; path=/; domain=.google.com; SameSite=none, NID=189=K1LFDX7rwYGGQ74fbrLC7oPToRGnrEjLM-oFj2m5p4uYbHtKlmEaDmBW0qb7PZeYOXq7SFvdYlUCmqZmAU2Rrd1rMPqN2uKs0Iid30HiVFJKReQl8Dkjpm9iAgHjgbxgb0ouEQKo6dSCNSbLOyQTMnRLBqhvSavOsOT4DtmeCrs; expires=Mon, 13-Apr-2020 16:11:15 GMT; path=/; domain=.google.com; HttpOnly",
"Transfer-Encoding": "chunked",
"Content-Type": "text/html; charset=UTF-8",
"P3P": "CP=\"This is not a P3P policy! See g.co/p3phelp for more info.\"",
"Server": "gws",
"X-Frame-Options": "SAMEORIGIN",
"Strict-Transport-Security": "max-age=31536000",
"Alt-Svc": "quic=\":443\"; ma=2592000; v=\"46,43\",h3-Q048=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000",
"Date": "Sun, 13 SEP 2018 16:11:15 GMT",
"X-XSS-Protection": "0",
"Expires": "-1",
"Content-Encoding": "gzip",
"Cache-Control": "private, max-age=0"
}
},
I would like to get a converter, which reads any json file. The keys in the first place are considered to be the headers for each column (e.g. User-Agent, Transfer-Encoding, Cache-Control, Date a.s.o), and the given values should be within the corresponding column/row.
so you have
User-Agent | Date | Url | status_code
Firefox | Sun,... | www.google.com | 200
Chrome | Sat,... | www.google.com | 301
Edge | Wed,...
.
.
Thanks in advance!
PS: If you know any link, which helps me to find a proper solution, I am also happy.

This is my solution for now:
import pandas as pd
df = pd.read_json('file.json')
df.to_csv('file.csv')

Related

can not get X-AppEngine info from req header in 2nd generation AppEngine

I build 2 functions in GoogleCloudFunctions today, with the same code and different environment (1st gen and 2nd gen).
res.json(req.headers)
the 1st generation with X-Appengine-* in headers but 2nd generation don't have it.
1st generation res:
{
"host": "xxxxx",
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:106.0) Gecko/20100101 Firefox/106.0",
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"accept-encoding": "gzip, deflate, br",
"accept-language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
"forwarded": "for=\"xx.xx.xx.xx\";proto=https",
"function-execution-id": "z93h1p8dezsd",
"sec-fetch-dest": "document",
"sec-fetch-mode": "navigate",
"sec-fetch-site": "none",
"sec-fetch-user": "?1",
"traceparent": "00-c6fbb14b26a1999f7203caa810bd82bd-f4e8995eb815facc-01",
"upgrade-insecure-requests": "1",
"x-appengine-appversionid": "h~j3d1cb91ff7bbe64cp-tp/a8aa78b2557e1c923250159d17af9995:2.447902922919183830",
"x-appengine-city": "?",
"x-appengine-citylatlong": "0.000000,0.000000",
"x-appengine-country": "HK",
"x-appengine-default-version-hostname": "j3d1cb91ff7bbe64cp-tp.appspot.com",
"x-appengine-https": "on",
"x-appengine-region": "?",
"x-appengine-request-log-id": "63745ec000ff00ff035e0349af4c0001687e6a33643163623931666637626265363463702d7470000161386161373862323535376531633932333235303135396431376166393939353a32000100",
"x-appengine-timeout-ms": "599999",
"x-appengine-user-ip": "xx.xx.xx.xx",
"x-cloud-trace-context": "c6fbb14b26a1999f7203caa810bd82bd/17647523771945712332;o=1",
"x-forwarded-for": "xx.xx.xx.xx",
"x-forwarded-proto": "https",
"connection": "close"
}
2nd generation res:
{
"host": "xxxxx.run.app",
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:106.0) Gecko/20100101 Firefox/106.0",
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"accept-language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
"upgrade-insecure-requests": "1",
"sec-fetch-dest": "document",
"sec-fetch-mode": "navigate",
"sec-fetch-site": "none",
"sec-fetch-user": "?1",
"x-cloud-trace-context": "7adcb5fe556c66fc94f83b6dfe62dfe6/5799981330522755859;o=1",
"traceparent": "00-7adcb5fe556c66fc94f83b6dfe62dfe6-507dac4a5db4d313-01",
"x-forwarded-for": "xxx.xxx.xxx.xxx",
"x-forwarded-proto": "https",
"forwarded": "for=\"xxx.xxx.xxx.xxx\";proto=https",
"accept-encoding": "gzip, deflate, br"
}
Could I get X-Appengine-* from 2nd generation Functions?
Thank you
App Engine-specific headers is not supported for second generation environment.Because Cloud Functions (2nd gen) is built on Cloud Run,you can refer to this document
As mentioned by john hanley in above comment If you want those headers, deploy on gen1.
If you think it’s a valid feature request you may raise here with a clear description.Good feature requests will solve common problems or enable new use cases.

How can I test a CSP report-uri endpoint?

I've added a Content Security Policy to my website and made a report-uri endpoint with AWS API Gateway, Lambda, and DynamoDB. I've tested it with Postman using the following JSON
{
"resource": "/",
"path": "/",
"requestContext": {
"resourcePath": "/",
"httpMethod": "POST",
"path": "/latest"
},
"headers": {
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"accept-encoding": "gzip, deflate, br",
"Host": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36",
"X-Amzn-Trace-Id": "Root=1-5e66d96f-7491f09xmpl79d18acf3d050"
},
"multiValueHeaders": {
"accept": [
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
],
"accept-encoding": [
"gzip, deflate, br"
]
},
"queryStringParameters": null,
"multiValueQueryStringParameters": null,
"pathParameters": null,
"stageVariables": null,
"body": {
"csp-report": {
"document-uri": "https://example.com/signup.html",
"referrer": "",
"blocked-uri": "https://example.com/css/style.css",
"violated-directive": "style-src cdn.example.com",
"original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports"
}
},
"isBase64Encoded": false
}
It seems to work properly when using Postman. But when I added the endpoint to my Content Security Policy and attempt to violate the policy, I can't seem to get it to report correctly.
Does the JSON above adequately demonstrate what a real CSP violation would look like?
I've looked around and haven't seen much about developing your own endpoint. Any resources or other advice is greatly appreciated.
It depends on the browser
some browser sends the Json and CSP violation report some sends thec csp-report.
Few browser sends the request base64 encoded.
Specifically in chrome browser it sends base64 encoded and as Json format. In your payload.
Hopefully it answers your question.

jq - insert values into subkey

I have a httpie session file that looks like this:
{
"headers": {
"Host": "34.213.0.202",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"DNT": "1",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Cache-Control": "max-age=0"
}
}
I would like to insert an item into headers (think '.headers + {"Cookie": "xyz"}') but I would like the output to be the whole JSON. Using jq '.headers + {"Cookie": "xyz"}' only prints out the .headers value. What I am looking to get is the whole entire JSON, but with the cookie subkey included.
What's the way to get that?
Use assignment operators:
.headers += { Cookie: "xyz" }
.headers.Cookie = "xyz"
The latter one changes a bit when there are multiple fields to be added:
.headers |= (.Cookies = "xyz" | .Referer = "xyz")

the key you provided doesn't work with this thing error in Thing space GET opertion

While i am performing a GET operation in Thing space, it was showing the following error.
Request URL
https://thingspace.io:443/dweet/for/pathetic-honey? key=fZC4GAPSVxMrBVrG9HvQgGfg7Rsa
Response Body
{
"this": "failed",
"because": "the key you provided doesn't work with this thing"
}
Response Code
200
Response Headers
{
"Access-Control-Allow-Origin": "*",
"Date": "Thu, 23 Mar 2017 09:09:45 GMT",
"Content-Encoding": "gzip",
"Connection": "keep-alive",
"Transfer-Encoding": "chunked",
"Content-Type": "application/json"
}
i solved the question. don't pass the key_value while you are passing the API.
just pass the thing name only.
eg:https://thingspace.io/dweet/for/YOUR_THINGNAME

Why is a media upload breaking my app assocation (in firefox)?

My javascript app creates a file and then uploads the media content. In Chrome, everything is hunky dorey. In Firefox, the act of uploading media is somehow breaking the association Drive holds between the file and my app, such that the icon is no longer my application icon (it's the default Google blue box) and clicking to open the file gives an error page.
So the steps are ...
Create the file (POST to /files)
Observe in Drive that the file exists and is displayed with my application icon
Upload the file contents (PUT with uploadType=media and convert=false)
Observe in Drive that the file's icon is now the Google blue
If I do exactly the same in Chrome, at step 4, the file is still associated with my app and displays my app icon.
Here is the media PUT from Chrome (ie the working one)
PUT https://content.googleapis.com/upload/drive/v2/files/0B6B-RNrxsCu2SERMMEFXMkdiOWM?uploadType=media&convert=false&useContentAsIndexableText=true&key=AIzaSyCt2bxTnrxo_IGvSUCBBAN_-29HJnzX_MU HTTP/1.1
:host: content.googleapis.com
x-origin: http://foo.myapp.appspot.com
x-javascript-user-agent: google-api-javascript-client/1.1.0-beta
x-goog-encode-response-if-executable: base64
user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
accept-language: en-US,en;q=0.8,en-AU;q=0.6
authorization: Bearer ya29.AHES6ZQq1wAGltlEsnGKr6Dgtgkvp4zHCJsNTrXohnqrRmm3Ji8Yb14
x-referer: http://foo.myapp.appspot.com
x-clientdetails: appVersion=5.0%20(X11%3B%20Linux%20x86_64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F28.0.1500.95%20Safari%2F537.36&platform=Linux%20x86_64&userAgent=Mozilla%2F5.0%20(X11%3B%20Linux%20x86_64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F28.0.1500.95%20Safari%2F537.36
referer: https://content.googleapis.com/static/proxy.html?jsh=m%3B%2F_%2Fscs%2Fapps-static%2F_%2Fjs%2Fk%3Doz.gapi.en.l49lMhuyXyk.O%2Fm%3D__features__%2Fam%3DEQ%2Frt%3Dj%2Fd%3D1%2Frs%3DAItRSTOvD2NxxPLz0HiGHMXTek7IhOVTHg
content-length: 9
:version: HTTP/1.1
origin: https://content.googleapis.com
accept-encoding: gzip,deflate,sdch
:path: /upload/drive/v2/files/0B6B-RNrxsCu2SERMMEFXMkdiOWM?uploadType=media&convert=false&useContentAsIndexableText=true&key=AIzaSyCt1bxTnrxo_IGvSUCBBAN_-29HJnzX_MU
content-type: text/html
accept: */*
:scheme: https
:method: PUT
Query String
uploadType=media
&convert=false
&useContentAsIndexableText=true
&key=AIzaSyCt2bxTnrxo_IGvSUCBBAN_-29HJnzX_MU
and here is the media PUT from Firefox (ie. the one that breaks the file association)
firefox
PUT /upload/drive/v2/files/0B6B-RNrxsCu2UFZxbjExd0dGeTQ?uploadType=media&convert=false&useContentAsIndexableText=true&key=AIzaSyCt2bxTnrxo_IGvSUCBBAN_-29HJnzX_MU HTTP/1.1
Host: content.googleapis.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:21.0) Gecko/20100101 Firefox/21.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: text/html; charset=UTF-8
Authorization: Bearer ya29.AHES6ZQrG_PQOmEZD4cBwgrjiNKNZUBc2RzAnOTmZwTJReX664MWvu8
X-ClientDetails: appVersion=5.0%20(X11)&platform=Linux%20x86_64&userAgent=Mozilla%2F5.0%20(X11%3B%20Linux%20x86_64%3B%20rv%3A21.0)%20Gecko%2F20100101%20Firefox%2F21.0
X-JavaScript-User-Agent: google-api-javascript-client/1.1.0-beta
X-Origin: http://foo.myapp.appspot.com
X-Referer: http://foo.myapp.appspot.com
X-Goog-Encode-Response-If-Executable: base64
Referer: https://content.googleapis.com/static/proxy.html?jsh=m%3B%2F_%2Fscs%2Fapps-static%2F_%2Fjs%2Fk%3Doz.gapi.en.l49lMhuyXyk.O%2Fm%3D__features__%2Fam%3DEQ%2Frt%3Dj%2Fd%3D1%2Frs%3DAItRSTOvD2NxxPLz0HiGHMXTek7IhOVTHg
Content-Length: 12
Connection: keep-alive
convert false
key AIzaSyCt2bxTnrxo_IGvSUCBBAN_-29HJnzX_MU
uploadType media
useContentAsIndexableText true
The responses are below. The only difference between the return Item json is that the Chrome version has a mimetype "text/html" whereas Firefox has mimetype "text/html; charset=UTF-8"
firefox response
Content-Length 2986
Content-Type application/json
Date Sat, 24 Aug 2013 10:44:37 GMT
Etag "NaUPR8AuDOKgpQqXUqmAHnRC-Nk/R_dzQ2tl2e997lu1SqOGTX63YoE"
Server HTTP Upload Server Built on Aug 7 2013 16:51:13 (1375919473)
X-Firefox-Spdy 3
"kind":"drive#file",
"id":"0B6B-RNrxsCu2cjlldTNoV01JVHc",
"etag":"\"NaUPR8AuDOKgpQqXUqmAHnRC-Nk/NM5C-3sulAfFZA1V-IIsA-E9_AA\"",
"selfLink":"https://content.googleapis.com/drive/v2/files/0B6B-RNrxsCu2cjlldTNoV01JVHc",
"webContentLink":"https://docs.google.com/uc?id=0B6B-RNrxsCu2cjlldTNoV01JVHc&export=download",
"alternateLink":"https://docs.google.com/file/d/0B6B-RNrxsCu2cjlldTNoV01JVHc/edit?usp=drivesdk",
"iconLink":"https://ssl.gstatic.com/docs/doclist/images/icon_10_generic_list.png",
"thumbnailLink":"https://lh3.googleusercontent.com/1KctCx9tjxe6vSn7piLUzfYQuNKQVzMUd6Phn8dTdlHKfQlQsXi77PyOOLkwS-0q3g=s220",
"title":"burcu",
"mimeType":"text/html; charset=UTF-8",
"labels":{
"starred":false,
"hidden":false,
"trashed":false,
"restricted":false,
"viewed":true
},
"createdDate":"2013-08-24T10:44:12.851Z",
"modifiedDate":"2013-08-24T10:44:36.440Z",
"modifiedByMeDate":"2013-08-24T10:44:36.440Z",
"lastViewedByMeDate":"2013-08-24T10:44:36.440Z",
"parents":[
{
"kind":"drive#parentReference",
"id":"0B6B-RNrxsCu2RVVQZ1NFWGZYUW8",
"selfLink":"https://content.googleapis.com/drive/v2/files/0B6B-RNrxsCu2cjlldTNoV01JVHc/parents/0B6B-RNrxsCu2RVVQZ1NFWGZYUW8",
"parentLink":"https://content.googleapis.com/drive/v2/files/0B6B-RNrxsCu2RVVQZ1NFWGZYUW8",
"isRoot":false
},
{
"kind":"drive#parentReference",
"id":"0B6B-RNrxsCu2MFZ0dEx6a2xEQU0",
"selfLink":"https://content.googleapis.com/drive/v2/files/0B6B-RNrxsCu2cjlldTNoV01JVHc/parents/0B6B-RNrxsCu2MFZ0dEx6a2xEQU0",
"parentLink":"https://content.googleapis.com/drive/v2/files/0B6B-RNrxsCu2MFZ0dEx6a2xEQU0",
"isRoot":false
}
],
"downloadUrl":"https://doc-0k-54-docs.googleusercontent.com/docs/securesc/i6kcvi4n5dug3hk78lqkpogagkdpecs6/krhjojomqafnrdg6943a1fhtnfjg4b8v/1377338400000/15125351317662028975/15125351317662028975/0B6B-RNrxsCu2cjlldTNoV01JVHc?h=16653014193614665626&e=download&gd=true",
"userPermission":{
"kind":"drive#permission",
"etag":"\"NaUPR8AuDOKgpQqXUqmAHnRC-Nk/ajH3QRzRTY6aEeYY5k2JAipDckI\"",
"id":"me",
"selfLink":"https://content.googleapis.com/drive/v2/files/0B6B-RNrxsCu2cjlldTNoV01JVHc/permissions/me",
"role":"owner",
"type":"user"
},
"originalFilename":"burcu",
"fileExtension":"",
"md5Checksum":"47088846bea0768b700fa76afc1e2aee",
"fileSize":"6",
"quotaBytesUsed":"6",
"ownerNames":[
" Demo"
],
"owners":[
{
"kind":"drive#user",
"displayName":" Demo",
"isAuthenticatedUser":true,
"permissionId":"15125351317662028975"
}
],
"lastModifyingUserName":" Demo",
"lastModifyingUser":{
"kind":"drive#user",
"displayName":" Demo",
"isAuthenticatedUser":true,
"permissionId":"15125351317662028975"
},
"editable":true,
"copyable":true,
"writersCanShare":true,
"shared":false,
"appDataContents":false,
"headRevisionId":"0B6B-RNrxsCu2MWN5clphQUlBNStwM1FLTWZWS3R0RkViVkh3PQ"
}
chrome response
content-length:
2977
content-type:
application/json
date:
Sat, 24 Aug 2013 10:48:29 GMT
etag:
"NaUPR8AuDOKgpQqXUqmAHnRC-Nk/pESqU9sAUSQgLet1Hkz2wJT0Nyw"
server:
HTTP Upload Server Built on Aug 7 2013 16:51:13 (1375919473)
status:
200 OK
version:
HTTP/1.1
{
"kind": "drive#file",
"id": "0B6B-RNrxsCu2cjlldTNoV01JVHc",
"etag": "\"NaUPR8AuDOKgpQqXUqmAHnRC-Nk/7kdHmkAGWmpQ_v_pNZFbF-GLMic\"",
"selfLink": "https://content.googleapis.com/drive/v2/files/0B6B-RNrxsCu2cjlldTNoV01JVHc",
"webContentLink": "https://docs.google.com/uc?id=0B6B-RNrxsCu2cjlldTNoV01JVHc&export=download",
"alternateLink": "https://docs.google.com/file/d/0B6B-RNrxsCu2cjlldTNoV01JVHc/edit?usp=drivesdk",
"iconLink": "https://ssl.gstatic.com/docs/doclist/images/icon_10_generic_list.png",
"thumbnailLink": "https://lh4.googleusercontent.com/AXTF6nVY78BZi00eTaAEwmdTfeXVC5Ny3zYEIVEPOTwPNGqy7LC9dKiqzZBg9-q3LA=s220",
"title": "burcu",
"mimeType": "text/html",
"labels": {
"starred": false,
"hidden": false,
"trashed": false,
"restricted": false,
"viewed": true
},
"createdDate": "2013-08-24T10:44:12.851Z",
"modifiedDate": "2013-08-24T10:48:27.913Z",
"modifiedByMeDate": "2013-08-24T10:48:27.913Z",
"lastViewedByMeDate": "2013-08-24T10:48:27.913Z",
"parents": [
{
"kind": "drive#parentReference",
"id": "0B6B-RNrxsCu2RVVQZ1NFWGZYUW8",
"selfLink": "https://content.googleapis.com/drive/v2/files/0B6B-RNrxsCu2cjlldTNoV01JVHc/parents/0B6B-RNrxsCu2RVVQZ1NFWGZYUW8",
"parentLink": "https://content.googleapis.com/drive/v2/files/0B6B-RNrxsCu2RVVQZ1NFWGZYUW8",
"isRoot": false
},
{
"kind": "drive#parentReference",
"id": "0B6B-RNrxsCu2MFZ0dEx6a2xEQU0",
"selfLink": "https://content.googleapis.com/drive/v2/files/0B6B-RNrxsCu2cjlldTNoV01JVHc/parents/0B6B-RNrxsCu2MFZ0dEx6a2xEQU0",
"parentLink": "https://content.googleapis.com/drive/v2/files/0B6B-RNrxsCu2MFZ0dEx6a2xEQU0",
"isRoot": false
}
],
"downloadUrl": "https://doc-0k-54-docs.googleusercontent.com/docs/securesc/i6kcvi4n5dug3hk78lqkpogagkdpecs6/krhjojomqafnrdg6943a1fhtnfjg4b8v/1377338400000/15125351317662028975/15125351317662028975/0B6B-RNrxsCu2cjlldTNoV01JVHc?h=16653014193614665626&e=download&gd=true",
"userPermission": {
"kind": "drive#permission",
"etag": "\"NaUPR8AuDOKgpQqXUqmAHnRC-Nk/ajH3QRzRTY6aEeYY5k2JAipDckI\"",
"id": "me",
"selfLink": "https://content.googleapis.com/drive/v2/files/0B6B-RNrxsCu2cjlldTNoV01JVHc/permissions/me",
"role": "owner",
"type": "user"
},
"originalFilename": "burcu",
"fileExtension": "",
"md5Checksum": "423f5e2804f551616956ca8cb4a684b0",
"fileSize": "9527",
"quotaBytesUsed": "9527",
"ownerNames": [
" Demo"
],
"owners": [
{
"kind": "drive#user",
"displayName": " Demo",
"isAuthenticatedUser": true,
"permissionId": "15125351317662028975"
}
],
"lastModifyingUserName": " Demo",
"lastModifyingUser": {
"kind": "drive#user",
"displayName": " Demo",
"isAuthenticatedUser": true,
"permissionId": "15125351317662028975"
},
"editable": true,
"copyable": true,
"writersCanShare": true,
"shared": false,
"appDataContents": false,
"headRevisionId": "0B6B-RNrxsCu2Zmg1M0todDBPcERUREtmTjZuQjlCQjJIOUVJPQ"
}
I'll answer my own question by saying this is a bug.
To summarise, using the GAPI Javascript client with Firefox to update content is causing the mime-type in Drive to include the character set (eg. "text/html; charset=UTF-8"). Because this doesn't match the mime-type declared in the API Console ("text/html"), the Drive webapp doesn't associate the file with my application.
The bug could be deemed to be in one of three places:-
It could be a GAPI JS client bug that it is setting the content-type header to be "text/html; charset=UTF-8".
It could be a Drive SDK bug, that the file mime type should always be the one I explicitly declared when I created the file, and should ignore the mime type header of any media uploads. Or it could be considered that the Drive SDK should strip the character set from the content-type header before using it to set the mime type on the file.
It could be a Drive webapp bug, that it should consider "text/html" and "text/html; charset=UTF-8" to be the same mime type.