Metadata-Version: 2.4
Name: solvedrive
Version: 0.0.1
Summary: Google Drive client built on the Drive API
Author-email: Nathan Cooper <nathanacooper@proton.me>
License: Apache-2.0
Project-URL: Repository, https://github.com/answerDotAI/solvedrive
Project-URL: Documentation, https://answerDotAI.github.io/solvedrive/
Keywords: nbdev
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastcore
Requires-Dist: fastgws>=0.2.5
Requires-Dist: fastspec>=0.1.3
Dynamic: license-file

# solvedrive


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

solvedrive is an async Python client for Google Drive. It wraps the Drive REST API in a few small classes ([`Drive`](https://answerDotAI.github.io/solvedrive/core.html#drive), [`File`](https://answerDotAI.github.io/solvedrive/core.html#file), [`Folder`](https://answerDotAI.github.io/solvedrive/core.html#folder), and the [`Files`](https://answerDotAI.github.io/solvedrive/core.html#files) collection), so you can upload and download files, search with Drive’s query syntax, export Google Docs, organize with folders, and share, all with plain method calls.

It is built on [fastgws](https://github.com/AnswerDotAI/fastgws) for OAuth and API access, and runs every call asynchronously, so you `await` each one. Searches come back with the useful fields (`name`, `mimeType`, `size`, `parents`, `trashed`, `webViewLink`) already populated in one request, and reprs render file names as links that open the file in Drive.

## Installation

Install latest from [pypi](https://pypi.org/project/solvedrive/)

``` sh
$ pip install solvedrive
```

## How to use

solvedrive signs in with OAuth 2.0 through [fastgws](https://github.com/AnswerDotAI/fastgws), which expects an OAuth client secret at `~/.config/fastgws/credentials.json`. The fastgws docs cover how to create that file from a Google Cloud project. The first connection opens a browser to authorize the scopes you asked for, then caches the token so later runs don’t prompt again.

Create a [`Drive`](https://answerDotAI.github.io/solvedrive/core.html#drive) client with the scopes you need: `readonly` to search and download, `file` to also manage the files your app created, or `full` for everything. `about()` returns the signed-in account, with the address on its `email` attribute.

``` python
drive = await Drive.init(scopes='full')
about = await drive.about()
about.email
```

    'nc@answer.ai'

### Uploading

`upload` sends bytes or a local path to Drive, returning the new [`File`](https://answerDotAI.github.io/solvedrive/core.html#file). Its repr shows the essentials, with the name linking to the file in Drive.

``` python
f = await drive.upload(data=b'hello from solvedrive!', name='solvedrive_hello.txt')
f
```

File(1q7Ki1z40Q2Ec5Xl9eEHMDwMfx4lwGw3Q: <a href="https://drive.google.com/file/d/1q7Ki1z40Q2Ec5Xl9eEHMDwMfx4lwGw3Q/view?usp=drivesdk" target="_blank">solvedrive_hello.txt</a> (text/plain, 22B) 2026-07-28T13:48:55.654Z)

### Searching

`search_files` takes Drive’s own [query syntax](https://developers.google.com/workspace/drive/api/guides/search-files), the same operators the Drive search box uses, and returns a [`Files`](https://answerDotAI.github.io/solvedrive/core.html#files) collection with a table repr.

``` python
fs = await drive.search_files("name = 'solvedrive_hello.txt' and trashed=false")
fs
```

| id | name | type | size | modified |
|----|----|----|----|----|
| 1q7Ki1z40Q2Ec5Xl9eEHMDwMfx4lwGw3Q | <a href="https://drive.google.com/file/d/1q7Ki1z40Q2Ec5Xl9eEHMDwMfx4lwGw3Q/view?usp=drivesdk" target="_blank">solvedrive_hello.txt</a> | text/plain | 22B | 2026-07-28 |

### Downloading

`download` returns a file’s bytes. Google-native files (Docs, Sheets, Slides) have no bytes of their own, so they are exported to a regular format instead: docx for Docs, xlsx for Sheets, pptx for Slides, or any supported `mime=` you ask for.

``` python
await f.download()
```

    b'hello from solvedrive!'

### Folders

A folder is a file with a special `mimeType`. `create_folder` makes one, `move` puts files in it, and `ls` lists what it holds.

``` python
folder = await drive.create_folder('solvedrive demo')
await f.move(folder)
await folder.ls()
```

| id | name | type | size | modified |
|----|----|----|----|----|
| 1q7Ki1z40Q2Ec5Xl9eEHMDwMfx4lwGw3Q | <a href="https://drive.google.com/file/d/1q7Ki1z40Q2Ec5Xl9eEHMDwMfx4lwGw3Q/view?usp=drivesdk" target="_blank">solvedrive_hello.txt</a> | text/plain | 22B | 2026-07-28 |

### Sharing

`share` grants access, either to an email address or to anyone with the link when none is given. `permissions` lists the current grants, and `unshare` revokes one.

``` python
p = await f.share()
await f.permissions
```

    [{'id': 'anyoneWithLink', 'type': 'anyone', 'role': 'reader'}, {'id': '12635610242443046038', 'type': 'user', 'emailAddress': 'nc@answer.ai', 'role': 'owner'}]

There’s more in `solvedrive.core`: renaming and copying, trash versus permanent deletion, and operating on a whole [`Files`](https://answerDotAI.github.io/solvedrive/core.html#files) collection at once through Google’s batch protocol. See the [docs](https://answerDotAI.github.io/solvedrive/) for the full tour.

### Use as an LLM skill

solvedrive registers a [pyskills](https://github.com/AnswerDotAI/pyskills) skill, so an LLM host such as solveit can load it and use the safe API (searching, downloading, uploading, creating folders) by default. Renaming, moving, trash, deletion, and sharing are documented in the skill but are not enabled, so you turn them on when a task needs them.
