pytest fixture finding an unused local port
Project description
pytest-unused-port
pytest fixture finding an unused local port, built using Claude Code
Installation
Install this library using pip:
pip install pytest-unused-port
Usage
Command-line Interface
You can use pytest-unused-port as a standalone tool to serve a directory on an unused port:
# Serve a specific directory
pytest-unused-port /tmp/blah
# Or use the shorter alias
uport /tmp/blah
# Or using uvx
uvx pytest-unused-port /tmp/blah
# Or as a Python module
python -m pytest_unused_port /tmp/blah
# Serve the current directory (default)
pytest-unused-port
uport
This will start Python's http.server serving the specified directory on an automatically-selected unused port. The server will print the URL and run until you press Ctrl+C.
Pytest Fixtures
This pytest plugin provides a unused_port fixture that returns an available TCP port on localhost that your tests can use.
Basic Example
def test_my_server(unused_port):
# unused_port is an integer containing an available port number
server = start_my_server(port=unused_port)
assert server.is_running()
Starting an HTTP Server
import http.server
def test_http_server(unused_port):
handler = http.server.SimpleHTTPRequestHandler
server = http.server.HTTPServer(('127.0.0.1', unused_port), handler)
# Now you can test your server on the unused port
assert server.server_port == unused_port
Using with Socket Programming
import socket
def test_socket_server(unused_port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('127.0.0.1', unused_port))
sock.listen(1)
# Your test code here
sock.close()
The fixture automatically finds an available port by binding to port 0 (which tells the OS to assign any available port), getting the assigned port number, and then releasing it for your test to use.
The unused_port_server fixture
For convenience, this plugin also provides an unused_port_server fixture that manages an HTTP server for you. This is especially useful for testing applications that need to fetch content from a local server.
Basic Example
def test_fetch_from_server(unused_port_server, tmp_path):
# Create a test file
test_file = tmp_path / "index.html"
test_file.write_text("<h1>Hello</h1>")
# Start the server serving the directory
unused_port_server.start(tmp_path)
# Make requests to http://127.0.0.1:{unused_port_server.port}/
# Server automatically stops at the end of the test
Features
- Automatic cleanup: The server automatically stops when the test ends
- Explicit control: Call
.stop()to stop the server manually if needed - Port access: Access the port number via
unused_port_server.port - Method chaining:
.start()returns self for convenience
Example with explicit stop
def test_server_lifecycle(unused_port_server, tmp_path):
unused_port_server.start(tmp_path)
# Do some testing...
# Explicitly stop the server
unused_port_server.stop()
# Server is now stopped
Example fetching a file
from urllib.request import urlopen
def test_fetch_file(unused_port_server, tmp_path):
# Create a test file
(tmp_path / "data.txt").write_text("test data")
# Start server
unused_port_server.start(tmp_path)
# Fetch the file
url = f"http://127.0.0.1:{unused_port_server.port}/data.txt"
response = urlopen(url)
assert response.read().decode() == "test data"
Using as a context manager
You can also use StaticServer directly as a context manager if you need more control:
from pytest_unused_port import StaticServer
def test_with_context_manager(unused_port, tmp_path):
with StaticServer(unused_port) as server:
server.start(tmp_path)
# Server runs here
# ... your test code ...
# Server automatically stops when exiting the context
The server runs python -m http.server in a subprocess, serving static files from the specified directory.
Development
To contribute to this library, first checkout the code. Then install the dependencies using uv:
cd pytest-unused-port
uv pip install -e '.[test]'
To run the tests:
uv run pytest
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pytest_unused_port-0.2.tar.gz.
File metadata
- Download URL: pytest_unused_port-0.2.tar.gz
- Upload date:
- Size: 10.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3d443b9b8d25506fa2b627d35dfdc94148a611ab7cefb9c65428daef2146395c
|
|
| MD5 |
08957f2a686057844a4f38a14ceeb084
|
|
| BLAKE2b-256 |
612796e530adc51b7d3106d5e4223317b99586d74765a0201e828e52ca34700c
|
Provenance
The following attestation bundles were made for pytest_unused_port-0.2.tar.gz:
Publisher:
publish.yml on simonw/pytest-unused-port
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytest_unused_port-0.2.tar.gz -
Subject digest:
3d443b9b8d25506fa2b627d35dfdc94148a611ab7cefb9c65428daef2146395c - Sigstore transparency entry: 630572838
- Sigstore integration time:
-
Permalink:
simonw/pytest-unused-port@96ee5828996d7c04cbd760430175dad5f7dfd308 -
Branch / Tag:
refs/tags/0.2 - Owner: https://github.com/simonw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@96ee5828996d7c04cbd760430175dad5f7dfd308 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pytest_unused_port-0.2-py3-none-any.whl.
File metadata
- Download URL: pytest_unused_port-0.2-py3-none-any.whl
- Upload date:
- Size: 9.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca5bcf00cdf516a372f3a3e0f651bcf9dfdb1c4ac44ad0d7cdfc950a9cbfefed
|
|
| MD5 |
1a36a42a1671924f41e3ef7739b24cd6
|
|
| BLAKE2b-256 |
7f6533d0be055b30b8a3cfadfe8fe722105b72ec6e45971e15e86b1d3ee57e88
|
Provenance
The following attestation bundles were made for pytest_unused_port-0.2-py3-none-any.whl:
Publisher:
publish.yml on simonw/pytest-unused-port
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytest_unused_port-0.2-py3-none-any.whl -
Subject digest:
ca5bcf00cdf516a372f3a3e0f651bcf9dfdb1c4ac44ad0d7cdfc950a9cbfefed - Sigstore transparency entry: 630572840
- Sigstore integration time:
-
Permalink:
simonw/pytest-unused-port@96ee5828996d7c04cbd760430175dad5f7dfd308 -
Branch / Tag:
refs/tags/0.2 - Owner: https://github.com/simonw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@96ee5828996d7c04cbd760430175dad5f7dfd308 -
Trigger Event:
release
-
Statement type: