intugle-appcore 0.4.2
A modular core library with cryptography, logging, database, and messaging utilities.
Requires Python: >=3.10

# AppCore

A modular core library with cryptography, logging, database, and messaging utilities.

### Build wheel files

```shell
make build
```

### Install for development (runtime + dev dependencies)

```shell
make install
```

Or directly with pip:

```shell
pip install -e ".[dev]"
```

### Install runtime dependencies only

```shell
pip install .
```

## Setup

1. Add package keyrings.google-artifactregistry-auth in your python environment

```shell
pip install --no-cache-dir -U keyrings.google-artifactregistry-auth
```

2. Create envrionment vaiable GOOGLE_APPLICATION_CREDENTIALS pointing to your service account key json file.

```shell
export GOOGLE_APPLICATION_CREDENTIALS=$(path to service account)
```

3. Install appcore using extra index url as https://asia-south1-python.pkg.dev/dev-platform-444908/dev/simple

```shell
pip install --extra-index-url https://asia-south1-python.pkg.dev/dev-platform-444908/dev/simple appcore
```

OR in requirements file

```txt
--extra-index-url https://asia-south1-python.pkg.dev/dev-platform-444908/dev/simple
appcore
```

## Usage

### 1. Postgres


```python
# Create a singleton instance of asyncdb from appcore.db.psql
from appcore.db import PsqlPool

PsqlPool(
    user,
    password,
    host,
    database,
    port="5432",
    schema="public",
    min_pool_size: int = 1,
    max_pool_size: int = 10,
    command_timeout: int = 60,
)
```

### 2. Redis

```python
# Create a singleton instance of redis from appcore
from appcore.db import CacheDB

CacheDB(
    host: str = "localhost",
    database: str = "0",
    password: str = "",
    port: int = 6379,
    socket_timeout: int = 5,
    socket_connect_timeout: int = 5,
    socket_keepalive: bool = True,
    health_check_interval: int = 60,
    decode_response: bool = True,
    retry_on_timeout: bool = True,
    max_connections: int = 20,
    **kwargs,
)
```

### 3. Logger (NOT IMPLEMENTED)

### 4. Message Queue (Kafka)

### Producer

```python
from appcore.message_queue import Producer
import json

async def produce():
    producer = Producer(
        bootstrap_servers="localhost:9092",  # Replace with your Kafka brokers
        max_retries=20,                      # Default: 20
        retry_backoff_ms=10_000,            # Default: 10,000ms
        request_timeout_ms=10_000,          # Default: 10,000ms
        acks="all",                         # Default: "all"
        # Additional aiokafka producer options can be passed as **kwargs
    )
    async with producer:
        message = {"key": "value"}
        await producer._send(
            "my-topic",
            value=json.dumps(message).encode('utf-8'),  # Ensure message is encoded to bytes
            key=None  # Optional: message key
        )
```

### Consumer

```python
from appcore.message_queue import Consumer
import json

async def consume():
    consumer = Consumer(
        "my-topic",                         # Topic(s) to consume from
        bootstrap_servers="localhost:9092", # Replace with your Kafka brokers
        group_id="grp1",                    # Default: "grp1"
        auto_offset_reset="earliest",       # Default: "earliest"
        max_retries=20,                     # Default: 20
        retry_backoff_ms=10_000,           # Default: 10,000ms
        request_timeout_ms=10_000,         # Default: 10,000ms
        enable_auto_commit=False,          # Default: False
        # Additional aiokafka consumer options can be passed as **kwargs
    )
    async with consumer:
        async for msg in consumer:
            message = json.loads(msg.value.decode('utf-8'))
            print(f"Consumed: {message}")
            await consumer.commit({msg.topicPartition: msg.offset + 1})  # Commit offset after processing
```

### 5. Crypto

```python
from appcore.crypto import Crypto

# Initialize Crypto with a secret key
crypto = Crypto(key="your-secret-key", algorithm="HS256")

# Example payload
payload = {"user_id": 123, "username": "testuser"}

# Create a token that expires in 3600 seconds (1 hour)
token, expires = crypto.create_token(payload, expires_in=3600)
print(f"Generated token: {token}")

# Decode the token
decoded_payload = crypto.decode_token(token)
print(f"Decoded payload: {decoded_payload}")

# Hash a value
hashed_value = crypto.hash_value("some-value-to-hash")
print(f"Hashed value: {hashed_value}")

```