python-validators / validators

Python Data Validation for Humans™.
MIT License
953 stars 151 forks source link

0.21.0: remoed sphinx suport #258

Closed kloczek closed 1 year ago

kloczek commented 1 year ago

Is it any reason why docsconf.py has been removed? mkdoc does not support generate man page which swill is most common U*nix documentation format.

yozachar commented 1 year ago

Validators is not a CLI tool (yet?), so I doubt man pages are unavoidable. On the other hand Python's help() works fine.

>>> help(validators)

Help on package validators:

NAME
    validators - Validate Anything!

PACKAGE CONTENTS
    _extremes
    between
    btc_address
    card
    domain
    email
    hashes
    hostname
    i18n (package)
    iban
    ip_address
    length
    mac_address
    slug
    url
    utils
    uuid

CLASSES
    builtins.Exception(builtins.BaseException)
        validators.utils.ValidationFailure

    class ValidationFailure(builtins.Exception)

...
kloczek commented 1 year ago

Wo sayid that man pages are only for CLI? 🤔 What Cli or not ha sto do witj generated documentation format?

Here is man page documetation for prev ersion

PYTHON-VALIDATORS(3)                                                                   validators                                                                   PYTHON-VALIDATORS(3)

NAME
       python-validators - validators Python Module Documentation

       Python Data Validation for Humans™.

       Python  has  all kinds of validation tools, but every one of them requires defining a schema. I wanted to create a simple validation library where validating a simple value does
       not require defining a form or a schema.  Apparently some other guys have felt the same way.

       Often I've had for example a case where I just wanted to check if given string is an email. With validators this use case becomes as easy as:

          >>> import validators

          >>> validators.email('someone@example.com')
          True

       You can install validators using pip:

          pip install validators

       Currently validators supports python versions 2.7, 3.3, 3.4, 3.5, 3.6, 3.7 and PyPy.

       Each validator in validators is a simple function that takes the value to validate and possibly some additional key-value arguments. Each function returns True  when  validation
       succeeds and ValidationFailure object when validation fails.

       ValidationFailure class implements __bool__ method so you can easily check if validation failed:

          >>> if not validators.email('some_bogus_email@@@'):
          ...     # Do something here
          ...     pass

       ValidationFailure object also holds all the arguments passed to original function:

          >>> result = validators.between(3, min=5)
          >>> result.value
          3
          >>> result.min
          5

BETWEEN
       validators.between.between(value, min=None, max=None)
              Validate that a number is between minimum and/or maximum value.

              This will work with any comparable type, such as floats, decimals and dates not just integers.

              This validator is originally based on WTForms NumberRange validator.

              Examples:

                 >>> from datetime import datetime

                 >>> between(5, min=2)
                 True

                 >>> between(13.2, min=13, max=14)
                 True

                 >>> between(500, max=400)
                 ValidationFailure(func=between, args=...)

                 >>> between(
                 ...     datetime(2000, 11, 11),
                 ...     min=datetime(1999, 11, 11)
                 ... )
                 True

              Parameters

                     • min -- The minimum required value of the number. If not provided, minimum value will not be checked.

                     • max -- The maximum value of the number. If not provided, maximum value will not be checked.

              New in version 0.2.

BTC_ADDRESS
       validators.btc_address.btc_address(value)
              Return whether or not given value is a valid bitcoin address.

              If the value is valid bitcoin address this function returns True, otherwise ValidationFailure.

              Full validation is implemented for P2PKH and P2SH addresses.  For segwit addresses a regexp is used to provide a reasonable estimate on whether the address is valid.

              Examples:

                 >>> btc_address('3Cwgr2g7vsi1bXDUkpEnVoRLA9w4FZfC69')
                 True

              Parameters
                     value -- Bitcoin address string to validate

DOMAIN
       validators.domain.domain(value)
              Return whether or not given value is a valid domain.

              If the value is valid domain name this function returns True, otherwise ValidationFailure.

              Examples:

                 >>> domain('example.com')
                 True

                 >>> domain('example.com/')
                 ValidationFailure(func=domain, ...)

              Supports IDN domains as well:

                 >>> domain('xn----gtbspbbmkef.xn--p1ai')
                 True

              New in version 0.9.

              Changed in version 0.10: Added support for internationalized domain name (IDN) validation.

              Parameters
                     value -- domain string to validate

EMAIL
       validators.email.email(value, whitelist=None)
              Validate an email address.

              This validator is based on Django's email validator. Returns True on success and ValidationFailure when validation fails.

              Examples:

                 >>> email('someone@example.com')
                 True

                 >>> email('bogus@@')
                 ValidationFailure(func=email, ...)

              New in version 0.1.

              Parameters

                     • value -- value to validate

                     • whitelist -- domain names to whitelist

              Copyright

                     c. Django Software Foundation and individual contributors.

              License
                     BSD

IBAN
       validators.iban.iban(value)
              Return whether or not given value is a valid IBAN code.

              If the value is a valid IBAN this function returns True, otherwise ValidationFailure.

              Examples:

                 >>> iban('DE29100500001061045672')
                 True

                 >>> iban('123456')
                 ValidationFailure(func=iban, ...)

              New in version 0.8.

              Parameters
                     value -- IBAN string to validate

IPV4
       validators.ip_address.ipv4(value)
              Return whether a given value is a valid IP version 4 address.

              This validator is based on WTForms IPAddress validator

              Examples:

                 >>> ipv4('123.0.0.7')
                 True

                 >>> ipv4('900.80.70.11')
                 ValidationFailure(func=ipv4, args={'value': '900.80.70.11'})

              New in version 0.2.

              Parameters
                     value -- IP address string to validate

IPV6
       validators.ip_address.ipv6(value)
              Return whether a given value is a valid IP version 6 address (including IPv4-mapped IPv6 addresses).

              This validator is based on WTForms IPAddress validator.

              Examples:

                 >>> ipv6('abcd:ef::42:1')
                 True

                 >>> ipv6('::ffff:192.0.2.128')
                 True

                 >>> ipv6('::192.0.2.128')
                 True

                 >>> ipv6('abc.0.0.1')
                 ValidationFailure(func=ipv6, args={'value': 'abc.0.0.1'})

              New in version 0.2.

              Parameters
                     value -- IP address string to validate

LENGTH
       validators.length.length(value, min=None, max=None)
              Return whether or not the length of given string is within a specified range.

              Examples:

                 >>> length('something', min=2)
                 True

                 >>> length('something', min=9, max=9)
                 True

                 >>> length('something', max=5)
                 ValidationFailure(func=length, ...)

              Parameters

                     • value -- The string to validate.

                     • min -- The minimum required length of the string. If not provided, minimum length will not be checked.

                     • max -- The maximum length of the string. If not provided, maximum length will not be checked.

              New in version 0.2.

MAC_ADDRESS
       validators.mac_address.mac_address(value)
              Return whether or not given value is a valid MAC address.

              If the value is valid MAC address this function returns True, otherwise ValidationFailure.

              This validator is based on WTForms MacAddress validator.

              Examples:

                 >>> mac_address('01:23:45:67:ab:CD')
                 True

                 >>> mac_address('00:00:00:00:00')
                 ValidationFailure(func=mac_address, args={'value': '00:00:00:00:00'})

              New in version 0.2.

              Parameters
                     value -- Mac address string to validate

MD5
       validators.hashes.md5(value)
              Return whether or not given value is a valid MD5 hash.

              Examples:

                 >>> md5('d41d8cd98f00b204e9800998ecf8427e')
                 True

                 >>> md5('900zz11')
                 ValidationFailure(func=md5, args={'value': '900zz11'})

              Parameters
                     value -- MD5 string to validate

SHA1
       validators.hashes.sha1(value)
              Return whether or not given value is a valid SHA1 hash.

              Examples:

                 >>> sha1('da39a3ee5e6b4b0d3255bfef95601890afd80709')
                 True

                 >>> sha1('900zz11')
                 ValidationFailure(func=sha1, args={'value': '900zz11'})

              Parameters
                     value -- SHA1 string to validate

SHA224
       validators.hashes.sha224(value)
              Return whether or not given value is a valid SHA224 hash.

              Examples:

                 >>> sha224('d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f')
                 True

                 >>> sha224('900zz11')
                 ValidationFailure(func=sha224, args={'value': '900zz11'})

              Parameters
                     value -- SHA224 string to validate

SHA256
       validators.hashes.sha256(value)
              Return whether or not given value is a valid SHA256 hash.

              Examples:

                 >>> sha256(
                 ...     'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b'
                 ...     '855'
                 ... )
                 True

                 >>> sha256('900zz11')
                 ValidationFailure(func=sha256, args={'value': '900zz11'})

              Parameters
                     value -- SHA256 string to validate

SHA512
       validators.hashes.sha512(value)
              Return whether or not given value is a valid SHA512 hash.

              Examples:

                 >>> sha512(
                 ...     'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce'
                 ...     '9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af9'
                 ...     '27da3e'
                 ... )
                 True

                 >>> sha512('900zz11')
                 ValidationFailure(func=sha512, args={'value': '900zz11'})

              Parameters
                     value -- SHA512 string to validate

SLUG
       validators.slug.slug(value)
              Validate whether or not given value is valid slug.

              Valid slug can contain only alphanumeric characters, hyphens and underscores.

              Examples:

                 >>> slug('my.slug')
                 ValidationFailure(func=slug, args={'value': 'my.slug'})

                 >>> slug('my-slug-2134')
                 True

              New in version 0.6.

              Parameters
                     value -- value to validate

TRUTHY
       validators.truthy.truthy(value)
              Validate that given value is not a falsey value.

              This validator is based on WTForms DataRequired validator.

              Examples:

                 >>> truthy(1)
                 True

                 >>> truthy('someone')
                 True

                 >>> truthy(0)
                 ValidationFailure(func=truthy, args={'value': 0})

                 >>> truthy('    ')
                 ValidationFailure(func=truthy, args={'value': '    '})

                 >>> truthy(False)
                 ValidationFailure(func=truthy, args={'value': False})

                 >>> truthy(None)
                 ValidationFailure(func=truthy, args={'value': None})

              New in version 0.2.

URL
       validators.url.url(value, public=False)
              Return whether or not given value is a valid URL.

              If the value is valid URL this function returns True, otherwise ValidationFailure.

              This validator is based on the wonderful URL validator of dperini.

              Examples:

                 >>> url('http://foobar.dk')
                 True

                 >>> url('ftp://foobar.dk')
                 True

                 >>> url('http://10.0.0.1')
                 True

                 >>> url('http://foobar.d')
                 ValidationFailure(func=url, ...)

                 >>> url('http://10.0.0.1', public=True)
                 ValidationFailure(func=url, ...)

              New in version 0.2.

              Changed in version 0.10.2: Added support for various exotic URLs and fixed various false positives.

              Changed in version 0.10.3: Added public parameter.

              Changed in version 0.11.0: Made the regular expression this function uses case insensitive.

              Changed in version 0.11.3: Added support for URLs containing localhost

              Parameters

                     • value -- URL address string to validate

                     • public -- (default=False) Set True to only allow a public IP address

UUID
       validators.uuid.uuid(value)
              Return whether or not given value is a valid UUID.

              If the value is valid UUID this function returns True, otherwise ValidationFailure.

              This validator is based on WTForms UUID validator.

              Examples:

                 >>> uuid('2bc1c94f-0deb-43e9-92a1-4775189ec9f8')
                 True

                 >>> uuid('2bc1c94f 0deb-43e9-92a1-4775189ec9f8')
                 ValidationFailure(func=uuid, ...)

              New in version 0.2.

              Parameters
                     value -- UUID value to validate

SPANISH
   es_doi
       validators.i18n.es.es_doi(doi)
              Validate a Spanish DOI.

              A DOI in spain is all NIF / CIF / NIE / DNI -- a digital ID. For more information see wikipedia.org/doi.

              This validator is based on generadordni.es.

              Examples:

                 >>> es_doi('X0095892M')
                 True

                 >>> es_doi('X0095892X')
                 ValidationFailure(func=es_doi, args=...)

              New in version 0.13.0.

              Parameters
                     doi -- DOI to validate

   es_nif
       validators.i18n.es.es_nif(doi)
              Validate a Spanish NIF.

              Each  entity,  be it person or company in Spain has a distinct NIF. Since we've designated CIF to be a company NIF, this NIF is only for person.  For more information see
              wikipedia.org/nif.

              This validator is based on generadordni.es.

              Examples:

                 >>> es_nif('26643189N')
                 True

                 >>> es_nif('26643189X')
                 ValidationFailure(func=es_nif, args=...)

              New in version 0.13.0.

              Parameters
                     doi -- DOI to validate

   es_nie
       validators.i18n.es.es_nie(doi)
              Validate a Spanish NIE.

              The NIE is a tax identification number in Spain, known in Spanish as the NIE, or  more  formally  the  Número  de  identidad  de  extranjero.  For  more  information  see
              wikipedia.org/nie.

              This validator is based on generadordni.es.

              Examples:

                 >>> es_nie('X0095892M')
                 True

                 >>> es_nie('X0095892X')
                 ValidationFailure(func=es_nie, args=...)

              New in version 0.13.0.

              Parameters
                     doi -- DOI to validate

   es_cif
       validators.i18n.es.es_cif(doi)
              Validate a Spanish CIF.

              Each company in Spain prior to 2008 had a distinct CIF and has been discontinued. For more information see wikipedia.org/cif.

              The  new  replacement  is to use NIF for absolutely everything. The issue is that there are "types" of NIFs now: company, person[citizen vs recident] all distinguished by
              the first character of the DOI. For this reason we will continue to call CIF NIFs that are used for companies.

              This validator is based on generadordni.es.

              Examples:

                 >>> es_cif('B25162520')
                 True

                 >>> es_cif('B25162529')
                 ValidationFailure(func=es_cif, args=...)

              New in version 0.13.0.

              Parameters
                     doi -- DOI to validate

FINNISH
   fi_business_id
       validators.i18n.fi.fi_business_id(business_id)
              Validate a Finnish Business ID.

              Each company in Finland has a distinct business id. For more information see Finnish Trade Register

              Examples:

                 >>> fi_business_id('0112038-9')  # Fast Monkeys Ltd
                 True

                 >>> fi_business_id('1234567-8')  # Bogus ID
                 ValidationFailure(func=fi_business_id, ...)

              New in version 0.4.

              Changed in version 0.5: Method renamed from finnish_business_id to fi_business_id

              Parameters
                     business_id -- business_id to validate

   fi_ssn
       validators.i18n.fi.fi_ssn(ssn, allow_temporal_ssn=True)
              Validate a Finnish Social Security Number.

              This validator is based on django-localflavor-fi.

              Examples:

                 >>> fi_ssn('010101-0101')
                 True

                 >>> fi_ssn('101010-0102')
                 ValidationFailure(func=fi_ssn, args=...)

              New in version 0.5.

              Parameters

                     • ssn -- Social Security Number to validate

                     • allow_temporal_ssn -- Whether to accept temporal SSN numbers. Temporal SSN numbers are the ones where the serial is in the range [900-999]. By  default  temporal
                       SSN numbers are valid.

VALIDATOR
       class validators.utils.ValidationFailure(func, args)

       validators.utils.validator(func, *args, **kwargs)
              A decorator that makes given function validator.

              Whenever the given function is called and returns False value this decorator returns ValidationFailure object.

              Example:

                 >>> @validator
                 ... def even(value):
                 ...     return not (value % 2)

                 >>> even(4)
                 True

                 >>> even(5)
                 ValidationFailure(func=even, args={'value': 5})

              Parameters

                     • func -- function to decorate

                     • args -- positional function arguments

                     • kwargs -- key value function arguments

AUTHOR
       Konsta Vesterinen

COPYRIGHT
       2013-2014, Konsta Vesterinen

0.20.0                                                                                Jan 28, 2023                                                                  PYTHON-VALIDATORS(3)
yozachar commented 1 year ago

I have not qualms in adding Sphinx, except that it feels clunky and redundant.

Wo sayid that man pages are only for CLI?

Help me understand, how do you use man pages, of a library (a non-CLI tool)?

(For reference of course, but you can refer online docs and offline with help(validators)) how else do you use the documentation?

I see there's a Debian policy to have man pages for each package.

kloczek commented 1 year ago

I have not qualms in adding Sphinx, except that it feels clunky and redundant.

Issue is that documentation include is packaged mdule is not only for you.

Help me understand, how do you use man pages, of a library (a non-CLI tool)?

Man command provides acess to the DOCUMENTATION. From man1(1):

       The table below shows the section numbers of the manual followed by the types of pages they contain.

       1   Executable programs or shell commands
       2   System calls (functions provided by the kernel)
       3   Library calls (functions within program libraries)
       4   Special files (usually found in /dev)
       5   File formats and conventions, e.g. /etc/passwd
       6   Games
       7   Miscellaneous (including macro packages and conventions), e.g. man(7), groff(7), man-pages(7)
       8   System administration commands (usually only for root)
       9   Kernel routines [Non standard]

       A manual page consists of several sections.

On packagin modules I'm packaging python modules documentation as lvl 3 man pages and if you will look on copied generated man page for your module that man page provides exactly what shoud bi provided on that level.

Reall .. pleas restore conf,py to allow generate documentation for your module as man page.

yozachar commented 1 year ago

Issue is that documentation include is packaged mdule is not only for you.

Agreed, that's why I've taken extra steps to generate markdown documentation for offline package distribution.

https://github.com/python-validators/validators/blob/68227f223d92146f87e3cd2c55e0d77564243e28/build.py#L13

https://github.com/python-validators/validators/blob/68227f223d92146f87e3cd2c55e0d77564243e28/.github/workflows/build.yml#L37-L41

Man command provides acess to the DOCUMENTATION.

I understand what man-pages do.

On packagin modules I'm packaging python modules documentation as lvl 3 man pages.

Can you please elaborate?


By the way you can still generate man-formatted documentation using podc3 and pandoc.

$ pdoc --html --output-dir html-docs validators
$ pandoc -s -t man html-docs/validators/index.html -o validators.1
$ man ./validators.1
validators API documentation()                                     validators API documentation()

Package validators
       Validate Anything!  Expand source code

              """Validate Anything!"""
              # -*- coding: utf-8 -*-

              # isort: skip_file

              # The following imports are sorted alphabetically, manually.
              # Each line is grouped based first or type, then sorted alphabetically.
              # This is for the reference documentation.

              # local
              from .between import between
              from .btc_address import btc_address
              from .card import amex, card_number, diners, discover, jcb, mastercard, unionpay, visa
kloczek commented 1 year ago

By the way you can still generate man-formatted documentation using podc3 and pandoc.

Please try to compare your result with what I've copied here. Again .. mkdoc does not offer anything else than html and mkdoc maintainer do not see any needs to provide sometning else. Sphinx ATM provides possibility natively rendering to 16 formats.

Maybe this will convince you.

[tkloczko@pers-jacek SPECS]$ grep %pyproject_wheel *spec -l | wc -l
1133
[tkloczko@pers-jacek SPECS]$ grep %pyproject_wheel *spec -l | xargs grep %sphinx_build_man -l | wc -l
540

So above shows that I have +1.1k rpm spec files amongst which almost half provides documentation which is possible to render using sphinx. Example commandline output in devel env which I'm using now working on another package with python module:

[tkloczko@pers-jacek SPECS]$ man python-<tab><tab>
python-aiosqlite                 python-jinja2                    python-prompt_toolkit
python-anyiodoc                  python-jsonpointer               python-psutil
python-argon2-cffi               python-jsonschema                python-ptyprocess
python-arrow                     python-jupyter-client            python-pygments
python-asttokens                 python-jupyter-core              python-pyparsing
python-babel                     python-jupyter-events            python-pyproject-hooks
python-backcall                  python-jupyter-server            python-pyrsistent
python-beautifulsoup             python-jupyter-server-fileid     python-pytest
python-bleach                    python-jupyter-server-terminals  python-requests
python-build                     python-jupyter-server-ydoc       python-setuptools
python-cffi                      python-jupyter-ydoc              python-six
python-charset-normalizer        python-jupyterlab-server         python-sniffio
python-contourpy                 python-jupyternotebook           python-terminado
python-cycler                    python-kiwi                      python-tinycss2
python-dateutil                  python-markupsafe                python-traitlets
python-decorator                 python-metaextract               python-urllib3
python-fastjsonschema            python-mistune                   python-wcwidth
python-fonttools                 python-nbclient                  python-webcolors
python-fqdn                      python-nbconvert                 python-webencodings
python-html5lib                  python-nbformat                  python-websocket-client
python-importlib-metadata        python-olefile                   python-wheel
python-importlib_resources       python-parso                     python-y-py
python-ipykernel                 python-pillow                    python-zipp
python-ipython                   python-platformdirs              python-zmq
python-jedi                      python-pluggy

html is nice however if you need to find someting quckly with man page you can find that still way faster than using web page using web browser.

kloczek commented 1 year ago

Thank you 👍

yozachar commented 1 year ago
VALIDATORS(1)                                                        validators                                                       VALIDATORS(1)

NAME
       validators - Python Data Validation for Humans™

       Tests Bandit Version Status Downloads

       Python has all kinds of data validation tools, but every one of them seems to require defining a schema or form. I wanted to create a simple
       validation library where validating a simple value does not require defining a form or a schema.

          >>> import validators

          >>> validators.email('someone@example.com')
          True

RESOURCES
       • Documentation

       • Issue Tracker

       • Security

       • Code

   between
       validators.between.between(value: PossibleValueTypes, /, *, min_val: PossibleValueTypes | AbsMin | None = None, max_val:  PossibleValueTypes
       | AbsMax | None = None)
              Validate that a number is between minimum and/or maximum value.

              This  will work with any comparable type, such as floats, decimals and dates not just integers. This validator is originally based on
              [WTForms-NumberRange-Validator][1].

              [1]: https://github.com/wtforms/wtforms/blob/master/src/wtforms/validators.py#L166-L220

              Examples

              >>> from datetime import datetime
              >>> between(5, min_val=2)
              # Output: True
              >>> between(13.2, min_val=13, max_val=14)
              # Output: True
              >>> between(500, max_val=400)
              # Output: ValidationFailure(func=between, args=...)
              >>> between(
              ...     datetime(2000, 11, 11),
              ...     min_val=datetime(1999, 11, 11)
              ... )
              # Output: True

              Parameters

                     • value -- Value which is to be compared.

                     • min_val -- The minimum required value of the number.  If not provided, minimum value will not be checked.

                     • max_val -- The maximum value of the number.  If not provided, maximum value will not be checked.

              Returns
                     If value is in between the given conditions.  (ValidationFailure):
                        If value is not in between the given conditions.

              Return type
                     (Literal[True])

              Raises

                     • ValueError -- If both min_val and max_val are None,
                           or if min_val is greater than max_val.

                     • TypeError -- If there's a type mismatch before comparison.

              NOTE:

                 • PossibleValueTypes = TypeVar("PossibleValueTypes", int, float, str, datetime)

                 • Either one of min_val or max_val must be provided.

              > New in version 0.2.0.

...
...
...

   uuid
       validators.uuid.uuid(value: str | UUID, /)
              Return whether or not given value is a valid UUID-v4 string.

              This validator is based on [WTForms UUID validator][1].

              [1]: https://github.com/wtforms/wtforms/blob/master/src/wtforms/validators.py#L539

              Examples

              >>> uuid('2bc1c94f-0deb-43e9-92a1-4775189ec9f8')
              # Output: True
              >>> uuid('2bc1c94f 0deb-43e9-92a1-4775189ec9f8')
              # Output: ValidationFailure(func=uuid, ...)

              Parameters
                     value -- UUID string or object to validate.

              Returns
                     If value is a valid UUID.  (ValidationFailure):
                        If value is an invalid UUID.

              Return type
                     (Literal[True])

              > New in version 0.2.0.

AUTHOR
       Konsta Vesterinen

COPYRIGHT
       2013 - 2023, Konsta Vesterinen

0.21.0                                                              Mar 30, 2023                                                      VALIDATORS(1)
 Manual page validators.1 line 1010/1049 (END) (press h for help or q to quit)
kloczek commented 1 year ago

Thank you very much 👍 Will try to test recent comits in ~2h when will back home 😄