lumi-filter


Namelumi-filter JSON
Version 0.1.0 PyPI version JSON
download
home_pageNone
SummaryA powerful and flexible data filtering library with unified interface for multiple data sources
upload_time2025-07-22 08:24:43
maintainerNone
docs_urlNone
authorNone
requires_python>=3.12
licenseMIT
keywords data filter orm peewee pydantic query
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # lumi_filter

[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/chaleaoch/lumi_filter)

A powerful and flexible data filtering library for Python that provides a unified interface for filtering and ordering data across different sources.

## Features

- **Universal Filtering Interface**: Work with Peewee ORM queries, Pydantic models, and iterable data structures using the same API
- **Automatic Field Detection**: Automatically map field types from your data sources to appropriate filter fields
- **Rich Lookup Expressions**: Support for complex filtering operations including equality, comparison, and text matching
- **Type Safety**: Built-in validation and type conversion for filter values
- **Extensible**: Easy to extend with custom field types and operators
- **Backend Agnostic**: Seamlessly switch between different data backends

## Installation

```bash
pip install lumi-filter
```

## Quick Start

### Basic Usage with Peewee ORM

```python
import peewee
from lumi_filter import Model, IntField, StrField

# Define your Peewee model
class User(peewee.Model):
    name = peewee.CharField()
    age = peewee.IntegerField()
    email = peewee.CharField()

# Define your filter model
class UserFilter(Model):
    name = StrField()
    age = IntField()
    
    class Meta:
        schema = User

# Apply filters
query = User.select()
request_args = {
    'name__in': 'john',  # Contains 'john'
    'age__gte': 18       # Age >= 18
}

filtered_data = UserFilter.cls_filter(query, request_args)
```

### Automatic Model Generation

```python
from lumi_filter.shortcut import AutoQueryModel

# Automatically generate filter model from data
query = User.select()
request_args = {'name__in': 'john', 'age__gte': 18}

# AutoQueryModel inspects the query and creates appropriate filters
model = AutoQueryModel(query, request_args)
result = model.filter().order().result()
```

### Working with Dictionaries

```python
from lumi_filter.shortcut import AutoQueryModel

# Sample data
users = [
    {'name': 'John Doe', 'age': 25, 'active': True},
    {'name': 'Jane Smith', 'age': 30, 'active': False},
    {'name': 'Bob Johnson', 'age': 35, 'active': True}
]

request_args = {
    'name__in': 'john',  # Case-insensitive contains
    'active': True
}

model = AutoQueryModel(users, request_args)
filtered_users = model.filter().result()
```

### Pydantic Integration

```python
import pydantic
from lumi_filter import Model

class UserSchema(pydantic.BaseModel):
    name: str
    age: int
    email: str

class UserFilter(Model):
    class Meta:
        schema = UserSchema
        fields = ['name', 'age']  # Only include specific fields

# Use with any iterable data that matches the schema
data = [{'name': 'John', 'age': 25, 'email': 'john@example.com'}]
filtered_data = UserFilter.cls_filter(data, {'name__in': 'john'})
```

## Lookup Expressions

lumi_filter supports various lookup expressions for fine-grained filtering:

- **Exact match**: `field` or `field__exact`
- **Not equal**: `field__!` or `field__ne`
- **Comparison**: `field__gt`, `field__gte`, `field__lt`, `field__lte`
- **Contains**: `field__in` (case-sensitive), `field__iin` (case-insensitive)
- **Not contains**: `field__nin`

### Examples

```python
request_args = {
    'name': 'John Doe',           # Exact match
    'age__gte': 18,               # Age >= 18
    'age__lt': 65,                # Age < 65
    'email__in': '@gmail.com',    # Contains '@gmail.com'
    'status__!': 'inactive'       # Not equal to 'inactive'
}
```

## Ordering

Control result ordering using the `ordering` parameter:

```python
request_args = {
    'name__in': 'john',
    'ordering': 'age,-name'  # Order by age ascending, then name descending
}

model = UserFilter(data, request_args)
result = model.filter().order().result()
```

## Advanced Usage

### Custom Filter Fields

```python
from lumi_filter.field import FilterField
import datetime

class CustomDateField(FilterField):
    """Custom date field with flexible parsing"""
    
    SUPPORTED_LOOKUP_EXPR = frozenset({'', '!', 'gt', 'lt', 'gte', 'lte'})
    
    def parse_value(self, value):
        if isinstance(value, datetime.date):
            return value, True
        try:
            # Support multiple date formats
            for fmt in ['%Y-%m-%d', '%m/%d/%Y', '%d.%m.%Y']:
                try:
                    return datetime.datetime.strptime(value, fmt).date(), True
                except ValueError:
                    continue
            return None, False
        except (ValueError, TypeError):
            return None, False

class UserFilter(Model):
    birth_date = CustomDateField()
    name = StrField()
```

### Nested Field Support

For nested data structures, use dot notation:

```python
# Data structure
users = [
    {
        'name': 'John',
        'profile': {
            'age': 25,
            'location': {'city': 'New York'}
        }
    }
]

# Filter nested fields
request_args = {
    'profile__age__gte': 21,
    'profile__location__city__in': 'york'
}

model = AutoQueryModel(users, request_args)
result = model.filter().result()
```

## Supported Field Types

- **IntField**: Integer values with comparison operations
- **StrField**: String values with text matching operations
- **DecimalField**: Decimal values for precise arithmetic
- **BooleanField**: Boolean values with flexible string parsing
- **DateField**: Date values with format parsing
- **DateTimeField**: DateTime values with format parsing

## Requirements

- Python 3.12+
- peewee >= 3.18.2
- pydantic >= 2.11.7

## Development

### Running Tests

```bash
pytest
```

### Coverage Report

```bash
pytest --cov=lumi_filter --cov-report=html
```

## License

This project is licensed under the MIT License - see the LICENSE file for details.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "lumi-filter",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.12",
    "maintainer_email": "chaleaoch <your-email@example.com>",
    "keywords": "data, filter, orm, peewee, pydantic, query",
    "author": null,
    "author_email": "chaleaoch <your-email@example.com>",
    "download_url": "https://files.pythonhosted.org/packages/bf/e3/182e1468edabc2e81c226c06cab40bd16c774b9725599a06b66e314e0ac5/lumi_filter-0.1.0.tar.gz",
    "platform": null,
    "description": "# lumi_filter\n\n[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/chaleaoch/lumi_filter)\n\nA powerful and flexible data filtering library for Python that provides a unified interface for filtering and ordering data across different sources.\n\n## Features\n\n- **Universal Filtering Interface**: Work with Peewee ORM queries, Pydantic models, and iterable data structures using the same API\n- **Automatic Field Detection**: Automatically map field types from your data sources to appropriate filter fields\n- **Rich Lookup Expressions**: Support for complex filtering operations including equality, comparison, and text matching\n- **Type Safety**: Built-in validation and type conversion for filter values\n- **Extensible**: Easy to extend with custom field types and operators\n- **Backend Agnostic**: Seamlessly switch between different data backends\n\n## Installation\n\n```bash\npip install lumi-filter\n```\n\n## Quick Start\n\n### Basic Usage with Peewee ORM\n\n```python\nimport peewee\nfrom lumi_filter import Model, IntField, StrField\n\n# Define your Peewee model\nclass User(peewee.Model):\n    name = peewee.CharField()\n    age = peewee.IntegerField()\n    email = peewee.CharField()\n\n# Define your filter model\nclass UserFilter(Model):\n    name = StrField()\n    age = IntField()\n    \n    class Meta:\n        schema = User\n\n# Apply filters\nquery = User.select()\nrequest_args = {\n    'name__in': 'john',  # Contains 'john'\n    'age__gte': 18       # Age >= 18\n}\n\nfiltered_data = UserFilter.cls_filter(query, request_args)\n```\n\n### Automatic Model Generation\n\n```python\nfrom lumi_filter.shortcut import AutoQueryModel\n\n# Automatically generate filter model from data\nquery = User.select()\nrequest_args = {'name__in': 'john', 'age__gte': 18}\n\n# AutoQueryModel inspects the query and creates appropriate filters\nmodel = AutoQueryModel(query, request_args)\nresult = model.filter().order().result()\n```\n\n### Working with Dictionaries\n\n```python\nfrom lumi_filter.shortcut import AutoQueryModel\n\n# Sample data\nusers = [\n    {'name': 'John Doe', 'age': 25, 'active': True},\n    {'name': 'Jane Smith', 'age': 30, 'active': False},\n    {'name': 'Bob Johnson', 'age': 35, 'active': True}\n]\n\nrequest_args = {\n    'name__in': 'john',  # Case-insensitive contains\n    'active': True\n}\n\nmodel = AutoQueryModel(users, request_args)\nfiltered_users = model.filter().result()\n```\n\n### Pydantic Integration\n\n```python\nimport pydantic\nfrom lumi_filter import Model\n\nclass UserSchema(pydantic.BaseModel):\n    name: str\n    age: int\n    email: str\n\nclass UserFilter(Model):\n    class Meta:\n        schema = UserSchema\n        fields = ['name', 'age']  # Only include specific fields\n\n# Use with any iterable data that matches the schema\ndata = [{'name': 'John', 'age': 25, 'email': 'john@example.com'}]\nfiltered_data = UserFilter.cls_filter(data, {'name__in': 'john'})\n```\n\n## Lookup Expressions\n\nlumi_filter supports various lookup expressions for fine-grained filtering:\n\n- **Exact match**: `field` or `field__exact`\n- **Not equal**: `field__!` or `field__ne`\n- **Comparison**: `field__gt`, `field__gte`, `field__lt`, `field__lte`\n- **Contains**: `field__in` (case-sensitive), `field__iin` (case-insensitive)\n- **Not contains**: `field__nin`\n\n### Examples\n\n```python\nrequest_args = {\n    'name': 'John Doe',           # Exact match\n    'age__gte': 18,               # Age >= 18\n    'age__lt': 65,                # Age < 65\n    'email__in': '@gmail.com',    # Contains '@gmail.com'\n    'status__!': 'inactive'       # Not equal to 'inactive'\n}\n```\n\n## Ordering\n\nControl result ordering using the `ordering` parameter:\n\n```python\nrequest_args = {\n    'name__in': 'john',\n    'ordering': 'age,-name'  # Order by age ascending, then name descending\n}\n\nmodel = UserFilter(data, request_args)\nresult = model.filter().order().result()\n```\n\n## Advanced Usage\n\n### Custom Filter Fields\n\n```python\nfrom lumi_filter.field import FilterField\nimport datetime\n\nclass CustomDateField(FilterField):\n    \"\"\"Custom date field with flexible parsing\"\"\"\n    \n    SUPPORTED_LOOKUP_EXPR = frozenset({'', '!', 'gt', 'lt', 'gte', 'lte'})\n    \n    def parse_value(self, value):\n        if isinstance(value, datetime.date):\n            return value, True\n        try:\n            # Support multiple date formats\n            for fmt in ['%Y-%m-%d', '%m/%d/%Y', '%d.%m.%Y']:\n                try:\n                    return datetime.datetime.strptime(value, fmt).date(), True\n                except ValueError:\n                    continue\n            return None, False\n        except (ValueError, TypeError):\n            return None, False\n\nclass UserFilter(Model):\n    birth_date = CustomDateField()\n    name = StrField()\n```\n\n### Nested Field Support\n\nFor nested data structures, use dot notation:\n\n```python\n# Data structure\nusers = [\n    {\n        'name': 'John',\n        'profile': {\n            'age': 25,\n            'location': {'city': 'New York'}\n        }\n    }\n]\n\n# Filter nested fields\nrequest_args = {\n    'profile__age__gte': 21,\n    'profile__location__city__in': 'york'\n}\n\nmodel = AutoQueryModel(users, request_args)\nresult = model.filter().result()\n```\n\n## Supported Field Types\n\n- **IntField**: Integer values with comparison operations\n- **StrField**: String values with text matching operations\n- **DecimalField**: Decimal values for precise arithmetic\n- **BooleanField**: Boolean values with flexible string parsing\n- **DateField**: Date values with format parsing\n- **DateTimeField**: DateTime values with format parsing\n\n## Requirements\n\n- Python 3.12+\n- peewee >= 3.18.2\n- pydantic >= 2.11.7\n\n## Development\n\n### Running Tests\n\n```bash\npytest\n```\n\n### Coverage Report\n\n```bash\npytest --cov=lumi_filter --cov-report=html\n```\n\n## License\n\nThis project is licensed under the MIT License - see the LICENSE file for details.\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A powerful and flexible data filtering library with unified interface for multiple data sources",
    "version": "0.1.0",
    "project_urls": {
        "Bug Tracker": "https://github.com/chaleaoch/lumi_filter/issues",
        "Documentation": "https://github.com/chaleaoch/lumi_filter",
        "Homepage": "https://github.com/chaleaoch/lumi_filter",
        "Repository": "https://github.com/chaleaoch/lumi_filter"
    },
    "split_keywords": [
        "data",
        " filter",
        " orm",
        " peewee",
        " pydantic",
        " query"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "449ec5ff5514590aeb2ef3b8c753d17044552a451a6e8b2d6d44968ee93e0706",
                "md5": "b241c6c1dacf887a8eef6aed55e51270",
                "sha256": "d0a6bfea6b472c0e8b059d75f962efcea0a0ae45862a4e50c2656d18e36fdde3"
            },
            "downloads": -1,
            "filename": "lumi_filter-0.1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b241c6c1dacf887a8eef6aed55e51270",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.12",
            "size": 14453,
            "upload_time": "2025-07-22T08:24:41",
            "upload_time_iso_8601": "2025-07-22T08:24:41.106207Z",
            "url": "https://files.pythonhosted.org/packages/44/9e/c5ff5514590aeb2ef3b8c753d17044552a451a6e8b2d6d44968ee93e0706/lumi_filter-0.1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "bfe3182e1468edabc2e81c226c06cab40bd16c774b9725599a06b66e314e0ac5",
                "md5": "b2776add143daf66ffc3a0f2d9e0224d",
                "sha256": "35742929795be7f2c9389bda6ba2387ff1d4fa5ab0dbad0ebd124f0c40dfee59"
            },
            "downloads": -1,
            "filename": "lumi_filter-0.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "b2776add143daf66ffc3a0f2d9e0224d",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.12",
            "size": 58986,
            "upload_time": "2025-07-22T08:24:43",
            "upload_time_iso_8601": "2025-07-22T08:24:43.165825Z",
            "url": "https://files.pythonhosted.org/packages/bf/e3/182e1468edabc2e81c226c06cab40bd16c774b9725599a06b66e314e0ac5/lumi_filter-0.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-22 08:24:43",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "chaleaoch",
    "github_project": "lumi_filter",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "lumi-filter"
}
        
Elapsed time: 0.51752s