Werkzeug: Fails to color Windows console

Created on 3 May 2020  ·  6Comments  ·  Source: pallets/werkzeug

On windows the new Flask prints weird characters on console, instead of coloring the line as on linux. eg: "←[37m

I would rather go black/white (like in previous version) if coloring doesnt work.

2020-05-03 14:05:47,398 - INFO - 127.0.0.1 - - [03/May/2020 14:05:47] "←[37mGET /result HTTP/1.1←[0m" 200 -
2020-05-03 14:06:42,922 - INFO - 127.0.0.1 - - [03/May/2020 14:06:42] "←[37mGET /result HTTP/1.1←[0m" 200 -
2020-05-03 14:07:24,007 - INFO - 127.0.0.1 - - [03/May/2020 14:07:24] "←[37mGET /result HTTP/1.1←[0m" 200 -
2020-05-03 14:07:24,210 - INFO - 127.0.0.1 - - [03/May/2020 14:07:24] "←[37mGET /static/images/favicon.ico HTT
2020-05-03 14:08:19,539 - INFO - 127.0.0.1 - - [03/May/2020 14:08:19] "←[37mGET /result HTTP/1.1←[0m" 200 -
2020-05-03 14:09:15,065 - INFO - 127.0.0.1 - - [03/May/2020 14:09:15] "←[37mGET /result HTTP/1.1←[0m" 200 -
2020-05-03 14:10:10,579 - INFO - 127.0.0.1 - - [03/May/2020 14:10:10] "←[37mGET /result HTTP/1.1←[0m" 200 -

Env:
Flask==1.1.2
Win7 x64
Python 3.6.7 x64
Werkzeug==1.0.1

bug

Most helpful comment

I was able to correct the issue by adding the following code to my flask app

import os
import sys

if sys.platform.lower() == "win32": 
    os.system('color')

See https://stackoverflow.com/questions/287871/how-to-print-colored-text-in-python for details.

It seems that the double brackets are being filtered in the logs as @mrx23dot suggested.

All 6 comments

I was unable to duplicate.

Command Prompt view:
image

Pycharm Terminal:
image

PyCharm Run:
image

I'm running Windows 10 x64, Python 3.7.4, flask 1.1.2, Werkzeug 1.0.1

I'm not really sure how to explain this. If anything, is an issue with Click, but Click isn't supposed to emit color info on Windows if colorama isn't installed. I have seen more reports of this since switching to Click, but it's not consistent, as shown in the previous screenshots.

Tested on Win7 and Win10 same issue, although I see coloring working, just not for REST calls:
2020-05-04_215343

I have these installed:
click==7.1.1
colorama==0.4.3
coloredlogs==14.0

These all work with coloring:
from colorama import Fore, Back, Style
print(Fore.RED + 'some red text')
print('033[31m' + 'some red text')

import click
click.echo('033[31m' + 'some red text')

from Flask:
"←[37mGET " <- this might be escaped invalidly in the code (needs double back slashes?), it worked for me with single

I was able to correct the issue by adding the following code to my flask app

import os
import sys

if sys.platform.lower() == "win32": 
    os.system('color')

See https://stackoverflow.com/questions/287871/how-to-print-colored-text-in-python for details.

It seems that the double brackets are being filtered in the logs as @mrx23dot suggested.

I spent some more time investigating this issue. The color addition comes from click.style. Here's the relevant code from serving.WSGIRequestHandler:

def log_request(self, code="-", size="-") -> None:
        try:
            path = uri_to_iri(self.path)
            msg = f"{self.command} {path} {self.request_version}"
        except AttributeError:
            # path isn't set if the requestline was bad
            msg = self.requestline

        code = str(code)

        if click:
            color = click.style

            if code[0] == "1":  # 1xx - Informational
                msg = color(msg, bold=True)
            elif code[0] == "2":  # 2xx - Success
                msg = color(msg, fg="white")
            elif code == "304":  # 304 - Resource Not Modified
                msg = color(msg, fg="cyan")
            elif code[0] == "3":  # 3xx - Redirection
                msg = color(msg, fg="green")
            elif code == "404":  # 404 - Resource Not Found
                msg = color(msg, fg="yellow")
            elif code[0] == "4":  # 4xx - Client Error
                msg = color(msg, fg="red", bold=True)
            else:  # 5xx, or any other response
                msg = color(msg, fg="magenta", bold=True)

        self.log("info", '"%s" %s %s', msg, code, size)

You can see that the click.style function is simply wrapping the initial message in ANSI style codes. For Linux and OS X, ANSI codes are supported by default, so those users won't notice this issue. However, on Windows, the terminal does not support this by default. If using Windows 10, a simple workaround is to use the following command to enable ANSI styling:

import sys
import os

if sys.platform.lower() == 'win32':
    os.system('color')

This will address most users with the issue, but might not fix some edge cases (e.g. small-footprint or embedded unix distros). The os.system('color') (or really any os.system call) can be put almost anywhere in the code base. As long as it is called before the output is printed, the output will show up properly colored. This is probably why users of PyCharm don't notice the bug. The PyCharm python terminal likely makes an os.system call to handle colored text output.

So the way I see it there are 2 questions:

  1. Should werkzeug fix this minor issue or leave the burden on Windows 10 users to call os.system?
  2. If we fix this in werkzeug, where should we add the os.system call? It only needs to be called once, so perhaps it could be added to WSGIRequestHandler.__init__? There are probably better options, but that's all I can think of right now.

I was able to correct the issue by adding the following code to my flask app

import os
import sys

if sys.platform.lower() == "win32": 
    os.system('color')

See https://stackoverflow.com/questions/287871/how-to-print-colored-text-in-python for details.

It seems that the double brackets are being filtered in the logs as @mrx23dot suggested.

Thanks. add the code in config.py , it's works for me. 😀

Was this page helpful?
0 / 5 - 0 ratings

Related issues

evanlurvey picture evanlurvey  ·  22Comments

davidism picture davidism  ·  9Comments

KangOl picture KangOl  ·  16Comments

paihu picture paihu  ·  7Comments

miki725 picture miki725  ·  10Comments