Python SDK for the IndicSpace (ICS) platform
Project description
ics-ajgar
Official Python SDK for the IndicSpace (ICS) platform - India's sovereign cloud.
Built on bare metal in Mumbai. Priced in rupees. Built for Indian startups, enterprises, and regulated industries.
Install
pip install ics-ajgar
Requirements
- Python 3.10+
requests >= 2.28.0
Quickstart
import ajgar
client = ajgar.Client(
key_id="KEY_2026_00003",
secret="ICS_AK_xxxx_xxxx",
region="ICS-MUM",
)
Get your API key from the ICS Console → IAM → API Keys.
Regions
| Region | Location | Status |
|---|---|---|
ICS-MUM |
Mumbai | Live |
ICS-DEV |
Development | Live |
ICS-HYD |
Hyderabad | Coming Soon |
ICS-NOI |
Noida | Coming Soon |
ICS-DXB |
Dubai | Coming Soon |
# Production
client = ajgar.Client(key_id="...", secret="...", region="ICS-MUM")
# Development
client = ajgar.Client(key_id="...", secret="...", region="ICS-DEV")
ICS Object
Object storage with standard and vector buckets, secured by envelope encryption.
# Buckets
bucket = client.object.create_bucket("my-bucket")
client.object.wait_until_active(bucket["name"])
client.object.list_buckets()
client.object.get_bucket("my-bucket")
client.object.delete_bucket("my-bucket")
# Objects
client.object.upload("my-bucket", "reports/q1.csv", open("q1.csv", "rb").read())
data = client.object.download("my-bucket", "reports/q1.csv")
client.object.list("my-bucket", prefix="reports/")
client.object.delete("my-bucket", "reports/q1.csv")
# Vectors
client.object.upsert_vectors("my-bucket", [{"id": "v1", "values": [0.1, 0.2, 0.3]}])
results = client.object.search_vectors("my-bucket", query_vector=[0.1, 0.2, 0.3], top_k=5)
client.object.get_vector("my-bucket", "v1")
client.object.delete_vector("my-bucket", "v1")
ICS Database
Managed databases - PostgreSQL, MySQL, MongoDB, Cassandra.
# Create and wait
instance = client.database.create("my-db", engine="postgres", size="small")
client.database.wait_until_active(instance["instance_id"])
# Manage
client.database.list()
client.database.get("ICS-DB-001")
client.database.update("ICS-DB-001", size="medium")
client.database.delete("ICS-DB-001")
# Credentials
creds = client.database.get_credentials("ICS-DB-001")
# SQL - Vajra (PostgreSQL) / Tez (MySQL)
result = client.database.query(
"ICS-DB-001",
"SELECT * FROM users WHERE id = %s",
[user_id],
)
# MongoDB - Sutra
result = client.database.find(
"ICS-DB-002",
collection="users",
filter={"status": "active"},
)
# Cassandra - Sagar
result = client.database.cql(
"ICS-DB-003",
"SELECT * FROM events WHERE org_id = ?",
["ICS-00000067"],
)
# Backups
client.database.create_backup("ICS-DB-001")
client.database.list_backups("ICS-DB-001")
client.database.restore_backup("ICS-DB-001", "backup-id")
# Export to Object storage
client.database.export_to_object("ICS-DB-001", bucket="my-bucket", key="dumps/pg.dump")
ICS KMS
Customer-managed encryption keys with envelope encryption support.
# Keys
key = client.kms.create_key("app-master-key", description="Encrypts user PII")
client.kms.list_keys()
client.kms.describe_key("KEY-001")
client.kms.rotate("KEY-001")
client.kms.disable("KEY-001")
client.kms.enable("KEY-001")
client.kms.schedule_deletion("KEY-001", pending_days=7)
client.kms.cancel_deletion("KEY-001")
# Encrypt / Decrypt
enc = client.kms.encrypt("KEY-001", "my secret value")
dec = client.kms.decrypt("KEY-001", enc["ciphertext"])
# Envelope encryption
dk = client.kms.generate_data_key("KEY-001")
# encrypt your data with dk["plaintext_data_key"]
# store dk["encrypted_data_key"] alongside your ciphertext
# discard dk["plaintext_data_key"]
ICS Secrets
Encrypted secret storage with versioning and rotation.
client.secrets.create("DB_PASSWORD", "supersecret123")
secret = client.secrets.get("DB_PASSWORD") # {"value": "...", "version": 1}
client.secrets.list()
client.secrets.update("DB_PASSWORD", "newvalue")
client.secrets.rotate("DB_PASSWORD", "rotatedvalue")
client.secrets.get_version("DB_PASSWORD", 1) # get previous version
client.secrets.delete("DB_PASSWORD")
ICS IAM
Users, roles, policies, groups, and API key management.
# Users
client.iam.list_users()
client.iam.invite_user("dev@startup.com")
client.iam.get_user("user-id")
client.iam.suspend_user("user-id")
client.iam.reactivate_user("user-id")
client.iam.delete_user("user-id")
# Roles
role = client.iam.create_role("developer")
client.iam.assign_role(role["id"], "user-id")
client.iam.list_roles()
# Policies
policy = client.iam.create_policy(
"object-read-only",
statements=[{"effect": "allow", "action": "object:read", "resource": "*"}],
)
client.iam.attach_role_policy(role["id"], policy["id"])
client.iam.list_policies()
# Groups
group = client.iam.create_group("backend-team")
client.iam.add_group_member(group["id"], "user-id")
client.iam.assign_group_role(group["id"], role["id"])
# API Keys
key = client.iam.create_api_key(
"ci-pipeline",
scopes=["object:read", "database:write"],
expires_in_days=90,
)
# key["secret"] is shown once - store it immediately
client.iam.rotate_api_key(key["id"])
client.iam.revoke_api_key(key["id"])
# Check permission
result = client.iam.check_permission("object:read", "my-bucket")
print(result["allowed"]) # True or False
Error Handling
from ajgar import (
ICSError,
AuthError,
APIKeyInvalidError,
APIKeyExpiredError,
OrgSuspendedError,
PermissionDeniedError,
NotFoundError,
AlreadyExistsError,
ValidationError,
BillingError,
RateLimitError,
QuotaError,
ServerError,
ServiceUnavailableError,
)
try:
data = client.object.download("my-bucket", "missing.csv")
except NotFoundError as e:
print(e.code, e.message)
except APIKeyInvalidError:
print("invalid or revoked API key")
except APIKeyExpiredError:
print("API key expired - create a new one in ICS Console")
except OrgSuspendedError:
print("organisation suspended - check billing")
except BillingError:
print("credits exhausted - add payment method")
except RateLimitError as e:
print(f"rate limited - retry after {e.retry_after}s")
except ServerError:
print("server error - retried automatically 3 times")
except ICSError as e:
print(f"unexpected error: {e}")
Retryable errors (ICS_ERR_INTERNAL, ICS_ERR_DB_CONNECTION, ICS_ERR_SERVICE_UNREACHABLE etc.)
are retried automatically up to 3 times with exponential backoff (1s → 2s → 4s).
Links
- Website: https://indicspace.com
- Console: https://console.indicspace.com
- Docs: https://docs.indicspace.com/sdk/ics-ajgar
- Support: support@indicspace.com
- PyPI: https://pypi.org/project/ics-ajgar
License
Apache 2.0 - see LICENSE
Copyright 2026 Indicspace Cloud Services
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 ics_ajgar-1.0.1.tar.gz.
File metadata
- Download URL: ics_ajgar-1.0.1.tar.gz
- Upload date:
- Size: 27.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f93f3322819ee480b4d4299dc1faf064c7c5e4bd51ee53a803fe24246f32883f
|
|
| MD5 |
3e22574822844d0c9dd44b90428d9794
|
|
| BLAKE2b-256 |
a10c78609d40d3c6b51a64dcb3bc79a8963514910b49dc4b20d1bc7b09a1a059
|
File details
Details for the file ics_ajgar-1.0.1-py3-none-any.whl.
File metadata
- Download URL: ics_ajgar-1.0.1-py3-none-any.whl
- Upload date:
- Size: 29.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
661810b3b22fe2414e2fa14dbf3ecb7b5dbc309fce87390d034d24a01e659a65
|
|
| MD5 |
dbcbf22d20f9e456c7464a946d62c4b3
|
|
| BLAKE2b-256 |
598fb3969c29eff61993b2b8a045594830d85d4660ec14a4d02ad172633d12c6
|