Using insertAll works, but it has a couple of problems;
-- if you haven't written to a table recently it could take a few minutes for your data to be loaded
-- it requires an existing table
-- if there is an error, you could end up with a situation where part of your data is loaded
-- it costs money to use (or will soon .. $1 per 10 million rows.. not much, but not free)

You may be better off using a load job with media upload.
There is an example using this here:
https://code.google.com/p/bigquery-e2e/source/browse/samples/ch06/run_load.py
If you use a MediaInMemoryUpload (see http://google-api-python-client.googlecode.com/hg/docs/epy/apiclient.http.MediaInMemoryUpload-class.html), 
you can pass an in-memory newline-delimited json buffer and don't need a file.

The advantages are that it is free, it has better error semantics (it all succeeds or none of it does, it is easier to look up what happened when there was an error since you have a job id, it will create a table at the same time if the table doesn't already exist (you'll need to include a schema, however. If you have an existing table, you don't need to provide a schema).