repos: 459821110
This data as json
id | node_id | name | full_name | private | owner | html_url | description | fork | created_at | updated_at | pushed_at | homepage | size | stargazers_count | watchers_count | language | has_issues | has_projects | has_downloads | has_wiki | has_pages | forks_count | archived | disabled | open_issues_count | license | topics | forks | open_issues | watchers | default_branch | permissions | temp_clone_token | organization | network_count | subscribers_count | readme | readme_html | allow_forking | visibility | is_template | template_repository | web_commit_signoff_required | has_discussions |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
459821110 | R_kgDOG2hQNg | google-drive-to-sqlite | simonw/google-drive-to-sqlite | 0 | 9599 | https://github.com/simonw/google-drive-to-sqlite | Create a SQLite database containing metadata from Google Drive | 0 | 2022-02-16T02:16:29Z | 2022-05-17T00:30:43Z | 2022-05-21T16:56:11Z | https://datasette.io/tools/google-drive-to-sqlite | 74 | 133 | 133 | Python | 1 | 1 | 1 | 1 | 0 | 11 | 0 | 0 | 9 | apache-2.0 | [] | 11 | 9 | 133 | main | {"admin": false, "maintain": false, "push": false, "triage": false, "pull": false} | 11 | 3 | # google-drive-to-sqlite [](https://pypi.org/project/google-drive-to-sqlite/) [](https://github.com/simonw/google-drive-to-sqlite/releases) [](https://github.com/simonw/google-drive-to-sqlite/actions?query=workflow%3ATest) [](https://github.com/simonw/google-drive-to-sqlite/blob/master/LICENSE) Create a SQLite database containing metadata from [Google Drive](https://www.google.com/drive) For background on this project, see [Google Drive to SQLite](https://simonwillison.net/2022/Feb/20/google-drive-to-sqlite/) on my blog. If you use Google Drive, and especially if you have shared drives with other people there's a good chance you have hundreds or even thousands of files that you may not be fully aware of. This tool can download metadata about those files - their names, sizes, folders, content types, permissions, creation dates and more - and store them in a SQLite database. This lets you use SQL to analyze your Google Drive contents, using [Datasette](https://datasette.io/) or the SQLite command-line tool or any other SQLite database browsing software. ## Installation Install this tool using `pip`: pip install google-drive-to-sqlite ## Quickstart Authenticate with Google Drive by running: google-drive-to-sqlite auth Now create a SQLite database with metadata about all of the files you have starred using: google-drive-to-sqlite files starred.db --starred You can explore the resulting database using [Datasette](https://datasette.io/): $ pip install datasette $ datasette starred.db INFO: Started server process [24661] INFO: Uvicorn running on http://127.0.0.1:8001 ## Authentication > :warning: **This application has not yet been verified by Google** - you may find you are unable to authenticate until that verification is complete. [#10](https://github.com/simonw/google-drive-to-sqlite/issues/10) > > You can work around this issue by [creating your own OAuth client ID key](https://til.simonwillison.net/googlecloud/google-oauth-cli-application) and passing it to the `auth` command using `--google-client-id` and `--google-client-secret`. First, authenticate with Google Drive using the `auth` command: $ google-drive-to-sqlite auth Visit the following URL to authenticate with Google Drive https://accounts.google.com/o/oauth2/v2/auth?... Then return here and paste in the resulting code: Paste code here: Follow the link, sign in with Google Drive and then copy and paste the resulting code back into the tool. This will save an authentication token to the file called `auth.json` in the current directory. To specify a different location for that file, use the `--auth` option: google-drive-to-sqlite auth --auth ~/google-drive-auth.json The `auth` command also provides options for using a different scope, Google client ID and Google client secret. You can use these to create your own custom authentication tokens that can work with other Google APIs, see [issue #5](https://github.com/simonw/google-drive-to-sqlite/issues/5) for details. Full `--help`: <!-- [[[cog import cog from google_drive_to_sqlite import cli from click.testing import CliRunner runner = CliRunner() result = runner.invoke(cli.cli, ["auth", "--help"]) help = result.output.replace("Usage: cli", "Usage: google-drive-to-sqlite") cog.out( "```\n{}\n```\n".format(help) ) ]]] --> ``` Usage: google-drive-to-sqlite auth [OPTIONS] Authenticate user and save credentials Options: -a, --auth FILE Path to save token, defaults to auth.json --google-client-id TEXT Custom Google client ID --google-client-secret TEXT Custom Google client secret --scope TEXT Custom token scope --help Show this message and exit. ``` <!-- [[[end]]] --> To revoke the token that is stored in `auth.json`, such that it cannot be used to access Google Drive in the future, run the `revoke` command: google-drive-to-sqlite revoke Or if your token is stored in another location: google-drive-to-sqlite revoke -a ~/google-drive-auth.json You will need to obtain a fresh token using the `auth` command in order to continue using this tool. ## google-drive-to-sqlite files To retrieve metadata about the files in your Google Drive, or a folder or search within it, use the `google-drive-to-sqlite files` command. This will default to writing details about every file in your Google Drive to a SQLite database: google-drive-to-sqlite files files.db Files and folders will be written to databases tables, which will be created if they do not yet exist. The database schema is [shown below](#database-schema). If a file or folder already exists, based on a matching `id`, it will be replaced with fresh data. Instead of writing to SQLite you can use `--json` to output as JSON, or `--nl` to output as newline-delimited JSON: google-drive-to-sqlite files --nl Use `--folder ID` to retrieve everything in a specified folder and its sub-folders: google-drive-to-sqlite files files.db --folder 1E6Zg2X2bjjtPzVfX8YqdXZDCoB3AVA7i Use `--q QUERY` to use a [custom search query](https://developers.google.com/drive/api/v3/reference/query-ref): google-drive-to-sqlite files files.db -q "viewedByMeTime > '2022-01-01'" The following shortcut options help build queries: - `--full-text TEXT` to search for files where the full text matches a search term - `--starred` for files and folders you have starred - `--trashed` for files and folders in the trash - `--shared-with-me` for files and folders that have been shared with you - `--apps` for Google Apps documents, spreadsheets, presentations and drawings (equivalent to setting all of the next four options) - `--docs` for Google Apps documents - `--sheets` for Google Apps spreadsheets - `--presentations` for Google Apps presentations - `--drawings` for Google Apps drawings You can combine these - for example, this returns all files that you have starred and that were shared with you: google-drive-to-sqlite files highlights.db \ --starred --shared-with-me Multiple options are treated as AND, with the exception of the Google Apps options which are treated as OR - so the following would retrieve all spreadsheets and presentations that have also been starred: google-drive-to-sqlite files highlights.db \ --starred --sheets --presentations You can use `--stop-after X` to stop after retrieving X files, useful for trying out a new search pattern and seeing results straight away. The `--import-json` and `--import-nl` options are mainly useful for testing and developing this tool. They allow you to replay the JSON or newline-delimited JSON that was previously fetched using `--json` or `--nl` and use it to create a fresh SQLite database, without needing to make any outbound API calls: # Fetch all starred files from the API, write to starred.json google-drive-to-sqlite files -q 'starred = true' --json > starred.json # Now import that data into a new SQLite database file google-drive-to-sqlite files starred.db --import-json starred.json Full `--help`: <!-- [[[cog result = runner.invoke(cli.cli, ["files", "--help"]) help = result.output.replace("Usage: cli", "Usage: google-drive-to-sqlite") cog.out( "```\n{}\n```\n".format(help) ) ]]] --> ``` Usage: google-drive-to-sqlite files [OPTIONS] [DATABASE] Retrieve metadata for files in Google Drive, and write to a SQLite database or output as JSON. google-drive-to-sqlite files files.db Use --json to output JSON, --nl for newline-delimited JSON: google-drive-to-sqlite files files.db --json Use a folder ID to recursively fetch every file in that folder and its sub- folders: google-drive-to-sqlite files files.db --folder 1E6Zg2X2bjjtPzVfX8YqdXZDCoB3AVA7i Fetch files you have starred: google-drive-to-sqlite files starred.db --starred Options: -a, --auth FILE Path to auth.json token file --folder TEXT Files in this folder ID and its sub-folders -q TEXT Files matching this query --full-text TEXT Search for files with text match --starred Files you have starred --trashed Files in the trash --shared-with-me Files that have been shared with you --apps Google Apps docs, spreadsheets, presentations and drawings --docs Google Apps docs --sheets Google Apps spreadsheets --presentations Google Apps presentations --drawings Google Apps drawings --json Output JSON rather than write to DB --nl Output newline-delimited JSON rather than write to DB --stop-after INTEGER Stop paginating after X results --import-json FILE Import from this JSON file instead of the API --import-nl FILE Import from this newline-delimited JSON file -v, --verbose Send verbose output to stderr --help Show this message and exit. ``` <!-- [[[end]]] --> ## google-drive-to-sqlite download FILE_ID The `download` command can be used to download files from Google Drive. You'll need one or more file IDs, which look something like `0B32uDVNZfiEKLUtIT1gzYWN2NDI4SzVQYTFWWWxCWUtvVGNB`. To download the file, run this: google-drive-to-sqlite download 0B32uDVNZfiEKLUtIT1gzYWN2NDI4SzVQYTFWWWxCWUtvVGNB This will detect the content type of the file and use that as the extension - so if this file is a JPEG the file would be downloaded as: 0B32uDVNZfiEKLUtIT1gzYWN2NDI4SzVQYTFWWWxCWUtvVGNB.jpeg You can pass multiple file IDs to the command at once. To hide the progress bar and filename output, use `-s` or `--silent`. If you are downloading a single file you can use the `-o` output to specify a filename and location: google-drive-to-sqlite download 0B32uDVNZfiEKLUtIT1gzYWN2NDI4SzVQYTFWWWxCWUtvVGNB \ -o my-image.jpeg Use `-o -` to write the file contents to standard output: google-drive-to-sqlite download 0B32uDVNZfiEKLUtIT1gzYWN2NDI4SzVQYTFWWWxCWUtvVGNB \ -o - > my-image.jpeg Full `--help`: <!-- [[[cog result = runner.invoke(cli.cli, ["download", "--help"]) help = result.output.replace("Usage: cli", "Usage: google-drive-to-sqlite") cog.out( "```\n{}\n```\n".format(help) ) ]]] --> ``` Usage: google-drive-to-sqlite download [OPTIONS] FILE_IDS... Download one or more files to disk, based on their file IDs. The file content will be saved to a file with the name: FILE_ID.ext Where the extension is automatically picked based on the type of file. If you are downloading a single file you can specify a filename with -o: google-drive-to-sqlite download MY_FILE_ID -o myfile.txt Options: -a, --auth FILE Path to auth.json token file -o, --output FILE File to write to, or - for standard output -s, --silent Hide progress bar and filename --help Show this message and exit. ``` <!-- [[[end]]] --> ## google-drive-to-sqlite export FORMAT FILE_ID The `export` command can be used to export Google Docs documents, spreadsheets and presentations in a number of different formats. You'll need one or more document IDs, which look something like `10BOHGDUYa7lBjUSo26YFCHTpgEmtXabdVFaopCTh1vU`. You can find these by looking at the URL of your document on the Google Docs site. To export that document as PDF, run this: google-drive-to-sqlite export pdf 10BOHGDUYa7lBjUSo26YFCHTpgEmtXabdVFaopCTh1vU The file will be exported as: 10BOHGDUYa7lBjUSo26YFCHTpgEmtXabdVFaopCTh1vU-export.pdf You can pass multiple file IDs to the command at once. For the `FORMAT` option you can use any of the mime type options listed [on this page](https://developers.google.com/drive/api/v3/ref-export-formats) - for example, to export as an Open Office document you could use: google-drive-to-sqlite export \ application/vnd.oasis.opendocument.text \ 10BOHGDUYa7lBjUSo26YFCHTpgEmtXabdVFaopCTh1vU For convenience the following shortcuts for common file formats are provided: - Google Docs: `html`, `txt`, `rtf`, `pdf`, `doc`, `zip`, `epub` - Google Sheets: `xls`, `pdf`, `csv`, `tsv`, `zip` - Presentations: `ppt`, `pdf`, `txt` - Drawings: `jpeg`, `png`, `svg` The `zip` option returns a zip file of HTML. `txt` returns plain text. The others should be self-evident. To hide the filename output, use `-s` or `--silent`. If you are exporting a single file you can use the `-o` output to specify a filename and location: google-drive-to-sqlite export pdf 10BOHGDUYa7lBjUSo26YFCHTpgEmtXabdVFaopCTh1vU \ -o my-document.pdf Use `-o -` to write the file contents to standard output: google-drive-to-sqlite export pdf 10BOHGDUYa7lBjUSo26YFCHTpgEmtXabdVFaopCTh1vU \ -o - > my-document.pdf Full `--help`: <!-- [[[cog result = runner.invoke(cli.cli, ["export", "--help"]) help = result.output.replace("Usage: cli", "Usage: google-drive-to-sqlite") cog.out( "```\n{}\n```\n".format(help) ) ]]] --> ``` Usage: google-drive-to-sqlite export [OPTIONS] FORMAT FILE_IDS... Export one or more files to the specified format. Usage: google-drive-to-sqlite export pdf FILE_ID_1 FILE_ID_2 The file content will be saved to a file with the name: FILE_ID-export.ext Where the extension is based on the format you specified. Available export formats can be seen here: https://developers.google.com/drive/api/v3/ref-export-formats Or you can use one of the following shortcuts: - Google Docs: html, txt, rtf, pdf, doc, zip, epub - Google Sheets: xls, pdf, csv, tsv, zip - Presentations: ppt, pdf, txt - Drawings: jpeg, png, svg "zip" returns a zip file of HTML. If you are exporting a single file you can specify a filename with -o: google-drive-to-sqlite export zip MY_FILE_ID -o myfile.zip Options: -a, --auth FILE Path to auth.json token file -o, --output FILE File to write to, or - for standard output -s, --silent Hide progress bar and filename --help Show this message and exit. ``` <!-- [[[end]]] --> ## google-drive-to-sqlite get URL The `get` command makes authenticated requests to the specified URL, using credentials derived from the `auth.json` file. For example: $ google-drive-to-sqlite get 'https://www.googleapis.com/drive/v3/about?fields=*' { "kind": "drive#about", "user": { "kind": "drive#user", "displayName": "Simon Willison", # ... If the resource you are fetching supports pagination you can use `--paginate key` to paginate through all of the rows in a specified key. For example, the following API has a `nextPageToken` key and a `files` list, suggesting it supports pagination: $ google-drive-to-sqlite get https://www.googleapis.com/drive/v3/files { "kind": "drive#fileList", "nextPageToken": "~!!~AI9...wogHHYlc=", "incompleteSearch": false, "files": [ { "kind": "drive#file", "id": "1YEsITp_X8PtDUJWHGM0osT-TXAU1nr0e7RSWRM2Jpyg", "name": "Title of a spreadsheet", "mimeType": "application/vnd.google-apps.spreadsheet" }, To paginate through everything in the `files` list you would use `--paginate files` like this: $ google-drive-to-sqlite get https://www.googleapis.com/drive/v3/files --paginate files [ { "kind": "drive#file", "id": "1YEsITp_X8PtDUJWHGM0osT-TXAU1nr0e7RSWRM2Jpyg", "name": "Title of a spreadsheet", "mimeType": "application/vnd.google-apps.spreadsheet" }, # ... Add `--nl` to stream paginated data as newline-delimited JSON: $ google-drive-to-sqlite get https://www.googleapis.com/drive/v3/files --paginate files --nl {"kind": "drive#file", "id": "1YEsITp_X8PtDUJWHGM0osT-TXAU1nr0e7RSWRM2Jpyg", "name": "Title of a spreadsheet", "mimeType": "application/vnd.google-apps.spreadsheet"} {"kind": "drive#file", "id": "1E6Zg2X2bjjtPzVfX8YqdXZDCoB3AVA7i", "name": "Subfolder", "mimeType": "application/vnd.google-apps.folder"} Add `--stop-after 5` to stop after 5 records - useful for testing. Full `--help`: <!-- [[[cog result = runner.invoke(cli.cli, ["get", "--help"]) help = result.output.replace("Usage: cli", "Usage: google-drive-to-sqlite") cog.out( "```\n{}\n```\n".format(help) ) ]]] --> ``` Usage: google-drive-to-sqlite get [OPTIONS] URL Make an authenticated HTTP GET to the specified URL Options: -a, --auth FILE Path to auth.json token file --paginate TEXT Paginate through all results in this key --nl Output paginated data as newline-delimited JSON --stop-after INTEGER Stop paginating after X results -v, --verbose Send verbose output to stderr --help Show this message and exit. ``` <!-- [[[end]]] --> ## Database schema The database created by this tool has the following schema: <!-- [[[cog import tempfile, pathlib, sqlite_utils tmpdir = pathlib.Path(tempfile.mkdtemp()) db_path = str(tmpdir / "docs.db") result = runner.invoke(cli.cli, [ "files", db_path, "--import-json", "tests/folder-and-children.json" ]) cog.out("```sql\n") schema = sqlite_utils.Database(db_path).schema # Tidy up some formatting schema = schema.replace(", [", ",\n [") schema = schema.replace("\n,\n", ",\n") schema = schema.replace("TEXT);", "TEXT\n);") cog.out(schema) cog.out("\n```") ]]] --> ```sql CREATE TABLE [drive_users] ( [permissionId] TEXT PRIMARY KEY, [kind] TEXT, [displayName] TEXT, [photoLink] TEXT, [me] INTEGER, [emailAddress] TEXT ); CREATE TABLE [drive_folders] ( [id] TEXT PRIMARY KEY, [_parent] TEXT, [_owner] TEXT, [lastModifyingUser] TEXT, [kind] TEXT, [name] TEXT, [mimeType] TEXT, [starred] INTEGER, [trashed] INTEGER, [explicitlyTrashed] INTEGER, [parents] TEXT, [spaces] TEXT, [version] TEXT, [webViewLink] TEXT, [iconLink] TEXT, [hasThumbnail] INTEGER, [thumbnailVersion] TEXT, [viewedByMe] INTEGER, [createdTime] TEXT, [modifiedTime] TEXT, [modifiedByMe] INTEGER, [shared] INTEGER, [ownedByMe] INTEGER, [viewersCanCopyContent] INTEGER, [copyRequiresWriterPermission] INTEGER, [writersCanShare] INTEGER, [folderColorRgb] TEXT, [quotaBytesUsed] TEXT, [isAppAuthorized] INTEGER, [linkShareMetadata] TEXT, FOREIGN KEY([_parent]) REFERENCES [drive_folders]([id]), FOREIGN KEY([_owner]) REFERENCES [drive_users]([permissionId]), FOREIGN KEY([lastModifyingUser]) REFERENCES [drive_users]([permissionId]) ); CREATE TABLE [drive_files] ( [id] TEXT PRIMARY KEY, [_parent] TEXT, [_owner] TEXT, [lastModifyingUser] TEXT, [kind] TEXT, [name] TEXT, [mimeType] TEXT, [starred] INTEGER, [trashed] INTEGER, [explicitlyTrashed] INTEGER, [parents] TEXT, [spaces] TEXT, [version] TEXT, [webViewLink] TEXT, [iconLink] TEXT, [hasThumbnail] INTEGER, [thumbnailVersion] TEXT, [viewedByMe] INTEGER, [createdTime] TEXT, [modifiedTime] TEXT, [modifiedByMe] INTEGER, [shared] INTEGER, [ownedByMe] INTEGER, [viewersCanCopyContent] INTEGER, [copyRequiresWriterPermission] INTEGER, [writersCanShare] INTEGER, [quotaBytesUsed] TEXT, [isAppAuthorized] INTEGER, [linkShareMetadata] TEXT, FOREIGN KEY([_parent]) REFERENCES [drive_folders]([id]), FOREIGN KEY([_owner]) REFERENCES [drive_users]([permissionId]), FOREIGN KEY([lastModifyingUser]) REFERENCES [drive_users]([permissionId]) ); ``` <!-- [[[end]]] --> ## Thumbnails You can construct a thumbnail image for a known file ID using the following URL: https://drive.google.com/thumbnail?sz=w800-h800&id=FILE_ID Users who are signed into Google Drive and have permission to view a file will be redirected to a thumbnail version of that file. You can tweak the `w800` and `h800` parameters to request different thumbnail sizes. ## Privacy policy This tool requests access to your Google Drive account in order to retrieve metadata about your files there. It also offers a feature that can download the content of those files. The credentials used to access your account are stored in the `auth.json` file on your computer. The metadata and content retrieved from Google Drive is also stored only on your own personal computer. At no point do the developers of this tool gain access to any of your data. ## Development To contribute to this tool, first checkout the code. Then create a new virtual environment: cd google-drive-to-sqlite python -m venv venv source venv/bin/activate Or if you are using `pipenv`: pipenv shell Now install the dependencies and test dependencies: pip install -e '.[test]' To run the tests: pytest | <div id="readme" class="md" data-path="README.md"><article class="markdown-body entry-content container-lg" itemprop="text"><h1 dir="auto"><a id="user-content-google-drive-to-sqlite" class="anchor" aria-hidden="true" href="#user-content-google-drive-to-sqlite"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>google-drive-to-sqlite</h1> <p dir="auto"><a href="https://pypi.org/project/google-drive-to-sqlite/" rel="nofollow"><img src="https://camo.githubusercontent.com/18fcd4b2930251d5e234ec0832e9dd82dde2d7b5bfc9dc31387e22107a1da0a3/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f676f6f676c652d64726976652d746f2d73716c6974652e737667" alt="PyPI" data-canonical-src="https://img.shields.io/pypi/v/google-drive-to-sqlite.svg" style="max-width: 100%;"></a> <a href="https://github.com/simonw/google-drive-to-sqlite/releases"><img src="https://camo.githubusercontent.com/7c733ea3efff14b60d66656573c9bdc05d5d6a2d84ec3fdec73cef08685decf1/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f73696d6f6e772f676f6f676c652d64726976652d746f2d73716c6974653f696e636c7564655f70726572656c6561736573266c6162656c3d6368616e67656c6f67" alt="Changelog" data-canonical-src="https://img.shields.io/github/v/release/simonw/google-drive-to-sqlite?include_prereleases&label=changelog" style="max-width: 100%;"></a> <a href="https://github.com/simonw/google-drive-to-sqlite/actions?query=workflow%3ATest"><img src="https://github.com/simonw/google-drive-to-sqlite/workflows/Test/badge.svg" alt="Tests" style="max-width: 100%;"></a> <a href="https://github.com/simonw/google-drive-to-sqlite/blob/master/LICENSE"><img src="https://camo.githubusercontent.com/1698104e976c681143eb0841f9675c6f802bb7aa832afc0c7a4e719b1f3cf955/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d417061636865253230322e302d626c75652e737667" alt="License" data-canonical-src="https://img.shields.io/badge/license-Apache%202.0-blue.svg" style="max-width: 100%;"></a></p> <p dir="auto">Create a SQLite database containing metadata from <a href="https://www.google.com/drive" rel="nofollow">Google Drive</a></p> <p dir="auto">For background on this project, see <a href="https://simonwillison.net/2022/Feb/20/google-drive-to-sqlite/" rel="nofollow">Google Drive to SQLite</a> on my blog.</p> <p dir="auto">If you use Google Drive, and especially if you have shared drives with other people there's a good chance you have hundreds or even thousands of files that you may not be fully aware of.</p> <p dir="auto">This tool can download metadata about those files - their names, sizes, folders, content types, permissions, creation dates and more - and store them in a SQLite database.</p> <p dir="auto">This lets you use SQL to analyze your Google Drive contents, using <a href="https://datasette.io/" rel="nofollow">Datasette</a> or the SQLite command-line tool or any other SQLite database browsing software.</p> <h2 dir="auto"><a id="user-content-installation" class="anchor" aria-hidden="true" href="#user-content-installation"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Installation</h2> <p dir="auto">Install this tool using <code>pip</code>:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="pip install google-drive-to-sqlite"><pre class="notranslate"><code>pip install google-drive-to-sqlite </code></pre></div> <h2 dir="auto"><a id="user-content-quickstart" class="anchor" aria-hidden="true" href="#user-content-quickstart"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Quickstart</h2> <p dir="auto">Authenticate with Google Drive by running:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="google-drive-to-sqlite auth"><pre class="notranslate"><code>google-drive-to-sqlite auth </code></pre></div> <p dir="auto">Now create a SQLite database with metadata about all of the files you have starred using:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="google-drive-to-sqlite files starred.db --starred"><pre class="notranslate"><code>google-drive-to-sqlite files starred.db --starred </code></pre></div> <p dir="auto">You can explore the resulting database using <a href="https://datasette.io/" rel="nofollow">Datasette</a>:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ pip install datasette $ datasette starred.db INFO: Started server process [24661] INFO: Uvicorn running on http://127.0.0.1:8001"><pre class="notranslate"><code>$ pip install datasette $ datasette starred.db INFO: Started server process [24661] INFO: Uvicorn running on http://127.0.0.1:8001 </code></pre></div> <h2 dir="auto"><a id="user-content-authentication" class="anchor" aria-hidden="true" href="#user-content-authentication"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Authentication</h2> <blockquote> <p dir="auto"><g-emoji class="g-emoji" alias="warning" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/26a0.png">⚠️</g-emoji> <strong>This application has not yet been verified by Google</strong> - you may find you are unable to authenticate until that verification is complete. <a href="https://github.com/simonw/google-drive-to-sqlite/issues/10" data-hovercard-type="issue" data-hovercard-url="/simonw/google-drive-to-sqlite/issues/10/hovercard">#10</a></p> <p dir="auto">You can work around this issue by <a href="https://til.simonwillison.net/googlecloud/google-oauth-cli-application" rel="nofollow">creating your own OAuth client ID key</a> and passing it to the <code>auth</code> command using <code>--google-client-id</code> and <code>--google-client-secret</code>.</p> </blockquote> <p dir="auto">First, authenticate with Google Drive using the <code>auth</code> command:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ google-drive-to-sqlite auth Visit the following URL to authenticate with Google Drive https://accounts.google.com/o/oauth2/v2/auth?... Then return here and paste in the resulting code: Paste code here: "><pre class="notranslate"><code>$ google-drive-to-sqlite auth Visit the following URL to authenticate with Google Drive https://accounts.google.com/o/oauth2/v2/auth?... Then return here and paste in the resulting code: Paste code here: </code></pre></div> <p dir="auto">Follow the link, sign in with Google Drive and then copy and paste the resulting code back into the tool.</p> <p dir="auto">This will save an authentication token to the file called <code>auth.json</code> in the current directory.</p> <p dir="auto">To specify a different location for that file, use the <code>--auth</code> option:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="google-drive-to-sqlite auth --auth ~/google-drive-auth.json"><pre class="notranslate"><code>google-drive-to-sqlite auth --auth ~/google-drive-auth.json </code></pre></div> <p dir="auto">The <code>auth</code> command also provides options for using a different scope, Google client ID and Google client secret. You can use these to create your own custom authentication tokens that can work with other Google APIs, see <a href="https://github.com/simonw/google-drive-to-sqlite/issues/5" data-hovercard-type="issue" data-hovercard-url="/simonw/google-drive-to-sqlite/issues/5/hovercard">issue #5</a> for details.</p> <p dir="auto">Full <code>--help</code>:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Usage: google-drive-to-sqlite auth [OPTIONS] Authenticate user and save credentials Options: -a, --auth FILE Path to save token, defaults to auth.json --google-client-id TEXT Custom Google client ID --google-client-secret TEXT Custom Google client secret --scope TEXT Custom token scope --help Show this message and exit. "><pre class="notranslate"><code>Usage: google-drive-to-sqlite auth [OPTIONS] Authenticate user and save credentials Options: -a, --auth FILE Path to save token, defaults to auth.json --google-client-id TEXT Custom Google client ID --google-client-secret TEXT Custom Google client secret --scope TEXT Custom token scope --help Show this message and exit. </code></pre></div> <p dir="auto">To revoke the token that is stored in <code>auth.json</code>, such that it cannot be used to access Google Drive in the future, run the <code>revoke</code> command:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="google-drive-to-sqlite revoke"><pre class="notranslate"><code>google-drive-to-sqlite revoke </code></pre></div> <p dir="auto">Or if your token is stored in another location:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="google-drive-to-sqlite revoke -a ~/google-drive-auth.json"><pre class="notranslate"><code>google-drive-to-sqlite revoke -a ~/google-drive-auth.json </code></pre></div> <p dir="auto">You will need to obtain a fresh token using the <code>auth</code> command in order to continue using this tool.</p> <h2 dir="auto"><a id="user-content-google-drive-to-sqlite-files" class="anchor" aria-hidden="true" href="#user-content-google-drive-to-sqlite-files"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>google-drive-to-sqlite files</h2> <p dir="auto">To retrieve metadata about the files in your Google Drive, or a folder or search within it, use the <code>google-drive-to-sqlite files</code> command.</p> <p dir="auto">This will default to writing details about every file in your Google Drive to a SQLite database:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="google-drive-to-sqlite files files.db"><pre class="notranslate"><code>google-drive-to-sqlite files files.db </code></pre></div> <p dir="auto">Files and folders will be written to databases tables, which will be created if they do not yet exist. The database schema is <a href="#user-content-database-schema">shown below</a>.</p> <p dir="auto">If a file or folder already exists, based on a matching <code>id</code>, it will be replaced with fresh data.</p> <p dir="auto">Instead of writing to SQLite you can use <code>--json</code> to output as JSON, or <code>--nl</code> to output as newline-delimited JSON:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="google-drive-to-sqlite files --nl"><pre class="notranslate"><code>google-drive-to-sqlite files --nl </code></pre></div> <p dir="auto">Use <code>--folder ID</code> to retrieve everything in a specified folder and its sub-folders:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="google-drive-to-sqlite files files.db --folder 1E6Zg2X2bjjtPzVfX8YqdXZDCoB3AVA7i"><pre class="notranslate"><code>google-drive-to-sqlite files files.db --folder 1E6Zg2X2bjjtPzVfX8YqdXZDCoB3AVA7i </code></pre></div> <p dir="auto">Use <code>--q QUERY</code> to use a <a href="https://developers.google.com/drive/api/v3/reference/query-ref" rel="nofollow">custom search query</a>:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="google-drive-to-sqlite files files.db -q "viewedByMeTime > '2022-01-01'""><pre class="notranslate"><code>google-drive-to-sqlite files files.db -q "viewedByMeTime > '2022-01-01'" </code></pre></div> <p dir="auto">The following shortcut options help build queries:</p> <ul dir="auto"> <li><code>--full-text TEXT</code> to search for files where the full text matches a search term</li> <li><code>--starred</code> for files and folders you have starred</li> <li><code>--trashed</code> for files and folders in the trash</li> <li><code>--shared-with-me</code> for files and folders that have been shared with you</li> <li><code>--apps</code> for Google Apps documents, spreadsheets, presentations and drawings (equivalent to setting all of the next four options)</li> <li><code>--docs</code> for Google Apps documents</li> <li><code>--sheets</code> for Google Apps spreadsheets</li> <li><code>--presentations</code> for Google Apps presentations</li> <li><code>--drawings</code> for Google Apps drawings</li> </ul> <p dir="auto">You can combine these - for example, this returns all files that you have starred and that were shared with you:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="google-drive-to-sqlite files highlights.db \ --starred --shared-with-me"><pre class="notranslate"><code>google-drive-to-sqlite files highlights.db \ --starred --shared-with-me </code></pre></div> <p dir="auto">Multiple options are treated as AND, with the exception of the Google Apps options which are treated as OR - so the following would retrieve all spreadsheets and presentations that have also been starred:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="google-drive-to-sqlite files highlights.db \ --starred --sheets --presentations"><pre class="notranslate"><code>google-drive-to-sqlite files highlights.db \ --starred --sheets --presentations </code></pre></div> <p dir="auto">You can use <code>--stop-after X</code> to stop after retrieving X files, useful for trying out a new search pattern and seeing results straight away.</p> <p dir="auto">The <code>--import-json</code> and <code>--import-nl</code> options are mainly useful for testing and developing this tool. They allow you to replay the JSON or newline-delimited JSON that was previously fetched using <code>--json</code> or <code>--nl</code> and use it to create a fresh SQLite database, without needing to make any outbound API calls:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="# Fetch all starred files from the API, write to starred.json google-drive-to-sqlite files -q 'starred = true' --json > starred.json # Now import that data into a new SQLite database file google-drive-to-sqlite files starred.db --import-json starred.json"><pre class="notranslate"><code># Fetch all starred files from the API, write to starred.json google-drive-to-sqlite files -q 'starred = true' --json > starred.json # Now import that data into a new SQLite database file google-drive-to-sqlite files starred.db --import-json starred.json </code></pre></div> <p dir="auto">Full <code>--help</code>:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Usage: google-drive-to-sqlite files [OPTIONS] [DATABASE] Retrieve metadata for files in Google Drive, and write to a SQLite database or output as JSON. google-drive-to-sqlite files files.db Use --json to output JSON, --nl for newline-delimited JSON: google-drive-to-sqlite files files.db --json Use a folder ID to recursively fetch every file in that folder and its sub- folders: google-drive-to-sqlite files files.db --folder 1E6Zg2X2bjjtPzVfX8YqdXZDCoB3AVA7i Fetch files you have starred: google-drive-to-sqlite files starred.db --starred Options: -a, --auth FILE Path to auth.json token file --folder TEXT Files in this folder ID and its sub-folders -q TEXT Files matching this query --full-text TEXT Search for files with text match --starred Files you have starred --trashed Files in the trash --shared-with-me Files that have been shared with you --apps Google Apps docs, spreadsheets, presentations and drawings --docs Google Apps docs --sheets Google Apps spreadsheets --presentations Google Apps presentations --drawings Google Apps drawings --json Output JSON rather than write to DB --nl Output newline-delimited JSON rather than write to DB --stop-after INTEGER Stop paginating after X results --import-json FILE Import from this JSON file instead of the API --import-nl FILE Import from this newline-delimited JSON file -v, --verbose Send verbose output to stderr --help Show this message and exit. "><pre class="notranslate"><code>Usage: google-drive-to-sqlite files [OPTIONS] [DATABASE] Retrieve metadata for files in Google Drive, and write to a SQLite database or output as JSON. google-drive-to-sqlite files files.db Use --json to output JSON, --nl for newline-delimited JSON: google-drive-to-sqlite files files.db --json Use a folder ID to recursively fetch every file in that folder and its sub- folders: google-drive-to-sqlite files files.db --folder 1E6Zg2X2bjjtPzVfX8YqdXZDCoB3AVA7i Fetch files you have starred: google-drive-to-sqlite files starred.db --starred Options: -a, --auth FILE Path to auth.json token file --folder TEXT Files in this folder ID and its sub-folders -q TEXT Files matching this query --full-text TEXT Search for files with text match --starred Files you have starred --trashed Files in the trash --shared-with-me Files that have been shared with you --apps Google Apps docs, spreadsheets, presentations and drawings --docs Google Apps docs --sheets Google Apps spreadsheets --presentations Google Apps presentations --drawings Google Apps drawings --json Output JSON rather than write to DB --nl Output newline-delimited JSON rather than write to DB --stop-after INTEGER Stop paginating after X results --import-json FILE Import from this JSON file instead of the API --import-nl FILE Import from this newline-delimited JSON file -v, --verbose Send verbose output to stderr --help Show this message and exit. </code></pre></div> <h2 dir="auto"><a id="user-content-google-drive-to-sqlite-download-file_id" class="anchor" aria-hidden="true" href="#user-content-google-drive-to-sqlite-download-file_id"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>google-drive-to-sqlite download FILE_ID</h2> <p dir="auto">The <code>download</code> command can be used to download files from Google Drive.</p> <p dir="auto">You'll need one or more file IDs, which look something like <code>0B32uDVNZfiEKLUtIT1gzYWN2NDI4SzVQYTFWWWxCWUtvVGNB</code>.</p> <p dir="auto">To download the file, run this:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="google-drive-to-sqlite download 0B32uDVNZfiEKLUtIT1gzYWN2NDI4SzVQYTFWWWxCWUtvVGNB"><pre class="notranslate"><code>google-drive-to-sqlite download 0B32uDVNZfiEKLUtIT1gzYWN2NDI4SzVQYTFWWWxCWUtvVGNB </code></pre></div> <p dir="auto">This will detect the content type of the file and use that as the extension - so if this file is a JPEG the file would be downloaded as:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="0B32uDVNZfiEKLUtIT1gzYWN2NDI4SzVQYTFWWWxCWUtvVGNB.jpeg"><pre class="notranslate"><code>0B32uDVNZfiEKLUtIT1gzYWN2NDI4SzVQYTFWWWxCWUtvVGNB.jpeg </code></pre></div> <p dir="auto">You can pass multiple file IDs to the command at once.</p> <p dir="auto">To hide the progress bar and filename output, use <code>-s</code> or <code>--silent</code>.</p> <p dir="auto">If you are downloading a single file you can use the <code>-o</code> output to specify a filename and location:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="google-drive-to-sqlite download 0B32uDVNZfiEKLUtIT1gzYWN2NDI4SzVQYTFWWWxCWUtvVGNB \ -o my-image.jpeg"><pre class="notranslate"><code>google-drive-to-sqlite download 0B32uDVNZfiEKLUtIT1gzYWN2NDI4SzVQYTFWWWxCWUtvVGNB \ -o my-image.jpeg </code></pre></div> <p dir="auto">Use <code>-o -</code> to write the file contents to standard output:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="google-drive-to-sqlite download 0B32uDVNZfiEKLUtIT1gzYWN2NDI4SzVQYTFWWWxCWUtvVGNB \ -o - > my-image.jpeg"><pre class="notranslate"><code>google-drive-to-sqlite download 0B32uDVNZfiEKLUtIT1gzYWN2NDI4SzVQYTFWWWxCWUtvVGNB \ -o - > my-image.jpeg </code></pre></div> <p dir="auto">Full <code>--help</code>:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Usage: google-drive-to-sqlite download [OPTIONS] FILE_IDS... Download one or more files to disk, based on their file IDs. The file content will be saved to a file with the name: FILE_ID.ext Where the extension is automatically picked based on the type of file. If you are downloading a single file you can specify a filename with -o: google-drive-to-sqlite download MY_FILE_ID -o myfile.txt Options: -a, --auth FILE Path to auth.json token file -o, --output FILE File to write to, or - for standard output -s, --silent Hide progress bar and filename --help Show this message and exit. "><pre class="notranslate"><code>Usage: google-drive-to-sqlite download [OPTIONS] FILE_IDS... Download one or more files to disk, based on their file IDs. The file content will be saved to a file with the name: FILE_ID.ext Where the extension is automatically picked based on the type of file. If you are downloading a single file you can specify a filename with -o: google-drive-to-sqlite download MY_FILE_ID -o myfile.txt Options: -a, --auth FILE Path to auth.json token file -o, --output FILE File to write to, or - for standard output -s, --silent Hide progress bar and filename --help Show this message and exit. </code></pre></div> <h2 dir="auto"><a id="user-content-google-drive-to-sqlite-export-format-file_id" class="anchor" aria-hidden="true" href="#user-content-google-drive-to-sqlite-export-format-file_id"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>google-drive-to-sqlite export FORMAT FILE_ID</h2> <p dir="auto">The <code>export</code> command can be used to export Google Docs documents, spreadsheets and presentations in a number of different formats.</p> <p dir="auto">You'll need one or more document IDs, which look something like <code>10BOHGDUYa7lBjUSo26YFCHTpgEmtXabdVFaopCTh1vU</code>. You can find these by looking at the URL of your document on the Google Docs site.</p> <p dir="auto">To export that document as PDF, run this:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="google-drive-to-sqlite export pdf 10BOHGDUYa7lBjUSo26YFCHTpgEmtXabdVFaopCTh1vU"><pre class="notranslate"><code>google-drive-to-sqlite export pdf 10BOHGDUYa7lBjUSo26YFCHTpgEmtXabdVFaopCTh1vU </code></pre></div> <p dir="auto">The file will be exported as:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="10BOHGDUYa7lBjUSo26YFCHTpgEmtXabdVFaopCTh1vU-export.pdf"><pre class="notranslate"><code>10BOHGDUYa7lBjUSo26YFCHTpgEmtXabdVFaopCTh1vU-export.pdf </code></pre></div> <p dir="auto">You can pass multiple file IDs to the command at once.</p> <p dir="auto">For the <code>FORMAT</code> option you can use any of the mime type options listed <a href="https://developers.google.com/drive/api/v3/ref-export-formats" rel="nofollow">on this page</a> - for example, to export as an Open Office document you could use:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="google-drive-to-sqlite export \ application/vnd.oasis.opendocument.text \ 10BOHGDUYa7lBjUSo26YFCHTpgEmtXabdVFaopCTh1vU"><pre class="notranslate"><code>google-drive-to-sqlite export \ application/vnd.oasis.opendocument.text \ 10BOHGDUYa7lBjUSo26YFCHTpgEmtXabdVFaopCTh1vU </code></pre></div> <p dir="auto">For convenience the following shortcuts for common file formats are provided:</p> <ul dir="auto"> <li>Google Docs: <code>html</code>, <code>txt</code>, <code>rtf</code>, <code>pdf</code>, <code>doc</code>, <code>zip</code>, <code>epub</code></li> <li>Google Sheets: <code>xls</code>, <code>pdf</code>, <code>csv</code>, <code>tsv</code>, <code>zip</code></li> <li>Presentations: <code>ppt</code>, <code>pdf</code>, <code>txt</code></li> <li>Drawings: <code>jpeg</code>, <code>png</code>, <code>svg</code></li> </ul> <p dir="auto">The <code>zip</code> option returns a zip file of HTML. <code>txt</code> returns plain text. The others should be self-evident.</p> <p dir="auto">To hide the filename output, use <code>-s</code> or <code>--silent</code>.</p> <p dir="auto">If you are exporting a single file you can use the <code>-o</code> output to specify a filename and location:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="google-drive-to-sqlite export pdf 10BOHGDUYa7lBjUSo26YFCHTpgEmtXabdVFaopCTh1vU \ -o my-document.pdf"><pre class="notranslate"><code>google-drive-to-sqlite export pdf 10BOHGDUYa7lBjUSo26YFCHTpgEmtXabdVFaopCTh1vU \ -o my-document.pdf </code></pre></div> <p dir="auto">Use <code>-o -</code> to write the file contents to standard output:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="google-drive-to-sqlite export pdf 10BOHGDUYa7lBjUSo26YFCHTpgEmtXabdVFaopCTh1vU \ -o - > my-document.pdf"><pre class="notranslate"><code>google-drive-to-sqlite export pdf 10BOHGDUYa7lBjUSo26YFCHTpgEmtXabdVFaopCTh1vU \ -o - > my-document.pdf </code></pre></div> <p dir="auto">Full <code>--help</code>:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Usage: google-drive-to-sqlite export [OPTIONS] FORMAT FILE_IDS... Export one or more files to the specified format. Usage: google-drive-to-sqlite export pdf FILE_ID_1 FILE_ID_2 The file content will be saved to a file with the name: FILE_ID-export.ext Where the extension is based on the format you specified. Available export formats can be seen here: https://developers.google.com/drive/api/v3/ref-export-formats Or you can use one of the following shortcuts: - Google Docs: html, txt, rtf, pdf, doc, zip, epub - Google Sheets: xls, pdf, csv, tsv, zip - Presentations: ppt, pdf, txt - Drawings: jpeg, png, svg "zip" returns a zip file of HTML. If you are exporting a single file you can specify a filename with -o: google-drive-to-sqlite export zip MY_FILE_ID -o myfile.zip Options: -a, --auth FILE Path to auth.json token file -o, --output FILE File to write to, or - for standard output -s, --silent Hide progress bar and filename --help Show this message and exit. "><pre class="notranslate"><code>Usage: google-drive-to-sqlite export [OPTIONS] FORMAT FILE_IDS... Export one or more files to the specified format. Usage: google-drive-to-sqlite export pdf FILE_ID_1 FILE_ID_2 The file content will be saved to a file with the name: FILE_ID-export.ext Where the extension is based on the format you specified. Available export formats can be seen here: https://developers.google.com/drive/api/v3/ref-export-formats Or you can use one of the following shortcuts: - Google Docs: html, txt, rtf, pdf, doc, zip, epub - Google Sheets: xls, pdf, csv, tsv, zip - Presentations: ppt, pdf, txt - Drawings: jpeg, png, svg "zip" returns a zip file of HTML. If you are exporting a single file you can specify a filename with -o: google-drive-to-sqlite export zip MY_FILE_ID -o myfile.zip Options: -a, --auth FILE Path to auth.json token file -o, --output FILE File to write to, or - for standard output -s, --silent Hide progress bar and filename --help Show this message and exit. </code></pre></div> <h2 dir="auto"><a id="user-content-google-drive-to-sqlite-get-url" class="anchor" aria-hidden="true" href="#user-content-google-drive-to-sqlite-get-url"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>google-drive-to-sqlite get URL</h2> <p dir="auto">The <code>get</code> command makes authenticated requests to the specified URL, using credentials derived from the <code>auth.json</code> file.</p> <p dir="auto">For example:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ google-drive-to-sqlite get 'https://www.googleapis.com/drive/v3/about?fields=*' { "kind": "drive#about", "user": { "kind": "drive#user", "displayName": "Simon Willison", # ..."><pre class="notranslate"><code>$ google-drive-to-sqlite get 'https://www.googleapis.com/drive/v3/about?fields=*' { "kind": "drive#about", "user": { "kind": "drive#user", "displayName": "Simon Willison", # ... </code></pre></div> <p dir="auto">If the resource you are fetching supports pagination you can use <code>--paginate key</code> to paginate through all of the rows in a specified key. For example, the following API has a <code>nextPageToken</code> key and a <code>files</code> list, suggesting it supports pagination:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ google-drive-to-sqlite get https://www.googleapis.com/drive/v3/files { "kind": "drive#fileList", "nextPageToken": "~!!~AI9...wogHHYlc=", "incompleteSearch": false, "files": [ { "kind": "drive#file", "id": "1YEsITp_X8PtDUJWHGM0osT-TXAU1nr0e7RSWRM2Jpyg", "name": "Title of a spreadsheet", "mimeType": "application/vnd.google-apps.spreadsheet" },"><pre class="notranslate"><code>$ google-drive-to-sqlite get https://www.googleapis.com/drive/v3/files { "kind": "drive#fileList", "nextPageToken": "~!!~AI9...wogHHYlc=", "incompleteSearch": false, "files": [ { "kind": "drive#file", "id": "1YEsITp_X8PtDUJWHGM0osT-TXAU1nr0e7RSWRM2Jpyg", "name": "Title of a spreadsheet", "mimeType": "application/vnd.google-apps.spreadsheet" }, </code></pre></div> <p dir="auto">To paginate through everything in the <code>files</code> list you would use <code>--paginate files</code> like this:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ google-drive-to-sqlite get https://www.googleapis.com/drive/v3/files --paginate files [ { "kind": "drive#file", "id": "1YEsITp_X8PtDUJWHGM0osT-TXAU1nr0e7RSWRM2Jpyg", "name": "Title of a spreadsheet", "mimeType": "application/vnd.google-apps.spreadsheet" }, # ..."><pre class="notranslate"><code>$ google-drive-to-sqlite get https://www.googleapis.com/drive/v3/files --paginate files [ { "kind": "drive#file", "id": "1YEsITp_X8PtDUJWHGM0osT-TXAU1nr0e7RSWRM2Jpyg", "name": "Title of a spreadsheet", "mimeType": "application/vnd.google-apps.spreadsheet" }, # ... </code></pre></div> <p dir="auto">Add <code>--nl</code> to stream paginated data as newline-delimited JSON:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ google-drive-to-sqlite get https://www.googleapis.com/drive/v3/files --paginate files --nl {"kind": "drive#file", "id": "1YEsITp_X8PtDUJWHGM0osT-TXAU1nr0e7RSWRM2Jpyg", "name": "Title of a spreadsheet", "mimeType": "application/vnd.google-apps.spreadsheet"} {"kind": "drive#file", "id": "1E6Zg2X2bjjtPzVfX8YqdXZDCoB3AVA7i", "name": "Subfolder", "mimeType": "application/vnd.google-apps.folder"}"><pre class="notranslate"><code>$ google-drive-to-sqlite get https://www.googleapis.com/drive/v3/files --paginate files --nl {"kind": "drive#file", "id": "1YEsITp_X8PtDUJWHGM0osT-TXAU1nr0e7RSWRM2Jpyg", "name": "Title of a spreadsheet", "mimeType": "application/vnd.google-apps.spreadsheet"} {"kind": "drive#file", "id": "1E6Zg2X2bjjtPzVfX8YqdXZDCoB3AVA7i", "name": "Subfolder", "mimeType": "application/vnd.google-apps.folder"} </code></pre></div> <p dir="auto">Add <code>--stop-after 5</code> to stop after 5 records - useful for testing.</p> <p dir="auto">Full <code>--help</code>:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Usage: google-drive-to-sqlite get [OPTIONS] URL Make an authenticated HTTP GET to the specified URL Options: -a, --auth FILE Path to auth.json token file --paginate TEXT Paginate through all results in this key --nl Output paginated data as newline-delimited JSON --stop-after INTEGER Stop paginating after X results -v, --verbose Send verbose output to stderr --help Show this message and exit. "><pre class="notranslate"><code>Usage: google-drive-to-sqlite get [OPTIONS] URL Make an authenticated HTTP GET to the specified URL Options: -a, --auth FILE Path to auth.json token file --paginate TEXT Paginate through all results in this key --nl Output paginated data as newline-delimited JSON --stop-after INTEGER Stop paginating after X results -v, --verbose Send verbose output to stderr --help Show this message and exit. </code></pre></div> <h2 dir="auto"><a id="user-content-database-schema" class="anchor" aria-hidden="true" href="#user-content-database-schema"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Database schema</h2> <p dir="auto">The database created by this tool has the following schema:</p> <div class="highlight highlight-source-sql notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="CREATE TABLE [drive_users] ( [permissionId] TEXT PRIMARY KEY, [kind] TEXT, [displayName] TEXT, [photoLink] TEXT, [me] INTEGER, [emailAddress] TEXT ); CREATE TABLE [drive_folders] ( [id] TEXT PRIMARY KEY, [_parent] TEXT, [_owner] TEXT, [lastModifyingUser] TEXT, [kind] TEXT, [name] TEXT, [mimeType] TEXT, [starred] INTEGER, [trashed] INTEGER, [explicitlyTrashed] INTEGER, [parents] TEXT, [spaces] TEXT, [version] TEXT, [webViewLink] TEXT, [iconLink] TEXT, [hasThumbnail] INTEGER, [thumbnailVersion] TEXT, [viewedByMe] INTEGER, [createdTime] TEXT, [modifiedTime] TEXT, [modifiedByMe] INTEGER, [shared] INTEGER, [ownedByMe] INTEGER, [viewersCanCopyContent] INTEGER, [copyRequiresWriterPermission] INTEGER, [writersCanShare] INTEGER, [folderColorRgb] TEXT, [quotaBytesUsed] TEXT, [isAppAuthorized] INTEGER, [linkShareMetadata] TEXT, FOREIGN KEY([_parent]) REFERENCES [drive_folders]([id]), FOREIGN KEY([_owner]) REFERENCES [drive_users]([permissionId]), FOREIGN KEY([lastModifyingUser]) REFERENCES [drive_users]([permissionId]) ); CREATE TABLE [drive_files] ( [id] TEXT PRIMARY KEY, [_parent] TEXT, [_owner] TEXT, [lastModifyingUser] TEXT, [kind] TEXT, [name] TEXT, [mimeType] TEXT, [starred] INTEGER, [trashed] INTEGER, [explicitlyTrashed] INTEGER, [parents] TEXT, [spaces] TEXT, [version] TEXT, [webViewLink] TEXT, [iconLink] TEXT, [hasThumbnail] INTEGER, [thumbnailVersion] TEXT, [viewedByMe] INTEGER, [createdTime] TEXT, [modifiedTime] TEXT, [modifiedByMe] INTEGER, [shared] INTEGER, [ownedByMe] INTEGER, [viewersCanCopyContent] INTEGER, [copyRequiresWriterPermission] INTEGER, [writersCanShare] INTEGER, [quotaBytesUsed] TEXT, [isAppAuthorized] INTEGER, [linkShareMetadata] TEXT, FOREIGN KEY([_parent]) REFERENCES [drive_folders]([id]), FOREIGN KEY([_owner]) REFERENCES [drive_users]([permissionId]), FOREIGN KEY([lastModifyingUser]) REFERENCES [drive_users]([permissionId]) );"><pre>CREATE TABLE [drive_users] ( [permissionId] <span class="pl-k">TEXT</span> <span class="pl-k">PRIMARY KEY</span>, [kind] <span class="pl-k">TEXT</span>, [displayName] <span class="pl-k">TEXT</span>, [photoLink] <span class="pl-k">TEXT</span>, [me] <span class="pl-k">INTEGER</span>, [emailAddress] <span class="pl-k">TEXT</span> ); CREATE TABLE [drive_folders] ( [id] <span class="pl-k">TEXT</span> <span class="pl-k">PRIMARY KEY</span>, [_parent] <span class="pl-k">TEXT</span>, [_owner] <span class="pl-k">TEXT</span>, [lastModifyingUser] <span class="pl-k">TEXT</span>, [kind] <span class="pl-k">TEXT</span>, [name] <span class="pl-k">TEXT</span>, [mimeType] <span class="pl-k">TEXT</span>, [starred] <span class="pl-k">INTEGER</span>, [trashed] <span class="pl-k">INTEGER</span>, [explicitlyTrashed] <span class="pl-k">INTEGER</span>, [parents] <span class="pl-k">TEXT</span>, [spaces] <span class="pl-k">TEXT</span>, [version] <span class="pl-k">TEXT</span>, [webViewLink] <span class="pl-k">TEXT</span>, [iconLink] <span class="pl-k">TEXT</span>, [hasThumbnail] <span class="pl-k">INTEGER</span>, [thumbnailVersion] <span class="pl-k">TEXT</span>, [viewedByMe] <span class="pl-k">INTEGER</span>, [createdTime] <span class="pl-k">TEXT</span>, [modifiedTime] <span class="pl-k">TEXT</span>, [modifiedByMe] <span class="pl-k">INTEGER</span>, [shared] <span class="pl-k">INTEGER</span>, [ownedByMe] <span class="pl-k">INTEGER</span>, [viewersCanCopyContent] <span class="pl-k">INTEGER</span>, [copyRequiresWriterPermission] <span class="pl-k">INTEGER</span>, [writersCanShare] <span class="pl-k">INTEGER</span>, [folderColorRgb] <span class="pl-k">TEXT</span>, [quotaBytesUsed] <span class="pl-k">TEXT</span>, [isAppAuthorized] <span class="pl-k">INTEGER</span>, [linkShareMetadata] <span class="pl-k">TEXT</span>, <span class="pl-k">FOREIGN KEY</span>([_parent]) <span class="pl-k">REFERENCES</span> [drive_folders]([id]), <span class="pl-k">FOREIGN KEY</span>([_owner]) <span class="pl-k">REFERENCES</span> [drive_users]([permissionId]), <span class="pl-k">FOREIGN KEY</span>([lastModifyingUser]) <span class="pl-k">REFERENCES</span> [drive_users]([permissionId]) ); CREATE TABLE [drive_files] ( [id] <span class="pl-k">TEXT</span> <span class="pl-k">PRIMARY KEY</span>, [_parent] <span class="pl-k">TEXT</span>, [_owner] <span class="pl-k">TEXT</span>, [lastModifyingUser] <span class="pl-k">TEXT</span>, [kind] <span class="pl-k">TEXT</span>, [name] <span class="pl-k">TEXT</span>, [mimeType] <span class="pl-k">TEXT</span>, [starred] <span class="pl-k">INTEGER</span>, [trashed] <span class="pl-k">INTEGER</span>, [explicitlyTrashed] <span class="pl-k">INTEGER</span>, [parents] <span class="pl-k">TEXT</span>, [spaces] <span class="pl-k">TEXT</span>, [version] <span class="pl-k">TEXT</span>, [webViewLink] <span class="pl-k">TEXT</span>, [iconLink] <span class="pl-k">TEXT</span>, [hasThumbnail] <span class="pl-k">INTEGER</span>, [thumbnailVersion] <span class="pl-k">TEXT</span>, [viewedByMe] <span class="pl-k">INTEGER</span>, [createdTime] <span class="pl-k">TEXT</span>, [modifiedTime] <span class="pl-k">TEXT</span>, [modifiedByMe] <span class="pl-k">INTEGER</span>, [shared] <span class="pl-k">INTEGER</span>, [ownedByMe] <span class="pl-k">INTEGER</span>, [viewersCanCopyContent] <span class="pl-k">INTEGER</span>, [copyRequiresWriterPermission] <span class="pl-k">INTEGER</span>, [writersCanShare] <span class="pl-k">INTEGER</span>, [quotaBytesUsed] <span class="pl-k">TEXT</span>, [isAppAuthorized] <span class="pl-k">INTEGER</span>, [linkShareMetadata] <span class="pl-k">TEXT</span>, <span class="pl-k">FOREIGN KEY</span>([_parent]) <span class="pl-k">REFERENCES</span> [drive_folders]([id]), <span class="pl-k">FOREIGN KEY</span>([_owner]) <span class="pl-k">REFERENCES</span> [drive_users]([permissionId]), <span class="pl-k">FOREIGN KEY</span>([lastModifyingUser]) <span class="pl-k">REFERENCES</span> [drive_users]([permissionId]) );</pre></div> <h2 dir="auto"><a id="user-content-thumbnails" class="anchor" aria-hidden="true" href="#user-content-thumbnails"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Thumbnails</h2> <p dir="auto">You can construct a thumbnail image for a known file ID using the following URL:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="https://drive.google.com/thumbnail?sz=w800-h800&id=FILE_ID"><pre class="notranslate"><code>https://drive.google.com/thumbnail?sz=w800-h800&id=FILE_ID </code></pre></div> <p dir="auto">Users who are signed into Google Drive and have permission to view a file will be redirected to a thumbnail version of that file. You can tweak the <code>w800</code> and <code>h800</code> parameters to request different thumbnail sizes.</p> <h2 dir="auto"><a id="user-content-privacy-policy" class="anchor" aria-hidden="true" href="#user-content-privacy-policy"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Privacy policy</h2> <p dir="auto">This tool requests access to your Google Drive account in order to retrieve metadata about your files there. It also offers a feature that can download the content of those files.</p> <p dir="auto">The credentials used to access your account are stored in the <code>auth.json</code> file on your computer. The metadata and content retrieved from Google Drive is also stored only on your own personal computer.</p> <p dir="auto">At no point do the developers of this tool gain access to any of your data.</p> <h2 dir="auto"><a id="user-content-development" class="anchor" aria-hidden="true" href="#user-content-development"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Development</h2> <p dir="auto">To contribute to this tool, first checkout the code. Then create a new virtual environment:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="cd google-drive-to-sqlite python -m venv venv source venv/bin/activate"><pre class="notranslate"><code>cd google-drive-to-sqlite python -m venv venv source venv/bin/activate </code></pre></div> <p dir="auto">Or if you are using <code>pipenv</code>:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="pipenv shell"><pre class="notranslate"><code>pipenv shell </code></pre></div> <p dir="auto">Now install the dependencies and test dependencies:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="pip install -e '.[test]'"><pre class="notranslate"><code>pip install -e '.[test]' </code></pre></div> <p dir="auto">To run the tests:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="pytest"><pre class="notranslate"><code>pytest </code></pre></div> </article></div> | 1 | public | 0 |
Links from other tables
- 6 rows from repo in releases