diff --git a/.github/workflows/docs.yaml.bkp b/.github/workflows/docs.yaml.bkp index c77eab94..c9d29cbb 100644 --- a/.github/workflows/docs.yaml.bkp +++ b/.github/workflows/docs.yaml.bkp @@ -27,7 +27,7 @@ jobs: pip install . pip install -r package/requirements.mkdocs.txt - name: Build documentation - run: python package/export docs + run: python package/export doc # set up Pages - name: Set up Pages uses: actions/configure-pages@v4 diff --git a/docs/conf.py b/docs/conf.py index faf5cfee..a2f052df 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -33,7 +33,8 @@ # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -html_theme = "alabaster" +html_theme = "furo" +html_favicon = "./assets/icons/favicon.svg" # -- Options for manpage generation ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-man_pages diff --git a/docs/index.rst b/docs/index.rst index 04a5fdcc..f83a560f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -63,7 +63,15 @@ Resources .. toctree:: :hidden: :maxdepth: 2 - :caption: Reference: + :caption: Quick Start: + :glob: + + install_and_use + +.. toctree:: + :hidden: + :maxdepth: 2 + :caption: API Reference: :glob: api/* diff --git a/docs/install_and_use.md b/docs/install_and_use.md new file mode 100644 index 00000000..ed136587 --- /dev/null +++ b/docs/install_and_use.md @@ -0,0 +1,43 @@ +# Install and Use + +## Installation + +Execute the following command: + +```text +pip install validators +``` + +> It's preferable to use `pip` within a virtual environment. + +## Usage + +```python +import validators +print(validators.email('someone@example.com')) +``` + +### To raise validation error + +1. Either set the environment variable `RAISE_VALIDATION_ERROR` to `True` + + ```console + $ export RAISE_VALIDATION_ERROR=True + $ python -c "from validators import url; print(url('https//bad_url'))" + Traceback (most recent call last): + File "", line 1, in + File "/path/to/lib/validators/utils.py", line 87, in wrapper + raise ValidationError(func, _func_args_as_dict(func, *args, **kwargs)) + validators.utils.ValidationError: ValidationError(func=url, args={'value': 'https//bad_url'}) + ``` + +2. Or pass `r_ve=True` to each caller function: + + ```console + $ python -c "from validators.card import visa; print(visa('bad_visa_number', r_ve=True))" + Traceback (most recent call last): + File "", line 1, in + File "/path/to/lib/validators/utils.py", line 87, in wrapper + raise ValidationError(func, _func_args_as_dict(func, *args, **kwargs)) + validators.utils.ValidationError: ValidationError(func=visa, args={'value': 'bad_visa_number'}) + ``` diff --git a/docs/install_and_use.rst b/docs/install_and_use.rst new file mode 100644 index 00000000..7673cefb --- /dev/null +++ b/docs/install_and_use.rst @@ -0,0 +1,50 @@ +Install and Use +=============== + +Installation +------------ + +Execute the following command: + +.. code:: text + + pip install validators + +.. + + It's preferable to use ``pip`` within a virtual environment. + +Usage +----- + +.. code:: python + + import validators + print(validators.email('someone@example.com')) + +To raise validation error +~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. Either set the environment variable ``RAISE_VALIDATION_ERROR`` to + ``True`` + + .. code:: console + + $ export RAISE_VALIDATION_ERROR=True + $ python -c "from validators import url; print(url('https//bad_url'))" + Traceback (most recent call last): + File "", line 1, in + File "/path/to/lib/validators/utils.py", line 87, in wrapper + raise ValidationError(func, _func_args_as_dict(func, *args, **kwargs)) + validators.utils.ValidationError: ValidationError(func=url, args={'value': 'https//bad_url'}) + +2. Or pass ``r_ve=True`` to each caller function: + + .. code:: console + + $ python -c "from validators.card import visa; print(visa('bad_visa_number', r_ve=True))" + Traceback (most recent call last): + File "", line 1, in + File "/path/to/lib/validators/utils.py", line 87, in wrapper + raise ValidationError(func, _func_args_as_dict(func, *args, **kwargs)) + validators.utils.ValidationError: ValidationError(func=visa, args={'value': 'bad_visa_number'}) diff --git a/mkdocs.yaml b/mkdocs.yaml index 62033761..915054c7 100644 --- a/mkdocs.yaml +++ b/mkdocs.yaml @@ -15,6 +15,8 @@ theme: font: text: Inter code: "Fira Code" + features: + - content.code.copy palette: - media: "(prefers-color-scheme: light)" scheme: default @@ -65,6 +67,7 @@ copyright: Copyright © 2013 - 2024 Konsta Vesterinen nav: - Home: index.md + - Install and Use: install_and_use.md - API: - api/between.md - api/btc_address.md diff --git a/package/export/__main__.py b/package/export/__main__.py index 91ae018f..6f36808e 100644 --- a/package/export/__main__.py +++ b/package/export/__main__.py @@ -5,7 +5,7 @@ from os import getenv from os.path import getsize from pathlib import Path -from shutil import copy, rmtree +from shutil import copy from subprocess import Popen # nosec @@ -71,10 +71,24 @@ def _gen_rst_docs(source: Path, refs_path: Path, only_web: bool = False, only_ma + "\n\n.. toctree::" + "\n :hidden:" + "\n :maxdepth: 2" - + "\n :caption: Reference:" + + "\n :caption: Quick Start:" + + "\n :glob:\n" + + "\n install_and_use" + + "\n\n.. toctree::" + + "\n :hidden:" + + "\n :maxdepth: 2" + + "\n :caption: API Reference:" + "\n :glob:\n" + "\n api/*\n" ) + + with open(source / "docs/install_and_use.rst", "wt") as iau_f: + iau_f.write( + convert_file(source_file=source / "docs/install_and_use.md", format="md", to="rst") + .replace("\r\n", "\n") # remove carriage return in windows + .replace("’", "'") + ) + # generate rST reference documentation for module_name, aliases in _parse_package(source / "src/validators/__init__.py"): for alias in aliases: @@ -85,6 +99,7 @@ def _gen_rst_docs(source: Path, refs_path: Path, only_web: bool = False, only_ma web_build = Popen(("sphinx-build", "docs", "docs/_build/web"), shell=False) # nosec web_build.communicate() exit_code = web_build.returncode + print("Run `python -m http.server -d docs/_build/web` to preview.") if not only_web: # build sphinx man pages as subprocess man_build = Popen( # nosec @@ -102,7 +117,6 @@ def _generate_documentation( only_md: bool = False, only_rst_web: bool = False, only_rst_man: bool = False, - discard_refs: bool = True, ): """Generate documentation.""" if only_md is only_rst_web is only_rst_man is True: @@ -123,16 +137,12 @@ def _generate_documentation( if exit_code == 0 else exit_code ) - # optionally discard reference folder - if discard_refs: - rmtree(refs_path) return exit_code def package(source: Path): """Package the source code.""" - _generate_documentation(source, only_rst_man=True, discard_refs=False) - # print() + _generate_documentation(source, only_rst_man=True) if getenv("CI", "false") == "true": process = Popen(("./.venv/bin/python", "-m", "build"), shell=False) # nosec else: @@ -149,18 +159,17 @@ def package(source: Path): from sys import argv if len(argv) != 2: - quit(exit_code) + print("Expected one of these augments: `pkg` `doc` `man` or `web`") + quit(1) if argv[1] == "pkg": exit_code = package(project_root) - if argv[1] == "docs": - exit_code = _generate_documentation( - project_root, - only_md=True, - only_rst_web=False, - only_rst_man=False, - discard_refs=False, - ) + elif argv[1] == "doc": + exit_code = _generate_documentation(project_root, only_md=True) + elif argv[1] == "man": + exit_code = _generate_documentation(project_root, only_rst_man=True) + elif argv[1] == "web": + exit_code = _generate_documentation(project_root, only_rst_web=True) quit(exit_code) # TODO: Address all '# nosec' diff --git a/package/requirements.sphinx.txt b/package/requirements.sphinx.txt index ca7438a3..b09ae4b0 100644 --- a/package/requirements.sphinx.txt +++ b/package/requirements.sphinx.txt @@ -7,6 +7,9 @@ alabaster==0.7.13 \ babel==2.14.0 \ --hash=sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363 \ --hash=sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287 +beautifulsoup4==4.12.3 \ + --hash=sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051 \ + --hash=sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed certifi==2024.2.2 \ --hash=sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f \ --hash=sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1 @@ -94,6 +97,9 @@ colorama==0.4.6 \ docutils==0.20.1 \ --hash=sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6 \ --hash=sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b +furo==2024.1.29 \ + --hash=sha256:3548be2cef45a32f8cdc0272d415fcb3e5fa6a0eb4ddfe21df3ecf1fe45a13cf \ + --hash=sha256:4d6b2fe3f10a6e36eb9cc24c1e7beb38d7a23fc7b3c382867503b7fcac8a1e02 idna==3.6 \ --hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \ --hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f @@ -233,9 +239,15 @@ requests==2.31.0 \ snowballstemmer==2.2.0 \ --hash=sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1 \ --hash=sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a +soupsieve==2.5 \ + --hash=sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690 \ + --hash=sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7 sphinx==7.1.2 \ --hash=sha256:780f4d32f1d7d1126576e0e5ecc19dc32ab76cd24e950228dcf7b1f6d3d9e22f \ --hash=sha256:d170a81825b2fcacb6dfd5a0d7f578a053e45d3f2b153fecc948c37344eb4cbe +sphinx-basic-ng==1.0.0b2 \ + --hash=sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9 \ + --hash=sha256:eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b sphinxcontrib-applehelp==1.0.4 \ --hash=sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228 \ --hash=sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e diff --git a/pdm.lock b/pdm.lock index bd9c0ac7..a0a55004 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,7 +5,7 @@ groups = ["default", "package", "runner", "sast", "docs-offline", "hooks", "docs-online", "tooling"] strategy = ["cross_platform", "inherit_metadata"] lock_version = "4.4.1" -content_hash = "sha256:14e8926f6b74e07094cf798e8c94470f980f937e3875fdf07449f00247491376" +content_hash = "sha256:a37c1c1865fb738cc810cdef45dd58fd2af400ae3f24a490b7ce23e23271167d" [[package]] name = "alabaster" @@ -80,6 +80,20 @@ files = [ {file = "bandit-1.7.8.tar.gz", hash = "sha256:36de50f720856ab24a24dbaa5fee2c66050ed97c1477e0a1159deab1775eab6b"}, ] +[[package]] +name = "beautifulsoup4" +version = "4.12.3" +requires_python = ">=3.6.0" +summary = "Screen-scraping library" +groups = ["docs-offline"] +dependencies = [ + "soupsieve>1.2", +] +files = [ + {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, + {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, +] + [[package]] name = "black" version = "24.3.0" @@ -337,6 +351,23 @@ files = [ {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, ] +[[package]] +name = "furo" +version = "2024.1.29" +requires_python = ">=3.8" +summary = "A clean customisable Sphinx documentation theme." +groups = ["docs-offline"] +dependencies = [ + "beautifulsoup4", + "pygments>=2.7", + "sphinx-basic-ng", + "sphinx<8.0,>=6.0", +] +files = [ + {file = "furo-2024.1.29-py3-none-any.whl", hash = "sha256:3548be2cef45a32f8cdc0272d415fcb3e5fa6a0eb4ddfe21df3ecf1fe45a13cf"}, + {file = "furo-2024.1.29.tar.gz", hash = "sha256:4d6b2fe3f10a6e36eb9cc24c1e7beb38d7a23fc7b3c382867503b7fcac8a1e02"}, +] + [[package]] name = "ghp-import" version = "2.1.0" @@ -1289,6 +1320,17 @@ files = [ {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] +[[package]] +name = "soupsieve" +version = "2.5" +requires_python = ">=3.8" +summary = "A modern CSS selector implementation for Beautiful Soup." +groups = ["docs-offline"] +files = [ + {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, + {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, +] + [[package]] name = "sphinx" version = "7.1.2" @@ -1319,6 +1361,20 @@ files = [ {file = "sphinx-7.1.2.tar.gz", hash = "sha256:780f4d32f1d7d1126576e0e5ecc19dc32ab76cd24e950228dcf7b1f6d3d9e22f"}, ] +[[package]] +name = "sphinx-basic-ng" +version = "1.0.0b2" +requires_python = ">=3.7" +summary = "A modern skeleton for Sphinx themes." +groups = ["docs-offline"] +dependencies = [ + "sphinx>=4.0", +] +files = [ + {file = "sphinx_basic_ng-1.0.0b2-py3-none-any.whl", hash = "sha256:eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b"}, + {file = "sphinx_basic_ng-1.0.0b2.tar.gz", hash = "sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9"}, +] + [[package]] name = "sphinxcontrib-applehelp" version = "1.0.4" diff --git a/pyproject.toml b/pyproject.toml index 908df622..bab34fde 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,7 +54,12 @@ Changelog = "https://github.com/python-validators/validators/blob/master/CHANGES ############################## [tool.pdm.dev-dependencies] -docs-offline = ["myst-parser>=2.0.0", "pypandoc-binary>=1.13", "sphinx>=7.1.2"] +docs-offline = [ + "myst-parser>=2.0.0", + "pypandoc-binary>=1.13", + "sphinx>=7.1.2", + "furo>=2024.1.29", +] docs-online = [ "mkdocs>=1.5.3", "mkdocs-git-revision-date-localized-plugin>=1.2.4",