Observed since 21 Oct, 10:44 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Python SDK for the AI Forge Control Plane API
Python SDK for the AI Forge Control Plane API.
The SDK provides a typed, developer-friendly wrapper around AI Forge REST APIs for organizations, workspaces, connectors, service catalog, compute, storage, IAM, and long-running operations.
Package name:
ai-forge-sdk
Import name:ai_forge
CLI command:ai-forge
Install the following on your development machine:
3.10 or latermake optional, but recommendedvenvCheck Python version:
python --version
Expected:
Python 3.10+
git clone https://github.com/onstak/ai-forge-sdk-python.git
cd ai-forge-sdk-python
If you are using the generated template locally:
cd ai-forge-python-sdk-template
python -m venv .venv
source .venv/bin/activate
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m venv .venv
.\.venv\Scripts\activate.bat
Upgrade pip:
python -m pip install --upgrade pip
Install the package in editable mode with development dependencies:
pip install -e ".[dev]"
This installs:
Verify package import:
python -c "import ai_forge; print(ai_forge.__version__)"
Verify CLI:
ai-forge --version
Create a local .env file from the example file:
cp .env.example .env
Update .env:
AI_FORGE_BASE_URL=https://api.ai-forge.example.com
AI_FORGE_API_KEY=replace-with-api-key
AI_FORGE_BEARER_TOKEN=
AI_FORGE_TENANT_ID=replace-with-tenant-id
AI_FORGE_WORKSPACE_ID=replace-with-workspace-id
AI_FORGE_TIMEOUT_SECONDS=30
AI_FORGE_MAX_RETRIES=3
| Variable | Required | Description |
|---|---|---|
AI_FORGE_BASE_URL | Yes | Base URL of the AI Forge API Gateway |
AI_FORGE_API_KEY | Recommended | API key for SDK authentication |
AI_FORGE_BEARER_TOKEN | Optional | OAuth/OIDC bearer token. Takes priority over API key if set |
AI_FORGE_TENANT_ID | Optional | Tenant scope header |
AI_FORGE_WORKSPACE_ID | Optional | Workspace scope header |
AI_FORGE_TIMEOUT_SECONDS | Optional | HTTP timeout. Default is 30 |
AI_FORGE_MAX_RETRIES | Optional | Retry count for transient errors. Default is 3 |
Do not commit
.envto Git.
To load .env variables manually in Linux/macOS:
set -a
source .env
set +a
In Windows PowerShell:
$env:AI_FORGE_BASE_URL="https://api.ai-forge.example.com"
$env:AI_FORGE_API_KEY="replace-with-api-key"
$env:AI_FORGE_TENANT_ID="replace-with-tenant-id"
$env:AI_FORGE_WORKSPACE_ID="replace-with-workspace-id"
from ai_forge import AIForgeClient
with AIForgeClient.from_env() as client:
workspaces = client.workspaces.list()
for workspace in workspaces.items:
print(workspace.id, workspace.name, workspace.status)
Run:
python examples/list_workspaces.py
Use this when you do not want to rely on environment variables:
from ai_forge import AIForgeClient, AIForgeConfig
config = AIForgeConfig(
base_url="https://api.ai-forge.example.com",
api_key="replace-with-api-key",
tenant_id="tenant-uuid",
workspace_id="workspace-uuid",
timeout_seconds=30,
max_retries=3,
)
with AIForgeClient(config) as client:
catalog_items = client.service_catalog.list()
print(catalog_items.items)
Show version:
ai-forge --version
List workspaces:
ai-forge workspaces
List service catalog items:
ai-forge catalog
The CLI reads configuration from the same environment variables used by AIForgeClient.from_env().
from ai_forge import AIForgeClient
with AIForgeClient.from_env() as client:
page = client.workspaces.list(limit=50)
for workspace in page.items:
print(workspace.id, workspace.name)
from ai_forge import AIForgeClient
from ai_forge.models import CreateWorkspaceRequest
request = CreateWorkspaceRequest(
name="demo-workspace",
organizationId="organization-uuid",
)
with AIForgeClient.from_env() as client:
workspace = client.workspaces.create(
request,
idempotency_key="create-workspace-demo-001",
)
print(workspace.id)
from ai_forge import AIForgeClient
workspace_id = "workspace-uuid"
with AIForgeClient.from_env() as client:
connectors = client.connectors.list(workspace_id)
for connector in connectors.items:
print(connector.id, connector.name, connector.connector_type, connector.status)
from ai_forge import AIForgeClient
from ai_forge.models import CreateConnectorRequest
workspace_id = "workspace-uuid"
request = CreateConnectorRequest(
name="openshift-prod",
connectorType="openshift",
endpoint="https://api.openshift.example.com:6443",
credentialsRef="vault://tenants/demo/workspaces/main/connectors/openshift-prod",
config={
"watchNamespaces": ["default", "apps"],
"enableMetrics": True,
},
)
with AIForgeClient.from_env() as client:
operation = client.connectors.create(
workspace_id,
request,
idempotency_key="create-connector-openshift-prod-001",
)
print(operation.id, operation.status)
from ai_forge import AIForgeClient
workspace_id = "workspace-uuid"
with AIForgeClient.from_env() as client:
operation = client.compute.create_vm(
workspace_id,
name="demo-vm-01",
instance_type="standard-2c-8g",
image="ubuntu-22.04",
disk_gb=80,
idempotency_key="create-demo-vm-01",
)
print(operation.id, operation.status)
from ai_forge import AIForgeClient
operation_id = "operation-uuid"
with AIForgeClient.from_env() as client:
result = client.operations.wait(
operation_id,
timeout_seconds=600,
poll_interval_seconds=5,
)
print(result.status)
from ai_forge import AIForgeClient
workspace_id = "workspace-uuid"
with AIForgeClient.from_env() as client:
operation = client.storage.create_bucket(
workspace_id,
name="ml-datasets",
region="us-east-1",
versioning_enabled=True,
encrypted=True,
idempotency_key="create-bucket-ml-datasets-001",
)
print(operation.id, operation.status)
Run all tests:
pytest
Run tests with coverage:
pytest --cov=ai_forge --cov-report=term-missing
Run one test file:
pytest tests/test_client.py
Run one test case:
pytest tests/test_client.py::test_client_lists_workspaces
Using Makefile:
make test
Format code:
ruff format src tests
Auto-fix lint issues:
ruff check --fix src tests
Check lint only:
ruff check src tests
Run type checking:
mypy src
Using Makefile:
make format
make lint
Install pre-commit hooks:
pre-commit install
Run hooks manually:
pre-commit run --all-files
Clean old build artifacts:
rm -rf dist build *.egg-info src/*.egg-info
Build source distribution and wheel:
python -m build
Validate package metadata:
python -m twine check dist/*
Using Makefile:
make build
Expected output:
dist/ai_forge_sdk-<version>.tar.gz
dist/ai_forge_sdk-<version>-py3-none-any.whl
Create a clean temporary environment:
python -m venv /tmp/ai-forge-sdk-test
source /tmp/ai-forge-sdk-test/bin/activate
python -m pip install --upgrade pip
Install the built wheel:
pip install dist/*.whl
Verify import:
python -c "from ai_forge import AIForgeClient; print(AIForgeClient)"
Verify CLI:
ai-forge --version
Deactivate:
deactivate
Install documentation dependencies:
pip install -e ".[docs]"
Serve docs locally:
mkdocs serve
Open:
http://127.0.0.1:8000
Build static docs:
mkdocs build
Build first:
make build
Upload to TestPyPI:
python -m twine upload --repository testpypi dist/*
Using Makefile:
make publish-test
Install from TestPyPI in a clean environment:
python -m venv /tmp/ai-forge-testpypi
source /tmp/ai-forge-testpypi/bin/activate
python -m pip install --upgrade pip
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple ai-forge-sdk
Verify:
python -c "import ai_forge; print(ai_forge.__version__)"
Only publish to PyPI after validating the package on TestPyPI.
make build
python -m twine upload dist/*
Using Makefile:
make publish
Install from PyPI:
pip install ai-forge-sdk
The package version is stored in:
src/ai_forge/__about__.py
Example:
__version__ = "0.1.0"
Recommended versioning strategy:
0.1.0 Initial alpha SDK
0.2.0 New resources or non-breaking features
0.2.1 Bug fixes
1.0.0 Stable public SDK contract
Update version before every release:
sed -i 's/__version__ = "0.1.0"/__version__ = "0.2.0"/' src/ai_forge/__about__.py
On macOS:
sed -i '' 's/__version__ = "0.1.0"/__version__ = "0.2.0"/' src/ai_forge/__about__.py
The template includes GitHub Actions workflows:
.github/workflows/ci.yml
.github/workflows/publish.yml
Runs automatically on pull requests and pushes.
Typical checks:
Publishes the package when a release tag is created.
Recommended tag format:
git tag v0.1.0
git push origin v0.1.0
Add this repository secret in GitHub:
PYPI_API_TOKEN
Use a PyPI API token, not your PyPI password.
.
├── pyproject.toml
├── README.md
├── LICENSE
├── Makefile
├── .env.example
├── src/
│ └── ai_forge/
│ ├── __init__.py
│ ├── __about__.py
│ ├── auth.py
│ ├── client.py
│ ├── config.py
│ ├── exceptions.py
│ ├── pagination.py
│ ├── transport.py
│ ├── cli.py
│ ├── models/
│ └── resources/
├── tests/
├── examples/
├── docs/
└── .github/workflows/
| File | Purpose |
|---|---|
pyproject.toml | Python package metadata, dependencies, build config |
src/ai_forge/client.py | Main SDK client |
src/ai_forge/config.py | Runtime config and environment loading |
src/ai_forge/transport.py | HTTP transport, retries, headers, error handling |
src/ai_forge/auth.py | API key / bearer token auth providers |
src/ai_forge/resources/ | API resource clients |
src/ai_forge/models/ | Pydantic request/response models |
tests/ | Unit tests |
examples/ | Usage examples |
docs/ | MkDocs documentation |
Recommended daily workflow:
source .venv/bin/activate
pip install -e ".[dev]"
make format
make lint
make test
Before opening a pull request:
make format
make lint
make test
make build
Before releasing:
rm -rf dist build *.egg-info src/*.egg-info
make lint
make test
make build
python -m twine check dist/*
from ai_forge import AIForgeClient
from ai_forge.exceptions import AIForgeAPIError, AIForgeAuthenticationError, AIForgeRateLimitError
try:
with AIForgeClient.from_env() as client:
workspaces = client.workspaces.list()
except AIForgeAuthenticationError:
print("Invalid or expired AI Forge credentials")
except AIForgeRateLimitError:
print("Rate limit exceeded. Retry later")
except AIForgeAPIError as exc:
print(exc.message)
print(exc.error_code)
print(exc.details)
from ai_forge import AIForgeClient
with AIForgeClient.from_env() as client:
cursor = None
while True:
page = client.workspaces.list(cursor=cursor, limit=100)
for workspace in page.items:
print(workspace.id, workspace.name)
if not page.next_cursor:
break
cursor = page.next_cursor
Use idempotency keys for create/update operations that may be retried safely:
operation = client.compute.create_vm(
workspace_id="workspace-uuid",
name="demo-vm-01",
instance_type="standard-2c-8g",
image="ubuntu-22.04",
disk_gb=80,
idempotency_key="create-demo-vm-01",
)
Required environment variable is missing: AI_FORGE_BASE_URLSet the base URL:
export AI_FORGE_BASE_URL="https://api.ai-forge.example.com"
401 UnauthorizedCheck that one of these is valid:
export AI_FORGE_API_KEY="your-api-key"
# or
export AI_FORGE_BEARER_TOKEN="your-oauth-token"
403 ForbiddenThe token is valid, but the user/service account does not have permission for the target tenant, workspace, or resource.
429 Too Many RequestsThe AI Forge API Gateway rate limit was reached. Increase backoff, reduce concurrency, or request a quota increase.
ModuleNotFoundError: No module named 'ai_forge'Install the SDK locally:
pip install -e ".[dev]"
mypy fails after adding new modelsMake sure all fields are typed and Pydantic aliases are declared correctly:
from pydantic import Field
workspace_id: str = Field(alias="workspaceId")
Before every release:
src/ai_forge/__about__.pyCHANGELOG.md if availablemake formatmake lintmake testmake buildMIT License. See LICENSE.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.2.4 | 8 Jul 2026 | 14 |
This describes our collected data; it is not a security assessment.
Shared repository data · GitHub
Observed since 21 Oct, 10:44 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:69c91b0c20618dadfecdacc8adca62c9637e7e306a624bcccab59fb0f68c4d66