Skip to content

Commit 4a61fb9

Browse files
authored
Alternative recipe for serving static files
1 parent 0c2c412 commit 4a61fb9

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

pytest/subprocess-server.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,47 @@ def test_server_starts(ds_server):
4141
response = httpx.get("http://127.0.0.1:8041/")
4242
assert response.status_code == 200
4343
```
44+
45+
## Alternative recipe for serving static files
46+
47+
While [adding tests to Datasette Lite](https://github.com/simonw/datasette-lite/issues/35) I found myself needing to run a localhost server that served static files directly.
48+
49+
I completely forgot about this TIL, and instead took inspiration [from pytest-simplehttpserver](https://github.com/ppmdo/pytest-simplehttpserver/blob/a82ad31912121c074ff1a76c4628a1c42c32b41b/src/pytest_simplehttpserver/pytest_plugin.py#L17-L28) - coming up with this pattern:
50+
51+
```python
52+
from subprocess import Popen, PIPE
53+
import pathlib
54+
import pytest
55+
import time
56+
from http.client import HTTPConnection
57+
58+
root = pathlib.Path(__file__).parent.parent.absolute()
59+
60+
61+
@pytest.fixture(scope="module")
62+
def static_server():
63+
process = Popen(
64+
["python", "-m", "http.server", "8123", "--directory", root], stdout=PIPE
65+
)
66+
retries = 5
67+
while retries > 0:
68+
conn = HTTPConnection("localhost:8123")
69+
try:
70+
conn.request("HEAD", "/")
71+
response = conn.getresponse()
72+
if response is not None:
73+
yield process
74+
break
75+
except ConnectionRefusedError:
76+
time.sleep(1)
77+
retries -= 1
78+
79+
if not retries:
80+
raise RuntimeError("Failed to start http server")
81+
else:
82+
process.terminate()
83+
process.wait()
84+
```
85+
Again, including `static_server` as a fixture is enough to ensure requests to `http://localhost:8123/` will be served by that temporary server.
86+
87+
I like how this version polls for a successful HEAD request (a trick inspired by `pytest-simplehttpserver`) rather than just sleeping.

0 commit comments

Comments
 (0)