webdev 2.0.0__tar.gz → 2.1.0__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 (39) hide show
  1. {webdev-2.0.0 → webdev-2.1.0}/.gitignore +1 -0
  2. {webdev-2.0.0 → webdev-2.1.0}/PKG-INFO +91 -50
  3. {webdev-2.0.0 → webdev-2.1.0}/README.rst +90 -49
  4. webdev-2.1.0/tests/test_mime.py +47 -0
  5. {webdev-2.0.0 → webdev-2.1.0}/tests/test_static.py +27 -2
  6. webdev-2.1.0/tests/testfiles/app.config +2 -0
  7. webdev-2.1.0/tests/testfiles/config.yaml +2 -0
  8. webdev-2.1.0/tests/testfiles/config.yml +2 -0
  9. webdev-2.1.0/tests/testfiles/data.json +4 -0
  10. webdev-2.1.0/tests/testfiles/email.j2 +1 -0
  11. webdev-2.1.0/tests/testfiles/newsletter.jinja2 +1 -0
  12. webdev-2.1.0/tests/testfiles/page.tpl +1 -0
  13. webdev-2.1.0/tests/testfiles/sample.toml +2 -0
  14. webdev-2.1.0/tests/testfiles/sample.txt +1 -0
  15. webdev-2.1.0/tests/testfiles/setup.ini +2 -0
  16. webdev-2.1.0/tests/testfiles/site.template +1 -0
  17. {webdev-2.0.0 → webdev-2.1.0}/webdev/__init__.py +1 -1
  18. {webdev-2.0.0 → webdev-2.1.0}/webdev/static.py +7 -0
  19. {webdev-2.0.0 → webdev-2.1.0}/LICENSE +0 -0
  20. {webdev-2.0.0 → webdev-2.1.0}/pyproject.toml +0 -0
  21. {webdev-2.0.0 → webdev-2.1.0}/tests/conftest.py +0 -0
  22. {webdev-2.0.0 → webdev-2.1.0}/tests/test_config.py +0 -0
  23. {webdev-2.0.0 → webdev-2.1.0}/tests/test_index.py +0 -0
  24. {webdev-2.0.0 → webdev-2.1.0}/tests/test_livereload.py +0 -0
  25. {webdev-2.0.0 → webdev-2.1.0}/tests/test_net.py +0 -0
  26. {webdev-2.0.0 → webdev-2.1.0}/tests/test_server.py +0 -0
  27. {webdev-2.0.0 → webdev-2.1.0}/webdev/__main__.py +0 -0
  28. {webdev-2.0.0 → webdev-2.1.0}/webdev/cli.py +0 -0
  29. {webdev-2.0.0 → webdev-2.1.0}/webdev/config.py +0 -0
  30. {webdev-2.0.0 → webdev-2.1.0}/webdev/index.py +0 -0
  31. {webdev-2.0.0 → webdev-2.1.0}/webdev/livereload.py +0 -0
  32. {webdev-2.0.0 → webdev-2.1.0}/webdev/net.py +0 -0
  33. {webdev-2.0.0 → webdev-2.1.0}/webdev/run.py +0 -0
  34. {webdev-2.0.0 → webdev-2.1.0}/webdev/server.py +0 -0
  35. {webdev-2.0.0 → webdev-2.1.0}/webdev/templates/dark/base.html.jinja2 +0 -0
  36. {webdev-2.0.0 → webdev-2.1.0}/webdev/templates/dark/index.html.jinja2 +0 -0
  37. {webdev-2.0.0 → webdev-2.1.0}/webdev/templates/dark/partials/sort.js.jinja2 +0 -0
  38. {webdev-2.0.0 → webdev-2.1.0}/webdev/templates/dark/partials/styles.css.jinja2 +0 -0
  39. {webdev-2.0.0 → webdev-2.1.0}/webdev/tls.py +0 -0
@@ -13,6 +13,7 @@ build/*
13
13
  .pytest_cache/
14
14
  .mypy_cache/
15
15
  .ruff_cache/
16
+ uv.lock
16
17
 
17
18
  # Misc
18
19
  *~
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: webdev
3
- Version: 2.0.0
3
+ Version: 2.1.0
4
4
  Summary: Small, fast development web server with a modern dark directory index
5
5
  Project-URL: Homepage, https://github.com/kuralabs/webdev
6
6
  Project-URL: Repository, https://github.com/kuralabs/webdev
@@ -32,49 +32,77 @@ Description-Content-Type: text/x-rst
32
32
  Development Web Server
33
33
  ======================
34
34
 
35
- About
36
- =====
37
-
38
- ``webdev`` is a small, fast development web server. It serves any local
39
- directory over HTTP (or HTTPS) with developer-friendly conveniences, and ships
40
- a modern, dark-themed directory index.
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.
41
38
 
42
39
  It is built on `Starlette <https://www.starlette.io/>`_ and
43
- `Uvicorn <https://www.uvicorn.org/>`_ (an ASGI stack), and requires Python 3.10+.
40
+ `Uvicorn <https://www.uvicorn.org/>`_ (an async ASGI stack) and requires
41
+ **Python 3.10+**.
44
42
 
45
- Features
46
- ========
43
+ Quick start
44
+ ===========
47
45
 
48
- - **Serve any directory** — passed as the first positional argument; defaults to
49
- 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, which is great with build systems that perform clean/rebuild
54
- actions.
55
- - **Automatic port selection** — if the base port is busy, the next free port in
56
- a range is used. Can be forced to a single port.
57
- - **Serve a not-yet-existing folder** — ``--future`` assumes the folder will be
58
- created later.
59
- - **Modern dark directory index** — breadcrumbs, file-type icons, human-readable
60
- sizes, modified dates and client-side sortable columns. Themable: drop a new
61
- directory under ``webdev/templates/<theme>/``.
62
- - **Live reload** — connected browsers refresh automatically on file changes
63
- (via a WebSocket; a tiny auto-reconnecting snippet is injected into HTML).
64
- - **No-cache headers** for always-fresh development content.
65
- - **SPA fallback** — optionally serve ``index.html`` for unknown routes.
66
- - **Gzip**, **CORS**, optional **HTTPS** (self-signed if no cert/key is given),
67
- and a startup **QR code / LAN URL** for quick mobile testing.
68
- - **Config file** — every option can be set via ``webdev.toml`` (or a
69
- ``[tool.webdev]`` table). Precedence: CLI flag > config file > default.
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
70
59
 
71
60
  Installation
72
61
  ============
73
62
 
74
- ::
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::
75
72
 
76
73
  pip install webdev
77
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
+ - 👀 **Previews text inline** — plain-text, config and template files (``.txt``,
98
+ ``.json``, ``.yaml``, ``.ini``, ``.toml``, ``.j2``/``.jinja2``, ``.template``,
99
+ ``.config`` and more) open in the browser instead of being downloaded.
100
+ - 🧭 **SPA fallback** — optionally serve ``index.html`` for unknown routes.
101
+ - 📦 **Gzip**, **CORS** and optional **HTTPS** (self-signed if no cert/key is
102
+ given).
103
+ - ⚙️ **Config file** — every option can be set via ``webdev.toml`` (or a
104
+ ``[tool.webdev]`` table). Precedence: CLI flag > config file > default.
105
+
78
106
  Usage
79
107
  =====
80
108
 
@@ -100,6 +128,9 @@ Examples::
100
128
  # Single-page app: fall back to index.html for client-side routes
101
129
  webdev --spa ./dist
102
130
 
131
+ # Serve a build output folder that does not exist yet
132
+ webdev --future ./dist
133
+
103
134
  Options and config keys
104
135
  -----------------------
105
136
 
@@ -125,30 +156,19 @@ Colorized logs ``--color/--no-color`` ``color`` enabled
125
156
  HTTPS/TLS ``--https/--no-https`` ``https`` disabled
126
157
  TLS cert / key ``--cert`` / ``--key`` ``cert`` / ``key`` self-signed
127
158
  Index theme ``--theme`` ``theme`` dark
159
+ Verbosity ``-v`` (repeatable) ``verbose`` 0
128
160
  ===================== ======================== ================== ==========
129
161
 
130
- Example ``webdev.toml``::
162
+ Commit a ``webdev.toml`` next to your project to share settings with your team.
163
+ Any option works as a flat key, or under a ``[tool.webdev]`` table (handy inside
164
+ a ``pyproject.toml``)::
131
165
 
166
+ # webdev.toml
132
167
  port = 3000
133
168
  force_port = true
134
169
  spa = true
135
170
  cors = true
136
171
 
137
- Design notes
138
- ============
139
-
140
- - **Framework:** Starlette + Uvicorn was chosen over a full framework such as
141
- Sanic because this is a static file server: Starlette provides exactly the
142
- primitives needed (routing, static serving, WebSockets, middleware) with a
143
- small surface, and Uvicorn handles fast binding, HTTP keep-alive, HTTPS and
144
- graceful shutdown.
145
- - **The legacy reload hack is gone.** The old server patched ``send_head`` to
146
- ``chdir`` back into the served folder; modern ``http.server`` captures the
147
- working directory in the handler constructor, so that hook stopped running and
148
- a removed folder crashed the request. ``webdev`` now resolves every request
149
- against the live filesystem, so missing folders yield a real ``404`` and
150
- recover automatically.
151
-
152
172
  Development
153
173
  ===========
154
174
 
@@ -165,12 +185,32 @@ only tool you need preinstalled::
165
185
  # Build and verify the distribution
166
186
  tox -e build
167
187
 
188
+ # Build, install in a throwaway venv and run (pass args after --)
189
+ tox -e run -- -p 3000 ./public
190
+
168
191
  Each environment declares its own tooling dependencies in ``tox.ini`` so it
169
192
  installs only what it needs.
170
193
 
171
194
  Changelog
172
195
  =========
173
196
 
197
+ 2.1.0
198
+ -----
199
+
200
+ **New**
201
+
202
+ - Plain-text, config and template files (such as ``.yaml``, ``.tpl``, ``.j2``,
203
+ ``.jinja2``, ``.template`` and ``.config``) now open inline in the browser
204
+ instead of being downloaded (issue #8). Thanks to zaro0508 for the report.
205
+
206
+ 2.0.1
207
+ -----
208
+
209
+ **Changed**
210
+
211
+ - Modernized and expanded the README (uv-first installation, refreshed feature
212
+ overview and usage).
213
+
174
214
  2.0.0
175
215
  -----
176
216
 
@@ -224,7 +264,8 @@ License
224
264
 
225
265
  ::
226
266
 
227
- Copyright (C) 2015-2026 Carlos Jenkins <carlos@jenkins.co.cr>
267
+ Copyright (C) 2026 KuraLabs S.R.L <info@kuralabs.io>
268
+ Copyright (C) 2015-2016 Carlos Jenkins <carlos@jenkins.co.cr>
228
269
 
229
270
  Licensed under the Apache License, Version 2.0 (the "License");
230
271
  you may not use this file except in compliance with the License.
@@ -2,49 +2,77 @@
2
2
  Development Web Server
3
3
  ======================
4
4
 
5
- About
6
- =====
7
-
8
- ``webdev`` is a small, fast development web server. It serves any local
9
- directory over HTTP (or HTTPS) with developer-friendly conveniences, and ships
10
- a modern, dark-themed directory index.
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.
11
8
 
12
9
  It is built on `Starlette <https://www.starlette.io/>`_ and
13
- `Uvicorn <https://www.uvicorn.org/>`_ (an ASGI stack), and requires Python 3.10+.
10
+ `Uvicorn <https://www.uvicorn.org/>`_ (an async ASGI stack) and requires
11
+ **Python 3.10+**.
14
12
 
15
- Features
16
- ========
13
+ Quick start
14
+ ===========
17
15
 
18
- - **Serve any directory** — passed as the first positional argument; defaults to
19
- the current directory.
20
- - **Graceful when the folder disappears** — responds with ``404`` instead of
21
- crashing if the served directory is removed, and **recovers automatically**
22
- the moment it is recreated. Paths are resolved against the live filesystem on
23
- every request, which is great with build systems that perform clean/rebuild
24
- actions.
25
- - **Automatic port selection** — if the base port is busy, the next free port in
26
- a range is used. Can be forced to a single port.
27
- - **Serve a not-yet-existing folder** — ``--future`` assumes the folder will be
28
- created later.
29
- - **Modern dark directory index** — breadcrumbs, file-type icons, human-readable
30
- sizes, modified dates and client-side sortable columns. Themable: drop a new
31
- directory under ``webdev/templates/<theme>/``.
32
- - **Live reload** — connected browsers refresh automatically on file changes
33
- (via a WebSocket; a tiny auto-reconnecting snippet is injected into HTML).
34
- - **No-cache headers** for always-fresh development content.
35
- - **SPA fallback** — optionally serve ``index.html`` for unknown routes.
36
- - **Gzip**, **CORS**, optional **HTTPS** (self-signed if no cert/key is given),
37
- and a startup **QR code / LAN URL** for quick mobile testing.
38
- - **Config file** — every option can be set via ``webdev.toml`` (or a
39
- ``[tool.webdev]`` table). Precedence: CLI flag > config file > default.
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
40
29
 
41
30
  Installation
42
31
  ============
43
32
 
44
- ::
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::
45
42
 
46
43
  pip install webdev
47
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
+ - 👀 **Previews text inline** — plain-text, config and template files (``.txt``,
68
+ ``.json``, ``.yaml``, ``.ini``, ``.toml``, ``.j2``/``.jinja2``, ``.template``,
69
+ ``.config`` and more) open in the browser instead of being downloaded.
70
+ - 🧭 **SPA fallback** — optionally serve ``index.html`` for unknown routes.
71
+ - 📦 **Gzip**, **CORS** and optional **HTTPS** (self-signed if no cert/key is
72
+ given).
73
+ - ⚙️ **Config file** — every option can be set via ``webdev.toml`` (or a
74
+ ``[tool.webdev]`` table). Precedence: CLI flag > config file > default.
75
+
48
76
  Usage
49
77
  =====
50
78
 
@@ -70,6 +98,9 @@ Examples::
70
98
  # Single-page app: fall back to index.html for client-side routes
71
99
  webdev --spa ./dist
72
100
 
101
+ # Serve a build output folder that does not exist yet
102
+ webdev --future ./dist
103
+
73
104
  Options and config keys
74
105
  -----------------------
75
106
 
@@ -95,30 +126,19 @@ Colorized logs ``--color/--no-color`` ``color`` enabled
95
126
  HTTPS/TLS ``--https/--no-https`` ``https`` disabled
96
127
  TLS cert / key ``--cert`` / ``--key`` ``cert`` / ``key`` self-signed
97
128
  Index theme ``--theme`` ``theme`` dark
129
+ Verbosity ``-v`` (repeatable) ``verbose`` 0
98
130
  ===================== ======================== ================== ==========
99
131
 
100
- Example ``webdev.toml``::
132
+ Commit a ``webdev.toml`` next to your project to share settings with your team.
133
+ Any option works as a flat key, or under a ``[tool.webdev]`` table (handy inside
134
+ a ``pyproject.toml``)::
101
135
 
136
+ # webdev.toml
102
137
  port = 3000
103
138
  force_port = true
104
139
  spa = true
105
140
  cors = true
106
141
 
107
- Design notes
108
- ============
109
-
110
- - **Framework:** Starlette + Uvicorn was chosen over a full framework such as
111
- Sanic because this is a static file server: Starlette provides exactly the
112
- primitives needed (routing, static serving, WebSockets, middleware) with a
113
- small surface, and Uvicorn handles fast binding, HTTP keep-alive, HTTPS and
114
- graceful shutdown.
115
- - **The legacy reload hack is gone.** The old server patched ``send_head`` to
116
- ``chdir`` back into the served folder; modern ``http.server`` captures the
117
- working directory in the handler constructor, so that hook stopped running and
118
- a removed folder crashed the request. ``webdev`` now resolves every request
119
- against the live filesystem, so missing folders yield a real ``404`` and
120
- recover automatically.
121
-
122
142
  Development
123
143
  ===========
124
144
 
@@ -135,12 +155,32 @@ only tool you need preinstalled::
135
155
  # Build and verify the distribution
136
156
  tox -e build
137
157
 
158
+ # Build, install in a throwaway venv and run (pass args after --)
159
+ tox -e run -- -p 3000 ./public
160
+
138
161
  Each environment declares its own tooling dependencies in ``tox.ini`` so it
139
162
  installs only what it needs.
140
163
 
141
164
  Changelog
142
165
  =========
143
166
 
167
+ 2.1.0
168
+ -----
169
+
170
+ **New**
171
+
172
+ - Plain-text, config and template files (such as ``.yaml``, ``.tpl``, ``.j2``,
173
+ ``.jinja2``, ``.template`` and ``.config``) now open inline in the browser
174
+ instead of being downloaded (issue #8). Thanks to zaro0508 for the report.
175
+
176
+ 2.0.1
177
+ -----
178
+
179
+ **Changed**
180
+
181
+ - Modernized and expanded the README (uv-first installation, refreshed feature
182
+ overview and usage).
183
+
144
184
  2.0.0
145
185
  -----
146
186
 
@@ -194,7 +234,8 @@ License
194
234
 
195
235
  ::
196
236
 
197
- Copyright (C) 2015-2026 Carlos Jenkins <carlos@jenkins.co.cr>
237
+ Copyright (C) 2026 KuraLabs S.R.L <info@kuralabs.io>
238
+ Copyright (C) 2015-2016 Carlos Jenkins <carlos@jenkins.co.cr>
198
239
 
199
240
  Licensed under the Apache License, Version 2.0 (the "License");
200
241
  you may not use this file except in compliance with the License.
@@ -0,0 +1,47 @@
1
+ """
2
+ Serve the committed ``testfiles`` fixtures and assert plain-text, config and
3
+ template files load inline in the browser instead of being downloaded.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from pathlib import Path
9
+
10
+ import pytest
11
+ from starlette.testclient import TestClient
12
+
13
+ from webdev.config import Settings
14
+ from webdev.server import create_app
15
+ from webdev.static import guess_media_type
16
+
17
+ TESTFILES = Path(__file__).parent / 'testfiles'
18
+
19
+ #: Every committed fixture, discovered dynamically.
20
+ FIXTURES = sorted(p for p in TESTFILES.iterdir() if p.is_file())
21
+
22
+ #: Content types browsers render inline rather than offering to download.
23
+ INLINE_TYPES = {'text/plain', 'application/json'}
24
+
25
+
26
+ @pytest.fixture
27
+ def testfiles_client() -> TestClient:
28
+ settings = Settings(
29
+ path=str(TESTFILES),
30
+ reload=False,
31
+ qr=False,
32
+ gzip=False,
33
+ ).normalized()
34
+ return TestClient(create_app(settings))
35
+
36
+
37
+ @pytest.mark.parametrize('fixture', FIXTURES, ids=lambda p: p.name)
38
+ def test_file_served_inline(testfiles_client: TestClient, fixture: Path) -> None:
39
+ with testfiles_client as c:
40
+ resp = c.get('/{}'.format(fixture.name))
41
+ assert resp.status_code == 200
42
+
43
+ content_type = resp.headers['content-type'].split(';')[0]
44
+ assert content_type == guess_media_type(fixture)
45
+ assert content_type in INLINE_TYPES
46
+ # The browser must render the file, never download it.
47
+ assert 'attachment' not in resp.headers.get('content-disposition', '')
@@ -46,10 +46,35 @@ def test_find_index_file(served_dir: Path) -> None:
46
46
 
47
47
 
48
48
  def test_guess_media_type_registered_extensions(tmp_path: Path) -> None:
49
- for name in ('conf.toml', 'setup.ini', 'app.cfg', 'notes.log'):
49
+ extensions = (
50
+ 'conf.toml',
51
+ 'setup.ini',
52
+ 'app.cfg',
53
+ 'notes.log',
54
+ 'config.yaml',
55
+ 'config.yml',
56
+ 'site.template',
57
+ 'page.tmpl',
58
+ 'legacy.tpl',
59
+ 'email.j2',
60
+ 'base.jinja',
61
+ 'newsletter.jinja2',
62
+ 'app.config',
63
+ )
64
+ for name in extensions:
50
65
  f = tmp_path / name
51
66
  f.write_text('key = 1')
52
- assert guess_media_type(f) == 'text/plain'
67
+ assert guess_media_type(f) == 'text/plain', name
68
+
69
+
70
+ def test_guess_media_type_txt_and_json(tmp_path: Path) -> None:
71
+ txt = tmp_path / 'notes.txt'
72
+ txt.write_text('hello')
73
+ assert guess_media_type(txt) == 'text/plain'
74
+
75
+ data = tmp_path / 'data.json'
76
+ data.write_text('{"ok": true}')
77
+ assert guess_media_type(data) == 'application/json'
53
78
 
54
79
 
55
80
  def test_guess_media_type_known_binary(tmp_path: Path) -> None:
@@ -0,0 +1,2 @@
1
+ debug = true
2
+ host = localhost
@@ -0,0 +1,2 @@
1
+ name: webdev
2
+ enabled: true
@@ -0,0 +1,2 @@
1
+ name: webdev
2
+ enabled: true
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "webdev",
3
+ "ok": true
4
+ }
@@ -0,0 +1 @@
1
+ Hello {{ name }}, this is a Jinja2 template.
@@ -0,0 +1 @@
1
+ <p>Hello {{ name }}</p>
@@ -0,0 +1 @@
1
+ Hello {{ name }}, this is a .tpl template.
@@ -0,0 +1,2 @@
1
+ [tool.webdev]
2
+ port = 8080
@@ -0,0 +1 @@
1
+ Just a plain text note.
@@ -0,0 +1,2 @@
1
+ [server]
2
+ port = 8080
@@ -0,0 +1 @@
1
+ Hello {{ name }}, this is a .template file.
@@ -25,6 +25,6 @@ index, optional HTTPS, and more.
25
25
 
26
26
  from __future__ import annotations
27
27
 
28
- __version__ = '2.0.0'
28
+ __version__ = '2.1.0'
29
29
 
30
30
  __all__ = ['__version__']
@@ -50,6 +50,13 @@ EXTRA_MIME_TYPES = {
50
50
  '.svelte': 'text/plain',
51
51
  '.yml': 'text/plain',
52
52
  '.yaml': 'text/plain',
53
+ '.template': 'text/plain',
54
+ '.tmpl': 'text/plain',
55
+ '.tpl': 'text/plain',
56
+ '.j2': 'text/plain',
57
+ '.jinja': 'text/plain',
58
+ '.jinja2': 'text/plain',
59
+ '.config': 'text/plain',
53
60
  }
54
61
 
55
62
  #: Number of bytes inspected when sniffing whether an unknown file is text.
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes