Metadata-Version: 2.4
Name: hiten-apicore
Version: 0.1.2
Summary: Lightweight API infrastructure toolkit for standardized responses, errors, and retry handling.
Author-email: Hiten Joshi <hiten.mmt@example.com>
License: MIT
Project-URL: Homepage, https://github.com/yourusername/apicore
Project-URL: Repository, https://github.com/yourusername/apicore
Project-URL: Issues, https://github.com/yourusername/apicore/issues
Keywords: api,apicore,infrastructure,backend,retry,response,logging
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: djangorestframework>=3.14.0
Requires-Dist: django>=4.0
Dynamic: license-file

# Apicore

Lightweight API infrastructure toolkit for Django REST Framework providing standardized responses, errors, permissions, CRUD operations, and default data initialization.

## Features

- **BaseModel** - Abstract model with timestamps, soft delete, and common fields
- **BaseViewSet** - Pre-configured CRUD operations with standardized responses
- **Standardized API Responses** - Consistent success/error response format
- **Custom Exception Classes** - ApiError, ValidationError, NotFoundError, UnauthorizedError, ForbiddenError
- **Permission Classes** - IsOwner, IsActiveUser, ReadOnly
- **Pagination** - StandardPagination with metadata
- **Request Tracing** - Decorator for logging with UUID and timing
- **Default Data Initializer** - Load default data for multiple models from JSON
- **Common Constants** - HTTP status codes, error codes, pagination defaults

## Installation

```bash
pip install hiten-apicore
```

## Quick Start

### 1. BaseModel

```python
from django.db import models
from apicore import BaseModel

class Product(BaseModel):
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    description = models.TextField(blank=True)

# Includes: created_at, updated_at, is_active fields
# Methods: soft_delete(), restore()
```

### 2. BaseViewSet

```python
from rest_framework import serializers
from apicore import BaseViewSet, StandardPagination, IsActiveUser

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = '__all__'

class ProductViewSet(BaseViewSet):
    queryset = Product.objects.filter(is_active=True)
    serializer_class = ProductSerializer
    permission_classes = [IsActiveUser]
    pagination_class = StandardPagination
```

### 3. Permissions

```python
from apicore import IsOwner, IsActiveUser, ReadOnly

class MyViewSet(BaseViewSet):
    permission_classes = [IsActiveUser, IsOwner]
```

### 4. Error Handling

```python
from apicore import NotFoundError, ValidationError, UnauthorizedError

def my_view(request):
    if not obj:
        raise NotFoundError("Product not found")
    if not valid:
        raise ValidationError("Invalid data", errors={"field": "error"})
    if not authorized:
        raise UnauthorizedError("Access denied")
```

### 5. Request Tracing

```python
from apicore import trace_request

class MyViewSet(BaseViewSet):
    @trace_request
    def list(self, request, *args, **kwargs):
        return super().list(request, *args, **kwargs)
```

### 6. Initialize Default Data

**Create JSON file (defaults.json):**
```json
{
  "myapp.Category": {
    "lookup_fields": ["code"],
    "data": [
      {"code": "electronics", "name": "Electronics"},
      {"code": "clothing", "name": "Clothing"}
    ]
  },
  "myapp.Status": {
    "lookup_fields": ["code"],
    "data": [
      {"code": "active", "name": "Active"},
      {"code": "inactive", "name": "Inactive"}
    ]
  }
}
```

**Load data:**
```bash
python manage.py initialize_defaults defaults.json
```

**Or in Python:**
```python
from apicore import initialize_from_json

results = initialize_from_json('defaults.json')
# Returns: {'myapp.Category': {'created': 2, 'updated': 0, 'total': 2}}
```

## Response Format

**Success:**
```json
{
    "status": "success",
    "data": {...},
    "message": "Operation successful",
    "meta": {
        "pagination": {
            "count": 100,
            "page_size": 10,
            "current_page": 1,
            "total_pages": 10
        }
    }
}
```

**Error:**
```json
{
    "status": "error",
    "message": "Error message",
    "error_code": "VALIDATION_ERROR",
    "errors": {"field": "error detail"}
}
```

## Available Components

### Models
- `BaseModel` - Abstract model with common fields

### ViewSets
- `BaseViewSet` - CRUD operations with standardized responses

### Responses
- `ApiResponse.success(data, message, meta)`
- `ApiResponse.error(message, error_code, errors)`

### Errors
- `ApiError(message, status_code, error_code)`
- `ValidationError(message, errors)`
- `NotFoundError(message)`
- `UnauthorizedError(message)`
- `ForbiddenError(message)`

### Permissions
- `IsOwner` - Check if user owns the object
- `IsActiveUser` - Check if user is active
- `ReadOnly` - Allow only GET, HEAD, OPTIONS

### Pagination
- `StandardPagination` - Page-based pagination with metadata

### Utilities
- `trace_request` - Decorator for request logging
- `initialize_from_json(path)` - Load defaults from JSON
- `initialize_from_dict(data)` - Load defaults from dict
- `DefaultDataInitializer` - Class-based initializer

### Constants
- `HTTP_STATUS_CODES` - Common HTTP status codes
- `ERROR_CODES` - Standard error codes
- `DEFAULT_PAGE_SIZE` - Default pagination size (10)
- `MAX_PAGE_SIZE` - Maximum pagination size (100)

## Requirements

- Python >= 3.8
- Django >= 4.0
- djangorestframework >= 3.14.0

## License

MIT
