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:
- Environment variable —
DATABASE_URL config.ini—[database] url = ...- 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
VivekaLogManageris a singleton.init()only runs once — subsequent calls are no-ops unless you pass a new config.get_instance()can be called beforeinit()— it auto-initializes withINFOlevel 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
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 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d4433250ea28291e63c6303ed77c7347ee179d83a049186a59f5fe98d4283758
|
|
| MD5 |
7f2a3112e6c87a0ed55f889cacd0f415
|
|
| BLAKE2b-256 |
44afd545744ae604a22ea4159e5064e234954b1ba00537a805235ef48b7cd7a1
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
07f521f69869c2e2c81ed012eb8eaf921ac25678c42b17e24d97f8194fc9e923
|
|
| MD5 |
314ac23a9a44dcab164aa39847df16b9
|
|
| BLAKE2b-256 |
045cf43c7cd386af5b1e121456f50e96f6f38456f163b81f084da895bbefab83
|