Metadata-Version: 2.1
Name: checkr
Version: 0.1.3
Summary: Data validation made easy
Project-URL: Homepage, https://github.com/celyes/checkr
Project-URL: Documentation, https://github.com/celyes/checkr#readme
Project-URL: Source, https://github.com/celyes/checkr
Author-email: Ilyes Chouia <ilyes.chouia@outlook.com>
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Environment :: MacOS X
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: Unix
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Internet
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.7
Requires-Dist: pytest>=7.2.2
Requires-Dist: requests>=2.28.2
Requires-Dist: ulid-py>=1.1.0
Requires-Dist: validators>=0.20.0
Description-Content-Type: text/markdown

# Checkr

Checkr is a powerful validation library that enables developers to easily and accurately validate user input and other
data. With Checkr, you can quickly perform a wide range of checks, and ensuring that data conforms to specific
formatting requirements. With a simple and intuitive API, Checkr is easy to integrate into any project, and its flexible
configuration options make it a powerful
tool for building robust and reliable applications.
### Installation
```shell
pip install checkr
```

### Usage

1. First of all, You need to create a request class that has two methods:

```python
from checkr.BaseRequest import BaseRequest
from typing import Dict


class SampleRequest(BaseRequest):

    @staticmethod
    def authorize() -> bool:
        return True

    @staticmethod
    def rules() -> Dict:
        return {
            'name': 'required|string|min:3',  # You can use the pipe
            'age': ['required', 'numeric', 'gte:18'],  # Or you can just provide a list
        }
```

2. Use the request class to validate data:

```python
from checkr import validate
from checkr.exceptions import ValidationError


request_data = {
    'name': 'john doe'
}

try:
    validate(SampleRequest, request_data)
except ValidationError as e:
    # Do anything with the validation result here.
    print(e.errors)
```

### Authorizing the request

This method is useful when you want to ensure that validation is performed only by certain parties or by specific users.
In your request class, include a static method named `authorize` that returns a boolean.

### Customizing the validation messages

To customize the validation messages returned when the validation of a field fails,
you can use the `messages` method. Here's an example:

```python
from typing import Dict
from checkr.BaseRequest import BaseRequest


class SampleRequest(BaseRequest):
    ...

    @classmethod
    def messages(cls) -> Dict:
        return {
            'name.required': 'Please provide a name!',
            'age.number': 'Oops! not a number!'
        }

    ...
```

### Adding fields before starting the validation

Sometimes, you may find it useful to add a field before the process of validation starts.
You can accomplish this by using the `prepare_for_validation` hook as demonstrated in the following example:

```python
from typing import Dict
from checkr.BaseRequest import BaseRequest


class SampleRequest(BaseRequest):
    ...

    @classmethod
    def prepare_for_validation(cls) -> Dict:
        cls.merge(data_to_add={'foo': 'bar'})

    ...
```

### Adding fields after finishing the validation

It's almost identical to adding fields before starting the validation. You'll use
`passed_validation` hook as demonstrated in the following example:

Notice that this method will not run if the validation finds invalid data.

```python
from typing import Dict
from checkr.BaseRequest import BaseRequest


class SampleRequest(BaseRequest):
    ...

    @classmethod
    def passed_validation(cls) -> Dict:
        cls.merge(data_to_add={'foo': 'bar'})

    ...
```

### Available rules

| Rule Name            | Description                                                                                                                                                                          | Usage                                                                                                                                     |
|----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------|
| between              | Checks if a value is between a minimum and maximum value                                                                                                                             | `between:x,y` where `x` and `y` are required. If provided with more than 2 numbers, the first and last numbers will be taken into account |
| string               | Checks if a value is a string                                                                                                                                                        | `string`                                                                                                                                  |
| int                  | Checks if a value is an integer                                                                                                                                                      | `int`                                                                                                                                     |
| required             | Checks if a value is present                                                                                                                                                         | `required`                                                                                                                                |
| numeric              | Checks if a value is numeric                                                                                                                                                         | `numeric`                                                                                                                                 |
| array                | Checks if a value is a valid Python list                                                                                                                                             | `array`                                                                                                                                   |
| array_of             | Checks if an array contains only elements of a specific type                                                                                                                         | `array_of:string`                                                                                                                         |
| in_array             | Checks if a value is in an array of valid options                                                                                                                                    | `in_array:a,b,c`                                                                                                                          |
| not_in_array         | Checks if a value is not in a list of invalid options                                                                                                                                | `not_in_array:a,b,c`                                                                                                                      |
| date_after           | Checks if a date is after a specific date                                                                                                                                            | `date_after:YYYY-mm-dd`                                                                                                                   |
| date_after_or_equal  | Checks if a date is after or equal to a specific date                                                                                                                                | `date_after_or_equal:YYYY-mm-dd`                                                                                                          |
| date_before          | Checks if a date is before a specific date                                                                                                                                           | `date_before:YYYY-mm-dd`                                                                                                                  |
| date_before_or_equal | Checks if a date is before or equal to a specific date                                                                                                                               | `date_before_or_equal:YYYY-mm-dd`                                                                                                         |
| min                  | Checks if a value is greater than or equal to a minimum value if it's a number. If provided a string, it checks if the string length is greater than or equal to the provided value. | `min:x` where `x` is a number amd required                                                                                                |
| max                  | Checks if a value is greater than or equal to a maximum value if it's a number. If provided a string, it checks if the string length is less than or equal to the provided value.	   | `max:x` where `x` is a number and required                                                                                                |
| min_digits           | Checks if a numeric value has at least a specified number of digits                                                                                                                  | `min_digits:n`                                                                                                                            |
| max_digits           | Checks if a numeric value has at most a specified number of digits                                                                                                                   | `max_digits:n`                                                                                                                            |
| json                 | Checks if a value is a valid JSON object                                                                                                                                             | `json`                                                                                                                                    |
| nullable             | Allows a value to be null or undefined                                                                                                                                               | `nullable`                                                                                                                                |
| decimal              | Checks if a value is a decimal number                                                                                                                                                | `decimal:x` where `x` is the number of decimal places and is optional                                                                     |
| gt                   | Checks if a value is greater than a specified value                                                                                                                                  | `gt:x` where `x` is a number                                                                                                              |
| gte                  | Checks if a value is greater than or equal to a specified value                                                                                                                      | `gte:x` where `x` is a number                                                                                                             |
| lt                   | Checks if a value is less than a specified value                                                                                                                                     | `lt:x` where `x` is a number                                                                                                              |
| lte                  | Checks if a value is less than or equal to a specified value                                                                                                                         | `lte:x` where `x` is a number                                                                                                             |
| ip                   | Checks if a value is a valid IPv4 or IPv6 address                                                                                                                                    | `ip`                                                                                                                                      |
| ipv4                 | Checks if a value is a valid IPv4 address                                                                                                                                            | `ipv4`                                                                                                                                    |
| ipv6                 | Checks if a value is a valid IPv6 address                                                                                                                                            | `ipv6`                                                                                                                                    |
| lowercase            | Checks if a string is lowercase                                                                                                                                                      | `lowercase`                                                                                                                               |
| uppercase            | Checks if a string is uppercase                                                                                                                                                      | `uppercase`                                                                                                                               |
| mac_address          | Checks if a value is a valid MAC address                                                                                                                                             | `mac_address`                                                                                                                             |
| uuid                 | Checks if a value is a valid UUID                                                                                                                                                    | `uuid:v` where `v` is the version and defaults to v4 if no version provided                                                               |
| ulid                 | Checks if a value is a valid ULID                                                                                                                                                    | `ulid`                                                                                                                                    |
| url                  | Checks if a value is a valid URL                                                                                                                                                     | `url`                                                                                                                                     |
| startswith           | Checks if a string starts with a specific value                                                                                                                                      | `startswith`                                                                                                                              |
| endswith             | Checks if a string ends with a specific value                                                                                                                                        | `endswith`                                                                                                                                |
| email                | Checks if a value is a valid email address                                                                                                                                           | `email`                                                                                                                                   |
| bool                 | Checks if a value is a boolean (true or false)                                                                                                                                       | `bool`                                                                                                                                    |

### Adding custom validation rules:

In some cases, it is useful to create a rule that validates an input in custom way like checking if a phone number has a
specific format or checking that a city name exists in reality. The following example demonstrates how to accomplish
this:

```python
from typing import Any
from checkr.rules.BaseRule import BaseRule

class CustomRule(BaseRule):

    def __str__(self):
        return 'custom_rule'  # required. If not provided, incorrect errors dictionary will be returned

    def validate(self, attribute: str, value: Any) -> bool:
        return True

    def message(self, attribute: str):
        return f'This field failed because something was incorrect'

```

You can use the `validate` method to validate against a condition.
note that this method takes two arguments:

* `attribute` which is the name of the field
* `value` which is the actual value.

There's also another method called `message` which is used to return a message in case the validation fails. This method
receives one parameter, `attribute`, which is the name of the field under validation.
