Unified Python interface for multiple APIs with plugin architecture
Project description
APIForge
One Python interface for thousands of APIs.
APIForge is a plugin-based Python framework that gives you a single, consistent way to talk to many APIs. The first release ships with plugins for GitHub, Discord, and Notion; the architecture is designed to grow to thousands.
from apiforge import APIForge
client = APIForge()
client.configure(
github_token="ghp_...",
discord_token="...",
notion_token="...",
)
# All of these look the same — no separate SDK to learn per service.
user = client.github.get_user("octocat")
msg = client.discord.send_message(channel_id="...", content="hi")
pages = client.notion.list_pages()
The same client also exposes a CLI:
apiforge list
apiforge plugins
apiforge info github
Why APIForge?
If you integrate with five services, you install five SDKs, learn five authentication schemes, and maintain five upgrade cycles. APIForge collapses that into one.
- One import.
from apiforge import APIForge. - One auth surface. Pass tokens once; they reach every plugin.
- One plugin contract. Adding a new service is a small, well-defined job.
- One way to fail. A small exception hierarchy that you can catch in one place.
- One direction. Async-first under the hood, with sync wrappers for ergonomics.
Installation
pip install apiforge
The base package installs the three first-party plugins (GitHub, Discord, Notion) automatically. Additional plugins are distributed as separate packages, e.g.:
pip install apiforge-plugin-stripe
Each one registers itself via the standard apiforge.plugins
entry-point group — there's nothing to wire up in your code.
Quickstart
Sync usage
The simplest path. Every method on a plugin is awaitable under the hood, but the client exposes a transparent sync wrapper, so you don't need an event loop for one-off scripts:
from apiforge import APIForge
client = APIForge()
client.configure(github_token="ghp_...")
user = client.github.get_user("octocat")
print(user["login"])
Async usage
For servers, batched jobs, or anything that benefits from concurrency:
import asyncio
from apiforge import APIForge
async def main() -> None:
async with APIForge() as client:
client.configure(github_token="ghp_...")
user, repos = await asyncio.gather(
client.github.get_user("octocat"),
client.github.list_repos("octocat", limit=5),
)
asyncio.run(main())
Credentials
APIForge looks for credentials in this order:
- Explicit —
client.configure(github_token="...") - Environment —
APIFORGE_GITHUB_TOKEN=... - Keyring — the OS secure store (
keyringpackage) - Config file —
~/.config/apiforge/credentials.toml
# Store a token in your OS keyring:
python -c "from apiforge import APIForge; APIForge().credentials.store('github', 'ghp_...')"
CLI
apiforge list # all registered plugins
apiforge plugins # alias for `list`
apiforge info github # details on one plugin
apiforge info notion --json # machine-readable
# Coming in later phases:
apiforge generate openapi.yaml --name myplugin # Phase 2
apiforge install apiforge-plugin-stripe # Phase 5
apiforge update # Phase 5
Writing a Plugin
A plugin is a class that subclasses BasePlugin and declares a
PluginMetadata:
from apiforge.plugins.base import BasePlugin
from apiforge.core.metadata import AuthType, OperationMetadata, PluginMetadata
class StripePlugin(BasePlugin):
metadata = PluginMetadata(
name="stripe",
version="0.1.0",
description="Stripe payments API.",
auth_type=AuthType.API_KEY,
base_url="https://api.stripe.com/v1",
operations=(
OperationMetadata(name="create_charge", parameters={"amount": "int"}),
),
)
async def setup(self) -> None:
...
async def create_charge(self, amount: int) -> dict:
...
Then register it in your package's pyproject.toml:
[project.entry-points."apiforge.plugins"]
stripe = "apiforge_plugin_stripe:StripePlugin"
Once installed, client.stripe.create_charge(...) works out of the
box. See Contributing.md for the full checklist.
Project Status
APIForge is in alpha. The core framework, the credential manager, the CLI, and the three first-party plugins are stable enough for everyday use, but the API may still evolve.
See ROADMAP.md for what's next.
Documentation
- Architecture.md — the design, the layers, the contracts.
- Contributing.md — how to write and ship a plugin.
- ROADMAP.md — Phase 1 through Phase 5.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file apiforge_sdk-0.1.0.tar.gz.
File metadata
- Download URL: apiforge_sdk-0.1.0.tar.gz
- Upload date:
- Size: 32.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8008e549e2407c822555ea74bc1936ef7781f8286bf2a225361b1f108f2775d2
|
|
| MD5 |
d1dbf92fd10038161e5028226d8c6ccc
|
|
| BLAKE2b-256 |
85f63fc4f78c7aa60471c37b24fb40f9c73e0a837fc9116d031ddf13d02dbff3
|
Provenance
The following attestation bundles were made for apiforge_sdk-0.1.0.tar.gz:
Publisher:
publish.yml on terminalkid-afk/apiforge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
apiforge_sdk-0.1.0.tar.gz -
Subject digest:
8008e549e2407c822555ea74bc1936ef7781f8286bf2a225361b1f108f2775d2 - Sigstore transparency entry: 1935290242
- Sigstore integration time:
-
Permalink:
terminalkid-afk/apiforge@83308df2b6a73050e41a4c41c13063e3561f7f28 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/terminalkid-afk
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@83308df2b6a73050e41a4c41c13063e3561f7f28 -
Trigger Event:
release
-
Statement type:
File details
Details for the file apiforge_sdk-0.1.0-py3-none-any.whl.
File metadata
- Download URL: apiforge_sdk-0.1.0-py3-none-any.whl
- Upload date:
- Size: 31.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a019a78107723ae816200995a873dceb71e9385385909838817ad4b5c21addf6
|
|
| MD5 |
ea4afe71662c8e556d788a12522d9ce5
|
|
| BLAKE2b-256 |
d4b929316171c22889510aa3ca3fe6b4da15c8eb06efdebc1c7f6e2cb80defa6
|
Provenance
The following attestation bundles were made for apiforge_sdk-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on terminalkid-afk/apiforge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
apiforge_sdk-0.1.0-py3-none-any.whl -
Subject digest:
a019a78107723ae816200995a873dceb71e9385385909838817ad4b5c21addf6 - Sigstore transparency entry: 1935290263
- Sigstore integration time:
-
Permalink:
terminalkid-afk/apiforge@83308df2b6a73050e41a4c41c13063e3561f7f28 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/terminalkid-afk
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@83308df2b6a73050e41a4c41c13063e3561f7f28 -
Trigger Event:
release
-
Statement type: