This was originally raised as an issue against Google Analytics itself:
https://issuetracker.google.com/issues/35353754
It was found there that the issue is with the api client stripping the filename from the POST body, so I'm raising this as an issue here, potentially to get a better response.
@gregroberts Do you by chance have a short sample? Were you using MediaFileUpload?
media = MediaFileUpload('cow.png', mimetype='image/png',
chunksize=1024*1024, resumable=True)
farm.animals().insert(
id='cow',
name='cow.png',
media_body=media).execute()
Some more information from the issue tracker issue:
There's a short sample here, if you have not already seen it.
# Note: This code assumes you have an authorized Analytics service object.
# See the Data Import Developer Guide for details.
# This request uploads a file custom_data.csv to a particular customDataSource.
# Note that this example makes use of the MediaFileUpload Object from the
# apiclient.http module.
from apiclient.http import MediaFileUpload
try:
media = MediaFileUpload('custom_data.csv',
mimetype='application/octet-stream',
resumable=False)
daily_upload = analytics.management().uploads().uploadData(
accountId='123456',
webPropertyId='UA-123456-1',
customDataSourceId='9876654321',
media_body=media).execute()
except TypeError, error:
# Handle errors in constructing a query.
print 'There was an error in constructing your query : %s' % error
except HttpError, error:
# Handle API errors.
print ('There was an API error : %s : %s' %
(error.resp.status, error.resp.reason))
Currently working on reproducing.
Reproduced with following code:
```from __future__ import print_function
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
from httplib2 import Http
from oauth2client import file, client, tools
SCOPES = ["https://www.googleapis.com/auth/analytics"]
def main():
"""Upload custom data to Google Analytics.
"""
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
store = file.Storage("token.json")
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets("credentials.json", SCOPES)
creds = tools.run_flow(flow, store)
service = build("analytics", "v3", http=creds.authorize(Http()))
# Call the Analytics API
media = MediaFileUpload(
"data.csv", mimetype="application/octet-stream", resumable=False
)
upload = (
service.management()
.uploads()
.uploadData(
accountId="144017141",
webPropertyId="UA-144017141-1",
customDataSourceId="AbuL8x04Qg2L4flXypb1ag",
media_body=media,
)
.execute()
)
print(upload)
if __name__ == "__main__":
main()
```
No longer have access to the codebase, but the code above is exactly what I was doing.
This is still reproducible. Any workaround available?
@alvarogomezuria You can avoid this by talking to the REST API directly. See https://issuetracker.google.com/issues/35353754#comment7
Thanks for the heads up!
Rather not to talk to the REST API directly. I'll keep an eye here! Hopefully it will be resolved soon
Sorry to insist, but i'd like to know if there is any updates/anyone working on this.
Thanks in advance
Hi @alvarogomezuria. If you have a support contract with Google, please reach out that way for faster resolution. I opened another issue internally on the Analytics team with the request below.
Internal issue 138960059
Discovery document based APIs with upload methods usually take a "filename" property or parameter. It looks like the Analytics V3 API does not have this. Would it be possible to add an optional filename parameter to the uploadData method?
The gmail API discovery document for comparison.
https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest
"MessagePart": {
"id": "MessagePart",
"type": "object",
"description": "A single MIME message part.",
"properties": {
"body": {
"$ref": "MessagePartBody",
"description": "The message part body for this part, which may be empty for container MIME message parts."
},
"filename": {
"type": "string",
"description": "The filename of the attachment. Only present if this message part represents an attachment."
},
"headers": {
"type": "array",
"description": "List of headers on this message part. For the top-level message part, representing the entire message payload, it will contain the standard RFC 2822 email headers such as To, From, and Subject.",
"items": {
"$ref": "MessagePartHeader"
}
},
"mimeType": {
"type": "string",
"description": "The MIME type of the message part."
},
"partId": {
"type": "string",
"description": "The immutable ID of the message part."
},
"parts": {
"type": "array",
"description": "The child MIME message parts of this part. This only applies to container MIME message parts, for example multipart/*. For non- container MIME message part types, such as text/plain, this field is empty. For more information, see RFC 1521.",
"items": {
"$ref": "MessagePart"
}
}
}
},
A year passed, and the mistake remained.
Is it so difficult to test the code that Google develops
Closing this as there is no action that can be taken on the library side until the API surface itself is updated. Please reference https://issuetracker.google.com/issues/35353754 for status.