Add black version header to blackd responses (#1046)
This commit is contained in:
parent
57ab909bde
commit
73bd7038fb
@ -893,6 +893,9 @@ Apart from the above, `blackd` can produce the following response codes:
|
|||||||
- `HTTP 500`: If there was any kind of error while trying to format the input.
|
- `HTTP 500`: If there was any kind of error while trying to format the input.
|
||||||
The response body contains a textual representation of the error.
|
The response body contains a textual representation of the error.
|
||||||
|
|
||||||
|
The response headers include a `X-Black-Version` header containing the version
|
||||||
|
of *Black*.
|
||||||
|
|
||||||
## Version control integration
|
## Version control integration
|
||||||
|
|
||||||
Use [pre-commit](https://pre-commit.com/). Once you [have it
|
Use [pre-commit](https://pre-commit.com/). Once you [have it
|
||||||
@ -1051,6 +1054,8 @@ More details can be found in [CONTRIBUTING](CONTRIBUTING.md).
|
|||||||
* *Black* is now able to format Python code that uses positional-only
|
* *Black* is now able to format Python code that uses positional-only
|
||||||
arguments (`/` as described in PEP-570) (#946)
|
arguments (`/` as described in PEP-570) (#946)
|
||||||
|
|
||||||
|
* `blackd` now returns the version of *Black* in the response headers (#1013)
|
||||||
|
|
||||||
|
|
||||||
### 19.3b0
|
### 19.3b0
|
||||||
|
|
||||||
|
24
blackd.py
24
blackd.py
@ -10,23 +10,29 @@
|
|||||||
import black
|
import black
|
||||||
import click
|
import click
|
||||||
|
|
||||||
|
from _version import version as __version__
|
||||||
|
|
||||||
# This is used internally by tests to shut down the server prematurely
|
# This is used internally by tests to shut down the server prematurely
|
||||||
_stop_signal = asyncio.Event()
|
_stop_signal = asyncio.Event()
|
||||||
|
|
||||||
VERSION_HEADER = "X-Protocol-Version"
|
# Request headers
|
||||||
|
PROTOCOL_VERSION_HEADER = "X-Protocol-Version"
|
||||||
LINE_LENGTH_HEADER = "X-Line-Length"
|
LINE_LENGTH_HEADER = "X-Line-Length"
|
||||||
PYTHON_VARIANT_HEADER = "X-Python-Variant"
|
PYTHON_VARIANT_HEADER = "X-Python-Variant"
|
||||||
SKIP_STRING_NORMALIZATION_HEADER = "X-Skip-String-Normalization"
|
SKIP_STRING_NORMALIZATION_HEADER = "X-Skip-String-Normalization"
|
||||||
FAST_OR_SAFE_HEADER = "X-Fast-Or-Safe"
|
FAST_OR_SAFE_HEADER = "X-Fast-Or-Safe"
|
||||||
|
|
||||||
BLACK_HEADERS = [
|
BLACK_HEADERS = [
|
||||||
VERSION_HEADER,
|
PROTOCOL_VERSION_HEADER,
|
||||||
LINE_LENGTH_HEADER,
|
LINE_LENGTH_HEADER,
|
||||||
PYTHON_VARIANT_HEADER,
|
PYTHON_VARIANT_HEADER,
|
||||||
SKIP_STRING_NORMALIZATION_HEADER,
|
SKIP_STRING_NORMALIZATION_HEADER,
|
||||||
FAST_OR_SAFE_HEADER,
|
FAST_OR_SAFE_HEADER,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Response headers
|
||||||
|
BLACK_VERSION_HEADER = "X-Black-Version"
|
||||||
|
|
||||||
|
|
||||||
class InvalidVariantHeader(Exception):
|
class InvalidVariantHeader(Exception):
|
||||||
pass
|
pass
|
||||||
@ -65,8 +71,9 @@ def make_app() -> web.Application:
|
|||||||
|
|
||||||
|
|
||||||
async def handle(request: web.Request, executor: Executor) -> web.Response:
|
async def handle(request: web.Request, executor: Executor) -> web.Response:
|
||||||
|
headers = {BLACK_VERSION_HEADER: __version__}
|
||||||
try:
|
try:
|
||||||
if request.headers.get(VERSION_HEADER, "1") != "1":
|
if request.headers.get(PROTOCOL_VERSION_HEADER, "1") != "1":
|
||||||
return web.Response(
|
return web.Response(
|
||||||
status=501, text="This server only supports protocol version 1"
|
status=501, text="This server only supports protocol version 1"
|
||||||
)
|
)
|
||||||
@ -110,15 +117,18 @@ async def handle(request: web.Request, executor: Executor) -> web.Response:
|
|||||||
executor, partial(black.format_file_contents, req_str, fast=fast, mode=mode)
|
executor, partial(black.format_file_contents, req_str, fast=fast, mode=mode)
|
||||||
)
|
)
|
||||||
return web.Response(
|
return web.Response(
|
||||||
content_type=request.content_type, charset=charset, text=formatted_str
|
content_type=request.content_type,
|
||||||
|
charset=charset,
|
||||||
|
headers=headers,
|
||||||
|
text=formatted_str,
|
||||||
)
|
)
|
||||||
except black.NothingChanged:
|
except black.NothingChanged:
|
||||||
return web.Response(status=204)
|
return web.Response(status=204, headers=headers)
|
||||||
except black.InvalidInput as e:
|
except black.InvalidInput as e:
|
||||||
return web.Response(status=400, text=str(e))
|
return web.Response(status=400, headers=headers, text=str(e))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception("Exception during handling a request")
|
logging.exception("Exception during handling a request")
|
||||||
return web.Response(status=500, text=str(e))
|
return web.Response(status=500, headers=headers, text=str(e))
|
||||||
|
|
||||||
|
|
||||||
def parse_python_variant_header(value: str) -> Tuple[bool, Set[black.TargetVersion]]:
|
def parse_python_variant_header(value: str) -> Tuple[bool, Set[black.TargetVersion]]:
|
||||||
|
@ -1569,7 +1569,7 @@ async def test_blackd_request_syntax_error(self) -> None:
|
|||||||
@unittest_run_loop
|
@unittest_run_loop
|
||||||
async def test_blackd_unsupported_version(self) -> None:
|
async def test_blackd_unsupported_version(self) -> None:
|
||||||
response = await self.client.post(
|
response = await self.client.post(
|
||||||
"/", data=b"what", headers={blackd.VERSION_HEADER: "2"}
|
"/", data=b"what", headers={blackd.PROTOCOL_VERSION_HEADER: "2"}
|
||||||
)
|
)
|
||||||
self.assertEqual(response.status, 501)
|
self.assertEqual(response.status, 501)
|
||||||
|
|
||||||
@ -1578,7 +1578,7 @@ async def test_blackd_unsupported_version(self) -> None:
|
|||||||
@unittest_run_loop
|
@unittest_run_loop
|
||||||
async def test_blackd_supported_version(self) -> None:
|
async def test_blackd_supported_version(self) -> None:
|
||||||
response = await self.client.post(
|
response = await self.client.post(
|
||||||
"/", data=b"what", headers={blackd.VERSION_HEADER: "1"}
|
"/", data=b"what", headers={blackd.PROTOCOL_VERSION_HEADER: "1"}
|
||||||
)
|
)
|
||||||
self.assertEqual(response.status, 200)
|
self.assertEqual(response.status, 200)
|
||||||
|
|
||||||
@ -1669,6 +1669,13 @@ async def test_blackd_invalid_line_length(self) -> None:
|
|||||||
)
|
)
|
||||||
self.assertEqual(response.status, 400)
|
self.assertEqual(response.status, 400)
|
||||||
|
|
||||||
|
@skip_if_exception("ClientOSError")
|
||||||
|
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
|
||||||
|
@unittest_run_loop
|
||||||
|
async def test_blackd_response_black_version_header(self) -> None:
|
||||||
|
response = await self.client.post("/")
|
||||||
|
self.assertIsNotNone(response.headers.get(blackd.BLACK_VERSION_HEADER))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main(module="test_black")
|
unittest.main(module="test_black")
|
||||||
|
Loading…
Reference in New Issue
Block a user