Skip to main content

fastgws

fastgws builds async Python clients for Google APIs from Google’s discovery documents. Each service gets a small Python surface: resource groups become attributes, operations become awaitable methods, and responses come back as lightweight objects instead of raw JSON dictionaries.

Installation

Install from pypi:

$ pip install fastgws

Or install the latest development version from GitHub:

$ pip install git+https://github.com/answerdotai/fastgws.git

How to use

Import the service clients you want to use. Each client is built from Google’s discovery documents and exposes resource groups as Python attributes, so calls look like await drive.files.list(...) or await calendar.events.list(...).

from fastgws import Calendar, Docs, Drive, GMail, Places
from fastgws.auth import *

fastgws supports both OAuth credentials and API keys. OAuth is the usual choice for Google Workspace APIs such as Gmail, Calendar, Drive, and Docs, because these APIs act on behalf of a user and require explicit scopes.

oauth_creds looks for a Google OAuth client file named credentials.json in the fastgws config directory, which defaults to ~/.config/fastgws/credentials.json. Create this OAuth client in Google Cloud Console as a web application, and register a redirect URI that displays the returned code for copy/paste, such as https://oauth.appapis.org/redirect. The authorization link uses the first entry of redirect_uris in credentials.json unless you pass redirect_uri=, so edit that file to change the default.

Pass oauth_creds the scopes your app needs. On the first run it prints or displays an authorization link; visit that link, approve access, then paste the returned code back into the prompt. fastgws saves the resulting token in the same config directory and reuses it on later runs when the saved token covers the requested scopes, including when you request only a subset of the scopes already granted. Requesting scopes beyond the saved token re-runs the flow asking for the union of old and new, so previously granted scopes are never lost.

Where a blocking prompt can’t work (agents, tool calls), split the flow: auth_url(scopes=...) returns the authorization link, and finish_auth(code) exchanges the pasted code (or the full redirect URL) and saves the token. Codes are PKCE-bound to the process that created the link, so they’re safe to relay through a chat.

API keys are useful for public Google APIs that support key-based access, such as Places. You can pass api_key=... directly or set GOOGLE_API_KEY or GWS_API_KEY in the environment.

creds = oauth_creds(scopes=['https://www.googleapis.com/auth/calendar',
                            'https://www.googleapis.com/auth/documents',
                            'https://www.googleapis.com/auth/drive.readonly',
                            'https://www.googleapis.com/auth/gmail.readonly'])

Auth complete

Responses are converted into lightweight Python objects. Known Google resource kinds get more specific classes such as FileList, Events, or Event; when a service does not provide enough schema information, fastgws falls back to the base GWSObject. Either way, fields are available as attributes as well as dictionary keys.

Use Docs to create a document, apply batch updates, and read the document back. The API accepts the same request dictionaries documented by Google, while fastgws handles auth, transport, and object conversion.

docs = Docs(creds=creds)
doc = await docs.documents.create(title='fastgws test doc')
doc
GWSObject(title='fastgws test doc', documentId='1ObmgD5GOA9zNZbUwCYeFZH8nUc_MKcJHKFqjPJGnkQs', body=1, documentStyle=11, namedStyles=1, tabs=1)
await docs.documents.batch_update(document_id=doc.documentId,
                                  requests=[{'insertText': {'location': {'index': 1},
                                             'text': 'Hello from fastgws\n'}}])
GWSObject(documentId='1ObmgD5GOA9zNZbUwCYeFZH8nUc_MKcJHKFqjPJGnkQs', replies=1, writeControl=1)
def doc_text(doc):
    return ''.join(e.textRun.content for b in doc.body.content if 'paragraph' in b for e in b.paragraph.elements if 'textRun' in e)

doc = await docs.documents.get(document_id=doc.documentId)
txt = doc_text(doc)
print(txt)
Hello from fastgws

Use Drive to search files and inspect metadata. This example returns a FileList, and its files collection contains file objects with attributes such as id, name, and mimeType.

drive = Drive(creds=creds)
fs = await drive.files.list(q="name contains 'fastgws' and trashed=false", page_size=10)
fs, fs.files[0]
(FileList(kind='drive#fileList', files=3),
 File(id='1ObmgD5GOA9zNZbUwCYeFZH8nUc_MKcJHKFqjPJGnkQs', name='fastgws test doc', mimeType='application/vnd.google-apps.document', kind='drive#file'))

Use Gmail to search messages with the Gmail query syntax. The result is still a Python object, so you can inspect message ids, thread ids, and any fields returned by the API without digging through raw JSON first.

gmail = GMail(creds=creds)
msgs = await gmail.users.messages.list(user_id='me', max_results=10)
msgs
GWSObject(messages=10)

Use Calendar to create, update, delete, and search events.

calendar = Calendar(creds=creds)
event = await calendar.events.insert(calendar_id='primary',
                                    summary='fastgws test event',
                                    start={'dateTime': '2030-01-01T09:00:00Z'},
                                    end={'dateTime': '2030-01-01T09:30:00Z'})
event
Event(id='u99k6q861u35h6mrmejdrgc0gg', summary='fastgws test event', kind='calendar#event', creator=2, organizer=2, start=2, end=2, reminders=1)
events = await calendar.events.list(calendar_id='primary', q='fastgws test event',
                                    max_results=10, single_events=True, order_by='startTime')
events, events['items'][0]
(Events(summary='nc@answer.ai', kind='calendar#events', defaultReminders=1, items=1),
 Event(id='u99k6q861u35h6mrmejdrgc0gg', summary='fastgws test event', kind='calendar#event', creator=2, organizer=2, start=2, end=2, reminders=1))
await calendar.events.delete(calendar_id='primary', event_id=event.id)
''

Use API-key services the same way. Places can run with an API key instead of OAuth credentials, and this example asks Google to return only the fields needed to render a link.

from IPython.display import Markdown

places = Places()
res = await places.places.search_text(text_query='coffee near San Francisco',
                                      _headers={'X-Goog-FieldMask':'places.displayName,places.formattedAddress,places.location,places.googleMapsUri'})
p = res.places[0]
Markdown(f'[{p.displayName.text}]({p.googleMapsUri})')

fastgws can also create service clients dynamically from Google’s discovery index. If Google publishes a discovery document for a service, you can usually import that service by name, for example from fastgws import Sheets, then use it with the same creds, token, or api_key arguments shown above.

PySkill support

fastgws includes a PySkill for agents working inside solveit. Load fastgws.skill when a task needs access to Google Workspace or Google APIs through the base GWSApi client.

The skill exposes GWSApi, GWSObject, oauth_creds, and svc_acct_creds, and allows generated Google API operations through GWSOpFunc. Agents should normally load OAuth credentials with interactive=False, which means they can only use scopes the user has already authorized manually.

creds = oauth_creds(scopes=['https://www.googleapis.com/auth/gmail.readonly'], interactive=False)
gmail = GWSApi('gmail', creds=creds)
msgs = await gmail.users.messages.list(user_id='me', max_results=10)

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastgws-0.2.6.tar.gz (18.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastgws-0.2.6-py3-none-any.whl (17.6 kB view details)

Uploaded Python 3

File details

Details for the file fastgws-0.2.6.tar.gz.

File metadata

  • Download URL: fastgws-0.2.6.tar.gz
  • Upload date:
  • Size: 18.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.5

File hashes

Hashes for fastgws-0.2.6.tar.gz
Algorithm Hash digest
SHA256 2fa8560138db185e3eed3e57dab7071658f8b207641645107f07a63c4594dfc0
MD5 fcded0f4bd1beea910310090f6ef554a
BLAKE2b-256 24cdcc8d8e7370fc40a41cfc0200453b64114f0ce7c2375a88c9d7de88e7f70a

See more details on using hashes here.

File details

Details for the file fastgws-0.2.6-py3-none-any.whl.

File metadata

  • Download URL: fastgws-0.2.6-py3-none-any.whl
  • Upload date:
  • Size: 17.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.5

File hashes

Hashes for fastgws-0.2.6-py3-none-any.whl
Algorithm Hash digest
SHA256 d9dd960a3026df8dd57fb5a35155ac57de2b85be22468705e20bf2344f693764
MD5 0a226493c49709fbd11ca7652c83379f
BLAKE2b-256 4f58eb963349164d131e35ab3232e5180cb34eaee5b120947dc0beab87d9774a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page