Skip to main content

fastspec

Install

pip install fastspec

Quick Start

fastspec turns any OpenAPI (or Google Discovery) spec into a fully async Python client. Load a spec, create a client, and call any endpoint with attribute chaining.

Loading Specs

fastspec supports both OpenAPI (JSON/YAML) and Google Discovery specs:

from fastcore.utils import *
from fastspec.oapi import *
from fastspec.spec import *
import json, yaml
specs_path = Path('../specs/')

# OpenAPI specs (Anthropic, OpenAI, GitHub, Stripe)
ant_spec  = SpecParser.from_openapi(dict2obj(yaml.safe_load((specs_path/'anthropic.yml').read_text())))
oai_spec  = SpecParser.from_openapi(dict2obj(yaml.safe_load((specs_path/'openai.with-code-samples.yml').read_text())))
gh_spec   = SpecParser.from_openapi(dict2obj(json.loads((specs_path/'github.json').read_text())))

# Google Discovery spec (Gemini)
gem_spec  = SpecParser.from_discovery(dict2obj(json.loads((specs_path/'gemini.json').read_text())))

ant_spec, oai_spec, gh_spec, gem_spec
(SpecParser(base_url='https://api.anthropic.com', ops=47),
 SpecParser(base_url='https://api.openai.com/v1', ops=241),
 SpecParser(base_url='https://api.github.com', ops=1112),
 SpecParser(base_url='https://generativelanguage.googleapis.com/', ops=79))

Creating Clients

Pass a parsed spec and any required auth headers to OpenAPIClient. The examples on this page authenticate from environment variables – ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, and GITHUB_TOKEN – so set the ones you need for the providers you use:

ant_cli = OpenAPIClient(ant_spec, headers={"x-api-key": os.environ["ANTHROPIC_API_KEY"], "anthropic-version": "2023-06-01"})
oai_cli = OpenAPIClient(oai_spec, headers={"Authorization": f"Bearer {os.environ['OPENAI_API_KEY']}"})
gh_cli  = OpenAPIClient(gh_spec,  headers={"Authorization": f"token {os.environ['GITHUB_TOKEN']}"})

Exploring Operations

Every client organizes endpoints into groups. Use doc() to browse what’s available:

ant_cli.messages

Drill into any operation to see its full signature and parameter docs:

ant_cli.models.models_get

Get a Model

Parameters:

  • model_id (str, required): Model identifier or alias.

Anthropic

A simple message request:

resp = await ant_cli.messages.messages_post(
    model="claude-sonnet-4-20250514",
    messages=[{"role": "user", "content": "What is FastSpec?"}],
    max_tokens=64,)
resp['content'][0]['text']
"FastSpec could refer to a few different things depending on the context. Here are the most likely meanings:\n\n## 1. **Testing Framework**\nFastSpec is a testing framework, particularly associated with Scala development. It's designed to provide:\n- Fast test execution\n- Clear, readable test syntax"

With streaming — just pass stream=True and iterate:

resp = await ant_cli.messages.messages_post(
    model="claude-sonnet-4-20250514",
    messages=[{"role": "user", "content": "Say hello in 3 languages."}],
    max_tokens=128, stream=True)
async for ev in resp: 
    if ct:= nested_idx(ev,'delta','text'): print(ct, end=' ')
Hello! Here are gr eetings in 3 languages:

1. **English**: Hello!
2. **Spanish**: ¡Hola!
3 . **French**: Bonjour! 

OpenAI

Chat Completion

resp = await oai_cli.chat.create_chat_completion(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "What is fastspec?"}],
    max_tokens=64)
resp['choices'][0]['message']['content']
'As of my last update in October 2023, "fastspec" is not widely known or associated with a specific standalone technology, product, or concept in public discourse. However, the term could refer to various topics depending on the context, such as:\n\n1. **Software or Libraries**: It might denote a'

Text-to-Speech (file output)

resp = await oai_cli.audio.create_speech(model="tts-1", input="Hello from fastspec!", voice="alloy")
Path("hello.mp3").write_bytes(resp)
print(f"Saved {len(resp)} bytes to hello.mp3")
Saved 26400 bytes to hello.mp3

Transcription (file upload + streaming)

resp = await oai_cli.audio.create_transcription(
    file=open("hello.mp3", "rb"), model="gpt-4o-transcribe", stream=True)
async for ev in resp: print(ev.get('delta', ''), end='')
Hello from Fastbec.

Gemini

Google Discovery specs use nested resource groups with attribute chaining:

gem_cli = OpenAPIClient(gem_spec, headers={"x-goog-api-key": os.environ["GEMINI_API_KEY"]})
str(gem_cli.models)[:500]
'- models.generate_content(model, contents, access_token, alt, callback, fields, key, oauth_token, pretty_print, quota_user, upload_protocol, upload_type, xgafv, system_instruction, tools, tool_config, safety_settings, generation_config, cached_content, service_tier, store): *Generates a model response given an input `GenerateContentRequest`. Refer to the [text generation guide](https://ai.google.dev/gemini-api/docs/text-generation) for detailed usage information. Input capabilities differ betwee'
resp = await gem_cli.models.generate_content(
    model="models/gemini-2.5-flash",
    contents=[{"parts": [{"text": "What is fastspec?"}]}])
resp['candidates'][0]['content']['parts'][0]['text'][:200]
'**FastSpec** is a Ruby Gem designed to significantly speed up your local RSpec test suite execution by intelligently identifying and running only the specs relevant to your recent code changes.\n\n### T'

Nested resource groups are accessed with attribute chaining:

gem_cli.tuned_models.permissions.create

Create a permission to a specific resource.

Parameters:

  • parent (str, required): Required. The parent resource of the Permission. Formats: tunedModels/{tuned_model} corpora/{corpus}
  • role (str, required): Required. The role granted by this permission.
  • access_token (str, optional): OAuth access token.
  • alt (str, optional): Data format for response.
  • callback (str, optional): JSONP
  • fields (str, optional): Selector specifying which fields to include in a partial response.
  • key (str, optional): API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.
  • oauth_token (str, optional): OAuth 2.0 token for the current user.
  • pretty_print (bool, optional): Returns response with indentations and line breaks.
  • quota_user (str, optional): Available to use for quota purposes for server-side applications. Can be any arbitrary string assigned to a user, but should not exceed 40 characters.
  • upload_protocol (str, optional): Upload protocol for media (e.g. “raw”, “multipart”).
  • upload_type (str, optional): Legacy upload protocol for media (e.g. “media”, “multipart”).
  • xgafv (str, optional): V1 error format.
  • name (str, optional): Output only. Identifier. The permission name. A unique name will be generated on create. Examples: tunedModels/{tuned_model}/permissions/{permission} corpora/{corpus}/permissions/{permission} Output only.
  • grantee_type (str, optional): Optional. Immutable. The type of the grantee.
  • email_address (str, optional): Optional. Immutable. The email address of the user of group which this permission refers. Field is not set when permission’s grantee type is EVERYONE.

GitHub

Route parameters (like {owner} and {repo}) are passed as regular function arguments:

resp = await gh_cli.repos.get(owner="AnswerDotAI", repo="fastcore")
resp['full_name'], resp['description'], resp['stargazers_count']
('AnswerDotAI/fastcore', 'Python supercharged for the fastai library', 1100)
gh_cli.repos.get

Get a repository

Docs: https://docs.github.com/rest/repos/repos#get-a-repository

Parameters:

  • owner (str, required): The account owner of the repository. The name is not case sensitive.
  • repo (str, required): The name of the repository without the .git extension. The name is not case sensitive.

GraphQL

The same spec-to-client philosophy covers GraphQL: distill an endpoint’s introspection answer once into a GqlSpec, and GqlClient builds schema-checked queries by attribute chaining – args as kwargs, selection as chaining – with batch running many queries as a single request. Here, the head commit of three repos in one round trip (see the gql page for discovery, raw queries, and error handling):

from fastspec.gql import GqlSpec, GqlClient, INTROSPECT
from fasttransport.core import AsyncTransport
gh_hdrs = {"Authorization": f"bearer {os.environ['GITHUB_TOKEN']}"}
raw = await AsyncTransport(base_headers=gh_hdrs).request('POST', 'https://api.github.com/graphql', json=dict(query=INTROSPECT))
gql = GqlClient(GqlSpec.from_introspection(raw), 'https://api.github.com/graphql', headers=gh_hdrs)
await gql.batch(*[gql.repository(owner='AnswerDotAI', name=n).defaultBranchRef.target.oid
    for n in ('fastcore', 'fasthtml', 'ghapi')])
['25c4f3228ccac3c5a63da71b5eaa4be3c428f602',
 'e5d967ae627c63035e296e6f319f220e278327e7',
 '4ca8469d7c2ccc42cb71e30a576c719f306b5cf7']

AI Tool Integration (python)

fastspec clients can be made available to AI assistants via solveit’s python sandbox using allow(). Registering an op lets the sandboxed code call it (including the network access it needs); everything else stays blocked. Four levels of access are supported:

Single method access — lock down to specific operations:

allow(oai_cli.images.create_image)

Single group access — only specific groups:

allow(oai_cli.chat)

Single client access — all groups on one specific client:

allow(oai_cli)

Full API access — every operation on every client (any OpFunc may run):

allow({OpFunc: ['__call__']})

Going deeper

Parsed specs serialize to a compact form (SpecParser.to_dict/save/from_dict), so a client package can ship a pre-parsed spec and skip the multi-megabyte original at runtime – this is how ghapi stays small while covering GitHub’s full API, for both its REST and GraphQL surfaces (GqlSpec gives GraphQL schemas the same treatment). Under the hood, requests flow through fasttransport’s transports, and provider errors through the error layer, each documented on its own page.

Metadata

Release files for fastspec 0.2.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fastspec 0.2.4
File Size Uploaded
fastspec-0.2.4.tar.gz 30.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fastspec 0.2.4
File Interpreter ABI Platform
fastspec-0.2.4-py3-none-any.whl Python 3 none any Details

Total release size: 57.0 kB

Release files / fastspec-0.2.4.tar.gz

Download URL fastspec-0.2.4.tar.gz
Size 30.1 kB
Tags Source
SHA-256 checksum
How to use checksums
4a594a4abab4f715c801b2e2cba1045a4aa345830575343358186b15c98c21cb
BLAKE2b-256 checksum
How to use checksums
cadd1801813abfa461f81501bdce9ff1a57e786539bc424ade09197dc8d33adf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.15

Release files / fastspec-0.2.4-py3-none-any.whl

Download URL fastspec-0.2.4-py3-none-any.whl
Size 27.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c0811499a3ad7beb5a337c3d1bed4209c65cfeacd1f99ecb1e7c693f6fdff3c6
BLAKE2b-256 checksum
How to use checksums
c378208507d3d15a8f8ee925d345e0680478153cefe8e5404003edef24ccc04c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.15

Release history Release notifications | RSS feed

0.2.5

2 release files

This release

0.2.4 This release

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.11

2 release files

0.0.10

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page