{"id":13501408,"url":"https://github.com/shezadkhan137/required","last_synced_at":"2026-01-31T07:34:41.628Z","repository":{"id":57461376,"uuid":"82114546","full_name":"shezadkhan137/required","owner":"shezadkhan137","description":"Easy multi-field validation","archived":false,"fork":false,"pushed_at":"2018-12-13T18:19:10.000Z","size":79,"stargazers_count":60,"open_issues_count":8,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-08-24T22:55:45.617Z","etag":null,"topics":["api","cross-field","dependencies","django","flask","python","validation"],"latest_commit_sha":null,"homepage":"","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/shezadkhan137.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-02-15T22:45:52.000Z","updated_at":"2025-06-19T18:41:10.000Z","dependencies_parsed_at":"2022-09-17T08:11:22.428Z","dependency_job_id":null,"html_url":"https://github.com/shezadkhan137/required","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/shezadkhan137/required","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shezadkhan137%2Frequired","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shezadkhan137%2Frequired/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shezadkhan137%2Frequired/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shezadkhan137%2Frequired/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shezadkhan137","download_url":"https://codeload.github.com/shezadkhan137/required/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shezadkhan137%2Frequired/sbom","scorecard":{"id":818053,"data":{"date":"2025-08-11","repo":{"name":"github.com/shezadkhan137/required","commit":"be8b30a973a9e8ad567bf8731cf972735a2a2777"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 7 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-23T14:41:04.494Z","repository_id":57461376,"created_at":"2025-08-23T14:41:04.494Z","updated_at":"2025-08-23T14:41:04.494Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28933393,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-31T04:05:25.756Z","status":"ssl_error","status_checked_at":"2026-01-31T04:02:35.005Z","response_time":128,"last_error":"SSL_read: 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":["api","cross-field","dependencies","django","flask","python","validation"],"created_at":"2024-07-31T22:01:36.394Z","updated_at":"2026-01-31T07:34:41.613Z","avatar_url":"https://github.com/shezadkhan137.png","language":"Python","funding_links":[],"categories":["Python","Libraries in Python","Data validation"],"sub_categories":[],"readme":"# required: A easy to use DSL for validation\n\n[![PyPI](https://img.shields.io/pypi/v/required.svg)]()\n[![Build Status](https://travis-ci.org/shezadkhan137/required.svg?branch=master)](https://travis-ci.org/shezadkhan137/required)\n[![Coverage Status](https://coveralls.io/repos/github/shezadkhan137/required/badge.svg?branch=master)](https://coveralls.io/github/shezadkhan137/required?branch=master)\n\nRequired is a simple library which allows you to validate dependencies\nacross multiple fields. The goal is to make writing things like forms, seralizers and functions much easier by providing a declarative way to encode validation logic. It aims to:\n\n-  Have a declarative way to encode validation logic\n-  Allow you to maintain validation logic easily\n-  Allow you to reuse your validation logic easily\n-  Be flexible with what you want to validate\n\nIf this all sounds good. Read On!\n\n## Installation \n\nInstall using `pip`\n\n```\npip install required\n```\n\n## Quickstart\n\nYou can use required in a number of ways. The easiest way is to use the `validate` decorator to validate inputs to function calls. \n\n```python\nfrom required import validate\n\n@validate\ndef calculate_sum(positive_number, negative_number):\n    \"\"\"\n    positive_number -\u003e positive_number \u003e 0\n    negative_number -\u003e negative_number \u003c 0\n    \"\"\"\n    return positive_number + negative_number\n    \n# the following will raise a validation exception\ncalculate_sum(1, 1)\n\n# this will pass validation\ncalculate_sum(1, -1) # 0\n```\n\nIf you want to have other information in the docstring, the validation rules can be wrapped inside of `Requires { }` as shown below:\n\n```python\n\n@validate\ndef calculate_sum(positive_number, negative_number):\n    \"\"\"\n    Other documentation relating to calculate_sum\n    \n    Requires {\n        positive_number -\u003e positive_number \u003e 0\n        negative_number -\u003e negative_number \u003c 0\n    }\n    \n    You can also put information after the requires rules\n    \"\"\"\n    return positive_number + negative_number\n```\n\nValidation rules are written in the doc string of the function. They look like: \n\n`[param] -\u003e [expression_1] [comparator] [expression_2]`\n\nWhen `param` is present, it requires `expression_1 [comparator] expression_2` to evaluate to true. \n\nThe most simple expressions are just variables passed into the function to validate, however they can be more complex. See cookbook for more examples.\n\nThe comparator can be one of the standard python comparator operations; `==`, `!=`, `in`, `\u003e=` `\u003c=`, `\u003e`, `\u003c`.\n\n\n\n## Cookbook\n\nThe following shows some examples for writing validation rules\n\n```\n\n# Arithmetic on the objects follow normal maths rules.\n# you need to put brackets to define expressions\nx -\u003e (x + 1) \u003c 1\nx -\u003e (x - y) == 1\n\n# A value `x` needs to be in an array\nx -\u003e x in arr\n\n# The length of x must be 10\n# see section on registering functions\nx -\u003e len(x) == 10\n\n# The length of x and y must be the same\nx -\u003e len(x) == len(y)\n\n# when x is present y must not be present\n# TODO: not implemented in DSL yet\nx -\u003e x == \u003cempty\u003e\n\n# x must be equal to the return value of a function\nx -\u003e x == func(x)\n\n# Partial dependencies can be also specified\n\n# when x == 1 then y must be 2\nx == 1 -\u003e y == 2\n\n# when x == 1 then y must be set\nx == 1 -\u003e y\n```\n\n## Registering callables\n\nYou can register callables into the validation scope. This is useful when you want to call normal python builtins or custom callables. \n\n```python\nfrom required import validate\n\nscoped_validate = validate.register_callables({\n \"len\": len,\n \"abs\": abs\n})\n\n@scoped_validate\ndef return_first_element(arr):\n    \"\"\"\n    arr -\u003e len(arr) \u003e= 1\n    \"\"\"\n    return arr[0]\n\n\n# validation scoped callables can also be nested\n# len, abs and my_func are available in the second_scoped_validate decorator\n\nsecond_scoped_validate = scoped_validate.register_callables({\n    \"my_func\": my_func\n})\n\n# or inserted at function level\n@validate(callables_dict={\"new_func\": new_func})\ndef other_function(var):\n    \"\"\"\n    var -\u003e new_func(var) \u003e= 1\n    \"\"\"\n    return var\n```\n\n\n## Contributing \n\nIf you want to contribute you are most welcome! This project is distributed under the [MIT](https://choosealicense.com/licenses/mit/) licence. It is tested using [tox](https://pypi.python.org/pypi/tox) against Python 2.7 and 3.4+\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshezadkhan137%2Frequired","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshezadkhan137%2Frequired","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshezadkhan137%2Frequired/lists"}