How to modify Google Documents using Google Drive API

I’m working with Python on Google App Engine and trying to figure out how to edit Google Docs using the Drive API v2.

Back when I used the old Documents List API, I could export a Google Doc as HTML, make changes to the HTML content, and then upload it back as either a new document or update the existing one. This was really handy for creating PDF files from templates.

Now I’m trying to do the same thing with the newer Drive API but I’m running into issues. Here’s what I’ve tried so far:

client = # authenticated http client
drive_api = build('drive', 'v2', http=client)

# fetch the document
doc = drive_api.files().get(fileId=DOCUMENT_ID).execute()

# get html content
export_url = doc['exportLinks']['text/html']
resp, html_content = client.request(export_url)

# modify the html
modified_html = html_content.replace('old_text', 'new_text')

# try to create new document
file_metadata = {'title': 'Updated Document', 
                'description': 'Modified version', 
                'mimeType': 'text/html'}
media_upload = MediaIoBaseUpload(StringIO.StringIO(modified_html), 'text/html', resumable=False)
drive_api.files().insert(body=file_metadata, media_body=media_upload)

The problem is this just creates a regular HTML file in Drive instead of converting it to a proper Google Document format. How can I make it render as an actual Google Doc like the old API did?

Also having trouble with resumable uploads - when I set resumable=True I get an error about ‘_StreamSlice’ has no len(). Any ideas on fixing this?

set the mimeType to ‘application/vnd.google-apps.document’ in your file_metadata instead of ‘text/html’. drive will convert it to a proper google doc format. fixed the same issue for me last year.

Had the same headaches migrating from Documents List API a few months ago. What finally worked was using Drive API’s import functionality instead of the regular insert method. Try drive_api.files().import_() instead of insert() - it handles HTML to Google Docs conversion way better. You’ll still need convert=True, but import gives you more control. For the resumable upload issue, encode your modified HTML content properly before passing it to MediaIoBaseUpload. Setting encoding to UTF-8 explicitly fixed most of the length calculation problems that cause StreamSlice errors.

The conversion issue happens because you’re missing the correct MIME type setup. Keep ‘text/html’ as your MediaIoBaseUpload MIME type, but add ‘convert’: True to your file_metadata. This tells Drive to automatically convert the HTML to Google Docs format.

For the resumable upload error with ‘_StreamSlice’ - switch from StringIO to BytesIO for your HTML content. Resumable uploads need accurate content length calculations, and StringIO screws this up. I hit the same problem when migrating from the Documents List API, and BytesIO fixed it.