diff --git a/.bandit.yml b/.bandit.yml new file mode 100644 index 0000000..2237265 --- /dev/null +++ b/.bandit.yml @@ -0,0 +1,3 @@ +skips: +- B101 # assert_used, needed for mypy +exclude_dirs: ['tests'] diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..0856c03 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,3 @@ +[report] +exclude_lines = + if TYPE_CHECKING: diff --git a/.flake8 b/.flake8 index 9ee8f89..f06e676 100644 --- a/.flake8 +++ b/.flake8 @@ -1,6 +1,10 @@ [flake8] +extend-select = TC, TC1 ignore = +max-line-length = 88 per-file-ignores = + # F401: Imported but unused + form2request/__init__.py:F401 # D100-D104: Missing docstring docs/conf.py:D100 tests/__init__.py:D104 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0d2ca22..70870f8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -41,7 +41,7 @@ jobs: fail-fast: false matrix: python-version: ['3.12'] - tox-job: ["pre-commit", "mypy", "docs", "twinecheck"] + tox-job: ["pre-commit", "mypy", "docs", "doctest", "twinecheck"] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} diff --git a/.gitignore b/.gitignore index b53725c..bc020ed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /.coverage /coverage.xml +/dist/ +/.tox/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 663563f..6d5a2de 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,8 +17,20 @@ repos: - flake8-debugger - flake8-docstrings - flake8-string-format + - flake8-type-checking - repo: https://github.com/asottile/pyupgrade rev: v3.16.0 hooks: - id: pyupgrade args: [--py38-plus] +- repo: https://github.com/pycqa/bandit + rev: 1.7.9 + hooks: + - id: bandit + args: [-r, -c, .bandit.yml] +- repo: https://github.com/adamchainz/blacken-docs + rev: 1.18.0 + hooks: + - id: blacken-docs + additional_dependencies: + - black==24.4.2 diff --git a/README.rst b/README.rst index 586477c..a6b7f0d 100644 --- a/README.rst +++ b/README.rst @@ -20,8 +20,8 @@ form2request .. description starts -``form2request`` is an AI-powered Python 3.8+ library to build HTTP requests -out of HTML forms. +``form2request`` is a Python 3.8+ library to build HTTP requests out of HTML +forms. .. description ends diff --git a/dist/form2request-0.0.0.tar.gz b/dist/form2request-0.0.0.tar.gz deleted file mode 100644 index f99bed9..0000000 Binary files a/dist/form2request-0.0.0.tar.gz and /dev/null differ diff --git a/docs/api.rst b/docs/api.rst index 29c1176..18f8d4b 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -2,4 +2,8 @@ API reference ============= -… +.. autofunction:: form2request.form2request + +.. autoclass:: form2request.Request + :members: + :undoc-members: diff --git a/docs/conf.py b/docs/conf.py index acc9c71..f2435e9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,11 +9,24 @@ html_theme = "sphinx_rtd_theme" -autodoc_member_order = "groupwise" - intersphinx_disabled_reftypes = [] intersphinx_mapping = { "lxml": ("https://lxml.de/apidoc/", None), "parsel": ("https://parsel.readthedocs.io/en/stable", None), "python": ("https://docs.python.org/3", None), + "scrapy": ("https://docs.scrapy.org/en/latest", None), } + +nitpick_ignore = [ + *( + ("py:class", cls) + for cls in ( + # https://github.com/sphinx-doc/sphinx/issues/11225 + "FormdataType", + "FormElement", + "HtmlElement", + "Selector", + "SelectorList", + ) + ), +] diff --git a/docs/usage.rst b/docs/usage.rst index d9237b5..08abe3a 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -2,4 +2,221 @@ Usage ===== -… +:ref:`Given an HTML form
""" +>>> selector = Selector(body=html, base_url="https://example.com") +>>> form = selector.css("form") + +You can use :func:`~form2request.form2request` to generate form submission +request data: + +>>> from form2request import form2request +>>> req = form2request(form) +>>> req +Request(url='https://example.com?foo=bar', method='GET', headers=[], body=b'') + +:func:`~form2request.form2request` does not make requests, but you can use its +output to build requests with any HTTP client software, e.g. with the requests_ +library: + +.. _requests: https://requests.readthedocs.io/en/latest/ + +.. _requests-example: + +>>> import requests +>>> requests.request(req.method, req.url, headers=req.headers, data=req.body) # doctest: +SKIP +