29

Say I want to use black as an API, and do something like:

import black

black.format("some python code")

Formatting code by calling the black binary with Popen is an alternative, but that's not what I'm asking.

laike9m
  • 18,344
  • 20
  • 107
  • 140
  • you may certainly need to give black a file. Because it parses the grammar based on the code and take indentation into consideration and stuff. You can see the [code](https://github.com/psf/black/blob/3dc461a41a13cc36303aff80d079786ef210ddae/blib2to3/pgen2/grammar.py#L97) – han solo Aug 26 '19 at 06:42
  • there is [blackd](https://black.readthedocs.io/en/stable/blackd.html), but that's probably even worse than using a subprocess. – Arne Aug 26 '19 at 07:04

4 Answers4

25

You could try using format_str:

from black import format_str, FileMode
res = format_str("some python code", mode=FileMode())
print(res)
Halvor Holsten Strand
  • 19,829
  • 17
  • 83
  • 99
  • 1
    @laike9m not that I'm aware, but you [can see](https://github.com/psf/black/blob/master/black.py#L424) that it is what is used if you supply the `--code` command line argument. – Halvor Holsten Strand Aug 26 '19 at 19:13
6

Use black.format_file_contents.

e.g.

import black

mode = black.FileMode()
fast = False
out = black.format_file_contents("some python code", fast, mode)

https://github.com/psf/black/blob/19.3b0/black.py#L642

Oluwafemi Sule
  • 36,144
  • 1
  • 56
  • 81
  • does not work for me make last line out = black.format_file_contents( "ex_black.py", fast = True , mode = mode ) – russ_hensel Jan 13 '23 at 19:11
  • 1
    @russ_hensel You have to pass the *contents* of the python module instead of the path of the python module. If you want to format using the path, use the [format_file_in_place function](https://github.com/psf/black/blob/19.3b0/black.py#L642) – Oluwafemi Sule Jan 14 '23 at 16:07
2

It's not officially supported, but you can call black.format_file_contents as seen in the black.format_stdin_to_stdout function.

When simplified, it's only following few lines:

import black  # version: 22.10.0

BLACK_MODE = black.Mode(target_versions={black.TargetVersion.PY311}, line_length=120)

code = ...  # some python code to reformat

try:
    code = black.format_file_contents(code, fast=False, mode=BLACK_MODE)
except black.NothingChanged:
    pass
finally:
    # Make sure there's a newline after the content
    if code and code[-1] != "\n":
        code += "\n"

print(code)  # print result
1

Does Black have an API?

Not yet. Black is fundamentally a command line tool. Many integrations are provided, but a Python interface is not one of them. A simple API is being planned though.

For now, you should call black using subprocess. The other answers which import black are unsupported and likely to break without warning.

Watch issue Black's public API #779 for possible further developments.

(source: the same question in black's FAQ page)

wim
  • 338,267
  • 99
  • 616
  • 750