Metadata-Version: 2.4
Name: ics-ajgar
Version: 1.0.2
Summary: Python SDK for the IndicSpace (ICS) platform
Author-email: Indicspace Cloud Services <support@indicspace.com>
License: Apache-2.0
Project-URL: Homepage, https://indicspace.com
Project-URL: Docs, https://docs.indicspace.com/sdk/ics-ajgar
Keywords: indicspace,ics,cloud,sdk,ajgar
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28.0
Dynamic: license-file

# ics-ajgar

ics-ajgar is the official Python SDK for IndicSpace Cloud Services(ICS).
Built for Python developers who want to interact with ICS services including Object Storage, Managed Databases, KMS, Secrets, and IAM - all from a single, lightweight client.

ics-ajgar (pronounced uj-gar) is named after the Indian Python - one of the largest and most powerful snakes native to the Indian subcontinent. Like the python it is named after, ics-ajgar is built for the cloud ecosystem - infrastructure priced in rupees, data sovereign to region, compliant with Indian regulations.
ics-ajgar is maintained and published by ICS.
Full documentation at docs.indicspace.com/sdk/ics-ajgar.

[![PyPI version](https://img.shields.io/pypi/v/ics-ajgar.svg)](https://pypi.org/project/ics-ajgar/)
[![Python](https://img.shields.io/pypi/pyversions/ics-ajgar.svg)](https://pypi.org/project/ics-ajgar/)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)

---

## Install

```bash
pip install ics-ajgar
```

## Requirements

- Python 3.10+
- `requests >= 2.28.0`

---

## Quickstart

```python
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](https://console.indicspace.com) → 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 |

```python
# 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.

```python
# 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.

```python
# 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.

```python
# 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.

```python
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.

```python
# 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

```python
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](LICENSE)

Copyright 2026 Indicspace Cloud Services
