Metadata-Version: 2.4
Name: viveka-grantha
Version: 0.1.0
Summary: Core shared library for Viveka — config, logging, and async cache management
License: VIVEKASUTRA PROPRIETARY SOFTWARE LICENSE
        
        Copyright (c) 2025 VivekaSutra. All rights reserved.
        https://vivekasutra.com/
        
        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
        IMPORTANT: READ THIS LICENSE CAREFULLY BEFORE DOWNLOADING,
        INSTALLING, OR USING THIS SOFTWARE.
        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
        
        By downloading, installing, or using this software ("viveka-grantha"),
        you agree to be bound by the terms of this license agreement.
        If you do not agree, do not download, install, or use this software.
        
        
        1. GRANT OF LICENSE
           VivekaSutra grants you a limited, non-exclusive, non-transferable,
           royalty-free license to download and use this software solely for
           your personal or internal business purposes.
        
        
        2. RESTRICTIONS
           You may NOT:
           a) Copy, modify, merge, or create derivative works of this software.
           b) Distribute, sell, sublicense, rent, lease, or transfer this
              software or any rights in it to any third party.
           c) Reverse engineer, decompile, disassemble, or attempt to derive
              the source code of this software.
           d) Remove, alter, or obscure any proprietary notices, labels,
              or markings on this software.
           e) Use this software to build a competing product or service.
        
        
        3. INTELLECTUAL PROPERTY
           This software and all copies thereof are proprietary to VivekaSutra.
           All title, ownership rights, and intellectual property rights in and
           to this software remain exclusively with VivekaSutra. This license
           does not grant you any rights to trademarks, service marks, or trade
           names of VivekaSutra.
        
        
        4. NO WARRANTY
           THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
           EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
           MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
           NON-INFRINGEMENT.
        
           VIVEKASUTRA DOES NOT WARRANT THAT:
           a) THE SOFTWARE WILL MEET YOUR REQUIREMENTS.
           b) THE SOFTWARE WILL OPERATE UNINTERRUPTED OR ERROR-FREE.
           c) ANY ERRORS IN THE SOFTWARE WILL BE CORRECTED.
           d) THE SOFTWARE IS COMPATIBLE WITH YOUR SYSTEMS OR ENVIRONMENT.
        
           YOU ASSUME ALL RISK ASSOCIATED WITH THE USE OF THIS SOFTWARE.
        
        
        5. LIMITATION OF LIABILITY
           TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
           VIVEKASUTRA, ITS DIRECTORS, EMPLOYEES, PARTNERS, AGENTS, SUPPLIERS,
           OR AFFILIATES BE LIABLE FOR ANY:
        
           a) DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
              CONSEQUENTIAL DAMAGES.
           b) LOSS OF PROFITS, REVENUE, DATA, BUSINESS, OR GOODWILL.
           c) BUSINESS INTERRUPTION OR LOSS OF BUSINESS OPPORTUNITY.
           d) COST OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES.
           e) ANY OTHER COMMERCIAL OR ECONOMIC LOSS.
        
           THIS LIMITATION APPLIES REGARDLESS OF WHETHER SUCH DAMAGES ARISE
           FROM CONTRACT, TORT, NEGLIGENCE, STRICT LIABILITY, OR ANY OTHER
           LEGAL THEORY, AND EVEN IF VIVEKASUTRA HAS BEEN ADVISED OF THE
           POSSIBILITY OF SUCH DAMAGES.
        
        
        6. INDEMNIFICATION
           You agree to indemnify, defend, and hold harmless VivekaSutra and
           its affiliates from and against any claims, liabilities, damages,
           losses, and expenses (including legal fees) arising out of or in
           connection with your use of this software or your violation of
           this license.
        
        
        7. TERMINATION
           This license is effective until terminated. Your rights under this
           license will terminate automatically and without notice from
           VivekaSutra if you fail to comply with any of its terms and
           conditions. Upon termination, you must immediately cease all use
           of this software and destroy all copies in your possession.
        
        
        8. GOVERNING LAW
           This license shall be governed by and construed in accordance with
           applicable laws. Any disputes arising under this license shall be
           subject to the exclusive jurisdiction of the competent courts.
        
        
        9. ENTIRE AGREEMENT
           This license constitutes the entire agreement between you and
           VivekaSutra with respect to this software and supersedes all prior
           or contemporaneous understandings, agreements, or representations.
        
        
        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
        For licensing inquiries or permissions beyond the scope of this
        license, please contact us at: https://vivekasutra.com/
        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
        
        VivekaSutra
        https://vivekasutra.com/
        Copyright (c) 2025. All rights reserved.
        
Project-URL: Homepage, https://vivekasutra.com/
Project-URL: Source, https://github.com/vivekasutra/viveka-grantha
Keywords: config,logging,cache,redis,async,viveka
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: Other/Proprietary License
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Framework :: AsyncIO
Classifier: Typing :: Typed
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE.txt
Requires-Dist: redis>=5.0
Requires-Dist: hiredis>=2.0
Requires-Dist: aiohttp>=3.9
Provides-Extra: dev
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Dynamic: license-file

# viveka-grantha

Core shared library for the Viveka platform — provides configuration management, structured logging, and async cache management as reusable infrastructure components.

Developed by [VivekaSutra](https://vivekasutra.com/)

---

## Overview

viveka-grantha is the foundation layer that all Viveka services depend on. It solves three cross-cutting concerns so individual services don't have to:

| Module | What it does |
|---|---|
| `viveka_common.config` | Reads config from `config.ini` and environment variables with a unified API |
| `viveka_common.log` | Singleton logging manager with console and rotating file handlers |
| `viveka_common.cache` | Async Redis cache with a pluggable backend interface |

---

## Installation

```bash
pip install viveka-grantha
```

---

## Configuration

### Structure

viveka-grantha reads from a `config.ini` file using `section.key` dot notation.

`config.ini`:

```ini
[app]
name    = my-service
env     = production

[logging]
level         = INFO
file_enabled  = true
file_path     = logs/app.log
console_enabled = true

[cache]
enabled     = true
backend     = redis
url         = redis://localhost:6379/0
default_ttl = 3600
```

### Priority order

When you call `config.get("database.url")`, the service checks in this order:

1. Environment variable — `DATABASE_URL`
2. `config.ini` — `[database] url = ...`
3. Default value you provide

This means you can override any config value with an environment variable without touching the file — useful for Docker and cloud deployments.

### Usage

```python
from viveka_common.config import ConfigService

config = ConfigService()                          # reads config.ini from current directory
config = ConfigService("path/to/config.ini")     # custom path

# Get values
db_url  = config.get("database.url")
port    = config.get("api.port", default=8000, data_type=int)
debug   = config.get("app.debug", default=False, data_type=bool)
hosts   = config.get("app.allowed_hosts", data_type=list)  # comma-separated in ini

# Read from environment variable directly
token = config.get_env_variable("api.secret_key")  # reads API_SECRET_KEY env var
```

`ConfigService` is a singleton — calling `ConfigService()` anywhere in the application returns the same instance initialized at startup.

### Supported data types

| Type | Config.ini example | Result |
|---|---|---|
| `str` (default) | `name = viveka` | `"viveka"` |
| `int` | `port = 8080` | `8080` |
| `float` | `timeout = 3.5` | `3.5` |
| `bool` | `debug = true` | `True` |
| `list` | `hosts = a.com, b.com` | `["a.com", "b.com"]` |

---

## Logging

### Setup

Initialize once at application startup before any other code runs:

```python
from viveka_common.log import VivekaLogManager, VivekaLoggingConfig

VivekaLogManager.init(VivekaLoggingConfig(
    level           = "INFO",
    console_enabled = True,
    file_enabled    = True,
    file_path       = "logs/app.log",
    file_max_bytes  = 10_485_760,   # 10 MB
    file_backup_count = 5,
))
```

### Getting a logger

Any class or module gets its own named logger:

```python
from viveka_common.log import VivekaLogManager

_logger = VivekaLogManager.get_instance(__name__)

class UserService:
    def create_user(self, name: str):
        _logger.info(f"Creating user: {name}")
        _logger.debug("Debug details here")
        _logger.error("Something went wrong", exc_info=True)
```

### VivekaLoggingConfig options

| Field | Default | Description |
|---|---|---|
| `level` | `"INFO"` | Root log level — DEBUG, INFO, WARNING, ERROR, CRITICAL |
| `format` | standard format | Log line format string |
| `console_enabled` | `True` | Print logs to stdout |
| `console_level` | inherits `level` | Override level for console only |
| `file_enabled` | `True` | Write logs to a rotating file |
| `file_path` | `"logs/viveka.log"` | Log file path |
| `file_level` | inherits `level` | Override level for file only |
| `file_max_bytes` | `10485760` (10 MB) | Max size before rotation |
| `file_backup_count` | `5` | Number of rotated files to keep |

### Notes

- `VivekaLogManager` is a singleton. `init()` only runs once — subsequent calls are no-ops unless you pass a new config.
- `get_instance()` can be called before `init()` — it auto-initializes with `INFO` level defaults.
- Rotating file handler prevents log files from growing unbounded.

---

## Cache

### Setup

Initialize once at application startup:

```python
from viveka_common.cache import VivekaCacheConfig, RedisCacheService, VivekaCacheManager

config = VivekaCacheConfig(
    enabled     = True,
    url         = "redis://localhost:6379/0",
    default_ttl = 3600,
)

service = RedisCacheService(config)
VivekaCacheManager.init(service)
```

To disable caching entirely without changing call sites:

```python
VivekaCacheConfig(enabled=False)  # all cache ops become silent no-ops
```

### Using the cache manager

`VivekaCacheManager` is the single access point for all cache operations across the application. All methods are async.

```python
from viveka_common.cache import VivekaCacheManager

# Store a value (ttl in seconds, optional — uses default_ttl if omitted)
await VivekaCacheManager.set("user:123", {"id": 123, "name": "Arjun"}, ttl=3600)

# Retrieve a value
user = await VivekaCacheManager.get("user:123")   # returns None on miss

# Delete a single key
await VivekaCacheManager.delete("user:123")

# Delete all keys matching a pattern (used by @cache_evict)
await VivekaCacheManager.delete_pattern("user:*")

# Health check
is_alive = await VivekaCacheManager.ping()
```

If the cache backend is down, every operation logs an error and returns a safe default (`None` / `False`) — business logic is never interrupted.

### Custom cache backend

`VivekaCacheService` is an abstract interface. You can implement your own backend (Memcached, in-memory, etc.) and plug it in:

```python
from viveka_common.cache import VivekaCacheService, VivekaCacheManager

class InMemoryCacheService(VivekaCacheService):
    def __init__(self):
        self._store = {}

    async def get(self, key): return self._store.get(key)
    async def set(self, key, value, ttl=None): self._store[key] = value; return True
    async def delete(self, key): self._store.pop(key, None); return True
    async def delete_pattern(self, pattern): ...
    async def ping(self): return True

VivekaCacheManager.init(InMemoryCacheService())
```

---

## Full startup example

```python
from viveka_common.config import ConfigService
from viveka_common.log import VivekaLogManager, VivekaLoggingConfig
from viveka_common.cache import VivekaCacheConfig, RedisCacheService, VivekaCacheManager

def bootstrap():
    # 1. Config
    config = ConfigService("config.ini")

    # 2. Logging
    VivekaLogManager.init(VivekaLoggingConfig(
        level      = config.get("logging.level", default="INFO"),
        file_path  = config.get("logging.file_path", default="logs/app.log"),
    ))

    # 3. Cache
    cache_config = VivekaCacheConfig(
        enabled     = config.get("cache.enabled", default=False, data_type=bool),
        url         = config.get("cache.url", default="redis://localhost:6379/0"),
        default_ttl = config.get("cache.default_ttl", default=3600, data_type=int),
    )
    VivekaCacheManager.init(RedisCacheService(cache_config))
```

---

## Dependencies

| Package | Role |
|---|---|
| `redis` | Async Redis client (`redis.asyncio`) |
| `hiredis` | High-performance Redis protocol parser |
| `aiohttp` | Async HTTP client for service-to-service calls |

---

## Part of the Viveka Platform

viveka-grantha is the foundation layer of the Viveka ecosystem:

- **viveka-grantha** — config, logging, cache ← you are here
- **viveka-kosha** — async database / ORM layer (depends on viveka-grantha)

Developed and maintained by [VivekaSutra](https://vivekasutra.com/)

---

## License

Copyright (c) 2025 VivekaSutra. All rights reserved.

This software is distributed under the **VivekaSutra Proprietary Software License**.

- Free to download and use for personal or commercial purposes
- Modification, redistribution, and reverse engineering are not permitted
- Provided "AS IS" — no warranty of any kind
- VivekaSutra is not liable for any damages arising from use

See [LICENSE.txt](LICENSE.txt) for the full license text.
For licensing inquiries visit [vivekasutra.com](https://vivekasutra.com/)
