webdev 1.1.0__tar.gz → 2.0.1__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.
- webdev-2.0.1/.gitignore +19 -0
- {webdev-1.1.0 → webdev-2.0.1}/LICENSE +1 -1
- webdev-2.0.1/PKG-INFO +269 -0
- webdev-2.0.1/README.rst +239 -0
- webdev-2.0.1/pyproject.toml +81 -0
- webdev-2.0.1/tests/conftest.py +28 -0
- webdev-2.0.1/tests/test_config.py +87 -0
- webdev-2.0.1/tests/test_index.py +68 -0
- webdev-2.0.1/tests/test_livereload.py +44 -0
- webdev-2.0.1/tests/test_net.py +53 -0
- webdev-2.0.1/tests/test_server.py +121 -0
- webdev-2.0.1/tests/test_static.py +70 -0
- webdev-2.0.1/webdev/__init__.py +30 -0
- webdev-2.0.1/webdev/__main__.py +29 -0
- webdev-2.0.1/webdev/cli.py +330 -0
- webdev-2.0.1/webdev/config.py +210 -0
- webdev-2.0.1/webdev/index.py +298 -0
- webdev-2.0.1/webdev/livereload.py +169 -0
- webdev-2.0.1/webdev/net.py +145 -0
- webdev-2.0.1/webdev/run.py +124 -0
- webdev-2.0.1/webdev/server.py +336 -0
- webdev-2.0.1/webdev/static.py +195 -0
- webdev-2.0.1/webdev/templates/dark/base.html.jinja2 +17 -0
- webdev-2.0.1/webdev/templates/dark/index.html.jinja2 +71 -0
- webdev-2.0.1/webdev/templates/dark/partials/sort.js.jinja2 +52 -0
- webdev-2.0.1/webdev/templates/dark/partials/styles.css.jinja2 +110 -0
- webdev-2.0.1/webdev/tls.py +159 -0
- webdev-1.1.0/MANIFEST.in +0 -2
- webdev-1.1.0/PKG-INFO +0 -123
- webdev-1.1.0/README.rst +0 -105
- webdev-1.1.0/setup.cfg +0 -5
- webdev-1.1.0/setup.py +0 -68
- webdev-1.1.0/webdev +0 -188
- webdev-1.1.0/webdev.egg-info/PKG-INFO +0 -123
- webdev-1.1.0/webdev.egg-info/SOURCES.txt +0 -10
- webdev-1.1.0/webdev.egg-info/dependency_links.txt +0 -1
- webdev-1.1.0/webdev.egg-info/pbr.json +0 -1
- webdev-1.1.0/webdev.egg-info/top_level.txt +0 -1
webdev-2.0.1/.gitignore
ADDED
webdev-2.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: webdev
|
|
3
|
+
Version: 2.0.1
|
|
4
|
+
Summary: Small, fast development web server with a modern dark directory index
|
|
5
|
+
Project-URL: Homepage, https://github.com/kuralabs/webdev
|
|
6
|
+
Project-URL: Repository, https://github.com/kuralabs/webdev
|
|
7
|
+
Project-URL: Issues, https://github.com/kuralabs/webdev/issues
|
|
8
|
+
Author-email: "KuraLabs S.R.L" <info@kuralabs.io>, Carlos Jenkins <carlos@jenkins.co.cr>
|
|
9
|
+
License-Expression: Apache-2.0
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: dev,development,http,server,static,web
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
|
|
20
|
+
Classifier: Topic :: Utilities
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: colorlog>=6.8
|
|
23
|
+
Requires-Dist: jinja2>=3.1
|
|
24
|
+
Requires-Dist: qrcode>=7.4
|
|
25
|
+
Requires-Dist: starlette>=0.37
|
|
26
|
+
Requires-Dist: tomli>=2.0; python_version < '3.11'
|
|
27
|
+
Requires-Dist: uvicorn[standard]>=0.29
|
|
28
|
+
Requires-Dist: watchfiles>=0.21
|
|
29
|
+
Description-Content-Type: text/x-rst
|
|
30
|
+
|
|
31
|
+
======================
|
|
32
|
+
Development Web Server
|
|
33
|
+
======================
|
|
34
|
+
|
|
35
|
+
``webdev`` is a **small, fast local development web server**. Point it at a
|
|
36
|
+
folder and it serves it over HTTP (or HTTPS) with developer-friendly
|
|
37
|
+
conveniences and a modern, dark-themed directory index.
|
|
38
|
+
|
|
39
|
+
It is built on `Starlette <https://www.starlette.io/>`_ and
|
|
40
|
+
`Uvicorn <https://www.uvicorn.org/>`_ (an async ASGI stack) and requires
|
|
41
|
+
**Python 3.10+**.
|
|
42
|
+
|
|
43
|
+
Quick start
|
|
44
|
+
===========
|
|
45
|
+
|
|
46
|
+
::
|
|
47
|
+
|
|
48
|
+
# Install (see more options below)
|
|
49
|
+
uv tool install webdev
|
|
50
|
+
|
|
51
|
+
# Serve the current directory on http://localhost:8080
|
|
52
|
+
webdev
|
|
53
|
+
|
|
54
|
+
# Serve a specific folder
|
|
55
|
+
webdev ./public
|
|
56
|
+
|
|
57
|
+
# See every option
|
|
58
|
+
webdev --help
|
|
59
|
+
|
|
60
|
+
Installation
|
|
61
|
+
============
|
|
62
|
+
|
|
63
|
+
With `uv <https://docs.astral.sh/uv/>`_ (recommended)::
|
|
64
|
+
|
|
65
|
+
uv tool install webdev
|
|
66
|
+
|
|
67
|
+
With `pipx <https://pipx.pypa.io/>`_::
|
|
68
|
+
|
|
69
|
+
pipx install webdev
|
|
70
|
+
|
|
71
|
+
Or with plain ``pip`` into an environment of your choice::
|
|
72
|
+
|
|
73
|
+
pip install webdev
|
|
74
|
+
|
|
75
|
+
Features
|
|
76
|
+
========
|
|
77
|
+
|
|
78
|
+
- 🗂️ **Serve any directory** — passed as the first positional argument; defaults
|
|
79
|
+
to the current directory.
|
|
80
|
+
- 🩹 **Graceful when the folder disappears** — responds with ``404`` instead of
|
|
81
|
+
crashing if the served directory is removed, and **recovers automatically**
|
|
82
|
+
the moment it is recreated. Paths are resolved against the live filesystem on
|
|
83
|
+
every request — ideal for build systems that clean and rebuild output.
|
|
84
|
+
- 🔀 **Automatic port selection** — if the base port is busy, the next free port
|
|
85
|
+
in a range is used. Can be forced to a single exact port.
|
|
86
|
+
- 🔮 **Serve a not-yet-existing folder** — ``--future`` assumes the folder will
|
|
87
|
+
be created later.
|
|
88
|
+
- 🎨 **Modern dark directory index** — breadcrumbs, file-type icons,
|
|
89
|
+
human-readable sizes, modified dates and client-side sortable columns.
|
|
90
|
+
**Themable**: drop a new directory under ``webdev/templates/<theme>/``.
|
|
91
|
+
- 🔁 **Live reload** — connected browsers refresh automatically on file changes
|
|
92
|
+
(via a WebSocket; a tiny auto-reconnecting snippet is injected into HTML).
|
|
93
|
+
- 📱 **Instant mobile testing** — a **QR code and LAN URL** are printed at
|
|
94
|
+
startup so you can open the site on your phone.
|
|
95
|
+
- 🌈 **Colorized, level-aware logs** for readable output.
|
|
96
|
+
- ⚡ **No-cache headers** for always-fresh development content.
|
|
97
|
+
- 🧭 **SPA fallback** — optionally serve ``index.html`` for unknown routes.
|
|
98
|
+
- 📦 **Gzip**, **CORS** and optional **HTTPS** (self-signed if no cert/key is
|
|
99
|
+
given).
|
|
100
|
+
- ⚙️ **Config file** — every option can be set via ``webdev.toml`` (or a
|
|
101
|
+
``[tool.webdev]`` table). Precedence: CLI flag > config file > default.
|
|
102
|
+
|
|
103
|
+
Usage
|
|
104
|
+
=====
|
|
105
|
+
|
|
106
|
+
::
|
|
107
|
+
|
|
108
|
+
$ webdev --help
|
|
109
|
+
usage: webdev [-h] [-v] [--version] [-i IP] [-p PORT] [-f] [-r RANGE] [-u]
|
|
110
|
+
[--reload | --no-reload] [--cache] [--no-cache]
|
|
111
|
+
[--spa | --no-spa] [--gzip | --no-gzip] [--cors | --no-cors]
|
|
112
|
+
[--qr | --no-qr] [--color | --no-color]
|
|
113
|
+
[--https | --no-https] [--cert CERT]
|
|
114
|
+
[--key KEY] [--theme THEME] [--config CONFIG]
|
|
115
|
+
[path]
|
|
116
|
+
|
|
117
|
+
Examples::
|
|
118
|
+
|
|
119
|
+
# Serve the current directory on http://localhost:8080
|
|
120
|
+
webdev
|
|
121
|
+
|
|
122
|
+
# Serve ./public on a forced port, over HTTPS, without live reload
|
|
123
|
+
webdev -p 3000 -f --https --no-reload ./public
|
|
124
|
+
|
|
125
|
+
# Single-page app: fall back to index.html for client-side routes
|
|
126
|
+
webdev --spa ./dist
|
|
127
|
+
|
|
128
|
+
# Serve a build output folder that does not exist yet
|
|
129
|
+
webdev --future ./dist
|
|
130
|
+
|
|
131
|
+
Options and config keys
|
|
132
|
+
-----------------------
|
|
133
|
+
|
|
134
|
+
Every option has both a CLI flag and a config-file key. Booleans accept
|
|
135
|
+
``--x`` / ``--no-x``.
|
|
136
|
+
|
|
137
|
+
===================== ======================== ================== ==========
|
|
138
|
+
Feature CLI flag Config key Default
|
|
139
|
+
===================== ======================== ================== ==========
|
|
140
|
+
Serve path positional ``path`` ``path`` CWD
|
|
141
|
+
Bind IP ``-i/--ip`` ``ip`` 0.0.0.0
|
|
142
|
+
Base port ``-p/--port`` ``port`` 8080
|
|
143
|
+
Force exact port ``-f/--force-port`` ``force_port`` false
|
|
144
|
+
Port range ``-r/--range`` ``range`` 20
|
|
145
|
+
Serve missing folder ``-u/--future`` ``future`` false
|
|
146
|
+
No-cache headers ``--no-cache/--cache`` ``no_cache`` enabled
|
|
147
|
+
Live reload ``--reload/--no-reload`` ``reload`` enabled
|
|
148
|
+
SPA fallback ``--spa/--no-spa`` ``spa`` disabled
|
|
149
|
+
Gzip ``--gzip/--no-gzip`` ``gzip`` enabled
|
|
150
|
+
CORS ``--cors/--no-cors`` ``cors`` disabled
|
|
151
|
+
QR / LAN URL ``--qr/--no-qr`` ``qr`` enabled
|
|
152
|
+
Colorized logs ``--color/--no-color`` ``color`` enabled
|
|
153
|
+
HTTPS/TLS ``--https/--no-https`` ``https`` disabled
|
|
154
|
+
TLS cert / key ``--cert`` / ``--key`` ``cert`` / ``key`` self-signed
|
|
155
|
+
Index theme ``--theme`` ``theme`` dark
|
|
156
|
+
Verbosity ``-v`` (repeatable) ``verbose`` 0
|
|
157
|
+
===================== ======================== ================== ==========
|
|
158
|
+
|
|
159
|
+
Commit a ``webdev.toml`` next to your project to share settings with your team.
|
|
160
|
+
Any option works as a flat key, or under a ``[tool.webdev]`` table (handy inside
|
|
161
|
+
a ``pyproject.toml``)::
|
|
162
|
+
|
|
163
|
+
# webdev.toml
|
|
164
|
+
port = 3000
|
|
165
|
+
force_port = true
|
|
166
|
+
spa = true
|
|
167
|
+
cors = true
|
|
168
|
+
|
|
169
|
+
Development
|
|
170
|
+
===========
|
|
171
|
+
|
|
172
|
+
The development workflow is driven by `tox <https://tox.wiki/>`_ using
|
|
173
|
+
`uv <https://docs.astral.sh/uv/>`_ as the backend (via ``tox-uv``). ``uv`` is the
|
|
174
|
+
only tool you need preinstalled::
|
|
175
|
+
|
|
176
|
+
# Lint, format-check and type-check
|
|
177
|
+
tox -e style
|
|
178
|
+
|
|
179
|
+
# Run the test suite
|
|
180
|
+
tox -e test
|
|
181
|
+
|
|
182
|
+
# Build and verify the distribution
|
|
183
|
+
tox -e build
|
|
184
|
+
|
|
185
|
+
# Build, install in a throwaway venv and run (pass args after --)
|
|
186
|
+
tox -e run -- -p 3000 ./public
|
|
187
|
+
|
|
188
|
+
Each environment declares its own tooling dependencies in ``tox.ini`` so it
|
|
189
|
+
installs only what it needs.
|
|
190
|
+
|
|
191
|
+
Changelog
|
|
192
|
+
=========
|
|
193
|
+
|
|
194
|
+
2.0.1
|
|
195
|
+
-----
|
|
196
|
+
|
|
197
|
+
**Changed**
|
|
198
|
+
|
|
199
|
+
- Modernized and expanded the README (uv-first installation, refreshed feature
|
|
200
|
+
overview and usage).
|
|
201
|
+
|
|
202
|
+
2.0.0
|
|
203
|
+
-----
|
|
204
|
+
|
|
205
|
+
**Reimplemented** on a modern async stack (Starlette + Uvicorn), Python 3.10+.
|
|
206
|
+
|
|
207
|
+
**New**
|
|
208
|
+
|
|
209
|
+
- Modern dark, themable directory index (breadcrumbs, icons, sizes, dates,
|
|
210
|
+
sortable columns), rendered with Jinja2.
|
|
211
|
+
- Live reload over WebSocket.
|
|
212
|
+
- No-cache headers, SPA fallback, gzip, CORS, optional HTTPS (self-signed),
|
|
213
|
+
startup QR code / LAN URL.
|
|
214
|
+
- Colorized, level-aware log output (``--color/--no-color``, via colorlog).
|
|
215
|
+
- Config-file support (``webdev.toml`` / ``[tool.webdev]``); every option has a
|
|
216
|
+
CLI flag and a config key (precedence CLI > config > default).
|
|
217
|
+
- ``pyproject.toml`` packaging; tox + uv development workflow; Ruff, mypy and a
|
|
218
|
+
pytest suite.
|
|
219
|
+
|
|
220
|
+
**Fixed**
|
|
221
|
+
|
|
222
|
+
- The directory auto-recovery feature, which silently broke on modern Python
|
|
223
|
+
when ``http.server`` began capturing the working directory in the request
|
|
224
|
+
handler constructor. Path resolution is now per-request against the live
|
|
225
|
+
filesystem.
|
|
226
|
+
|
|
227
|
+
**Changed**
|
|
228
|
+
|
|
229
|
+
- Dropped Python 2 support.
|
|
230
|
+
|
|
231
|
+
1.1.0
|
|
232
|
+
-----
|
|
233
|
+
|
|
234
|
+
**New**
|
|
235
|
+
|
|
236
|
+
- Added support for Python 3 (issue #5).
|
|
237
|
+
- Added support for incremental automatic port selection (issue #2).
|
|
238
|
+
- Added the ``--future`` flag that allows the webserver to serve a non-existent
|
|
239
|
+
folder, assuming it will be created in the future (issue #3).
|
|
240
|
+
|
|
241
|
+
**Changed**
|
|
242
|
+
|
|
243
|
+
- Ctrl+C is now handled (issue #4).
|
|
244
|
+
|
|
245
|
+
1.0.0
|
|
246
|
+
-----
|
|
247
|
+
|
|
248
|
+
- Initial release.
|
|
249
|
+
|
|
250
|
+
License
|
|
251
|
+
=======
|
|
252
|
+
|
|
253
|
+
::
|
|
254
|
+
|
|
255
|
+
Copyright (C) 2026 KuraLabs S.R.L <info@kuralabs.io>
|
|
256
|
+
Copyright (C) 2015-2016 Carlos Jenkins <carlos@jenkins.co.cr>
|
|
257
|
+
|
|
258
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
259
|
+
you may not use this file except in compliance with the License.
|
|
260
|
+
You may obtain a copy of the License at
|
|
261
|
+
|
|
262
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
263
|
+
|
|
264
|
+
Unless required by applicable law or agreed to in writing,
|
|
265
|
+
software distributed under the License is distributed on an
|
|
266
|
+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
267
|
+
KIND, either express or implied. See the License for the
|
|
268
|
+
specific language governing permissions and limitations
|
|
269
|
+
under the License.
|
webdev-2.0.1/README.rst
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
======================
|
|
2
|
+
Development Web Server
|
|
3
|
+
======================
|
|
4
|
+
|
|
5
|
+
``webdev`` is a **small, fast local development web server**. Point it at a
|
|
6
|
+
folder and it serves it over HTTP (or HTTPS) with developer-friendly
|
|
7
|
+
conveniences and a modern, dark-themed directory index.
|
|
8
|
+
|
|
9
|
+
It is built on `Starlette <https://www.starlette.io/>`_ and
|
|
10
|
+
`Uvicorn <https://www.uvicorn.org/>`_ (an async ASGI stack) and requires
|
|
11
|
+
**Python 3.10+**.
|
|
12
|
+
|
|
13
|
+
Quick start
|
|
14
|
+
===========
|
|
15
|
+
|
|
16
|
+
::
|
|
17
|
+
|
|
18
|
+
# Install (see more options below)
|
|
19
|
+
uv tool install webdev
|
|
20
|
+
|
|
21
|
+
# Serve the current directory on http://localhost:8080
|
|
22
|
+
webdev
|
|
23
|
+
|
|
24
|
+
# Serve a specific folder
|
|
25
|
+
webdev ./public
|
|
26
|
+
|
|
27
|
+
# See every option
|
|
28
|
+
webdev --help
|
|
29
|
+
|
|
30
|
+
Installation
|
|
31
|
+
============
|
|
32
|
+
|
|
33
|
+
With `uv <https://docs.astral.sh/uv/>`_ (recommended)::
|
|
34
|
+
|
|
35
|
+
uv tool install webdev
|
|
36
|
+
|
|
37
|
+
With `pipx <https://pipx.pypa.io/>`_::
|
|
38
|
+
|
|
39
|
+
pipx install webdev
|
|
40
|
+
|
|
41
|
+
Or with plain ``pip`` into an environment of your choice::
|
|
42
|
+
|
|
43
|
+
pip install webdev
|
|
44
|
+
|
|
45
|
+
Features
|
|
46
|
+
========
|
|
47
|
+
|
|
48
|
+
- 🗂️ **Serve any directory** — passed as the first positional argument; defaults
|
|
49
|
+
to the current directory.
|
|
50
|
+
- 🩹 **Graceful when the folder disappears** — responds with ``404`` instead of
|
|
51
|
+
crashing if the served directory is removed, and **recovers automatically**
|
|
52
|
+
the moment it is recreated. Paths are resolved against the live filesystem on
|
|
53
|
+
every request — ideal for build systems that clean and rebuild output.
|
|
54
|
+
- 🔀 **Automatic port selection** — if the base port is busy, the next free port
|
|
55
|
+
in a range is used. Can be forced to a single exact port.
|
|
56
|
+
- 🔮 **Serve a not-yet-existing folder** — ``--future`` assumes the folder will
|
|
57
|
+
be created later.
|
|
58
|
+
- 🎨 **Modern dark directory index** — breadcrumbs, file-type icons,
|
|
59
|
+
human-readable sizes, modified dates and client-side sortable columns.
|
|
60
|
+
**Themable**: drop a new directory under ``webdev/templates/<theme>/``.
|
|
61
|
+
- 🔁 **Live reload** — connected browsers refresh automatically on file changes
|
|
62
|
+
(via a WebSocket; a tiny auto-reconnecting snippet is injected into HTML).
|
|
63
|
+
- 📱 **Instant mobile testing** — a **QR code and LAN URL** are printed at
|
|
64
|
+
startup so you can open the site on your phone.
|
|
65
|
+
- 🌈 **Colorized, level-aware logs** for readable output.
|
|
66
|
+
- ⚡ **No-cache headers** for always-fresh development content.
|
|
67
|
+
- 🧭 **SPA fallback** — optionally serve ``index.html`` for unknown routes.
|
|
68
|
+
- 📦 **Gzip**, **CORS** and optional **HTTPS** (self-signed if no cert/key is
|
|
69
|
+
given).
|
|
70
|
+
- ⚙️ **Config file** — every option can be set via ``webdev.toml`` (or a
|
|
71
|
+
``[tool.webdev]`` table). Precedence: CLI flag > config file > default.
|
|
72
|
+
|
|
73
|
+
Usage
|
|
74
|
+
=====
|
|
75
|
+
|
|
76
|
+
::
|
|
77
|
+
|
|
78
|
+
$ webdev --help
|
|
79
|
+
usage: webdev [-h] [-v] [--version] [-i IP] [-p PORT] [-f] [-r RANGE] [-u]
|
|
80
|
+
[--reload | --no-reload] [--cache] [--no-cache]
|
|
81
|
+
[--spa | --no-spa] [--gzip | --no-gzip] [--cors | --no-cors]
|
|
82
|
+
[--qr | --no-qr] [--color | --no-color]
|
|
83
|
+
[--https | --no-https] [--cert CERT]
|
|
84
|
+
[--key KEY] [--theme THEME] [--config CONFIG]
|
|
85
|
+
[path]
|
|
86
|
+
|
|
87
|
+
Examples::
|
|
88
|
+
|
|
89
|
+
# Serve the current directory on http://localhost:8080
|
|
90
|
+
webdev
|
|
91
|
+
|
|
92
|
+
# Serve ./public on a forced port, over HTTPS, without live reload
|
|
93
|
+
webdev -p 3000 -f --https --no-reload ./public
|
|
94
|
+
|
|
95
|
+
# Single-page app: fall back to index.html for client-side routes
|
|
96
|
+
webdev --spa ./dist
|
|
97
|
+
|
|
98
|
+
# Serve a build output folder that does not exist yet
|
|
99
|
+
webdev --future ./dist
|
|
100
|
+
|
|
101
|
+
Options and config keys
|
|
102
|
+
-----------------------
|
|
103
|
+
|
|
104
|
+
Every option has both a CLI flag and a config-file key. Booleans accept
|
|
105
|
+
``--x`` / ``--no-x``.
|
|
106
|
+
|
|
107
|
+
===================== ======================== ================== ==========
|
|
108
|
+
Feature CLI flag Config key Default
|
|
109
|
+
===================== ======================== ================== ==========
|
|
110
|
+
Serve path positional ``path`` ``path`` CWD
|
|
111
|
+
Bind IP ``-i/--ip`` ``ip`` 0.0.0.0
|
|
112
|
+
Base port ``-p/--port`` ``port`` 8080
|
|
113
|
+
Force exact port ``-f/--force-port`` ``force_port`` false
|
|
114
|
+
Port range ``-r/--range`` ``range`` 20
|
|
115
|
+
Serve missing folder ``-u/--future`` ``future`` false
|
|
116
|
+
No-cache headers ``--no-cache/--cache`` ``no_cache`` enabled
|
|
117
|
+
Live reload ``--reload/--no-reload`` ``reload`` enabled
|
|
118
|
+
SPA fallback ``--spa/--no-spa`` ``spa`` disabled
|
|
119
|
+
Gzip ``--gzip/--no-gzip`` ``gzip`` enabled
|
|
120
|
+
CORS ``--cors/--no-cors`` ``cors`` disabled
|
|
121
|
+
QR / LAN URL ``--qr/--no-qr`` ``qr`` enabled
|
|
122
|
+
Colorized logs ``--color/--no-color`` ``color`` enabled
|
|
123
|
+
HTTPS/TLS ``--https/--no-https`` ``https`` disabled
|
|
124
|
+
TLS cert / key ``--cert`` / ``--key`` ``cert`` / ``key`` self-signed
|
|
125
|
+
Index theme ``--theme`` ``theme`` dark
|
|
126
|
+
Verbosity ``-v`` (repeatable) ``verbose`` 0
|
|
127
|
+
===================== ======================== ================== ==========
|
|
128
|
+
|
|
129
|
+
Commit a ``webdev.toml`` next to your project to share settings with your team.
|
|
130
|
+
Any option works as a flat key, or under a ``[tool.webdev]`` table (handy inside
|
|
131
|
+
a ``pyproject.toml``)::
|
|
132
|
+
|
|
133
|
+
# webdev.toml
|
|
134
|
+
port = 3000
|
|
135
|
+
force_port = true
|
|
136
|
+
spa = true
|
|
137
|
+
cors = true
|
|
138
|
+
|
|
139
|
+
Development
|
|
140
|
+
===========
|
|
141
|
+
|
|
142
|
+
The development workflow is driven by `tox <https://tox.wiki/>`_ using
|
|
143
|
+
`uv <https://docs.astral.sh/uv/>`_ as the backend (via ``tox-uv``). ``uv`` is the
|
|
144
|
+
only tool you need preinstalled::
|
|
145
|
+
|
|
146
|
+
# Lint, format-check and type-check
|
|
147
|
+
tox -e style
|
|
148
|
+
|
|
149
|
+
# Run the test suite
|
|
150
|
+
tox -e test
|
|
151
|
+
|
|
152
|
+
# Build and verify the distribution
|
|
153
|
+
tox -e build
|
|
154
|
+
|
|
155
|
+
# Build, install in a throwaway venv and run (pass args after --)
|
|
156
|
+
tox -e run -- -p 3000 ./public
|
|
157
|
+
|
|
158
|
+
Each environment declares its own tooling dependencies in ``tox.ini`` so it
|
|
159
|
+
installs only what it needs.
|
|
160
|
+
|
|
161
|
+
Changelog
|
|
162
|
+
=========
|
|
163
|
+
|
|
164
|
+
2.0.1
|
|
165
|
+
-----
|
|
166
|
+
|
|
167
|
+
**Changed**
|
|
168
|
+
|
|
169
|
+
- Modernized and expanded the README (uv-first installation, refreshed feature
|
|
170
|
+
overview and usage).
|
|
171
|
+
|
|
172
|
+
2.0.0
|
|
173
|
+
-----
|
|
174
|
+
|
|
175
|
+
**Reimplemented** on a modern async stack (Starlette + Uvicorn), Python 3.10+.
|
|
176
|
+
|
|
177
|
+
**New**
|
|
178
|
+
|
|
179
|
+
- Modern dark, themable directory index (breadcrumbs, icons, sizes, dates,
|
|
180
|
+
sortable columns), rendered with Jinja2.
|
|
181
|
+
- Live reload over WebSocket.
|
|
182
|
+
- No-cache headers, SPA fallback, gzip, CORS, optional HTTPS (self-signed),
|
|
183
|
+
startup QR code / LAN URL.
|
|
184
|
+
- Colorized, level-aware log output (``--color/--no-color``, via colorlog).
|
|
185
|
+
- Config-file support (``webdev.toml`` / ``[tool.webdev]``); every option has a
|
|
186
|
+
CLI flag and a config key (precedence CLI > config > default).
|
|
187
|
+
- ``pyproject.toml`` packaging; tox + uv development workflow; Ruff, mypy and a
|
|
188
|
+
pytest suite.
|
|
189
|
+
|
|
190
|
+
**Fixed**
|
|
191
|
+
|
|
192
|
+
- The directory auto-recovery feature, which silently broke on modern Python
|
|
193
|
+
when ``http.server`` began capturing the working directory in the request
|
|
194
|
+
handler constructor. Path resolution is now per-request against the live
|
|
195
|
+
filesystem.
|
|
196
|
+
|
|
197
|
+
**Changed**
|
|
198
|
+
|
|
199
|
+
- Dropped Python 2 support.
|
|
200
|
+
|
|
201
|
+
1.1.0
|
|
202
|
+
-----
|
|
203
|
+
|
|
204
|
+
**New**
|
|
205
|
+
|
|
206
|
+
- Added support for Python 3 (issue #5).
|
|
207
|
+
- Added support for incremental automatic port selection (issue #2).
|
|
208
|
+
- Added the ``--future`` flag that allows the webserver to serve a non-existent
|
|
209
|
+
folder, assuming it will be created in the future (issue #3).
|
|
210
|
+
|
|
211
|
+
**Changed**
|
|
212
|
+
|
|
213
|
+
- Ctrl+C is now handled (issue #4).
|
|
214
|
+
|
|
215
|
+
1.0.0
|
|
216
|
+
-----
|
|
217
|
+
|
|
218
|
+
- Initial release.
|
|
219
|
+
|
|
220
|
+
License
|
|
221
|
+
=======
|
|
222
|
+
|
|
223
|
+
::
|
|
224
|
+
|
|
225
|
+
Copyright (C) 2026 KuraLabs S.R.L <info@kuralabs.io>
|
|
226
|
+
Copyright (C) 2015-2016 Carlos Jenkins <carlos@jenkins.co.cr>
|
|
227
|
+
|
|
228
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
229
|
+
you may not use this file except in compliance with the License.
|
|
230
|
+
You may obtain a copy of the License at
|
|
231
|
+
|
|
232
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
233
|
+
|
|
234
|
+
Unless required by applicable law or agreed to in writing,
|
|
235
|
+
software distributed under the License is distributed on an
|
|
236
|
+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
237
|
+
KIND, either express or implied. See the License for the
|
|
238
|
+
specific language governing permissions and limitations
|
|
239
|
+
under the License.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "webdev"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Small, fast development web server with a modern dark directory index"
|
|
9
|
+
readme = "README.rst"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "Apache-2.0"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "KuraLabs S.R.L", email = "info@kuralabs.io" },
|
|
15
|
+
{ name = "Carlos Jenkins", email = "carlos@jenkins.co.cr" },
|
|
16
|
+
]
|
|
17
|
+
keywords = ["development", "web", "server", "static", "http", "dev"]
|
|
18
|
+
classifiers = [
|
|
19
|
+
"Development Status :: 5 - Production/Stable",
|
|
20
|
+
"Intended Audience :: Developers",
|
|
21
|
+
"Operating System :: OS Independent",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Topic :: Utilities",
|
|
27
|
+
"Topic :: Internet :: WWW/HTTP :: HTTP Servers",
|
|
28
|
+
]
|
|
29
|
+
dependencies = [
|
|
30
|
+
"starlette>=0.37",
|
|
31
|
+
"uvicorn[standard]>=0.29",
|
|
32
|
+
"jinja2>=3.1",
|
|
33
|
+
"watchfiles>=0.21",
|
|
34
|
+
"qrcode>=7.4",
|
|
35
|
+
"colorlog>=6.8",
|
|
36
|
+
"tomli>=2.0; python_version < '3.11'",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[project.scripts]
|
|
40
|
+
webdev = "webdev.cli:main"
|
|
41
|
+
|
|
42
|
+
[project.urls]
|
|
43
|
+
Homepage = "https://github.com/kuralabs/webdev"
|
|
44
|
+
Repository = "https://github.com/kuralabs/webdev"
|
|
45
|
+
Issues = "https://github.com/kuralabs/webdev/issues"
|
|
46
|
+
|
|
47
|
+
[tool.hatch.version]
|
|
48
|
+
path = "webdev/__init__.py"
|
|
49
|
+
|
|
50
|
+
[tool.hatch.build.targets.wheel]
|
|
51
|
+
packages = ["webdev"]
|
|
52
|
+
|
|
53
|
+
[tool.hatch.build.targets.sdist]
|
|
54
|
+
include = [
|
|
55
|
+
"/webdev",
|
|
56
|
+
"/tests",
|
|
57
|
+
"/README.rst",
|
|
58
|
+
"/LICENSE",
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
[tool.ruff]
|
|
62
|
+
line-length = 88
|
|
63
|
+
target-version = "py310"
|
|
64
|
+
|
|
65
|
+
[tool.ruff.lint]
|
|
66
|
+
# flake8-equivalent rule set: pycodestyle (E, W), pyflakes (F) and
|
|
67
|
+
# pep8-naming (N). Import sorting (I) is intentionally left out.
|
|
68
|
+
select = ["E", "W", "F", "N"]
|
|
69
|
+
|
|
70
|
+
[tool.ruff.format]
|
|
71
|
+
quote-style = "single"
|
|
72
|
+
|
|
73
|
+
[tool.mypy]
|
|
74
|
+
python_version = "3.10"
|
|
75
|
+
warn_unused_ignores = true
|
|
76
|
+
warn_redundant_casts = true
|
|
77
|
+
ignore_missing_imports = true
|
|
78
|
+
|
|
79
|
+
[tool.pytest.ini_options]
|
|
80
|
+
testpaths = ["tests"]
|
|
81
|
+
addopts = "-ra"
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Shared pytest fixtures."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
from webdev.config import Settings
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.fixture
|
|
13
|
+
def served_dir(tmp_path: Path) -> Path:
|
|
14
|
+
(tmp_path / 'hello.txt').write_text('hello world')
|
|
15
|
+
(tmp_path / 'page.html').write_text('<html><body>Hi</body></html>')
|
|
16
|
+
(tmp_path / 'sub').mkdir()
|
|
17
|
+
(tmp_path / 'sub' / 'nested.txt').write_text('nested')
|
|
18
|
+
return tmp_path
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@pytest.fixture
|
|
22
|
+
def settings(served_dir: Path) -> Settings:
|
|
23
|
+
return Settings(
|
|
24
|
+
path=str(served_dir),
|
|
25
|
+
reload=False,
|
|
26
|
+
qr=False,
|
|
27
|
+
gzip=False,
|
|
28
|
+
).normalized()
|