Skip to main content

Core shared library for Viveka — config, logging, and async cache management

Project description

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


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

pip install viveka-grantha

Configuration

Structure

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

config.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

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:

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:

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:

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:

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.

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:

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

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


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 for the full license text. For licensing inquiries visit vivekasutra.com

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

viveka_grantha-0.1.0.tar.gz (19.5 kB view details)

Uploaded Source

Built Distribution

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

viveka_grantha-0.1.0-py3-none-any.whl (18.7 kB view details)

Uploaded Python 3

File details

Details for the file viveka_grantha-0.1.0.tar.gz.

File metadata

  • Download URL: viveka_grantha-0.1.0.tar.gz
  • Upload date:
  • Size: 19.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for viveka_grantha-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d4433250ea28291e63c6303ed77c7347ee179d83a049186a59f5fe98d4283758
MD5 7f2a3112e6c87a0ed55f889cacd0f415
BLAKE2b-256 44afd545744ae604a22ea4159e5064e234954b1ba00537a805235ef48b7cd7a1

See more details on using hashes here.

File details

Details for the file viveka_grantha-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: viveka_grantha-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 18.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for viveka_grantha-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 07f521f69869c2e2c81ed012eb8eaf921ac25678c42b17e24d97f8194fc9e923
MD5 314ac23a9a44dcab164aa39847df16b9
BLAKE2b-256 045cf43c7cd386af5b1e121456f50e96f6f38456f163b81f084da895bbefab83

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