Black as a server (blackd)¶
blackd is a small HTTP server that exposes Black’s functionality over a simple
protocol. The main benefit of using it is to avoid the cost of starting up a new Black
process every time you want to blacken a file.
Warning
blackd should not be run as a publicly accessible server as there are no security
precautions in place to prevent abuse. It is intended for local use only.
Usage¶
blackd is not packaged alongside Black by default because it has additional
dependencies. You will need to execute pip install 'black[d]' to install it.
You can start the server on the default port, binding only to the local interface by
running blackd. You will see a single line mentioning the server’s version, and the
host and port it’s listening on. blackd will then print an access log similar to most
web servers on standard output, merged with any exception traces caused by invalid
formatting requests.
blackd provides even less options than Black. You can see them by running
blackd --help:
You can test that blackd is working using curl:
blackd --bind-port 9090 & # or let blackd choose a port
curl -s -XPOST "localhost:9090" -d "print('valid')"
Or using the python client:
import asyncio
from blackd.client import BlackDClient
async def main():
client = BlackDClient(url="http://127.0.0.1:9090")
unformatted_code = "def hello(): print('Hello, World!')"
formatted_code = await client.format_code(unformatted_code)
print(formatted_code)
if __name__ == "__main__":
asyncio.run(main())
Cross-origin browser requests are rejected by default. If you need to access blackd
from a browser-based client, pass one or more --cors-allow-origin options to allow
specific origins.
Protocol¶
blackd only accepts POST requests at the / path. The body of the request should
contain the python source code to be formatted, encoded according to the charset field
in the Content-Type request header. If no charset is specified, blackd assumes
UTF-8. Request bodies are limited to 5 MiB by default; use --max-body-size to change
that limit.
There are a few HTTP headers that control how the source code is formatted. These
correspond to command line flags for Black. There is one exception to this:
X-Protocol-Version which if present, should have the value 1, otherwise the request
is rejected with HTTP 501 (Not Implemented).
The headers controlling how source code is formatted are:
X-Line-Length: corresponds to the--line-lengthcommand line flag.X-Skip-Source-First-Line: corresponds to the--skip-source-first-linecommand line flag. If present and its value is not an empty string, the first line of the source code will be ignored.X-Skip-String-Normalization: corresponds to the--skip-string-normalizationcommand line flag. If present and its value is not the empty string, no string normalization will be performed.X-Skip-Magic-Trailing-Comma: corresponds to the--skip-magic-trailing-commacommand line flag. If present and its value is not an empty string, trailing commas will not be used as a reason to split lines.X-Preview: corresponds to the--previewcommand line flag. If present and its value is not an empty string, experimental and potentially disruptive style changes will be used.X-Unstable: corresponds to the--unstablecommand line flag. If present and its value is not an empty string, experimental style changes that are known to be buggy will be used.X-Enable-Unstable-Feature: corresponds to the--enable-unstable-featureflag. The contents of the flag must be a comma-separated list of unstable features to be enabled. Example:X-Enable-Unstable-Feature: feature1, feature2.X-Fast-Or-Safe: if set tofast,blackdwill act as Black does when passed the--fastcommand line flag.X-Python-Variant: if set topyi,blackdwill act as Black does when passed the--pyicommand line flag. Otherwise, its value must correspond to a Python version or a set of comma-separated Python versions, optionally prefixed withpy. For example, to request code that is compatible with Python 3.5 and 3.6, set the header topy3.5,py3.6.X-Diff: corresponds to the--diffcommand line flag. If present, a diff of the formats will be output.
If any of these headers are set to invalid values, blackd returns a HTTP 400 error
response, mentioning the name of the problematic header in the message body.
Apart from the above, blackd can produce the following response codes:
HTTP 204: If the input is already well-formatted. The response body is empty.HTTP 200: If formatting was needed on the input. The response body contains the blackened Python code, and theContent-Typeheader is set accordingly.HTTP 400: If the input contains a syntax error. Details of the error are returned in the response body.HTTP 500: If there was any other kind of error while trying to format the input. The response body contains a textual representation of the error.
The response headers include a X-Black-Version header containing the version of
Black.