| Name | pytest-unused-port JSON |
| Version |
0.2
JSON |
| download |
| home_page | None |
| Summary | pytest fixture finding an unused local port |
| upload_time | 2025-10-22 21:54:04 |
| maintainer | None |
| docs_url | None |
| author | Simon Willison |
| requires_python | >=3.10 |
| license | None |
| keywords |
|
| VCS |
 |
| bugtrack_url |
|
| requirements |
No requirements were recorded.
|
| Travis-CI |
No Travis.
|
| coveralls test coverage |
No coveralls.
|
# pytest-unused-port
[](https://pypi.org/project/pytest-unused-port/)
[](https://github.com/simonw/pytest-unused-port/actions/workflows/test.yml)
[](https://github.com/simonw/pytest-unused-port/releases)
[](https://github.com/simonw/pytest-unused-port/blob/main/LICENSE)
pytest fixture finding an unused local port, built [using Claude Code](https://gistpreview.github.io/?9ffa45bc69a545427009ca6283e2e672)
## Installation
Install this library using `pip`:
```bash
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:
```bash
# 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
```python
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
```python
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
```python
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
```python
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
```python
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
```python
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:
```python
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`:
```bash
cd pytest-unused-port
uv pip install -e '.[test]'
```
To run the tests:
```bash
uv run pytest
```
Raw data
{
"_id": null,
"home_page": null,
"name": "pytest-unused-port",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": null,
"author": "Simon Willison",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/61/27/96e530adc51b7d3106d5e4223317b99586d74765a0201e828e52ca34700c/pytest_unused_port-0.2.tar.gz",
"platform": null,
"description": "# pytest-unused-port\n\n[](https://pypi.org/project/pytest-unused-port/)\n[](https://github.com/simonw/pytest-unused-port/actions/workflows/test.yml)\n[](https://github.com/simonw/pytest-unused-port/releases)\n[](https://github.com/simonw/pytest-unused-port/blob/main/LICENSE)\n\npytest fixture finding an unused local port, built [using Claude Code](https://gistpreview.github.io/?9ffa45bc69a545427009ca6283e2e672)\n\n## Installation\n\nInstall this library using `pip`:\n```bash\npip install pytest-unused-port\n```\n## Usage\n\n### Command-line Interface\n\nYou can use pytest-unused-port as a standalone tool to serve a directory on an unused port:\n\n```bash\n# Serve a specific directory\npytest-unused-port /tmp/blah\n\n# Or use the shorter alias\nuport /tmp/blah\n\n# Or using uvx\nuvx pytest-unused-port /tmp/blah\n\n# Or as a Python module\npython -m pytest_unused_port /tmp/blah\n\n# Serve the current directory (default)\npytest-unused-port\nuport\n```\n\nThis 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.\n\n### Pytest Fixtures\n\nThis pytest plugin provides a `unused_port` fixture that returns an available TCP port on localhost that your tests can use.\n\n### Basic Example\n\n```python\ndef test_my_server(unused_port):\n # unused_port is an integer containing an available port number\n server = start_my_server(port=unused_port)\n assert server.is_running()\n```\n\n### Starting an HTTP Server\n\n```python\nimport http.server\n\ndef test_http_server(unused_port):\n handler = http.server.SimpleHTTPRequestHandler\n server = http.server.HTTPServer(('127.0.0.1', unused_port), handler)\n # Now you can test your server on the unused port\n assert server.server_port == unused_port\n```\n\n### Using with Socket Programming\n\n```python\nimport socket\n\ndef test_socket_server(unused_port):\n sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n sock.bind(('127.0.0.1', unused_port))\n sock.listen(1)\n # Your test code here\n sock.close()\n```\n\nThe 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.\n\n### The `unused_port_server` fixture\n\nFor 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.\n\n#### Basic Example\n\n```python\ndef test_fetch_from_server(unused_port_server, tmp_path):\n # Create a test file\n test_file = tmp_path / \"index.html\"\n test_file.write_text(\"<h1>Hello</h1>\")\n\n # Start the server serving the directory\n unused_port_server.start(tmp_path)\n\n # Make requests to http://127.0.0.1:{unused_port_server.port}/\n # Server automatically stops at the end of the test\n```\n\n#### Features\n\n- **Automatic cleanup**: The server automatically stops when the test ends\n- **Explicit control**: Call `.stop()` to stop the server manually if needed\n- **Port access**: Access the port number via `unused_port_server.port`\n- **Method chaining**: `.start()` returns self for convenience\n\n#### Example with explicit stop\n\n```python\ndef test_server_lifecycle(unused_port_server, tmp_path):\n unused_port_server.start(tmp_path)\n\n # Do some testing...\n\n # Explicitly stop the server\n unused_port_server.stop()\n\n # Server is now stopped\n```\n\n#### Example fetching a file\n\n```python\nfrom urllib.request import urlopen\n\ndef test_fetch_file(unused_port_server, tmp_path):\n # Create a test file\n (tmp_path / \"data.txt\").write_text(\"test data\")\n\n # Start server\n unused_port_server.start(tmp_path)\n\n # Fetch the file\n url = f\"http://127.0.0.1:{unused_port_server.port}/data.txt\"\n response = urlopen(url)\n assert response.read().decode() == \"test data\"\n```\n\n#### Using as a context manager\n\nYou can also use `StaticServer` directly as a context manager if you need more control:\n\n```python\nfrom pytest_unused_port import StaticServer\n\ndef test_with_context_manager(unused_port, tmp_path):\n with StaticServer(unused_port) as server:\n server.start(tmp_path)\n # Server runs here\n # ... your test code ...\n # Server automatically stops when exiting the context\n```\n\nThe server runs `python -m http.server` in a subprocess, serving static files from the specified directory.\n\n## Development\n\nTo contribute to this library, first checkout the code. Then install the dependencies using `uv`:\n```bash\ncd pytest-unused-port\nuv pip install -e '.[test]'\n```\nTo run the tests:\n```bash\nuv run pytest\n```\n",
"bugtrack_url": null,
"license": null,
"summary": "pytest fixture finding an unused local port",
"version": "0.2",
"project_urls": {
"CI": "https://github.com/simonw/pytest-unused-port/actions",
"Changelog": "https://github.com/simonw/pytest-unused-port/releases",
"Homepage": "https://github.com/simonw/pytest-unused-port",
"Issues": "https://github.com/simonw/pytest-unused-port/issues"
},
"split_keywords": [],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "7f6533d0be055b30b8a3cfadfe8fe722105b72ec6e45971e15e86b1d3ee57e88",
"md5": "1a36a42a1671924f41e3ef7739b24cd6",
"sha256": "ca5bcf00cdf516a372f3a3e0f651bcf9dfdb1c4ac44ad0d7cdfc950a9cbfefed"
},
"downloads": -1,
"filename": "pytest_unused_port-0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "1a36a42a1671924f41e3ef7739b24cd6",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 9629,
"upload_time": "2025-10-22T21:54:03",
"upload_time_iso_8601": "2025-10-22T21:54:03.298814Z",
"url": "https://files.pythonhosted.org/packages/7f/65/33d0be055b30b8a3cfadfe8fe722105b72ec6e45971e15e86b1d3ee57e88/pytest_unused_port-0.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "612796e530adc51b7d3106d5e4223317b99586d74765a0201e828e52ca34700c",
"md5": "08957f2a686057844a4f38a14ceeb084",
"sha256": "3d443b9b8d25506fa2b627d35dfdc94148a611ab7cefb9c65428daef2146395c"
},
"downloads": -1,
"filename": "pytest_unused_port-0.2.tar.gz",
"has_sig": false,
"md5_digest": "08957f2a686057844a4f38a14ceeb084",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 10498,
"upload_time": "2025-10-22T21:54:04",
"upload_time_iso_8601": "2025-10-22T21:54:04.594124Z",
"url": "https://files.pythonhosted.org/packages/61/27/96e530adc51b7d3106d5e4223317b99586d74765a0201e828e52ca34700c/pytest_unused_port-0.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-22 21:54:04",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "simonw",
"github_project": "pytest-unused-port",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "pytest-unused-port"
}