Metadata-Version: 2.4
Name: penguin-libs
Version: 0.1.0
Summary: Shared Python libraries for Penguin Tech applications
Author-email: Penguin Tech Inc <dev@penguintech.io>
License: AGPL-3.0
Project-URL: Homepage, https://www.penguintech.io
Project-URL: Repository, https://github.com/penguintechinc/penguin-libs
Project-URL: Issues, https://github.com/penguintechinc/penguin-libs/issues
Keywords: penguintech,validation,grpc,pydantic,utilities
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU Affero General Public License v3
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
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
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: pydantic>=2.0
Provides-Extra: flask
Requires-Dist: flask>=3.0; extra == "flask"
Requires-Dist: flask-security-too>=5.0; extra == "flask"
Provides-Extra: grpc
Requires-Dist: grpcio>=1.50.0; extra == "grpc"
Requires-Dist: grpcio-health-checking>=1.50.0; extra == "grpc"
Requires-Dist: grpcio-reflection>=1.50.0; extra == "grpc"
Requires-Dist: pyjwt>=2.0; extra == "grpc"
Provides-Extra: http
Requires-Dist: httpx>=0.24.0; extra == "http"
Provides-Extra: h3
Requires-Dist: aioquic>=1.3.0; extra == "h3"
Requires-Dist: hypercorn[h3]>=0.17.0; extra == "h3"
Requires-Dist: httpx>=0.27.0; extra == "h3"
Requires-Dist: httpx-h3>=0.1.0; extra == "h3"
Requires-Dist: quart>=0.19.0; extra == "h3"
Provides-Extra: all
Requires-Dist: flask>=3.0; extra == "all"
Requires-Dist: flask-security-too>=5.0; extra == "all"
Requires-Dist: flask-restx>=1.0; extra == "all"
Requires-Dist: grpcio>=1.50.0; extra == "all"
Requires-Dist: grpcio-health-checking>=1.50.0; extra == "all"
Requires-Dist: grpcio-reflection>=1.50.0; extra == "all"
Requires-Dist: httpx>=0.27.0; extra == "all"
Requires-Dist: pyjwt>=2.0; extra == "all"
Requires-Dist: aioquic>=1.3.0; extra == "all"
Requires-Dist: hypercorn[h3]>=0.17.0; extra == "all"
Requires-Dist: httpx-h3>=0.1.0; extra == "all"
Requires-Dist: quart>=0.19.0; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: black>=23.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Requires-Dist: mypy>=1.0; extra == "dev"

# Penguin Tech Python Libraries

Shared Python libraries for Penguin Tech applications.

## Installation

```bash
pip install penguin-libs

# With all extras
pip install penguin-libs[all]

# With specific extras
pip install penguin-libs[flask]
pip install penguin-libs[grpc]
pip install penguin-libs[http]
```

## Features

### Validation

PyDAL-style input validators with Pydantic integration:

```python
from penguin_libs.validation import IsEmail, IsLength, chain
from penguin_libs.pydantic import EmailStr, StrongPassword

# Direct validation
validator = IsEmail()
result = validator("user@example.com")

# Chained validators
validators = chain(IsNotEmpty(), IsLength(3, 255), IsEmail())
result = validators("user@example.com")

# Pydantic models
from pydantic import BaseModel

class User(BaseModel):
    email: EmailStr
    password: StrongPassword
```

### gRPC

Server helpers, client utilities, and security interceptors:

```python
from penguin_libs.grpc import create_server, GrpcClient, AuthInterceptor

# Server
interceptors = [AuthInterceptor(secret_key="your-secret")]
server = create_server(interceptors=interceptors)

# Client
client = GrpcClient('localhost:50051')
with client.channel() as channel:
    stub = MyServiceStub(channel)
    response = client.call_with_retry(stub.MyMethod, request)
```

### HTTP

Resilient HTTP client with retry logic and circuit breaker:

```python
from penguin_libs.http import HTTPClient, HTTPClientConfig, RetryConfig

config = HTTPClientConfig(
    timeout=30.0,
    retry=RetryConfig(max_retries=3, base_delay=1.0)
)
client = HTTPClient(config)
response = client.get("https://api.example.com/users")
```

### Pydantic Integration

Base models and Flask integration:

```python
from penguin_libs.pydantic import (
    RequestModel,
    validated_request,
    model_response,
)

class CreateUserRequest(RequestModel):
    name: str
    email: EmailStr

@app.route('/users', methods=['POST'])
@validated_request(body_model=CreateUserRequest)
def create_user(body: CreateUserRequest):
    return model_response(UserResponse(...))
```

## Modules

- **validation**: PyDAL-style validators (string, numeric, network, datetime, password)
- **grpc**: gRPC server/client helpers and security interceptors
- **http**: HTTP client with retries, circuit breaker, correlation ID
- **pydantic**: Base models, Flask integration, custom Annotated types
- **crypto**: Cryptographic utilities (placeholder)
- **security**: Security utilities (placeholder)

## Development

```bash
# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Format code
black src tests
ruff check src tests

# Type check
mypy src
```

## License

AGPL-3.0 - See [LICENSE](../../LICENSE) for details.
