Async-first, stateless Python client for the Insforge platform. Covers auth, database, storage, serverless functions, AI, email, and metadata APIs.
- Python 3.11+
pip install insforgeimportasynciofrominsforgeimportInsforgeClientasyncdefmain():
asyncwithInsforgeClient(base_url="https://your-project.insforge.app", api_key="ins_xxx") asclient:
# Public endpoint (API key only)config=awaitclient.auth.get_public_config()
# Sign insession=awaitclient.auth.sign_in_with_password(email="user@example.com", password="secret")
token=session.access_token# Authenticated requestme=awaitclient.auth.get_current_session(access_token=token)
print(me.user.email)
asyncio.run(main())User registration, sign-in, session management, email verification, password reset, admin auth, and OAuth.
# Sign insession=awaitclient.auth.sign_in_with_password(email="...", password="...")
# Create useruser=awaitclient.auth.create_user(email="...", password="...")
# Email verificationawaitclient.auth.send_email_verification(email="...")
awaitclient.auth.verify_email(email="...", otp="123456")
# Password resetawaitclient.auth.send_reset_password_email(email="...")
resp=awaitclient.auth.exchange_reset_password_token(email="...", code="123456")
awaitclient.auth.reset_password(new_password="...", token=resp.token)
# User management (admin)users=awaitclient.auth.list_users(access_token=admin_token)
awaitclient.auth.delete_users(["user-id-1"], access_token=admin_token)
# Configawaitclient.auth.get_config(access_token=admin_token)
awaitclient.auth.update_config({"requireEmailVerification": True}, access_token=admin_token)PostgREST-style query builder and table administration.
# Query recordsrows=awaitclient.database.from_("posts") \
.select("id,title") \
.eq("status", "published") \
.order("created_at", desc=True) \
.limit(10) \
.execute()
# Insertawaitclient.database.from_("posts").insert([{"title": "Hello", "status": "draft"}])
# Update with filtersawaitclient.database.from_("posts").eq("id", 1).update({"status": "published"})
# Delete with filtersawaitclient.database.from_("posts").eq("id", 1).delete()
# Table admintables=awaitclient.database.list_tables()
schema=awaitclient.database.get_table_schema("posts")
awaitclient.database.create_table(
table_name="comments",
columns=[{"name": "id", "type": "uuid", "nullable": False}],
)
awaitclient.database.update_table_schema("comments", add_columns=[...])
awaitclient.database.delete_table("comments")Object upload, download, and deletion.
buckets=awaitclient.storage.list_buckets()
awaitclient.storage.upload_object("my-bucket", "photos/cat.jpg", image_bytes, content_type="image/jpeg")
data=awaitclient.storage.download_object("my-bucket", "photos/cat.jpg")
awaitclient.storage.delete_object("my-bucket", "photos/cat.jpg")Serverless function admin and invocation.
# CRUDawaitclient.functions.create_function(name="greet", code="export default (req) => ...", access_token=token)
fns=awaitclient.functions.list_functions(access_token=token)
fn=awaitclient.functions.get_function("greet", access_token=token)
awaitclient.functions.update_function("greet", code="...", access_token=token)
awaitclient.functions.delete_function("greet", access_token=token)
# Invokeresult=awaitclient.functions.invoke("greet", body={"name": "World"})Chat completions, image generation, embeddings, configuration, usage tracking, and credits.
frominsforge.ai.modelsimportAIChatMessage# Chatresp=awaitclient.ai.chat_completion(
model="openai/gpt-4o",
messages=[AIChatMessage(role="user", content="Hello!")],
access_token=token,
)
print(resp.text)
# Image generationimages=awaitclient.ai.generate_images(model="openai/dall-e-3", prompt="A cat", access_token=token)
# Embeddingsemb=awaitclient.ai.generate_embeddings(model="openai/text-embedding-3-small", input="hello", access_token=token)
# Configuration & usageconfigs=awaitclient.ai.list_configurations(access_token=token)
summary=awaitclient.ai.get_usage_summary(access_token=token)
credits=awaitclient.ai.get_credits(access_token=token)
models=awaitclient.ai.list_models(access_token=token)awaitclient.email.send_raw(
to="recipient@example.com",
subject="Hello",
html="<h1>Hi there</h1>",
access_token=token,
)app=awaitclient.metadata.get_app_metadata()
db=awaitclient.metadata.get_database_metadata()
key=awaitclient.metadata.get_api_key()frominsforge.exceptionsimportInsforgeHTTPError, InsforgeAuthErrortry:
awaitclient.auth.sign_in_with_password(email="...", password="wrong")
exceptInsforgeAuthErrorase:
print(e.status_code, e.error, e.message, e.next_action)
exceptInsforgeHTTPErrorase:
print(e.method, e.path, e.status_code)Exception hierarchy:
InsforgeError- baseInsforgeHTTPError- HTTP errors (status code, parsed error/message)InsforgeAuthError- auth-specific HTTP errors
InsforgeValidationError- Pydantic validation failuresInsforgeSerializationError- serialization failures
The SDK uses Python's built-in logging module under the insforge logger. By default no logs are emitted. Call setup_logging to enable output:
importinsforge# INFO — SDK initialization details and important operation resultsinsforge.setup_logging("INFO")
# DEBUG — full HTTP request/response (method, URL, params, status code)insforge.setup_logging("DEBUG")You can also configure the insforge logger directly with the standard logging module for more advanced setups:
importlogginglogging.getLogger("insforge").setLevel(logging.DEBUG)The SDK is stateless - it never stores or caches tokens. Every method that requires user auth takes an explicit access_token parameter. The API key is sent as X-API-Key on every request automatically.
# API key only (default for all requests)config=awaitclient.auth.get_public_config()
# API key + bearer tokenme=awaitclient.auth.get_current_session(access_token="user_jwt_here")git clone <repo-url>cd insforge-python
python -m venv .venv &&source .venv/bin/activate
pip install -e ".[dev]"2>/dev/null || pip install -e .
pip install pytest pytest-asynciopython -m pytestpip install build
python -m buildThis produces dist/insforge-<version>.tar.gz and dist/insforge-<version>-py3-none-any.whl.
Publishing uses PyPI Trusted Publishing through .github/workflows/publish.yml; no PyPI API token is stored in GitHub. The workflow publishes both the wheel and source distribution and produces digital attestations.
- Update
project.versioninpyproject.tomland merge the change tomainafter CI passes. - Create and push an annotated tag that exactly matches the package version with a
vprefix:
git tag -a vX.Y.Z -m "vX.Y.Z"
git push origin vX.Y.ZThe tag triggers a build, metadata validation, and publication to PyPI. PEP 440 prerelease versions are supported as long as the tag exactly matches the version in pyproject.toml. After PyPI publication succeeds, stable X.Y.Z versions create a GitHub Release automatically; prerelease tags do not.
See LICENSE for details.