pytest_httpserver 1.0.9__tar.gz → 1.0.11__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/CHANGES.rst +40 -0
  2. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/PKG-INFO +15 -9
  3. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/README.md +14 -8
  4. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/doc/api.rst +23 -0
  5. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/doc/conf.py +4 -2
  6. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/doc/howto.rst +146 -0
  7. pytest_httpserver-1.0.11/doc/patch.py +16 -0
  8. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/pyproject.toml +77 -24
  9. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/pytest_httpserver/__init__.py +3 -0
  10. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/pytest_httpserver/blocking_httpserver.py +18 -16
  11. pytest_httpserver-1.0.11/pytest_httpserver/hooks.py +103 -0
  12. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/pytest_httpserver/httpserver.py +174 -87
  13. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/pytest_httpserver/pytest_plugin.py +4 -4
  14. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/examples/test_howto_custom_handler.py +2 -2
  15. pytest_httpserver-1.0.11/tests/examples/test_howto_custom_hooks.py +17 -0
  16. pytest_httpserver-1.0.11/tests/examples/test_howto_hooks.py +11 -0
  17. pytest_httpserver-1.0.11/tests/examples/test_howto_log_querying.py +56 -0
  18. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/test_blocking_httpserver.py +5 -2
  19. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/test_handler_errors.py +6 -6
  20. pytest_httpserver-1.0.11/tests/test_hooks.py +102 -0
  21. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/test_json_matcher.py +1 -1
  22. pytest_httpserver-1.0.11/tests/test_log_querying.py +73 -0
  23. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/test_parse_qs.py +4 -4
  24. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/test_permanent.py +1 -1
  25. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/test_port_changing.py +2 -2
  26. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/test_querymatcher.py +1 -1
  27. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/test_release.py +23 -10
  28. pytest_httpserver-1.0.11/tests/test_threaded.py +60 -0
  29. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/CONTRIBUTION.md +0 -0
  30. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/LICENSE +0 -0
  31. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/doc/Makefile +0 -0
  32. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/doc/_static/.placeholder +0 -0
  33. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/doc/background.rst +0 -0
  34. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/doc/changes.rst +0 -0
  35. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/doc/fixtures.rst +0 -0
  36. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/doc/guide.rst +0 -0
  37. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/doc/index.rst +0 -0
  38. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/doc/tutorial.rst +0 -0
  39. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/doc/upgrade.rst +0 -0
  40. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/example.py +0 -0
  41. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/example_pytest.py +0 -0
  42. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/pytest_httpserver/py.typed +0 -0
  43. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/assets/Makefile +0 -0
  44. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/assets/README +0 -0
  45. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/assets/rootCA.cnf +0 -0
  46. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/assets/rootCA.crt +0 -0
  47. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/assets/rootCA.key +0 -0
  48. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/assets/rootCA.srl +0 -0
  49. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/assets/server.cnf +0 -0
  50. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/assets/server.crt +0 -0
  51. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/assets/server.csr +0 -0
  52. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/assets/server.key +0 -0
  53. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/assets/v3.ext +0 -0
  54. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/conftest.py +0 -0
  55. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/examples/test_example_blocking_httpserver.py +0 -0
  56. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/examples/test_example_query_params1.py +0 -0
  57. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/examples/test_example_query_params2.py +0 -0
  58. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/examples/test_howto_authorization_headers.py +0 -0
  59. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/examples/test_howto_case_insensitive_matcher.py +0 -0
  60. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/examples/test_howto_check.py +0 -0
  61. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/examples/test_howto_check_handler_errors.py +0 -0
  62. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/examples/test_howto_header_value_matcher.py +0 -0
  63. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/examples/test_howto_json_matcher.py +0 -0
  64. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/examples/test_howto_query_params_dict.py +0 -0
  65. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/examples/test_howto_query_params_never_do_this.py +0 -0
  66. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/examples/test_howto_query_params_proper_use.py +0 -0
  67. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/examples/test_howto_regexp.py +0 -0
  68. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/examples/test_howto_timeout_requests.py +0 -0
  69. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/examples/test_howto_url_matcher.py +0 -0
  70. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/examples/test_howto_wait_success.py +0 -0
  71. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/test_headers.py +0 -0
  72. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/test_ip_protocols.py +0 -0
  73. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/test_mixed.py +0 -0
  74. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/test_oneshot.py +0 -0
  75. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/test_ordered.py +0 -0
  76. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/test_querystring.py +0 -0
  77. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/test_ssl.py +0 -0
  78. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/test_urimatch.py +0 -0
  79. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/test_wait.py +0 -0
  80. {pytest_httpserver-1.0.9 → pytest_httpserver-1.0.11}/tests/test_with_statement.py +0 -0
@@ -2,6 +2,46 @@
2
2
  Release Notes
3
3
  =============
4
4
 
5
+ .. _Release Notes_1.0.11:
6
+
7
+ 1.0.11
8
+ ======
9
+
10
+ .. _Release Notes_1.0.11_New Features:
11
+
12
+ New Features
13
+ ------------
14
+
15
+ - Hooks API
16
+
17
+ - New methods added to query for matching requests in the log.
18
+
19
+ - Threading support to serve requests in parallel
20
+
21
+
22
+ .. _Release Notes_1.0.10:
23
+
24
+ 1.0.10
25
+ ======
26
+
27
+ .. _Release Notes_1.0.10_New Features:
28
+
29
+ New Features
30
+ ------------
31
+
32
+ - When there's no handler for the request, add more details to the response
33
+ sent by the server about the request to help debugging.
34
+
35
+
36
+ .. _Release Notes_1.0.10_Other Notes:
37
+
38
+ Other Notes
39
+ -----------
40
+
41
+ - Use ruff for linting. It includes some source code changes which should not
42
+ introduce functional changes, or API changes.
43
+
44
+
5
45
  .. _Release Notes_1.0.9:
6
46
 
7
47
  1.0.9
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pytest_httpserver
3
- Version: 1.0.9
3
+ Version: 1.0.11
4
4
  Summary: pytest-httpserver is a httpserver for pytest
5
5
  Home-page: https://github.com/csernazs/pytest-httpserver
6
6
  License: MIT
@@ -27,10 +27,12 @@ Description-Content-Type: text/markdown
27
27
 
28
28
  [![Build Status](https://github.com/csernazs/pytest-httpserver/workflows/build/badge.svg?branch=master)](https://github.com/csernazs/pytest-httpserver/actions?query=workflow%3Abuild+branch%3Amaster)
29
29
  [![Documentation Status](https://readthedocs.org/projects/pytest-httpserver/badge/?version=latest)](https://pytest-httpserver.readthedocs.io/en/latest/?badge=latest)
30
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
31
- [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=K6PU3AGBZW4QC&item_name=pytest-httpserver&currency_code=EUR&source=url)
30
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
32
31
  [![codecov](https://codecov.io/gh/csernazs/pytest-httpserver/branch/master/graph/badge.svg?token=MX2JXbHqRH)](https://codecov.io/gh/csernazs/pytest-httpserver)
33
32
  [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
33
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
34
+ [![Downloads](https://static.pepy.tech/badge/pytest-httpserver/month)](https://pepy.tech/project/pytest-httpserver)
35
+ [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit)
34
36
 
35
37
  ## pytest_httpserver
36
38
 
@@ -144,12 +146,16 @@ documentation](https://pytest-httpserver.readthedocs.io/en/latest/api.html#block
144
146
 
145
147
  ### Donation
146
148
 
147
- If you want to donate to this project, you can find the donate button at the top
148
- of the README.
149
+ Currently, this project is based heavily on werkzeug and pytest.
149
150
 
150
- Currently, this project is based heavily on werkzeug. Werkzeug does all the heavy lifting
151
- behind the scenes, parsing HTTP request and defining Request and Response objects, which
152
- are currently transparent in the API.
151
+ Werkzeug does all the heavy lifting behind the scenes, parsing HTTP request and
152
+ defining Request and Response objects, which are currently transparent in the
153
+ API.
153
154
 
154
- If you wish to donate, please consider donating to them: https://palletsprojects.com/donate
155
+ If you wish to donate to werkzeug: https://palletsprojects.com/donate
156
+
157
+
158
+ Pytest is the de-facto test library for python.
159
+
160
+ If you wish to donate to pytest: https://opencollective.com/pytest
155
161
 
@@ -1,9 +1,11 @@
1
1
  [![Build Status](https://github.com/csernazs/pytest-httpserver/workflows/build/badge.svg?branch=master)](https://github.com/csernazs/pytest-httpserver/actions?query=workflow%3Abuild+branch%3Amaster)
2
2
  [![Documentation Status](https://readthedocs.org/projects/pytest-httpserver/badge/?version=latest)](https://pytest-httpserver.readthedocs.io/en/latest/?badge=latest)
3
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
4
- [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=K6PU3AGBZW4QC&item_name=pytest-httpserver&currency_code=EUR&source=url)
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
5
4
  [![codecov](https://codecov.io/gh/csernazs/pytest-httpserver/branch/master/graph/badge.svg?token=MX2JXbHqRH)](https://codecov.io/gh/csernazs/pytest-httpserver)
6
5
  [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
6
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
7
+ [![Downloads](https://static.pepy.tech/badge/pytest-httpserver/month)](https://pepy.tech/project/pytest-httpserver)
8
+ [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit)
7
9
 
8
10
  ## pytest_httpserver
9
11
 
@@ -117,11 +119,15 @@ documentation](https://pytest-httpserver.readthedocs.io/en/latest/api.html#block
117
119
 
118
120
  ### Donation
119
121
 
120
- If you want to donate to this project, you can find the donate button at the top
121
- of the README.
122
+ Currently, this project is based heavily on werkzeug and pytest.
122
123
 
123
- Currently, this project is based heavily on werkzeug. Werkzeug does all the heavy lifting
124
- behind the scenes, parsing HTTP request and defining Request and Response objects, which
125
- are currently transparent in the API.
124
+ Werkzeug does all the heavy lifting behind the scenes, parsing HTTP request and
125
+ defining Request and Response objects, which are currently transparent in the
126
+ API.
126
127
 
127
- If you wish to donate, please consider donating to them: https://palletsprojects.com/donate
128
+ If you wish to donate to werkzeug: https://palletsprojects.com/donate
129
+
130
+
131
+ Pytest is the de-facto test library for python.
132
+
133
+ If you wish to donate to pytest: https://opencollective.com/pytest
@@ -24,6 +24,13 @@ RequestHandler
24
24
  :inherited-members:
25
25
 
26
26
 
27
+ RequestMatcher
28
+ ~~~~~~~~~~~~~~
29
+
30
+ .. autoclass:: RequestMatcher
31
+ :members:
32
+
33
+
27
34
  BlockingHTTPServer
28
35
  ~~~~~~~~~~~~~~~~~~
29
36
 
@@ -93,3 +100,19 @@ by the user.
93
100
 
94
101
  .. autoclass:: pytest_httpserver.httpserver.RequestHandlerList
95
102
  :members:
103
+
104
+
105
+ pytest_httpserver.hooks
106
+ -----------------------
107
+
108
+ .. automodule:: pytest_httpserver.hooks
109
+
110
+
111
+ .. autoclass:: pytest_httpserver.hooks.Chain
112
+ :members:
113
+
114
+ .. autoclass:: pytest_httpserver.hooks.Delay
115
+ :members:
116
+
117
+ .. autoclass:: pytest_httpserver.hooks.Garbage
118
+ :members:
@@ -24,6 +24,7 @@ from typing import Dict
24
24
 
25
25
  sys.path.insert(0, os.path.abspath(".."))
26
26
 
27
+ import doc.patch
27
28
 
28
29
  # -- General configuration ------------------------------------------------
29
30
 
@@ -37,11 +38,12 @@ sys.path.insert(0, os.path.abspath(".."))
37
38
  extensions = [
38
39
  "sphinx.ext.autodoc",
39
40
  "sphinx.ext.intersphinx",
41
+ "sphinx.ext.autosectionlabel",
40
42
  ]
41
43
 
42
44
  intersphinx_mapping = {
43
45
  "python": ("https://docs.python.org/3", (None, "python-inv.txt")),
44
- "werkzeug": ("https://werkzeug.palletsprojects.com/en/2.1.x", None),
46
+ "werkzeug": ("https://werkzeug.palletsprojects.com/en/3.0.x", None),
45
47
  }
46
48
 
47
49
  # Add any paths that contain templates here, relative to this directory.
@@ -66,7 +68,7 @@ author = "Zsolt Cserna"
66
68
  # built documents.
67
69
  #
68
70
  # The short X.Y version.
69
- version = "1.0.9"
71
+ version = "1.0.11"
70
72
  # The full version, including alpha/beta/rc tags.
71
73
  release = version
72
74
 
@@ -512,3 +512,149 @@ Example:
512
512
 
513
513
  .. literalinclude :: ../tests/examples/test_example_blocking_httpserver.py
514
514
  :language: python
515
+
516
+
517
+ Querying the log
518
+ ----------------
519
+
520
+ *pytest-httpserver* keeps a log of request-response pairs in a python list. This
521
+ log can be accessed by the ``log`` attibute of the httpserver instance, but
522
+ there are methods made specifically to query the log.
523
+
524
+ Each of the log querying methods accepts a
525
+ :py:class:`pytest_httpserver.RequestMatcher` object which uses the same matching
526
+ logic which is used by the server itself. Its parameters are the same to the
527
+ parameters specified for the server's `except_request` (and the similar) methods.
528
+
529
+ The methods for querying:
530
+
531
+ * :py:meth:`pytest_httpserver.HTTPServer.get_matching_requests_count` returns
532
+ how many requests are matching in the log as an int
533
+
534
+ * :py:meth:`pytest_httpserver.HTTPServer.assert_request_made` asserts the given
535
+ amount of requests are matching in the log. By default it checks for one (1)
536
+ request but other value can be specified. For example, 0 can be specified to
537
+ check for requests not made.
538
+
539
+ * :py:meth:`pytest_httpserver.HTTPServer.iter_matching_requests` is a generator
540
+ yielding Request-Response tuples of the matching entries in the log. This
541
+ offers greater flexibility (compared to the other methods)
542
+
543
+ Example:
544
+
545
+ .. literalinclude :: ../tests/examples/test_howto_log_querying.py
546
+ :language: python
547
+
548
+
549
+ Serving requests in parallel
550
+ ----------------------------
551
+
552
+ *pytest-httpserver* serves the request in a single-threaded, blocking way. That
553
+ means that if multiple requests are made to it, those will be served one by one.
554
+
555
+ There can be cases where parallel processing is required, for those cases
556
+ *pytest-httpserver* allows running a server which start one thread per request
557
+ handler, so the requests are served in parallel way (depending on Global
558
+ Interpreter Lock this is not truly parallel, but from the I/O point of view it
559
+ is).
560
+
561
+ To set this up, you have two possibilities.
562
+
563
+
564
+ Overriding httpserver fixture
565
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
566
+
567
+ One is to customize how the HTTPServer object is created. This is possible by
568
+ defining the following fixture:
569
+
570
+ .. code:: python
571
+
572
+ @pytest.fixture(scope="session")
573
+ def make_httpserver() -> Iterable[HTTPServer]:
574
+ server = HTTPServer(threaded=True) # set threaded=True to enable thread support
575
+ server.start()
576
+ yield server
577
+ server.clear()
578
+ if server.is_running():
579
+ server.stop()
580
+
581
+
582
+ This will override the ``httpserver`` fixture in your tests.
583
+
584
+ Creating a different httpserver fixture
585
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
586
+
587
+ This way, you can create a different httpserver fixture and you can use it
588
+ besides the main one.
589
+
590
+ .. code:: python
591
+
592
+ @pytest.fixture()
593
+ def threaded() -> Iterable[HTTPServer]:
594
+ server = HTTPServer(threaded=True)
595
+ server.start()
596
+ yield server
597
+ server.clear()
598
+ if server.is_running():
599
+ server.stop()
600
+
601
+
602
+ def test_threaded(threaded: HTTPServer): ...
603
+
604
+
605
+ This will start and stop the server for each tests, which causes about 0.5
606
+ seconds waiting when the server is stopped. It won't override the ``httpserver``
607
+ fixture so you can keep the original single-threaded behavior.
608
+
609
+ .. warning::
610
+ Handler threads which are still running when the test is finished, will be
611
+ left behind and won't be join()ed between the tests. If you want to ensure
612
+ that all threads are properly cleaned up and you want to wait for them,
613
+ consider using the second option (:ref:`Creating a different httpserver fixture`)
614
+ described above.
615
+
616
+
617
+ Adding side effects
618
+ -------------------
619
+
620
+ Sometimes there's a need to add side effects to the handling of the requests.
621
+ Such side effect could be adding some amount of delay to the serving or adding
622
+ some garbage to response data.
623
+
624
+ While these can be achieved by using
625
+ :py:meth:`pytest_httpserver.RequestHandler.respond_with_handler` where you can
626
+ implement your own function to serve the request, *pytest-httpserver* provides a
627
+ hooks API where you can add side effects to request handlers such as
628
+ :py:meth:`pytest_httpserver.RequestHandler.respond_with_json` and others.
629
+ This allows to use the existing API of registering handlers.
630
+
631
+ Example:
632
+
633
+ .. literalinclude :: ../tests/examples/test_howto_hooks.py
634
+ :language: python
635
+
636
+ :py:mod:`pytest_httpserver.hooks` module provides some pre-defined hooks to
637
+ use.
638
+
639
+ You can implement your own hook as well. The requirement is to have a callable
640
+ object (a function) ``Callable[[Request, Response], Response]``. In details:
641
+
642
+ * Parameter :py:class:`werkzeug.Request` which represents the request
643
+ sent by the client.
644
+
645
+ * Parameter :py:class:`werkzeug.Response` which represents the response
646
+ made by the handler.
647
+
648
+ * Returns a :py:class:`werkzeug.Response` object which represents the
649
+ response will be returned to the client.
650
+
651
+
652
+ Example:
653
+
654
+ .. literalinclude :: ../tests/examples/test_howto_custom_hooks.py
655
+ :language: python
656
+
657
+ ``with_post_hook`` can be called multiple times, in this case *pytest-httpserver*
658
+ will register the hooks, and hooks will be called sequentially, one by one. Each
659
+ hook will receive the response what the previous hook returned, and the last
660
+ hook called will return the final response which will be sent back to the client.
@@ -0,0 +1,16 @@
1
+ # this is required to make sphinx able to find references for classes put inside
2
+ # typing.TYPE_CHECKING block
3
+
4
+ from ssl import SSLContext
5
+
6
+ from werkzeug import Request
7
+ from werkzeug import Response
8
+
9
+ import pytest_httpserver.blocking_httpserver
10
+ import pytest_httpserver.httpserver
11
+
12
+ pytest_httpserver.httpserver.SSLContext = SSLContext
13
+ pytest_httpserver.blocking_httpserver.SSLContext = SSLContext
14
+
15
+ pytest_httpserver.blocking_httpserver.Request = Request
16
+ pytest_httpserver.blocking_httpserver.Response = Response
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pytest_httpserver"
3
- version = "1.0.9"
3
+ version = "1.0.11"
4
4
  description = "pytest-httpserver is a httpserver for pytest"
5
5
  authors = ["Zsolt Cserna <cserna.zsolt@gmail.com>"]
6
6
  license = "MIT"
@@ -38,42 +38,43 @@ pytest_httpserver = "pytest_httpserver.pytest_plugin"
38
38
  optional = true
39
39
 
40
40
  [tool.poetry.group.develop.dependencies]
41
- pre-commit = "^2.20.0"
42
- requests = "^2.28.1"
43
- Sphinx = "^5.1.1"
44
- sphinx-rtd-theme = "^1.0.0"
45
- reno = "^3.5.0"
46
- mypy = "^0.971"
47
- types-requests = "^2.28.9"
48
- pytest = "^7.1.3"
49
- pytest-cov = ">=3,<5"
41
+ pre-commit = ">=2.20,<4.0"
42
+ requests = "*"
43
+ Sphinx = ">=5.1.1,<8.0.0"
44
+ sphinx-rtd-theme = ">=1,<3"
45
+ reno = "*"
46
+ types-requests = "*"
47
+ pytest = ">=7.1.3,<9.0.0"
48
+ pytest-cov = ">=3,<6"
50
49
  coverage = ">=6.4.4,<8.0.0"
51
- types-toml = "^0.10.8"
50
+ types-toml = "*"
52
51
  toml = "^0.10.2"
53
- black = "^23.1.0"
52
+ black = "*"
53
+ ruff = "*"
54
+ mypy = "*"
54
55
 
55
56
 
56
57
  [tool.poetry.group.doc]
57
58
  optional = true
58
59
 
59
60
  [tool.poetry.group.doc.dependencies]
60
- Sphinx = "^5.1.1"
61
- sphinx-rtd-theme = "^1.0.0"
61
+ Sphinx = ">=5.1.1,<8.0.0"
62
+ sphinx-rtd-theme = ">=1,<3"
62
63
 
63
64
 
64
65
  [tool.poetry.group.test]
65
66
  optional = true
66
67
 
67
68
  [tool.poetry.group.test.dependencies]
68
- pytest = "^7.1.3"
69
- pytest-cov = ">=3,<5"
70
- coverage = ">=6.4.4,<8.0.0"
71
- requests = "^2.28.1"
72
- mypy = "^0.971"
73
- types-requests = "^2.28.9"
74
- pre-commit = "^2.20.0"
75
- types-toml = "^0.10.8"
76
- toml = "^0.10.2"
69
+ pytest = "*"
70
+ pytest-cov = "*"
71
+ coverage = "*"
72
+ requests = "*"
73
+ types-requests = "*"
74
+ pre-commit = "*"
75
+ types-toml = "*"
76
+ toml = "*"
77
+ mypy = "*"
77
78
 
78
79
  [build-system]
79
80
  requires = ["poetry-core>=1.0.0"]
@@ -86,5 +87,57 @@ markers = [
86
87
  ]
87
88
 
88
89
  [tool.mypy]
89
- files = ["pytest_httpserver", "scripts", "tests", "doc"]
90
+ files = ["pytest_httpserver", "scripts", "tests"]
90
91
  implicit_reexport = false
92
+
93
+
94
+ [tool.black]
95
+ line-length = 120
96
+ safe = true
97
+
98
+ [tool.ruff]
99
+ lint.select = ["ALL"]
100
+ lint.ignore = [
101
+ "I",
102
+ "D",
103
+
104
+ "ANN",
105
+ "ARG005",
106
+ "B011",
107
+ "B904",
108
+ "C408",
109
+ "C901",
110
+ "COM812",
111
+ "EM101",
112
+ "EM103",
113
+ "FBT002",
114
+ "FIX002",
115
+ "INP001",
116
+ "PGH003",
117
+ "PLR0912",
118
+ "PLR0913",
119
+ "PLR2004",
120
+ "PLW2901",
121
+ "PT004",
122
+ "PT012",
123
+ "PT013",
124
+ "PTH118",
125
+ "PTH120",
126
+ "RET504",
127
+ "RET505",
128
+ "RET506",
129
+ "RUF005",
130
+ "S101",
131
+ "S113",
132
+ "S603",
133
+ "S607",
134
+ "SIM108",
135
+ "T201",
136
+ "TD002",
137
+ "TD003",
138
+ "TRY003",
139
+ "UP032",
140
+ ]
141
+ line-length = 120
142
+ target-version = "py38"
143
+ exclude = ["doc", "example*.py", "tests/examples/*.py"]
@@ -2,6 +2,7 @@
2
2
  This is package provides the main API for the pytest_httpserver package.
3
3
 
4
4
  """
5
+
5
6
  __all__ = [
6
7
  "HTTPServer",
7
8
  "HTTPServerError",
@@ -10,6 +11,7 @@ __all__ = [
10
11
  "WaitingSettings",
11
12
  "HeaderValueMatcher",
12
13
  "RequestHandler",
14
+ "RequestMatcher",
13
15
  "URIPattern",
14
16
  "URI_DEFAULT",
15
17
  "METHOD_ALL",
@@ -27,5 +29,6 @@ from .httpserver import HTTPServer
27
29
  from .httpserver import HTTPServerError
28
30
  from .httpserver import NoHandlerError
29
31
  from .httpserver import RequestHandler
32
+ from .httpserver import RequestMatcher
30
33
  from .httpserver import URIPattern
31
34
  from .httpserver import WaitingSettings
@@ -1,15 +1,11 @@
1
+ from __future__ import annotations
2
+
1
3
  from queue import Empty
2
4
  from queue import Queue
3
- from ssl import SSLContext
5
+ from typing import TYPE_CHECKING
4
6
  from typing import Any
5
- from typing import Dict
6
7
  from typing import Mapping
7
- from typing import Optional
8
8
  from typing import Pattern
9
- from typing import Union
10
-
11
- from werkzeug.wrappers import Request
12
- from werkzeug.wrappers import Response
13
9
 
14
10
  from pytest_httpserver.httpserver import METHOD_ALL
15
11
  from pytest_httpserver.httpserver import UNDEFINED
@@ -19,6 +15,12 @@ from pytest_httpserver.httpserver import QueryMatcher
19
15
  from pytest_httpserver.httpserver import RequestHandlerBase
20
16
  from pytest_httpserver.httpserver import URIPattern
21
17
 
18
+ if TYPE_CHECKING:
19
+ from ssl import SSLContext
20
+
21
+ from werkzeug import Request
22
+ from werkzeug import Response
23
+
22
24
 
23
25
  class BlockingRequestHandler(RequestHandlerBase):
24
26
  """
@@ -59,23 +61,23 @@ class BlockingHTTPServer(HTTPServerBase):
59
61
  self,
60
62
  host=DEFAULT_LISTEN_HOST,
61
63
  port=DEFAULT_LISTEN_PORT,
62
- ssl_context: Optional[SSLContext] = None,
64
+ ssl_context: SSLContext | None = None,
63
65
  timeout: int = 30,
64
66
  ):
65
67
  super().__init__(host, port, ssl_context)
66
68
  self.timeout = timeout
67
69
  self.request_queue: Queue[Request] = Queue()
68
- self.request_handlers: Dict[Request, Queue[BlockingRequestHandler]] = {}
70
+ self.request_handlers: dict[Request, Queue[BlockingRequestHandler]] = {}
69
71
 
70
72
  def assert_request(
71
73
  self,
72
- uri: Union[str, URIPattern, Pattern[str]],
74
+ uri: str | URIPattern | Pattern[str],
73
75
  method: str = METHOD_ALL,
74
- data: Union[str, bytes, None] = None,
76
+ data: str | bytes | None = None,
75
77
  data_encoding: str = "utf-8",
76
- headers: Optional[Mapping[str, str]] = None,
77
- query_string: Union[None, QueryMatcher, str, bytes, Mapping] = None,
78
- header_value_matcher: Optional[HeaderValueMatcher] = None,
78
+ headers: Mapping[str, str] | None = None,
79
+ query_string: None | QueryMatcher | str | bytes | Mapping = None,
80
+ header_value_matcher: HeaderValueMatcher | None = None,
79
81
  json: Any = UNDEFINED,
80
82
  timeout: int = 30,
81
83
  ) -> BlockingRequestHandler:
@@ -127,7 +129,7 @@ class BlockingHTTPServer(HTTPServerBase):
127
129
  try:
128
130
  request = self.request_queue.get(timeout=timeout)
129
131
  except Empty:
130
- raise AssertionError(f"Waiting for request {matcher} timed out")
132
+ raise AssertionError(f"Waiting for request {matcher} timed out") # noqa: EM102
131
133
 
132
134
  diff = matcher.difference(request)
133
135
 
@@ -137,7 +139,7 @@ class BlockingHTTPServer(HTTPServerBase):
137
139
 
138
140
  if diff:
139
141
  request_handler.respond_with_response(self.respond_nohandler(request))
140
- raise AssertionError(f"Request {matcher} does not match: {diff}")
142
+ raise AssertionError(f"Request {matcher} does not match: {diff}") # noqa: EM102
141
143
 
142
144
  return request_handler
143
145