Metadata-Version: 2.4
Name: felesh-framework
Version: 0.4.2
Summary: Shared package for Felesh microservices with scaffold utilities
Author-email: Felesh Team <team@felesh.com>
License: MIT
Project-URL: Homepage, https://github.com/felesh-ai/Felesh-framework
Project-URL: Repository, https://github.com/felesh-ai/Felesh-framework
Keywords: cqrs,microservices,fastapi,django,drf,scaffold
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastapi>=0.115.0
Requires-Dist: pydantic>=2.0
Requires-Dist: pydantic-settings>=2.0
Requires-Dist: redis[hiredis]>=5.0.0
Requires-Dist: httpx>=0.28.0
Requires-Dist: python-jose[cryptography]>=3.3.0
Requires-Dist: bcrypt>=4.0.0
Requires-Dist: sqlalchemy[asyncio]>=2.0.0
Requires-Dist: asyncpg>=0.30.0
Requires-Dist: uuid-utils>=0.9.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.24.0; extra == "dev"
Requires-Dist: pytest-cov>=6.0.0; extra == "dev"
Requires-Dist: ruff>=0.8.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Requires-Dist: pre-commit>=3.6.0; extra == "dev"
Provides-Extra: drf
Requires-Dist: djangorestframework>=3.15.0; extra == "drf"
Requires-Dist: django>=5.0.0; extra == "drf"
Provides-Extra: otel
Requires-Dist: opentelemetry-distro>=0.48b0; extra == "otel"
Requires-Dist: opentelemetry-exporter-otlp>=1.27.0; extra == "otel"
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.48b0; extra == "otel"
Requires-Dist: opentelemetry-instrumentation-sqlalchemy>=0.48b0; extra == "otel"
Requires-Dist: opentelemetry-instrumentation-redis>=0.48b0; extra == "otel"
Requires-Dist: opentelemetry-instrumentation-httpx>=0.48b0; extra == "otel"
Requires-Dist: opentelemetry-instrumentation-logging>=0.48b0; extra == "otel"
Requires-Dist: structlog>=24.0.0; extra == "otel"
Dynamic: license-file

# Felesh Shared Package

A foundational Python package providing scaffold utilities and SDK capabilities for all Felesh microservices. This package ensures consistent architecture patterns, code structure, and development practices across the entire microservices ecosystem.

## 🎯 Architecture Templates

Choose the architecture that fits your service requirements:

### Simple Architecture
- **Best for**: Traditional CRUD operations, straightforward business logic
- **Components**: Models, Repositories, GenericServices, UsecaseServices, Views
- **Complexity**: Low - 50% less boilerplate than CQRS
- **Use when**: No event publishing, synchronous workflows, fast development needed

### Event-Driven CQRS Architecture
- **Best for**: Event-driven services, distributed transactions, complete audit trails
- **Components**: Commands, Queries, Handlers, MessageBus, EventStore, Outbox Pattern
- **Complexity**: Higher - Full CQRS with event sourcing
- **Use when**: Event publishing required, zero event loss critical, distributed transactions

## 🚀 Features

### Shared Across All Architectures
- **Framework Support**: Native integration with Django REST Framework and FastAPI
- **Unit of Work**: Transaction management across repositories
- **Repository Pattern**: Abstraction for data access
- **Type Safety**: Full Pydantic V2 integration
- **Clean Architecture**: Separation of concerns maintained

### Event-Driven CQRS Only
- **CQRS Pattern**: Clean separation between commands (writes) and queries (reads)
- **Event-Driven Architecture**: Hybrid outbox pattern for guaranteed event delivery with zero loss
- **MessageBus**: Automatic command/query routing to handlers
- **Event Store**: Complete audit trail of all domain events

## 📦 Installation

### From Git Repository (Production)

```bash
# Install latest from develop branch (HTTPS)
uv add git+https://code.arshai.com/felesh-ai/platform/core-services/shared-package.git

# Install latest from develop branch (SSH)
uv add git+ssh://git@code.arshai.com:2222/felesh-ai/platform/core-services/shared-package.git

# Install specific version/tag
uv add git+https://code.arshai.com/felesh-ai/platform/core-services/shared-package.git@v0.1.0

# Or add to your pyproject.toml
```

```toml
[project.dependencies]
felesh-shared-package = { git = "https://code.arshai.com/felesh-ai/platform/core-services/shared-package.git", branch = "develop" }
```

### From Local Path (Development)

```bash
# Install in editable mode for local development
uv add --editable /path/to/felesh_shared_package

# Or add to your pyproject.toml
```

```toml
[project.dependencies]
felesh-shared-package = { path = "../felesh_shared_package", editable = true }
```

**Requirements**: Python 3.13+

### CLI Commands Available After Installation

Once installed, the package provides the `felesh-init` command:

```bash
# Check if installed correctly
felesh-init --help

# Create a new project from anywhere
felesh-init myservice --framework drf --arch simple
```

## 🔧 Development Setup

### Code Quality Enforcement

This package uses **pre-commit hooks** to automatically enforce code quality standards:

```bash
# Install pre-commit hooks (one-time setup)
uv run pre-commit install
# or
make precommit-install
```

Once installed, hooks run automatically on every commit, checking:
- File hygiene (trailing whitespace, EOF newlines, YAML/TOML syntax)
- Ruff linting and formatting (auto-fixes many issues)
- Large file detection and merge conflict markers

**Manual execution** (optional):
```bash
# Run hooks on all files
uv run pre-commit run --all-files
# or
make precommit-run
```

**Makefile targets**:
```bash
make lint            # Run Ruff linter
make format          # Format code with Ruff
make fix             # Auto-fix lint issues and format
make precommit-run   # Run all pre-commit hooks
```

## 🏗️ Project Structure

```
scaffold/
├── common/                      # Shared CQRS infrastructure
│   ├── seedwork/               # Base classes for CQRS pattern
│   │   ├── commands.py         # Command DTOs and handlers
│   │   ├── queries.py          # Query DTOs and handlers
│   │   ├── events.py           # Event system and dispatching
│   │   ├── uow.py              # Unit of Work pattern
│   │   └── repositories.py     # Repository pattern
│   ├── adapters/               # Framework adapters
│   │   ├── drf/                # Django REST Framework integration
│   │   └── fastapi/            # FastAPI integration
│   └── testing/                # Test utilities and mocks
├── project_templates/          # Ready-to-use project templates
│   ├── drf/                    # DRF project template
│   └── fastapi/                # FastAPI project template
├── examples/                   # Example implementations
│   └── cqrs_patterns/          # CQRS pattern examples
└── init_project.py            # Project initialization script
```

## 🚦 Quick Start

### Create a New Project

After installing the package, you can use the `felesh-init` CLI command from anywhere:

```bash
# Simple architecture (recommended for CRUD services)
felesh-init myservice --framework drf --arch simple

# Event-Driven CQRS architecture (for event-driven services)
felesh-init myservice --framework fastapi --arch event-driven-cqrs

# Create in specific directory
felesh-init myservice --framework drf --arch simple --path /path/to/projects

# Get help
felesh-init --help
```

**Alternative methods** (from felesh_shared_package directory):

```bash
# Using Makefile
make init-project NAME=myservice FRAMEWORK=drf ARCH=simple

# Using Python script directly
python scaffold/init_project.py myservice --framework drf --arch simple
```

### Architecture Decision Guide

| Criteria | Simple | Event-Driven CQRS |
|----------|--------|-------------------|
| **Event Publishing** | ❌ No cross-service events | ✅ Publishes to Kafka |
| **Distributed Transactions** | ❌ Single database | ✅ Eventual consistency |
| **Audit Trail** | Standard DB logs | ✅ Complete event history |
| **Team Experience** | ✅ Junior devs OK | ⚠️ CQRS knowledge needed |
| **Development Speed** | ✅ Faster (50% less code) | ⚠️ More boilerplate |
| **Use Cases** | CRUD, simple workflows | Event-driven, complex sagas |

### Define Commands and Queries

```python
from scaffold.common.seedwork import ICommand, IQuery
from pydantic import Field, EmailStr

class CreateUserCommand(ICommand):
    """Command to create a new user."""
    email: EmailStr = Field(..., description="User email")
    username: str = Field(..., min_length=3, max_length=50)
    full_name: str = Field(..., description="Full name")

class GetUserByIdQuery(IQuery):
    """Query to get user by ID."""
    user_id: int = Field(..., description="User ID")
```

### Implement Handlers

```python
from scaffold.common.seedwork import (
    ICommandHandler, ICommandResult, Status
)

class CreateUserHandler(ICommandHandler):
    """Handler for CreateUserCommand."""

    def __init__(self, uow, event_collector):
        self.uow = uow
        self.event_collector = event_collector

    def handle(self, command: CreateUserCommand) -> ICommandResult:
        """Execute the create user command."""
        with self.uow:
            # Business logic
            user = self.uow.user_repo.add({
                'email': command.email,
                'username': command.username,
                'full_name': command.full_name,
            })

            # Collect event (saved atomically with data)
            event = UserCreatedEvent(
                user_id=str(user['id']),
                email=user['email']
            )
            self.event_collector.add_event(event)

            self.uow.commit()

            return ICommandResult(
                status=Status.SUCCESS,
                data={'user_id': user['id']}
            )
```

### Use with Django REST Framework

```python
from scaffold.common.adapters.drf import CommandAPIView, QueryAPIView

class CreateUserView(CommandAPIView):
    command_class = CreateUserCommand
    handler_class = CreateUserHandler

class GetUserView(QueryAPIView):
    query_class = GetUserByIdQuery
    handler_class = GetUserByIdHandler

# urls.py
urlpatterns = [
    path('users/', CreateUserView.as_view()),
    path('users/<int:user_id>/', GetUserView.as_view()),
]
```

### Use with FastAPI

```python
from fastapi import FastAPI, Depends
from scaffold.common.adapters.fastapi import (
    create_command_handler_dependency
)

app = FastAPI()

@app.post("/users")
async def create_user(
    command: CreateUserCommand,
    handler = Depends(create_command_handler_dependency(CreateUserHandler))
):
    result = handler.handle(command)
    if result.is_success():
        return result.data
    raise HTTPException(status_code=400, detail=result.message)
```

## 📚 Documentation

All documentation is centralized in the [`/docs`](./docs/) directory:

### Getting Started
- **[Index](./docs/INDEX.md)**: Complete documentation index with all imports
- **[Quick Start](./docs/QUICKSTART.md)**: Getting started guide
- **[Architecture](./docs/ARCHITECTURE.md)**: System architecture overview
- **[Migration](./docs/MIGRATION.md)**: Migration guides

### CQRS Pattern
- **[CQRS Patterns](./docs/CQRS_PATTERNS.md)**: Commands, Queries, Events DTOs
- **[Handlers](./docs/HANDLERS.md)**: Base handler classes
- **[Handler Registry](./docs/HANDLER_REGISTRY.md)**: Handler registration and discovery
- **[Handler Result](./docs/HANDLER_RESULT.md)**: Result types and factory methods

### Event System
- **[Message Bus](./docs/MESSAGE_BUS.md)**: Async/Sync message routing
- **[Event Collector](./docs/EVENT_COLLECTOR.md)**: Event aggregation
- **[Outbox Pattern](./docs/OUTBOX_PATTERN.md)**: Reliable event publishing
- **[Inbox Pattern](./docs/INBOX_PATTERN.md)**: Exactly-once consumption
- **[Event System](./docs/EVENT_SYSTEM.md)**: Event backends and infrastructure

### Infrastructure
- **[Unit of Work](./docs/UNIT_OF_WORK.md)**: Transaction management
- **[Repository](./docs/REPOSITORY.md)**: Data access patterns
- **[Models](./docs/MODELS.md)**: Base model classes

### API Layer
- **[Filtering](./docs/FILTERING.md)**: Query filters with operators
- **[Pagination](./docs/PAGINATION.md)**: Page-based pagination
- **[API Responses](./docs/API_RESPONSES.md)**: Response formatting

### Framework Adapters
- **[FastAPI Adapters](./docs/ADAPTERS_FASTAPI.md)**: FastAPI integration
- **[DRF Adapters](./docs/ADAPTERS_DRF.md)**: Django REST Framework integration

### Utilities
- **[Decorators](./docs/DECORATORS.md)**: Handler and service decorators
- **[Testing](./docs/TESTING.md)**: Test strategies and utilities
- **[Troubleshooting](./docs/TROUBLESHOOTING.md)**: Common issues and solutions

### Examples
- **[Examples](scaffold/examples/cqrs_patterns/)**: Working examples of all patterns

## 🔄 Migration from v1.x

**Breaking Changes in v2.0:**
- Removed `scaffold/drf/seedwork/` and `scaffold/fastapi/seedwork/`
- All imports now from `scaffold.common.seedwork` and `scaffold.common.adapters`
- Service pattern completely removed in favor of CQRS handlers

See [Migration Guide](./docs/MIGRATION.md) for detailed migration instructions.

## 🎯 Best Practices

1. **Separation of Concerns**: Keep commands and queries separate
2. **Single Responsibility**: One handler for one command/query
3. **Explicit Transactions**: Always use Unit of Work for data modifications
4. **Event-Driven**: Emit events for important business operations
5. **Type Safety**: Leverage Pydantic for validation
6. **Testing**: Mock UoW and repositories, test business logic in isolation

## 🧪 Testing

```python
def test_create_user_handler():
    # Arrange
    handler = CreateUserHandler()
    handler.uow = Mock(spec=DjangoUnitOfWork)
    handler.uow.user_repo.add.return_value = {'id': 1}

    command = CreateUserCommand(
        email="test@example.com",
        username="testuser",
        full_name="Test User"
    )

    # Act
    result = handler.handle(command)

    # Assert
    assert result.is_success()
    assert result.data['user_id'] == 1
    handler.uow.commit.assert_called_once()
```

## 🏛️ Architecture

The package implements a simplified CQRS pattern with hybrid outbox pattern for event delivery:

```
┌─────────────────────────────────────────────────────────────┐
│              API Layer (DRF/FastAPI)                         │
├─────────────────────────────────────────────────────────────┤
│            Commands    │    Queries                          │
├─────────────────────────────────────────────────────────────┤
│           Handlers (Business Logic)                          │
│                   ↓                                          │
│           EventCollector (In-Memory)                         │
├─────────────────────────────────────────────────────────────┤
│          Unit of Work & Repositories                         │
│                   ↓                                          │
│      [Database] ← ATOMIC TRANSACTION → [Outbox Events]      │
│                                              ↓               │
│                                   [Immediate Publish 99%]    │
│                                              ↓               │
│                                          Kafka               │
│                                                              │
│      [Background Worker] → Retry Failed Events (1%)         │
└─────────────────────────────────────────────────────────────┘

Guarantees:
✅ Zero event loss (atomic commit)
✅ Low latency (~10-15ms for 99% of events)
✅ Guaranteed delivery (background worker retries)
```

## 🤝 Contributing

This package is used across all Felesh microservices. Any changes should be:
1. Backward compatible when possible
2. Thoroughly tested
3. Documented with examples
4. Reviewed by the architecture team

## 📄 License

Proprietary - Felesh Project

## 🆘 Support

- Check examples in `scaffold/examples/cqrs_patterns/`
- Review documentation in [`/docs`](./docs/) directory
- Start with [INDEX.md](./docs/INDEX.md) for complete reference
- Check [TROUBLESHOOTING.md](./docs/TROUBLESHOOTING.md) for common issues
