{"id":36937625,"url":"https://github.com/nitrosh/nitro-validate","last_synced_at":"2026-04-17T14:03:57.638Z","repository":{"id":326257774,"uuid":"1102541893","full_name":"nitrosh/nitro-validate","owner":"nitrosh","description":"A powerful, standalone, dependency-free data validation library for Python with extensible rules and a clean, intuitive API.","archived":false,"fork":false,"pushed_at":"2025-11-26T17:15:31.000Z","size":53,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-29T14:21:39.994Z","etag":null,"topics":["data","python3","validation","validation-library"],"latest_commit_sha":null,"homepage":"https://nitro.sh","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nitrosh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-23T16:42:15.000Z","updated_at":"2025-11-26T17:20:36.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/nitrosh/nitro-validate","commit_stats":null,"previous_names":["nitrosh/nitro-validate"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/nitrosh/nitro-validate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nitrosh%2Fnitro-validate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nitrosh%2Fnitro-validate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nitrosh%2Fnitro-validate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nitrosh%2Fnitro-validate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nitrosh","download_url":"https://codeload.github.com/nitrosh/nitro-validate/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nitrosh%2Fnitro-validate/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28380803,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-13T10:00:56.084Z","status":"ssl_error","status_checked_at":"2026-01-13T09:45:11.986Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data","python3","validation","validation-library"],"created_at":"2026-01-13T10:09:30.889Z","updated_at":"2026-04-17T14:03:57.628Z","avatar_url":"https://github.com/nitrosh.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Nitro Validate\n\nA powerful, standalone, dependency-free data validation library for Python with extensible rules and a clean, intuitive API.\n\n## Requirements\n\nPython `3.7` or higher is required.\n\n## Installation\n\n```bash\npip install nitro-validator\n```\n\n### AI Assistant Integration\n\nAdd Nitro Validator knowledge to your AI coding assistant:\n\n```bash\nnpx skills add nitrosh/nitro-validate\n```\n\nThis enables AI assistants like Claude Code to understand Nitro Validator and generate correct validation code.\n\n## Features\n\n- **Simple API** - Easy to learn with minimal boilerplate\n- **Zero Dependencies** - No external dependencies required\n- **Extensible** - Create custom validation rules with ease\n- **Clean Syntax** - Pipe-delimited rule strings or rule objects\n- **Custom Messages** - Override default error messages per field or rule\n- **Cross-field Validation** - Validate fields against other fields\n- **Type Safe** - Validates strings, numbers, booleans, dates, and more\n- **Comprehensive Rules** - 51+ built-in validation rules\n\n## Quick Start\n\n```python\nfrom nitro_validator import NitroValidator\n\n# Create a validator instance\nvalidator = NitroValidator()\n\n# Define your data and rules\ndata = {\n    'email': 'user@example.com',\n    'age': 25,\n    'password': 'secret123',\n    'confirm_password': 'secret123'\n}\n\nrules = {\n    'email': 'required|email',\n    'age': 'required|numeric|min:18',\n    'password': 'required|min:8',\n    'confirm_password': 'required|same:password'\n}\n\n# Validate\ntry:\n    validated_data = validator.validate(data, rules)\n    print(\"Validation passed!\", validated_data)\nexcept NitroValidationError as e:\n    print(\"Validation failed:\", e.errors)\n```\n\n**Note:** For convenience, you can also use `Validator` as an alias for `NitroValidator`, and `ValidationError` for `NitroValidationError`.\n\n## Available Rules\n\n### Basic Rules\n\n| Rule       | Description                         | Example                     |\n|------------|-------------------------------------|-----------------------------|\n| `required` | Field must be present and not empty | `'email': 'required'`       |\n| `optional` | Field is optional (always passes)   | `'middle_name': 'optional'` |\n\n### String Rules\n\n| Rule              | Description                           | Example                      |\n|-------------------|---------------------------------------|------------------------------|\n| `alpha`           | Only alphabetic characters            | `'name': 'alpha'`            |\n| `alphanumeric`    | Only alphanumeric characters          | `'username': 'alphanumeric'` |\n| `alpha_dash`      | Letters, numbers, dashes, underscores | `'slug': 'alpha_dash'`       |\n| `lowercase`       | Only lowercase characters             | `'code': 'lowercase'`        |\n| `uppercase`       | Only uppercase characters             | `'code': 'uppercase'`        |\n| `email`           | Valid email address                   | `'email': 'email'`           |\n| `url`             | Valid URL                             | `'website': 'url'`           |\n| `uuid`            | Valid UUID                            | `'id': 'uuid'`               |\n| `ip`              | Valid IP address (v4 or v6)           | `'address': 'ip'`            |\n| `ipv4`            | Valid IPv4 address                    | `'address': 'ipv4'`          |\n| `ipv6`            | Valid IPv6 address                    | `'address': 'ipv6'`          |\n| `json`            | Valid JSON string                     | `'data': 'json'`             |\n| `slug`            | Valid URL slug                        | `'slug': 'slug'`             |\n| `ascii`           | Only ASCII characters                 | `'text': 'ascii'`            |\n| `base64`          | Valid base64 encoding                 | `'encoded': 'base64'`        |\n| `hex_color`       | Valid hex color code                  | `'color': 'hex_color'`       |\n| `credit_card`     | Valid credit card number              | `'card': 'credit_card'`      |\n| `mac_address`     | Valid MAC address                     | `'mac': 'mac_address'`       |\n| `timezone`        | Valid timezone identifier             | `'tz': 'timezone'`           |\n| `locale`          | Valid locale code                     | `'locale': 'locale'`         |\n| `regex:pattern`   | Matches regex pattern                 | `'code': 'regex:^[A-Z]{3}$'` |\n| `starts_with:str` | Starts with substring                 | `'name': 'starts_with:Mr'`   |\n| `ends_with:str`   | Ends with substring                   | `'file': 'ends_with:.pdf'`   |\n| `contains:str`    | Contains substring                    | `'text': 'contains:hello'`   |\n\n### Numeric Rules\n\n| Rule              | Description             | Example                    |\n|-------------------|-------------------------|----------------------------|\n| `numeric`         | Must be numeric         | `'price': 'numeric'`       |\n| `integer`         | Must be an integer      | `'quantity': 'integer'`    |\n| `positive`        | Must be positive number | `'amount': 'positive'`     |\n| `negative`        | Must be negative number | `'deficit': 'negative'`    |\n| `min:value`       | Minimum value or length | `'age': 'min:18'`          |\n| `max:value`       | Maximum value or length | `'rating': 'max:5'`        |\n| `between:min,max` | Between two values      | `'score': 'between:0,100'` |\n| `divisible_by:n`  | Divisible by number     | `'even': 'divisible_by:2'` |\n\n### Comparison Rules\n\n| Rule               | Description                    | Example                               |\n|--------------------|--------------------------------|---------------------------------------|\n| `same:field`       | Must match another field       | `'password_confirm': 'same:password'` |\n| `different:field`  | Must differ from another field | `'new_email': 'different:old_email'`  |\n| `in:val1,val2`     | Must be in list of values      | `'role': 'in:admin,user,guest'`       |\n| `not_in:val1,val2` | Must not be in list            | `'status': 'not_in:banned,deleted'`   |\n\n### Boolean Rules\n\n| Rule       | Description              | Example                  |\n|------------|--------------------------|--------------------------|\n| `boolean`  | Must be a boolean value  | `'active': 'boolean'`    |\n\n### Date Rules\n\n| Rule               | Description            | Example                             |\n|--------------------|------------------------|-------------------------------------|\n| `date`             | Must be a valid date   | `'birthdate': 'date'`               |\n| `before:date`      | Date must be before    | `'start': 'before:2025-12-31'`      |\n| `after:date`       | Date must be after     | `'end': 'after:2024-01-01'`         |\n| `date_equals:date` | Date must equal        | `'today': 'date_equals:2024-11-23'` |\n| `date_format:fmt`  | Date must match format | `'date': 'date_format:%Y-%m-%d'`    |\n\n**Note:** The `date`, `before`, `after`, and `date_equals` rules accept unambiguous ISO 8601 formats only (`YYYY-MM-DD`, `YYYY/MM/DD`, and datetime variants like `YYYY-MM-DDTHH:MM:SS`). For specific regional formats like `DD-MM-YYYY` or `MM-DD-YYYY`, use the `date_format` rule with an explicit format string.\n\n### Convenience Rules\n\n| Rule        | Description                       | Example                   |\n|-------------|-----------------------------------|---------------------------|\n| `confirmed` | Matches {field}_confirmation      | `'password': 'confirmed'` |\n| `accepted`  | Must be accepted (yes/true/1/on)  | `'terms': 'accepted'`     |\n| `declined`  | Must be declined (no/false/0/off) | `'marketing': 'declined'` |\n\n### Length Rules\n\n| Rule           | Description         | Example                     |\n|----------------|---------------------|-----------------------------|\n| `length:value` | Exact length        | `'zip_code': 'length:5'`    |\n\n### Collection Rules\n\n| Rule       | Description                        | Example                     |\n|------------|------------------------------------|-----------------------------|\n| `array`    | Must be a list or tuple            | `'items': 'array'`          |\n| `size:n`   | Exact size (length)                | `'tags': 'size:3'`          |\n| `distinct` | Array must have unique values      | `'ids': 'distinct'`         |\n\n## Usage Examples\n\n### Basic Validation\n\n```python\nfrom nitro_validator import NitroValidator, NitroValidationError\n\nvalidator = NitroValidator()\n\ndata = {'username': 'johndoe', 'age': '25'}\nrules = {'username': 'required|alphanumeric', 'age': 'required|integer|min:18'}\n\ntry:\n    validated = validator.validate(data, rules)\n    print(validated)  # {'username': 'johndoe', 'age': '25'}\nexcept NitroValidationError as e:\n    print(e.errors)\n```\n\n### Custom Error Messages\n\n```python\n# Single message for all rules on a field\nmessages = {\n    'email': 'Please provide a valid email address'\n}\n\n# Or specific messages per rule\nmessages = {\n    'password': {\n        'required': 'Password is required',\n        'min': 'Password must be at least 8 characters'\n    }\n}\n\nvalidator.validate(data, rules, messages)\n```\n\n### Using Rule Objects\n\n```python\nfrom nitro_validator import Validator, RequiredRule, EmailRule, MinRule\n\nvalidator = Validator()\n\ndata = {'email': 'test@example.com', 'age': 25}\nrules = {\n    'email': [RequiredRule(), EmailRule()],\n    'age': [RequiredRule(), MinRule(18)]\n}\n\nvalidated = validator.validate(data, rules)\n```\n\n### Check Validation Without Exception\n\n```python\nvalidator = Validator()\n\nif validator.is_valid(data, rules):\n    print(\"Data is valid!\")\nelse:\n    print(\"Errors:\", validator.get_errors())\n```\n\n### Factory Method\n\n```python\nfrom nitro_validator import Validator\n\n# Create and validate in one call\ntry:\n    validator = Validator.make(data, rules)\n    print(\"Valid:\", validator.validated_data)\nexcept ValidationError as e:\n    print(\"Errors:\", e.errors)\n```\n\n## Creating Custom Rules\n\nExtend the `NitroValidationRule` class to create custom validation rules:\n\n```python\nfrom nitro_validator import NitroValidationRule, NitroValidator\n\nclass StrongPasswordRule(NitroValidationRule):\n    \"\"\"Validate that a password is strong.\"\"\"\n\n    name = \"strong_password\"\n    message = \"The {field} must contain uppercase, lowercase, numbers, and symbols.\"\n\n    def validate(self, field: str, value: Any, data: dict) -\u003e bool:\n        if not value:\n            return True\n\n        has_upper = any(c.isupper() for c in value)\n        has_lower = any(c.islower() for c in value)\n        has_digit = any(c.isdigit() for c in value)\n        has_symbol = any(c in '!@#$%^\u0026*()_+-=' for c in value)\n\n        return has_upper and has_lower and has_digit and has_symbol\n\n\n# Register and use the custom rule\nvalidator = NitroValidator()\nvalidator.register_rule(StrongPasswordRule)\n\ndata = {'password': 'MyP@ssw0rd!'}\nrules = {'password': 'required|strong_password'}\n\nvalidated = validator.validate(data, rules)\n```\n\n**Backward Compatibility:** You can also use `Rule` as an alias for `NitroValidationRule` for convenience.\n\n## Advanced Usage\n\n### Cross-field Validation\n\n```python\n# Validate that one field matches another\ndata = {\n    'password': 'secret123',\n    'password_confirmation': 'secret123'\n}\n\nrules = {\n    'password': 'required|min:8',\n    'password_confirmation': 'required|same:password'\n}\n\nvalidator.validate(data, rules)\n```\n\n### Conditional Validation\n\n```python\n# Validate email only if user type is 'customer'\ndata = {'user_type': 'customer', 'email': 'user@example.com'}\n\nif data.get('user_type') == 'customer':\n    rules = {'email': 'required|email'}\nelse:\n    rules = {'email': 'optional'}\n\nvalidator.validate(data, rules)\n```\n\n### Handling Validation Errors\n\n```python\nfrom nitro_validator import ValidationError\n\ntry:\n    validator.validate(data, rules)\nexcept ValidationError as e:\n    # Get all errors as a dictionary\n    print(e.errors)  # {'email': ['Email is required'], 'age': ['Age must be at least 18']}\n\n    # Or get flattened list of all error messages\n    flat_errors = validator.get_errors_flat()\n    print(flat_errors)  # ['Email is required', 'Age must be at least 18']\n```\n\n### Custom Rule Registry\n\n```python\nfrom nitro_validator import Validator, RuleRegistry\n\n# Create a custom registry\nregistry = RuleRegistry()\nregistry.register(MyCustomRule)\n\n# Use it with a validator\nvalidator = Validator(registry=registry)\n```\n\n## Examples\n\nThe `examples/` directory contains working examples:\n\n```bash\npython examples/basic_usage.py\npython examples/custom_rules.py\npython examples/advanced_validation.py\npython examples/date_validation.py\npython examples/formats.py\n```\n\n## Development\n\n### Setup\n\n```bash\ngit clone https://github.com/nitrosh/nitro-validate.git\ncd nitro-validate\npip install -e \".[dev]\"\n```\n\n### Run Tests\n\n```bash\npytest\npytest --cov=nitro_validator\n```\n\n### Format Code\n\n```bash\nblack nitro_validator tests examples\n```\n\n## Why Nitro Validator?\n\n- **No Dependencies**: Unlike other validation libraries, Nitro Validator has zero external dependencies\n- **Extensible**: Easy to create and register custom validation rules\n- **Clean API**: Simple, intuitive syntax that's easy to learn and use\n- **Pythonic**: Follows Python best practices and idioms\n- **Well-tested**: Comprehensive test suite with high code coverage\n- **Type-safe**: Works with strings, numbers, booleans, dates, and custom types\n\n## Comparison with GUMP\n\nNitro Validator is inspired by [GUMP](https://github.com/Wixel/GUMP) (a PHP validation library by the same author) but redesigned for Python with:\n\n- More Pythonic API and conventions\n- Better extensibility with the Rule class system\n- Cleaner error handling with custom exceptions\n- Type hints and modern Python features\n- No external dependencies (GUMP requires PHP extensions)\n\n## Ecosystem\n\n- **[nitro-cli](https://github.com/nitrosh/nitro-cli)** - Static site generator that builds sites with Python code\n- **[nitro-ui](https://github.com/nitrosh/nitro-ui)** - Build HTML with Python, not strings\n- **[nitro-datastore](https://github.com/nitrosh/nitro-datastore)** - Schema-free JSON data store with dot notation access\n- **[nitro-dispatch](https://github.com/nitrosh/nitro-dispatch)** - Framework-agnostic plugin system\n- **[nitro-image](https://github.com/nitrosh/nitro-image)** - Fast, friendly image processing for the web\n\n## License\n\nThis project is licensed under the BSD 3-Clause License. See the [LICENSE](LICENSE) file for details.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnitrosh%2Fnitro-validate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnitrosh%2Fnitro-validate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnitrosh%2Fnitro-validate/lists"}