Skip to main content

Python Code Formatter

Clean up Python source: normalize existing indentation to a consistent width, tidy comma/operator spacing, collapse long blank-line runs, and trim trailing whitespace — without touching triple-quoted strings, f-strings, or comments.

Input

Drop a file or browse
One file · text
Or

Formatting Options

Output

Formatted Code
 
Was this helpful?

Guides

Paste messy Python and get back cleaner, more consistent source — instantly, in your browser. The Python Code Formatter normalizes indentation to a consistent width, tidies spacing around commas and operators, collapses long runs of blank lines, and trims trailing whitespace, without touching the content of strings, f-strings, or comments.

An important honesty note

This tool is a whitespace/style normalizer, not a full PEP 8 or Black-equivalent formatter. In a brace-based language (Java, PHP, JavaScript...), a formatter can safely re-derive indentation from scratch by counting {/} pairs — brace depth is block structure. Python has no braces: indentation itself is the block structure. Rebuilding it correctly from nothing needs a real parser — get it wrong and you don't just misalign a line, you can change which lines belong to which block.

So instead of guessing new block structure, this tool takes the indentation you already wrote and remaps it onto a consistent depth, the same "INDENT/DEDENT" technique CPython's own tokenizer uses: it walks your existing indentation as a stack of levels and re-emits each level at your chosen width, even if the file mixes 2-space, 4-space, and tab indentation, or grows each nested level unevenly. It never invents an indent level that wasn't already present.

How to use it

  1. Paste your Python source, or upload a .py file.
  2. Pick your Indent width (2, 4, or 8 spaces, or tabs — 4 spaces is the PEP 8 default).
  3. Toggle Normalize comma & operator spacing and Normalize blank lines to taste.
  4. Copy the result, or download it as formatted.py.

Formatting runs automatically as you type or change an option.

What it normalizes

  • Indentation, remapped as described above. Lines inside an open (/[/{ or after a trailing \ continuation are left exactly as authored — that's your own alignment choice, not a block boundary.
  • Comma spacing — no space before, exactly one space after.
  • Operator spacing — an unambiguous set gets forced single-space padding: ==, !=, <=, >=, ->, :=, and the augmented-assignment operators (+=, -=, *=, /=, //=, %=, **=, &=, |=, ^=, >>=, <<=).
  • Blank lines — runs of 3+ collapse to 2.
  • Trailing whitespace — stripped from every code line.

What it deliberately leaves alone

  • A bare =. Telling an assignment (x = 1, wants spaces) from a keyword argument or default (f(x=1), must stay tight) requires knowing whether you're inside a call or def signature — exactly the parsing this tool avoids. Your = spacing passes through unchanged.
  • Quote style, import sorting, and line wrapping — all three need real semantic understanding to do without risking corrupting meaning.
  • Anything inside a string. Triple-quoted strings ('''...'''/"""...""") are preserved byte-for-byte — including internal indentation, blank lines, and trailing spaces — since they're often used for exact-format text like docstring examples. F-string {expr} interpolation is treated as opaque and never reformatted.
  • Comment text itself — only the whitespace before a # is touched; everything from # onward is copied through verbatim.

Is it the same as Black or autopep8?

No. Black and autopep8 parse Python into a real syntax tree, so they can safely rewrap lines, normalize quotes, and rebuild indentation from nothing. This tool works on text and existing whitespace — a fast, dependency-free cleanup for pasted snippets or generated code with inconsistent indentation, not a replacement for your project's formatter in CI.

Is my code private?

Completely. All formatting happens locally in your browser. Your source is never sent to a server, logged, or stored.

Does it handle f-strings and decorators?

Yes. F-strings (any prefix combination, like rf or Fr) are tokenized as whole strings, so their content — including {expr} interpolation — is never touched. Decorators (@decorator) and block-opening colons (if x:, def f():) need no special handling: they're ordinary code whose indentation is carried by the same depth-remapping as everything else.

pythoncode formatterbeautifyindentpep8whitespace

Use it from code

From 3 credits per call

REST API

curl -X POST https://api.iotools.cloud/v1/tool/python-code-formatter \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "pythonInput": "class Greeter:\n  def __init__(self, name):\n     …",
    "indent": "4",
    "normalizeSpacing": "true",
    "normalizeBlankLines": "true"
  }'

Swap in your own key from your account. The tool's fields are the body — no wrapper.

Ask an AI agent

Use the IOTools `python-code-formatter` tool (Python Code Formatter) on this input:

YOUR_INPUT_HERE

Paste this at any agent connected to the IOTools MCP server, then add your input.

Love the tools? Lose the ads.

One payment clears every ad from your account, for good. No subscription, no tracking.