Output Multi-line strings with Python Flask or other framework

13,128

Solution 1

Both Bottle and Flask can handle multi-line strings just fine. Your issue is that your data is being interpreted as text/html by default and in HTML any combination of whitespace is collapsed into a single space when displayed. In order to ensure that your data comes back exactly as you sent it you'll want to set the Content-Type header to text/plain.

In Flask:

# If you want *all* your responses to be text/plain
# then this is what you want
@app.after_request
def treat_as_plain_text(response):
    response.headers["content-type"] = "text/plain"
    return response

# If you want only *this* route to respond
# with Content-Type=text/plain
@app.route("/plain-text")
def a_plain_text_route():
    response = make_response(getKickstartFile())
    response.headers["content-type"] = "text/plain"
    return response

In Bottle:

@route("/plain-text")
def plain_text():
    response.content_type = "text/plain"
    return """This
              multi-line string
              will show up
              just fine"""

Solution 2

Sean's answer is the correct way to go, but if you just want to test something you could use the xmp tag:

@app.route("/"):
def hello():
    return """<xmp>
              Hello,
              Multiline!
              </xmp>"""

decorator version

You could also create your own decorator for this:

from functools import wraps

def multiline(fn):
    @wraps(fn)
    def _fn(*args, **kwargs):
        return "<xmp>" + fn(*args, **kwargs) + "</xmp>"
    return _fn

Then you can do:

    @app.route("/"):
    @multiline
    def hello():
    return """Hello,
              Multiline!"""
Share:
13,128

Related videos on Youtube

lumberjacked
Author by

lumberjacked

Updated on September 14, 2022

Comments

  • lumberjacked
    lumberjacked about 1 year

    I am trying to take Redhat kickstart files and modify them in python before using them in a server setup. My app uses python to curl the original kickstart file from my Redhat Satellite server then I'm doing a string replace on certain values in the kickstart file. When I curl the file in python it comes back as a multi-line string, which is what I need in order for redhat kickstart to interpret the file correctly. But when I return the string variable through one of these frameworks (web2py, bottle, flask) something is happening and it is not returning it as a multi-line string, I need it to preserve the exact format of the original file besides the areas I change. I don't want to put my kickstart files in templates because I manage them through satellite, if I curl the file from satellite then it picks up any modifications without needing to go into the template ever time. Then in a template or something I either return the string without a template or in a template file I only pass 1 variable to the template as the entire kickstart file.

    @route('/kickstart/<name>')
    def kickstart(name):
    
        ks = vula.kickstarter.kickstart.Kickstarter()
        ks_file = ks.getKickstartFile()
    
        return pystache.render('{{kickstart}}', {'kickstart': ks_file})
    

    Here is the method in my vula package. It returns the file exactly the way I need it. But again something is happening between this and returning this value through the framework.

    def getKickstartFile(self):
    
        response = urllib2.urlopen('https://my-satellite-server/core-kickstarter')
        ks_file = response.read()
    
        return ks_file
    

    I started off using Bottle as a framework but I found a statement that says they are not capable of returning multi-line strings, so scratch that. I moved over to Flask but currently Flask is doing the same thing. I am still learning python and possibly I'm doing something wrong, but I need any help possible to get this working correctly. I would like to output a multi-line string. I understand that you use either

    """ or '''
    

    for multi-line strings, but even after you do that and send it through a framework it will still print to the screen as one continuous line. What am I doing wrong? As a vary last resort I will be forced to put the kickstart files into templates if I cannot output multi-line strings.

  • lumberjacked
    lumberjacked over 10 years
    After reading your post I was able to find the documentation in Flask explaining this. Thanks for the help.