{"id":43390533,"url":"https://github.com/marcusfrdk/tomlval","last_synced_at":"2026-02-02T13:01:59.206Z","repository":{"id":275750694,"uuid":"927072210","full_name":"marcusfrdk/tomlval","owner":"marcusfrdk","description":"A flexible, easy-to-use, and dependency-free Python library for validating TOML data against custom schemas.","archived":false,"fork":false,"pushed_at":"2025-07-27T01:47:25.000Z","size":209,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-27T21:41:10.926Z","etag":null,"topics":["python","schema","toml","validation"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/tomlval/","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/marcusfrdk.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}},"created_at":"2025-02-04T11:04:04.000Z","updated_at":"2025-08-15T19:17:46.000Z","dependencies_parsed_at":"2025-02-04T17:47:33.000Z","dependency_job_id":"685739a7-b856-40fb-8cba-bd62c51114af","html_url":"https://github.com/marcusfrdk/tomlval","commit_stats":null,"previous_names":["marcusfrdk/toml-parser","marcusfrdk/tomlval"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/marcusfrdk/tomlval","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcusfrdk%2Ftomlval","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcusfrdk%2Ftomlval/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcusfrdk%2Ftomlval/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcusfrdk%2Ftomlval/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcusfrdk","download_url":"https://codeload.github.com/marcusfrdk/tomlval/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcusfrdk%2Ftomlval/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29012691,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-02T12:48:30.580Z","status":"ssl_error","status_checked_at":"2026-02-02T12:46:38.384Z","response_time":58,"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":["python","schema","toml","validation"],"created_at":"2026-02-02T13:01:57.173Z","updated_at":"2026-02-02T13:01:59.200Z","avatar_url":"https://github.com/marcusfrdk.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TOML Validator\n\n![top language](https://img.shields.io/github/languages/top/marcusfrdk/tomlval)\n![code size](https://img.shields.io/github/languages/code-size/marcusfrdk/tomlval)\n![last commit](https://img.shields.io/github/last-commit/marcusfrdk/tomlval)\n![issues](https://img.shields.io/github/issues/marcusfrdk/tomlval)\n![contributors](https://img.shields.io/github/contributors/marcusfrdk/tomlval)\n![PyPI](https://img.shields.io/pypi/v/tomlval)\n![License](https://img.shields.io/github/license/marcusfrdk/tomlval)\n![Downloads](https://static.pepy.tech/badge/tomlval)\n![Monthly Downloads](https://static.pepy.tech/badge/tomlval/month)\n\nA package used for validating TOML data against a schema and manually added handlers. It is designed to be flexible and easy to use, allowing you to customize the validation process to fit your needs.\n\n## Installation\n\nYou can install the package from [PyPI](https://pypi.org/project/tomlval/):\n\n```bash\npip install tomlval\n```\n\nThe package is available for Python 3.11 and newer.\n\n## Concepts\n\n### Handlers\n\nA handler is a validation function used by the validator to validate the value of a key. Handlers can be defined in a [schema](docs/SCHEMA.md) or added directly to the [validator](docs/VALIDATOR.md) using the `add_handler(key, fn) method.\n\nYou can read more about handlers in the [handler documentation](docs/HANDLER.md).\n\n### Schema\n\nA schema is a collection of keys and their associated handlers. It is defined as a dictionary where the keys are specific- or wildcard keys and the values are the functions ([handlers](docs/HANDLER.md)).\n\nYou can read more about schemas in the [schema documentation](docs/SCHEMA.md).\n\n### Validator\n\nThe validator is the object that performs the actual validation on the data. It uses the optionally defined schema alongside manually added [handlers](docs/HANDLER.md) to validate the data and returns a dictionary of errors.\n\nYou can read more about the validator in the [validator documentation](docs/VALIDATOR.md).\n\n## Examples\n\n```python\nfrom tomlval import TOMLSchema, TOMLValidator\n\n# Define a schema\nschema = TOMLSchema({\n    \"name\": str,\n    \"age\": int,\n})\n\n# Sample TOML data\ndata = {\n    \"name\": \"Alice\",\n    \"age\": 30,\n}\n\n# Create a validator\nvalidator = TOMLValidator(schema=schema)\n\n# Validate the data\nerrors = validator.validate(data)\n```\n\n```python\nfrom tomlval import TOMLSchema, TOMLValidator\n\n# Define a schema\nschema = TOMLSchema({\n    \"email?\": str,  # Optional email\n    \"username\": lambda value: \"invalid-username\" if len(value) \u003c 3 else None,  # Custom handler\n})\n\n# Sample TOML data\ndata = {\n    \"username\": \"ab\",\n}\n\n# Create a validator\nvalidator = TOMLValidator(schema=schema)\n\n# Validate the data\nerrors = validator.validate(data)\nprint(errors)\n```\n\n```python\nimport re\nfrom datetime import datetime\nfrom tomlval import TOMLSchema, TOMLValidator\n\n# Regex patterns\nusername_pattern = re.compile(r\"^[a-zA-Z0-9_]+$\")\nemail_pattern = re.compile(r\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\")\n\n# Sample TOML data\ndata = {\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"age\": 25,\n    \"email\": \"john.doe@example.com\",\n    \"username\": \"john_doe\",\n    \"birthday\": datetime(1999, 1, 1),\n    \"is_active\": True,\n    \"scores\": [85, 92, 78],\n    \"preferences\": {\n        \"theme\": \"dark\",\n        \"notifications\": True,\n        \"language\": \"en\"\n    },\n    \"social_profiles\": [\n        {\"platform\": \"twitter\", \"handle\": \"@johndoe\"},\n        {\"platform\": \"github\", \"handle\": \"johndoe\"}\n    ],\n    \"work_history\": [\n        {\n            \"company\": \"TechCorp\",\n            \"position\": \"Developer\",\n            \"skills\": [{\"name\": \"Python\", \"level\": 8}, {\"name\": \"JavaScript\", \"level\": 7}]\n        }\n    ],\n    \"metadata\": {\n        \"created_at\": datetime.now(),\n        \"tags\": [\"user\", \"premium\"]\n    }\n}\n\n# Define a schema\nschema = TOMLSchema({\n    # Basic type validation\n    \"first_name\": str,\n    \"age\": (int, float),  # Multiple types\n    \"birthday\": datetime,\n    \"is_active\": bool,\n\n    # Optional keys\n    \"middle_name?\": str,\n    \"phone?\": str,\n\n    # Regex pattern validation\n    \"username\": username_pattern,\n    \"email\": email_pattern,\n\n    # Custom handlers\n    \"last_name\": lambda value: \"too-short\" if len(value) \u003c 2 else None,\n    \"age\": lambda value: \"invalid-age\" if not (0 \u003c value \u003c 150) else None,\n    \"email\": lambda key: f\"missing-{key}\" if not key else None,\n    \"username\": lambda key, value: f\"invalid-{key}\" if len(value) \u003c 3 else None,\n\n    # List validation\n    \"scores\": [int],  # List of integers\n    \"tags?\": [str],   # Optional List of strings\n\n    # Nested object validation\n    \"preferences\": {\n        \"theme\": str,\n        \"notifications\": bool,\n        \"language?\": str  # Optional nested key\n    },\n\n    # List of objects\n    \"social_profiles\": [\n        {\n            \"platform\": str,\n            \"handle\": lambda value: \"invalid-handle\" if not value.startswith(\"@\") else None\n        }\n    ],\n\n    # Deeply nested list of objects\n    \"work_history\": [\n        {\n            \"company\": str,\n            \"position\": str,\n            \"skills\": [\n                {\n                    \"name\": str,\n                    \"level\": lambda value: \"invalid-level\" if not (1 \u003c= value \u003c= 10) else None\n                }\n            ]\n        }\n    ],\n\n    # Optional nested object\n    \"metadata?\": {\n        \"created_at\": datetime,\n        \"tags\": [str],\n        \"version?\": float\n    },\n\n    # Wildcard patterns\n    \"*_name\": str,                    # Matches first_name, last_name, etc.\n    \"preferences.*\": lambda: None,    # Matches any key in preferences\n    \"*_profiles\": [dict],             # Matches social_profiles, etc.\n\n    # Keys within lists\n    \"scores[]\": int,                  # Individual List elements\n    \"work_history[].company\": str,    # Nested List element validation\n    \"social_profiles[].platform\": lambda value: \"unsupported\" if value not in [\"twitter\", \"github\", \"linkedin\"] else None,\n\n    # Optional List elements\n    \"work_history[]?\": dict,          # Optional List elements\n    \"preferences?.*\": str,            # Optional wildcard in optional object\n\n    # Catch-all handler\n    \"*\": lambda: \"invalid-key\"\n})\n\n# Custom callback functions\ndef on_missing_key(key: str) -\u003e str:\n    return f\"Missing key '{key}'\"\n\ndef on_type_mismatch(key: str, expected, got) -\u003e str:\n    return f\"Key '{key}' expected {expected.__name__} but got {got.__name__}\"\n\ndef on_pattern_mismatch(key: str, pattern) -\u003e str:\n    return f\"Key '{key}' does not match pattern {pattern.pattern}\"\n\n# Override default handlers\nvalidator = TOMLValidator(\n    schema=schema,\n    on_missing=on_missing_key,\n    on_type_mismatch=on_type_mismatch,\n    on_pattern_mismatch=on_pattern_mismatch\n)\n\n# Manual handlers\nvalidator.add_handler(\"some.key\", lambda value: \"custom-error\" if value == \"invalid\" else None)\n\n# Validate\nerrors = validator.validate(data)\n```\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcusfrdk%2Ftomlval","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcusfrdk%2Ftomlval","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcusfrdk%2Ftomlval/lists"}