web-dev-qa-db-fra.com

Python Flask, comment définir le type de contenu

J'utilise Flask et je retourne un fichier XML à partir d'une requête get. Comment définir le type de contenu?

par exemple.

@app.route('/ajax_ddl')
def ajax_ddl():
    xml = 'foo'
    header("Content-type: text/xml")
    return xml
142
Tampa

Essayez comme ça:

from flask import Response
@app.route('/ajax_ddl')
def ajax_ddl():
    xml = 'foo'
    return Response(xml, mimetype='text/xml')

Le type de contenu réel est basé sur le paramètre mimetype et le jeu de caractères (par défaut, UTF-8).

Les objets de réponse (et de demande) sont documentés ici: http://werkzeug.pocoo.org/docs/wrappers/

196
Simon Sapin

Aussi simple que cela

x = "some data you want to return"
return x, 200, {'Content-Type': 'text/css; charset=utf-8'}

J'espère que ça aide

Mise à jour: Utilisez cette méthode car elle fonctionnera à la fois avec Python 2.x et 3.x

et deuxièmement, cela élimine également le problème de plusieurs en-têtes.

from flask import Response
r = Response(response="TEST OK", status=200, mimetype="application/xml")
r.headers["Content-Type"] = "text/xml; charset=utf-8"
return r
117
Harsh Daftary

J'aime et j'ai bien voté la réponse de @Simon Sapin. Cependant, j'ai fini par adopter une approche légèrement différente et j'ai créé mon propre décorateur:

from flask import Response
from functools import wraps

def returns_xml(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        r = f(*args, **kwargs)
        return Response(r, content_type='text/xml; charset=utf-8')
    return decorated_function

et utilisez-le ainsi:

@app.route('/ajax_ddl')
@returns_xml
def ajax_ddl():
    xml = 'foo'
    return xml

Je pense que c'est légèrement plus confortable.

37
Michael Wolf

Utilisez la méthode make_response pour obtenir une réponse avec vos données. Puis définissez l'attribut mimetype . Finalement, retournez cette réponse:

@app.route('/ajax_ddl')
def ajax_ddl():
    xml = 'foo'
    resp = app.make_response(xml)
    resp.mimetype = "text/xml"
    return resp

Si vous utilisez directement Response, vous perdez la possibilité de personnaliser les réponses en définissant app.response_class. La méthode make_response utilise le app.responses_class pour créer l'objet de réponse. En cela, vous pouvez créer votre propre classe, ajouter que votre application l’utilise de manière globale:

class MyResponse(app.response_class):
    def __init__(self, *args, **kwargs):
        super(MyResponse, self).__init__(*args, **kwargs)
        self.set_cookie("last-visit", time.ctime())

app.response_class = MyResponse  
20
Marianna Vassallo
from flask import Flask, render_template, make_response
app = Flask(__name__)

@app.route('/user/xml')
def user_xml():
    resp = make_response(render_template('xml/user.html', username='Ryan'))
    resp.headers['Content-type'] = 'text/xml; charset=utf-8'
    return resp
11
Ryan Liu

Généralement, vous n’avez pas à créer vous-même l’objet Response parce que make_response() s’occupe de cela pour vous.

from flask import Flask, make_response                                      
app = Flask(__name__)                                                       

@app.route('/')                                                             
def index():                                                                
    bar = '<body>foo</body>'                                                
    response = make_response(bar)                                           
    response.headers['Content-Type'] = 'text/xml; charset=utf-8'            
    return response

Une dernière chose, il semble que personne n’a mentionné le after_this_request , je veux dire quelque chose:

after_this_request

Exécute une fonction après cette demande. Ceci est utile pour modifier les objets de réponse. La fonction reçoit l'objet de réponse et doit renvoyer le même ou un nouveau.

afin que nous puissions le faire avec after_this_request , le code devrait ressembler à ceci:

from flask import Flask, after_this_request
app = Flask(__name__)

@app.route('/')
def index():
    @after_this_request
    def add_header(response):
        response.headers['Content-Type'] = 'text/xml; charset=utf-8'
        return response
    return '<body>foobar</body>'
5
lord63. j

Vous pouvez essayer la méthode suivante (python3.6.2):

cas un :

@app.route('/hello')
def hello():

    headers={ 'content-type':'text/plain' ,'location':'http://www.stackoverflow'}
    response = make_response('<h1>hello world</h1>',301)
    response.headers = headers
    return response

cas deux :

@app.route('/hello')
def hello():

    headers={ 'content-type':'text/plain' ,'location':'http://www.stackoverflow.com'}
    return '<h1>hello world</h1>',301,headers

J'utilise Flask. Et si vous voulez retourner JSON, vous pouvez écrire ceci:

import json # 
@app.route('/search/<keyword>')
def search(keyword):

    result = Book.search_by_keyword(keyword)
    return json.dumps(result),200,{'content-type':'application/json'}


from flask import jsonify
@app.route('/search/<keyword>')
def search(keyword):

    result = Book.search_by_keyword(keyword)
    return jsonify(result)
0
zhengGuo