Skip to main content

Backlot

python PyPI tests License: MIT

Discord X

Run enterprise SaaS APIs locally.

Backlot is a local emulator for Slack, Gmail, Google Drive, GitHub, Jira, Notion, S3 and other enterprise APIs. It reproduces the response shapes, pagination, authentication, errors and per-document access controls an integration has to handle, over a deterministic corpus you control — so you build and test against the official vendor SDKs with no vendor account, no OAuth approval, no secrets in CI and no network.

Try it in 60 seconds

pip install backlot
backlot import --bundled   # a corpus ships with the package; nothing to fetch or write
backlot serve              # every supported API, at http://127.0.0.1:8000

Point an official SDK at it by changing one base URL:

from slack_sdk import WebClient  # pip install slack_sdk

slack = WebClient(token="admin-service-token", base_url="http://127.0.0.1:8000/slack/api/")
print(slack.conversations_list()["channels"])

The same call targets Slack in production and Backlot in development. Backlot supplies the data and the credentials; your code keeps the vendor's request and response contract.

A test can run its own server instead, on a free port, with nothing to start or clean up:

import backlot
from slack_sdk import WebClient

with backlot.serve() as s:  # no arguments: a tiny hello-world corpus
    slack = WebClient(token=s.token, base_url=f"{s.base_url}/slack/api/")
    channels = slack.conversations_list()["channels"]

Let your coding agent run Backlot instantly

This repo is its own plugin marketplace, so the agent skill installs with no clone and no pip install first:

claude plugin marketplace add brekkylab/backlot && claude plugin install backlot@brekkylab
codex plugin marketplace add brekkylab/backlot && codex plugin add backlot@brekkylab

and prompt like this:

Mock our Slack workspace with three messages in an #incidents channel, get a server running, then show me what conversations.history actually returns for that channel.

Why not use mocks?

A hand-written mock returns the response your code already expects. Backlot implements the other side of the integration, so it exposes the assumptions a mock would repeat — it is for when the behavior of the API, not just the contents of one response, is what you need to test.

❌ Hand-written mocks ✅ Backlot
Test-specific response dictionaries Vendor-shaped responses served over HTTP
Usually cover the happy path Pagination, validation, auth and vendor-shaped errors
Custom test helpers Official vendor SDKs and ordinary HTTP clients
Little or no identity model Generated users, tokens, groups and document ACLs
Fixtures drift between tests One deterministic corpus, shared locally and in CI
Each API mocked differently Every API served from one process

What it serves

Every source on one local port, each behind the path prefix its own SDK expects, all reading one SQLite corpus.

The corpus defines the facts: messages, files, issues, authors, timestamps, threads, comments, labels, readers. Backlot derives stable ids, users, groups and tokens from them, so every run serves the same records, the same ACL-filtered views and the same pages.

It emulates the documented subset of each API it supports, not every vendor endpoint. The endpoint-by-endpoint matrix says which, and an implemented endpoint that diverges from the real API is a bug.

Service Base path Example, on the official SDK
Slack /slack/api slack.py
Gmail /gmail/v1 gmail.py
Google Drive (Docs, Sheets, Slides) /drive/v3 /docs/v1 /sheets/v4 /slides/v1 gdrive.py
GitHub /github github.py
Jira /atlassian/rest/api jira.py
Confluence /atlassian/wiki/rest/api confluence.py
Notion /notion/v1 notion.py
Linear /linear/graphql linear/
HubSpot /hubspot hubspot.py
Fireflies /fireflies/graphql fireflies.py
Amazon S3 /s3 s3.py

The roadmap lives in the tracking issue — ask there for the source you need.

When you need this

  • 🔌 Building or upgrading an integration. The cursors, page shapes and error bodies the real API returns, without an account to get them from.
  • 🧪 Testing it, and keeping it tested. One fixture on your laptop and in CI, with no secrets and nothing to flake. Every user in the corpus gets a token, so you can also assert that one caller's documents never reach another.
  • 🤖 Evaluating a RAG pipeline or an agent. The same corpus, the same ids and the same answers on every run, so a score that moves means your code moved.
  • 🐛 Reproducing a bug in data you can't see. A document inside someone else's workspace breaks your parser. Write one shaped like it, serve it, and keep the failing test.

Bring your own corpus

The bundled corpus covers every supported service, but the main workflow is to serve your own test world: a JSONL file, one source document per line.

{"source_type":"slack","channel":"incidents","author_email":"bob@acme.com","created":"2026-02-10T18:00:00Z","content":"Anyone seeing 502s from the gateway?","replies":[{"content":"Looking now.","author_email":"ava@acme.com","created":"2026-02-10T18:00:40Z"}]}
backlot import my-corpus.jsonl --dry-run   # validate against each service's schema, touch nothing
backlot import my-corpus.jsonl && backlot serve

Every imported identity gets deterministic credentials, listed at GET /_meta/users; send the same request with another user's token to test what that caller is allowed to see. Preparing a corpus covers schemas, rosters, sharded corpora and public datasets, and Auth and tokens covers each service's authentication style.

Examples

Point this at it Runnable
📦 Official vendor SDKs, one script per service examples/using-official-sdk/
🔗 MCP servers, or Backlot's own OpenAPI→MCP and GraphQL→MCP bridges examples/using-mcp-with-agents/
🦙 Load it as documents, with the official LlamaIndex readers examples/using-llamaindex-readers/
🐍 Read it with pandas, pyarrow or dask, over an fsspec filesystem examples/using-fsspec/
🗂️ Read it with ls, cat and grep, over mirage's virtual filesystem examples/using-mirage/
📥 Your own corpus, from a JSONL file examples/bring-your-own-corpus/

Documentation

Every source Backlot serves, and every endpoint of each docs/supported-sources.md
Building a corpus, and public datasets docs/corpus.md
Auth schemes and tokens docs/auth.md
Measuring Backlot against the real APIs docs/fidelity.md
Every BACKLOT_* setting, and Docker docs/configuration.md
Vendor names and trademarks NOTICE.md

Contributing

See CONTRIBUTING.md. Fidelity to the real APIs is the point, so a divergence is a bug — measure against the real service, and bring a test that fails without your fix.

License

MIT

Metadata

Release files for backlot 0.0.3

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

Source distribution (sdist)

Source distribution for backlot 0.0.3
File Size Uploaded
backlot-0.0.3.tar.gz 1.6 MB Details

Built distribution (wheel)

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

Total release size: 2.2 MB

Release files / backlot-0.0.3.tar.gz

Download URL backlot-0.0.3.tar.gz
Size 1.6 MB
Tags Source
SHA-256 checksum
How to use checksums
175e69bb8d280b59d67f6dc932a190ab03124174fd80a9115404d6ca4928b8f0
BLAKE2b-256 checksum
How to use checksums
939dd1baf454b4ca2bd149c62a307df6d66f61553b4fe347b9ff2bdfb77f505a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.15

Release files / backlot-0.0.3-py3-none-any.whl

Download URL backlot-0.0.3-py3-none-any.whl
Size 645.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0488ca04e8b8ed500069fdb719e35e555df91e2ad85f3b9be461f4ff6a5a9cda
BLAKE2b-256 checksum
How to use checksums
ed6c9d23a8a3b8cca3eb34d5a1c1bfa96a7731429014a00a6b308be625ffaa5f
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.0.5

2 release files

0.0.4

2 release files

This release

0.0.3 This release

2 release files

0.0.2

2 release files

0.0.1

2 release files

0.0.0

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