Skip to main content

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.

PyPI version Python License


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


License

Apache 2.0 - see LICENSE

Copyright 2026 Indicspace Cloud Services

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ics_ajgar-1.0.1.tar.gz (27.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ics_ajgar-1.0.1-py3-none-any.whl (29.9 kB view details)

Uploaded Python 3

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

Hashes for ics_ajgar-1.0.1.tar.gz
Algorithm Hash digest
SHA256 f93f3322819ee480b4d4299dc1faf064c7c5e4bd51ee53a803fe24246f32883f
MD5 3e22574822844d0c9dd44b90428d9794
BLAKE2b-256 a10c78609d40d3c6b51a64dcb3bc79a8963514910b49dc4b20d1bc7b09a1a059

See more details on using hashes here.

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

Hashes for ics_ajgar-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 661810b3b22fe2414e2fa14dbf3ecb7b5dbc309fce87390d034d24a01e659a65
MD5 dbcbf22d20f9e456c7464a946d62c4b3
BLAKE2b-256 598fb3969c29eff61993b2b8a045594830d85d4660ec14a4d02ad172633d12c6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page