标签归档:flask

在烧瓶中返回HTTP状态代码201

问题:在烧瓶中返回HTTP状态代码201

我们正在使用Flask作为我们的API之一,我只是想知道是否有人知道如何返回HTTP响应201?

对于诸如404之类的错误,我们可以调用:

from flask import abort
abort(404)

但是对于201我得到

LookupError:201也不exceptions

我是否需要创建自己的exceptions,像这样的文档?

We’re using Flask for one of our API’s and I was just wondering if anyone knew how to return a HTTP response 201?

For errors such as 404 we can call:

from flask import abort
abort(404)

But for 201 I get

LookupError: no exception for 201

Do I need to create my own exception like this in the docs?


回答 0

您可以在这里阅读

return render_template('page.html'), 201

You can read about it here.

return render_template('page.html'), 201

回答 1

您可以使用Response返回任何http状态代码。

> from flask import Response
> return Response("{'a':'b'}", status=201, mimetype='application/json')

You can use Response to return any http status code.

> from flask import Response
> return Response("{'a':'b'}", status=201, mimetype='application/json')

回答 2

由于缺乏建议,所以在return语句中发送状态代码,如果您将其存储在某些变量中,例如

notfound = 404
invalid = 403
ok = 200

和使用

return xyz, notfound

一定要确保其类型为int not str。当我遇到这个小问题时,这也是状态代码列表,在全球范围内 http://www.w3.org/Protocols/HTTP/HTRESP.html

希望能帮助到你。

As lacks suggested send status code in return statement and if you are storing it in some variable like

notfound = 404
invalid = 403
ok = 200

and using

return xyz, notfound

than time make sure its type is int not str. as I faced this small issue also here is list of status code followed globally http://www.w3.org/Protocols/HTTP/HTRESP.html

Hope it helps.


回答 3

你可以做

result = {'a': 'b'}
return jsonify(result), 201

如果您想在响应中返回JSON数据以及错误代码,请在此处此处阅读有关响应的信息,以获取make_response API详细信息

You can do

result = {'a': 'b'}
return jsonify(result), 201

if you want to return a JSON data in the response along with the error code You can read about responses here and here for make_response API details


回答 4

理想情况下,在烧瓶代码中,还应尽可能频繁地指定MIME类型:

return html_page_str, 200, {'ContentType':'text/html'}

return json.dumps({'success':True}), 200, {'ContentType':'application/json'}

…等等

In your flask code, you should ideally specify the MIME type as often as possible, as well:

return html_page_str, 200, {'ContentType':'text/html'}

return json.dumps({'success':True}), 200, {'ContentType':'application/json'}

…etc


回答 5

您还可以使用flask_api发送响应

from flask_api import status

@app.route('/your-api/')
def empty_view(self):
    content = {'your content here'}
    return content, status.HTTP_201_CREATED

您可以在这里找到参考http://www.flaskapi.org/api-guide/status-codes/

you can also use flask_api for sending response

from flask_api import status

@app.route('/your-api/')
def empty_view(self):
    content = {'your content here'}
    return content, status.HTTP_201_CREATED

you can find reference here http://www.flaskapi.org/api-guide/status-codes/


回答 6

根据API的创建方式,通常返回201(创建),您将返回创建的资源。例如,如果它正在创建一个用户帐户,您将执行以下操作:

return {"data": {"username": "test","id":"fdsf345"}}, 201

请注意,后缀数字是返回的状态码。

或者,您可能希望向客户端发送一条消息,例如:

return {"msg": "Created Successfully"}, 201

Dependent on how the API is created, normally with a 201 (created) you would return the resource which was created. For example if it was creating a user account you would do something like:

return {"data": {"username": "test","id":"fdsf345"}}, 201

Note the postfixed number is the status code returned.

Alternatively, you may want to send a message to the client such as:

return {"msg": "Created Successfully"}, 201

回答 7

就我而言,我必须将上述内容组合在一起才能使其正常工作

return Response(json.dumps({'Error': 'Error in payload'}), 
status=422, 
mimetype="application/json")

In my case I had to combine the above in order to make it work

return Response(json.dumps({'Error': 'Error in payload'}), 
status=422, 
mimetype="application/json")

回答 8

因此,如果您使用flask_restfulAPI的Package ,则返回201会像

def bla(*args, **kwargs):
    ...
    return data, 201

哪里data应该是任何hashable / JsonSerialiable值,例如dict,string。

So, if you are using flask_restful Package for API’s returning 201 would becomes like

def bla(*args, **kwargs):
    ...
    return data, 201

where data should be any hashable/ JsonSerialiable value, like dict, string.


在Flask中重定向到URL

问题:在Flask中重定向到URL

我是Python和Flask的新手,我正在尝试做与Response.redirectC#中相同的操作-即:重定向到特定的URL-我该如何处理?

这是我的代码:

import os
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello World!'

if __name__ == '__main__':
    # Bind to PORT if defined, otherwise default to 5000.
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)

I’m new to Python and Flask and I’m trying to do the equivalent of Response.redirect as in C# – ie: redirect to a specific URL – how do I go about this?

Here is my code:

import os
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello World!'

if __name__ == '__main__':
    # Bind to PORT if defined, otherwise default to 5000.
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)

回答 0

您必须返回重定向:

import os
from flask import Flask,redirect

app = Flask(__name__)

@app.route('/')
def hello():
    return redirect("http://www.example.com", code=302)

if __name__ == '__main__':
    # Bind to PORT if defined, otherwise default to 5000.
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)

请参阅flask文档上的文档。代码的默认值为302,因此code=302可以省略或替换为其他重定向代码(301、302、303、305和307中的一个)。

You have to return a redirect:

import os
from flask import Flask,redirect

app = Flask(__name__)

@app.route('/')
def hello():
    return redirect("http://www.example.com", code=302)

if __name__ == '__main__':
    # Bind to PORT if defined, otherwise default to 5000.
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)

See the documentation on flask docs. The default value for code is 302 so code=302 can be omitted or replaced by other redirect code (one in 301, 302, 303, 305, and 307).


回答 1

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
from flask import Flask, redirect, url_for

app = Flask(__name__)

@app.route('/')
def hello():
    return redirect(url_for('foo'))

@app.route('/foo')
def foo():
    return 'Hello Foo!'

if __name__ == '__main__':
    # Bind to PORT if defined, otherwise default to 5000.
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)

看一下文档中的示例

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
from flask import Flask, redirect, url_for

app = Flask(__name__)

@app.route('/')
def hello():
    return redirect(url_for('foo'))

@app.route('/foo')
def foo():
    return 'Hello Foo!'

if __name__ == '__main__':
    # Bind to PORT if defined, otherwise default to 5000.
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)

Take a look at the example in the documentation.


回答 2

Flask API文档(v。0.10):

烧瓶。重定向locationcode=302Response=None

返回一个响应对象(WSGI应用程序),如果调用该对象,它将客户端重定向到目标位置。支持的代码为301、302、303、305和307。不支持300,因为它不是真正的重定向;而由于它是带有定义的If-Modified-Since标头的请求的答案,因此不支持304。

0.6版的新增功能:该位置现在可以是使用iri_to_uri()函数编码的unicode字符串。

参数:

  • location –响应应重定向到的位置。
  • code–重定向状态代码。默认为302。
  • Response(类)–实例化响应时要使用的Response类。如果未指定,则默认值为werkzeug.wrappers.Response。

From the Flask API Documentation (v. 0.10):

flask.redirect(location, code=302, Response=None)

Returns a response object (a WSGI application) that, if called, redirects the client to the target location. Supported codes are 301, 302, 303, 305, and 307. 300 is not supported because it’s not a real redirect and 304 because it’s the answer for a request with a request with defined If-Modified-Since headers.

New in version 0.6: The location can now be a unicode string that is encoded using the iri_to_uri() function.

Parameters:

  • location – the location the response should redirect to.
  • code – the redirect status code. defaults to 302.
  • Response (class) – a Response class to use when instantiating a response. The default is werkzeug.wrappers.Response if unspecified.

回答 3

我认为这个问题值得更新:只需看看其他方法并进行比较即可。

这是在Flask(0.12.2)中从一个URL重定向(3xx)到另一个URL的方法:

#!/usr/bin/env python

from flask import Flask, redirect

app = Flask(__name__)

@app.route("/")
def index():
    return redirect('/you_were_redirected')

@app.route("/you_were_redirected")
def redirected():
    return "You were redirected. Congrats :)!"

if __name__ == "__main__":
    app.run(host="0.0.0.0",port=8000,debug=True)

如需其他官方参考,请点击此处

I believe that this question deserves an updated: just take a look on the other approaches and make the comparisons.

Here is how you do redirection (3xx) from one url to another in Flask (0.12.2):

#!/usr/bin/env python

from flask import Flask, redirect

app = Flask(__name__)

@app.route("/")
def index():
    return redirect('/you_were_redirected')

@app.route("/you_were_redirected")
def redirected():
    return "You were redirected. Congrats :)!"

if __name__ == "__main__":
    app.run(host="0.0.0.0",port=8000,debug=True)

For other official references, here.


回答 4

flask.redirect(location, code=302)

可以在这里找到文档。

flask.redirect(location, code=302)

Docs can be found here.


回答 5

Flask包含redirect用于重定向到任何URL 的功能。此外,您可以使用abort

from flask import abort, Flask, redirect, url_for

app = Flask(__name__)

@app.route('/')
def hello():
    return redirect(url_for('hello'))

@app.route('/hello'):
def world:
    abort(401)

默认情况下,每个错误代码均显示黑白错误页面。

redirect方法默认情况下采用代码302。此处是http状态代码的列表。

Flask includes the redirect function for redirecting to any url. Futhermore, you can abort a request early with an error code with abort:

from flask import abort, Flask, redirect, url_for

app = Flask(__name__)

@app.route('/')
def hello():
    return redirect(url_for('hello'))

@app.route('/hello'):
def world:
    abort(401)

By default a black and white error page is shown for each error code.

The redirect method takes by default the code 302. A list for http status codes here.


回答 6

为此,您可以简单地使用redirect包含在其中的功能flask

from flask import Flask, redirect

app = Flask(__name__)

@app.route('/')
def hello():
    return redirect("www.exampleURL.com", code = 302)

if __name__ == "__main__":
    app.run()

另一个有用的技巧(因为您是Flask的新手),是app.debug = True在初始化flask对象之后添加的,因为调试器的输出会在找出问题所在时提供很多帮助。

For this you can simply use the redirect function that is included in flask

from flask import Flask, redirect

app = Flask(__name__)

@app.route('/')
def hello():
    return redirect("https://www.exampleURL.com", code = 302)

if __name__ == "__main__":
    app.run()

Another useful tip(as you’re new to flask), is to add app.debug = True after initializing the flask object as the debugger output helps a lot while figuring out what’s wrong.


回答 7

您可以这样使用:

import os
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
     # Redirect from here, replace your custom site url "www.google.com"
    return redirect("www.google.com", code=200)

if __name__ == '__main__':
    # Bind to PORT if defined, otherwise default to 5000.
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)

这是此代码的引用链接。

You can use like this:

import os
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
     # Redirect from here, replace your custom site url "www.google.com"
    return redirect("https://www.google.com", code=200)

if __name__ == '__main__':
    # Bind to PORT if defined, otherwise default to 5000.
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)

Here is the referenced link to this code.


使用Flask for Python获取访问者的IP地址

问题:使用Flask for Python获取访问者的IP地址

我正在建立一个网站,用户可以使用使用Python(在我的情况下为2.6)的Flask微框架(基于Werkzeug)登录和下载文件。

我需要获得用户登录时的IP地址(出于记录目的)。有谁知道如何做到这一点?当然有办法用Python做到吗?

I’m making a website where users can log on and download files, using the Flask micro-framework (based on Werkzeug) which uses Python (2.6 in my case).

I need to get the IP address of users when they log on (for logging purposes). Does anyone know how to do this? Surely there is a way to do it with Python?


回答 0

请参阅有关如何访问Request对象,然后从同一Request对象(即attribute)获取文档remote_addr

代码示例

from flask import request
from flask import jsonify

@app.route("/get_my_ip", methods=["GET"])
def get_my_ip():
    return jsonify({'ip': request.remote_addr}), 200

有关更多信息,请参阅Werkzeug文档

See the documentation on how to access the Request object and then get from this same Request object, the attribute remote_addr.

Code example

from flask import request
from flask import jsonify

@app.route("/get_my_ip", methods=["GET"])
def get_my_ip():
    return jsonify({'ip': request.remote_addr}), 200

For more information see the Werkzeug documentation.


回答 1

代理会使这变得有些棘手,如果使用代理,请确保签出ProxyFixFlask docs)。看一下request.environ您的特定环境。使用nginx,有时我会做这样的事情:

from flask import request   
request.environ.get('HTTP_X_REAL_IP', request.remote_addr)   

当代理(例如nginx)转发地址时,它们通常在请求标头中的某处包括原始IP。

更新 请参见flask-security实现。同样,在实施之前,请阅读有关ProxyFix的文档。您的解决方案可能会因您的特定环境而异。

Proxies can make this a little tricky, make sure to check out ProxyFix (Flask docs) if you are using one. Take a look at request.environ in your particular environment. With nginx I will sometimes do something like this:

from flask import request   
request.environ.get('HTTP_X_REAL_IP', request.remote_addr)   

When proxies, such as nginx, forward addresses, they typically include the original IP somewhere in the request headers.

Update See the flask-security implementation. Again, review the documentation about ProxyFix before implementing. Your solution may vary based on your particular environment.


回答 2

实际上,您将发现,仅获取以下内容即可获得服务器的地址:

request.remote_addr

如果要客户端IP地址,请使用以下命令:

request.environ['REMOTE_ADDR']

Actually, what you will find is that when simply getting the following will get you the server’s address:

request.remote_addr

If you want the clients IP address, then use the following:

request.environ['REMOTE_ADDR']

回答 3

可以使用以下代码段检索用户的IP地址:

from flask import request
print(request.remote_addr)

The user’s IP address can be retrieved using the following snippet:

from flask import request
print(request.remote_addr)

回答 4

我有Nginx并且在Nginx Config下面:

server {
    listen 80;
    server_name xxxxxx;
    location / {
               proxy_set_header   Host                 $host;
               proxy_set_header   X-Real-IP            $remote_addr;
               proxy_set_header   X-Forwarded-For      $proxy_add_x_forwarded_for;
               proxy_set_header   X-Forwarded-Proto    $scheme;

               proxy_pass http://x.x.x.x:8000;
        }
}

@ tirtha-r解决方案为我工作

#!flask/bin/python
from flask import Flask, jsonify, request
app = Flask(__name__)

@app.route('/', methods=['GET'])
def get_tasks():
    if request.environ.get('HTTP_X_FORWARDED_FOR') is None:
        return jsonify({'ip': request.environ['REMOTE_ADDR']}), 200
    else:
        return jsonify({'ip': request.environ['HTTP_X_FORWARDED_FOR']}), 200

if __name__ == '__main__':
    app.run(debug=True,host='0.0.0.0', port=8000)

我的要求和回应:

curl -X GET http://test.api

{
    "ip": "Client Ip......"
}

I have Nginx and With below Nginx Config:

server {
    listen 80;
    server_name xxxxxx;
    location / {
               proxy_set_header   Host                 $host;
               proxy_set_header   X-Real-IP            $remote_addr;
               proxy_set_header   X-Forwarded-For      $proxy_add_x_forwarded_for;
               proxy_set_header   X-Forwarded-Proto    $scheme;

               proxy_pass http://x.x.x.x:8000;
        }
}

@tirtha-r solution worked for me

#!flask/bin/python
from flask import Flask, jsonify, request
app = Flask(__name__)

@app.route('/', methods=['GET'])
def get_tasks():
    if request.environ.get('HTTP_X_FORWARDED_FOR') is None:
        return jsonify({'ip': request.environ['REMOTE_ADDR']}), 200
    else:
        return jsonify({'ip': request.environ['HTTP_X_FORWARDED_FOR']}), 200

if __name__ == '__main__':
    app.run(debug=True,host='0.0.0.0', port=8000)

My Request and Response:

curl -X GET http://test.api

{
    "ip": "Client Ip......"
}

回答 5

以下代码始终提供客户端的公共IP(而不是代理后面的私有IP)。

from flask import request

if request.environ.get('HTTP_X_FORWARDED_FOR') is None:
    print(request.environ['REMOTE_ADDR'])
else:
    print(request.environ['HTTP_X_FORWARDED_FOR']) # if behind a proxy

The below code always gives the public IP of the client (and not a private IP behind a proxy).

from flask import request

if request.environ.get('HTTP_X_FORWARDED_FOR') is None:
    print(request.environ['REMOTE_ADDR'])
else:
    print(request.environ['HTTP_X_FORWARDED_FOR']) # if behind a proxy

回答 6

httpbin.org使用以下方法:

return jsonify(origin=request.headers.get('X-Forwarded-For', request.remote_addr))

httpbin.org uses this method:

return jsonify(origin=request.headers.get('X-Forwarded-For', request.remote_addr))

回答 7

如果您在其他平衡器(例如AWS Application Balancer)之后使用Nginx,则HTTP_X_FORWARDED_FOR返回地址列表。可以这样修复:

if 'X-Forwarded-For' in request.headers:
    proxy_data = request.headers['X-Forwarded-For']
    ip_list = proxy_data.split(',')
    user_ip = ip_list[0]  # first address in list is User IP
else:
    user_ip = request.remote_addr  # For local development

If you use Nginx behind other balancer, for instance AWS Application Balancer, HTTP_X_FORWARDED_FOR returns list of addresses. It can be fixed like that:

if 'X-Forwarded-For' in request.headers:
    proxy_data = request.headers['X-Forwarded-For']
    ip_list = proxy_data.split(',')
    user_ip = ip_list[0]  # first address in list is User IP
else:
    user_ip = request.remote_addr  # For local development

回答 8

如果您使用的是Gunicorn和Nginx环境,则以下代码模板适用于您。

addr_ip4 = request.remote_addr

If You are using Gunicorn and Nginx environment then the following code template works for you.

addr_ip4 = request.remote_addr

回答 9

这应该做的工作。它提供客户端IP地址(远程主机)。

请注意,此代码在服务器端运行。

from mod_python import apache

req.get_remote_host(apache.REMOTE_NOLOOKUP)

This should do the job. It provides the client IP address (remote host).

Note that this code is running on the server side.

from mod_python import apache

req.get_remote_host(apache.REMOTE_NOLOOKUP)

如何在Flask-SQLAlchemy应用中执行原始SQL

问题:如何在Flask-SQLAlchemy应用中执行原始SQL

如何在SQLAlchemy中执行原始SQL?

我有一个在烧瓶上运行的python Web应用程序,并通过SQLAlchemy连接到数据库。

我需要一种运行原始SQL的方法。该查询涉及多个表联接以及内联视图。

我试过了:

connection = db.session.connection()
connection.execute( <sql here> )

但是我不断收到网关错误。

How do you execute raw SQL in SQLAlchemy?

I have a python web app that runs on flask and interfaces to the database through SQLAlchemy.

I need a way to run the raw SQL. The query involves multiple table joins along with Inline views.

I’ve tried:

connection = db.session.connection()
connection.execute( <sql here> )

But I keep getting gateway errors.


回答 0

你有没有尝试过:

result = db.engine.execute("<sql here>")

要么:

from sqlalchemy import text

sql = text('select name from penguins')
result = db.engine.execute(sql)
names = [row[0] for row in result]
print names

Have you tried:

result = db.engine.execute("<sql here>")

or:

from sqlalchemy import text

sql = text('select name from penguins')
result = db.engine.execute(sql)
names = [row[0] for row in result]
print names

回答 1

SQL Alchemy会话对象具有自己的execute方法:

result = db.session.execute('SELECT * FROM my_table WHERE my_column = :val', {'val': 5})

您的所有应用程序查询都应通过会话对象,无论它们是否是原始SQL。这样可以确保由事务适当地管理查询,该事务允许将同一请求中的多个查询作为一个单元提交或回滚。使用引擎连接进行事务处理将使您面临更大的隐患,即可能很难检测到可能导致数据损坏的错误的风险。每个请求应仅与一个事务相关联,并且使用db.session可以确保您的应用程序是这种情况。

另请注意,它execute是为参数化查询设计的。使用:val示例中的参数作为查询的任何输入,以保护自己免受SQL注入攻击。您可以通过传递a dict作为第二个参数来提供这些参数的值,其中每个键都是在查询中显示的参数名称。参数本身的确切语法可能会有所不同,具体取决于您的数据库,但是所有主要的关系数据库都以某种形式支持它们。

假设这是一个SELECT查询,它将返回一个可迭代RowProxy对象。

您可以使用多种技术访问各个列:

for r in result:
    print(r[0]) # Access by positional index
    print(r['my_column']) # Access by column name as a string
    r_dict = dict(r.items()) # convert to dict keyed by column names

就个人而言,我更喜欢将结果转换为namedtuples:

from collections import namedtuple

Record = namedtuple('Record', result.keys())
records = [Record(*r) for r in result.fetchall()]
for r in records:
    print(r.my_column)
    print(r)

如果您不使用Flask-SQLAlchemy扩展,您仍然可以轻松使用会话:

import sqlalchemy
from sqlalchemy.orm import sessionmaker, scoped_session

engine = sqlalchemy.create_engine('my connection string')
Session = scoped_session(sessionmaker(bind=engine))

s = Session()
result = s.execute('SELECT * FROM my_table WHERE my_column = :val', {'val': 5})

SQL Alchemy session objects have their own execute method:

result = db.session.execute('SELECT * FROM my_table WHERE my_column = :val', {'val': 5})

All your application queries should be going through a session object, whether they’re raw SQL or not. This ensures that the queries are properly managed by a transaction, which allows multiple queries in the same request to be committed or rolled back as a single unit. Going outside the transaction using the engine or the connection puts you at much greater risk of subtle, possibly hard to detect bugs that can leave you with corrupted data. Each request should be associated with only one transaction, and using db.session will ensure this is the case for your application.

Also take note that execute is designed for parameterized queries. Use parameters, like :val in the example, for any inputs to the query to protect yourself from SQL injection attacks. You can provide the value for these parameters by passing a dict as the second argument, where each key is the name of the parameter as it appears in the query. The exact syntax of the parameter itself may be different depending on your database, but all of the major relational databases support them in some form.

Assuming it’s a SELECT query, this will return an iterable of RowProxy objects.

You can access individual columns with a variety of techniques:

for r in result:
    print(r[0]) # Access by positional index
    print(r['my_column']) # Access by column name as a string
    r_dict = dict(r.items()) # convert to dict keyed by column names

Personally, I prefer to convert the results into namedtuples:

from collections import namedtuple

Record = namedtuple('Record', result.keys())
records = [Record(*r) for r in result.fetchall()]
for r in records:
    print(r.my_column)
    print(r)

If you’re not using the Flask-SQLAlchemy extension, you can still easily use a session:

import sqlalchemy
from sqlalchemy.orm import sessionmaker, scoped_session

engine = sqlalchemy.create_engine('my connection string')
Session = scoped_session(sessionmaker(bind=engine))

s = Session()
result = s.execute('SELECT * FROM my_table WHERE my_column = :val', {'val': 5})

回答 2

docs:SQL表达式语言教程-使用文本

例:

from sqlalchemy.sql import text

connection = engine.connect()

# recommended
cmd = 'select * from Employees where EmployeeGroup = :group'
employeeGroup = 'Staff'
employees = connection.execute(text(cmd), group = employeeGroup)

# or - wee more difficult to interpret the command
employeeGroup = 'Staff'
employees = connection.execute(
                  text('select * from Employees where EmployeeGroup = :group'), 
                  group = employeeGroup)

# or - notice the requirement to quote 'Staff'
employees = connection.execute(
                  text("select * from Employees where EmployeeGroup = 'Staff'"))


for employee in employees: logger.debug(employee)
# output
(0, 'Tim', 'Gurra', 'Staff', '991-509-9284')
(1, 'Jim', 'Carey', 'Staff', '832-252-1910')
(2, 'Lee', 'Asher', 'Staff', '897-747-1564')
(3, 'Ben', 'Hayes', 'Staff', '584-255-2631')

docs: SQL Expression Language Tutorial – Using Text

example:

from sqlalchemy.sql import text

connection = engine.connect()

# recommended
cmd = 'select * from Employees where EmployeeGroup = :group'
employeeGroup = 'Staff'
employees = connection.execute(text(cmd), group = employeeGroup)

# or - wee more difficult to interpret the command
employeeGroup = 'Staff'
employees = connection.execute(
                  text('select * from Employees where EmployeeGroup = :group'), 
                  group = employeeGroup)

# or - notice the requirement to quote 'Staff'
employees = connection.execute(
                  text("select * from Employees where EmployeeGroup = 'Staff'"))


for employee in employees: logger.debug(employee)
# output
(0, 'Tim', 'Gurra', 'Staff', '991-509-9284')
(1, 'Jim', 'Carey', 'Staff', '832-252-1910')
(2, 'Lee', 'Asher', 'Staff', '897-747-1564')
(3, 'Ben', 'Hayes', 'Staff', '584-255-2631')

回答 3

你可以使用SELECT SQL查询的结果from_statement(),并text()如图所示这里。您不必以这种方式处理元组。作为User具有表名的类的示例,users您可以尝试,

from sqlalchemy.sql import text
.
.
.
user = session.query(User).from_statement(
    text("SELECT * FROM users where name=:name")).\
    params(name='ed').all()

return user

You can get the results of SELECT SQL queries using from_statement() and text() as shown here. You don’t have to deal with tuples this way. As an example for a class User having the table name users you can try,

from sqlalchemy.sql import text

user = session.query(User).from_statement(
    text("""SELECT * FROM users where name=:name""")
).params(name="ed").all()

return user

回答 4

result = db.engine.execute(text("<sql here>"))

<sql here>除非您处于autocommit模式,否则执行但不提交。因此,插入和更新不会反映在数据库中。

要在更改后提交,请执行

result = db.engine.execute(text("<sql here>").execution_options(autocommit=True))
result = db.engine.execute(text("<sql here>"))

executes the <sql here> but doesn’t commit it unless you’re on autocommit mode. So, inserts and updates wouldn’t reflect in the database.

To commit after the changes, do

result = db.engine.execute(text("<sql here>").execution_options(autocommit=True))

回答 5

这是如何从Flask Shell运行SQL查询的简化答案

首先,映射您的模块(如果您的模块/应用程序是principal文件夹中的manage.py,并且您在UNIX操作系统中),请运行:

export FLASK_APP=manage

运行烧瓶壳

flask shell

导入我们需要的::

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)
from sqlalchemy import text

运行查询:

result = db.engine.execute(text("<sql here>").execution_options(autocommit=True))

这将使用具有应用程序的当前数据库连接。

This is a simplified answer of how to run SQL query from Flask Shell

First, map your module (if your module/app is manage.py in the principal folder and you are in a UNIX Operating system), run:

export FLASK_APP=manage

Run Flask shell

flask shell

Import what we need::

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)
from sqlalchemy import text

Run your query:

result = db.engine.execute(text("<sql here>").execution_options(autocommit=True))

This use the currently database connection which has the application.


回答 6

您是否尝试过按照文档connection.execute(text( <sql here> ), <bind params here> )所述使用和绑定参数?这可以帮助解决许多参数格式设置和性能问题。也许网关错误是超时?绑定参数往往会使复杂的查询执行得更快。

Have you tried using connection.execute(text( <sql here> ), <bind params here> ) and bind parameters as described in the docs? This can help solve many parameter formatting and performance problems. Maybe the gateway error is a timeout? Bind parameters tend to make complex queries execute substantially faster.


回答 7

如果你想避免的元组,另一种方式是通过调用firstoneall方法:

query = db.engine.execute("SELECT * FROM blogs "
                           "WHERE id = 1 ")

assert query.first().name == "Welcome to my blog"

If you want to avoid tuples, another way is by calling the first, one or all methods:

query = db.engine.execute("SELECT * FROM blogs "
                           "WHERE id = 1 ")

assert query.first().name == "Welcome to my blog"

如何使Flask在端口80上运行?

问题:如何使Flask在端口80上运行?

我有一个通过端口5000运行的Flask服务器,很好。我可以在http://example.com:5000上访问它

但是是否可以在http://example.com上简单地访问它?我假设这意味着我必须将端口从5000更改为80。但是当我在Flask上尝试该端口时,运行该错误消息。

Traceback (most recent call last):
  File "xxxxxx.py", line 31, in <module>
app.run(host="0.0.0.0", port=int("80"), debug=True)
   File "/usr/local/lib/python2.6/dist-packages/flask/app.py", line 772, in run
run_simple(host, port, self, **options)
  File "/usr/local/lib/python2.6/dist-packages/werkzeug/serving.py", line 706, in run_simple
    test_socket.bind((hostname, port))
  File "<string>", line 1, in bind
socket.error: [Errno 98] Address already in use

连续lsof -i :80收益

COMMAND   PID     USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
apache2   467     root    3u  IPv4 92108840      0t0  TCP *:www (LISTEN)
apache2  4413 www-data    3u  IPv4 92108840      0t0  TCP *:www (LISTEN)
apache2 14346 www-data    3u  IPv4 92108840      0t0  TCP *:www (LISTEN)
apache2 14570 www-data    3u  IPv4 92108840      0t0  TCP *:www (LISTEN)
apache2 14571 www-data    3u  IPv4 92108840      0t0  TCP *:www (LISTEN)
apache2 14573 www-data    3u  IPv4 92108840      0t0  TCP *:www (LISTEN)

我需要先杀死这些进程吗?这样安全吗?还是有另一种方法可以使Flask在端口5000上运行,但是使主网站域以某种方式重定向?

I have a Flask server running through port 5000, and it’s fine. I can access it at http://example.com:5000

But is it possible to simply access it at http://example.com? I’m assuming that means I have to change the port from 5000 to 80. But when I try that on Flask, I get this error message when I run it.

Traceback (most recent call last):
  File "xxxxxx.py", line 31, in <module>
app.run(host="0.0.0.0", port=int("80"), debug=True)
   File "/usr/local/lib/python2.6/dist-packages/flask/app.py", line 772, in run
run_simple(host, port, self, **options)
  File "/usr/local/lib/python2.6/dist-packages/werkzeug/serving.py", line 706, in run_simple
    test_socket.bind((hostname, port))
  File "<string>", line 1, in bind
socket.error: [Errno 98] Address already in use

Running lsof -i :80 returns

COMMAND   PID     USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
apache2   467     root    3u  IPv4 92108840      0t0  TCP *:www (LISTEN)
apache2  4413 www-data    3u  IPv4 92108840      0t0  TCP *:www (LISTEN)
apache2 14346 www-data    3u  IPv4 92108840      0t0  TCP *:www (LISTEN)
apache2 14570 www-data    3u  IPv4 92108840      0t0  TCP *:www (LISTEN)
apache2 14571 www-data    3u  IPv4 92108840      0t0  TCP *:www (LISTEN)
apache2 14573 www-data    3u  IPv4 92108840      0t0  TCP *:www (LISTEN)

Do I need to kill these processes first? Is that safe? Or is there another way to keep Flask running on port 5000 but have the main website domain redirect somehow?


回答 0

因此,由于您已经apache2在端口80上运行,因此抛出了该错误消息。

如果这是为了开发,我将其保留在端口5000上。

如果用于生产:

不建议

  • apache2先停下来

不建议使用,因为它在文档中指出:

您可以在开发过程中使用内置服务器,但应该对生产应用程序使用完整的部署选项。(请勿在生产中使用内置的开发服务器。)

推荐的

  • 代理 HTTP通过apache2访问Flask。

这条路, apache2就可以处理所有静态文件(非常擅长-比Flask内置的调试服务器要好得多),并充当动态内容的反向代理,将这些请求传递给Flask。

这是一个链接有关使用Apache + mod_wsgi设置Flask的官方文档。

编辑1-澄清@Djack

通过apache2到Flask的代理HTTP流量

当请求通过端口80(HTTP)或端口443(HTTPS)到达服务器时,类似Apache或Nginx的Web服务器将处理请求的连接并确定如何处理该请求。在我们的情况下,应该将收到的请求配置为通过WSGI协议传递给Flask并由Python代码处理。这是“动态”部分。

动态内容的反向代理

像上面那样配置Web服务器有一些好处;

  • SSL终端-仅需少量配置即可优化Web服务器以处理HTTPS请求。相比之下,不要在Python中“自己动手”。
  • 安全性-打开Internet端口需要仔细考虑安全性。Flask的开发服务器不是为此目的而设计的,与为此目的设计的Web服务器相比,它可能存在开放的错误或安全问题。请注意,配置错误的Web服务器也可能不安全!
  • 静态文件处理-内置的Flask Web服务器可以处理静态文件,但是不建议这样做。Nginx / Apache在处理静态文件(如图像,CSS,Javascript文件)方面效率更高,并且仅传递“动态”请求(那些内容通常是从数据库中读取或内容发生更改的请求)以由Python代码处理。
  • +更多。这接近于该问题的范围。如果您想了解更多信息,请对该领域进行一些研究。

So it’s throwing up that error message because you have apache2 running on port 80.

If this is for development, I would just leave it as it is on port 5000.

If it’s for production either:

Not Recommended

  • Stop apache2 first;

Not recommended as it states in the documentation:

You can use the builtin server during development, but you should use a full deployment option for production applications. (Do not use the builtin development server in production.)

Recommended

  • Proxy HTTP traffic through apache2 to Flask.

This way, apache2 can handle all your static files (which it’s very good at – much better than the debug server built into Flask) and act as a reverse proxy for your dynamic content, passing those requests to Flask.

Here’s a link to the official documentation about setting up Flask with Apache + mod_wsgi.

Edit 1 – Clarification for @Djack

Proxy HTTP traffic to Flask through apache2

When a request comes to the server on port 80 (HTTP) or port 443 (HTTPS) a web server like Apache or Nginx handles the connection of the request and works out what to do with it. In our case a request received should be configured to be passed through to Flask on the WSGI protocol and handled by the Python code. This is the “dynamic” part.

reverse proxy for dynamic content

There are a few advantages to configuring your web server like the above;

  • SSL Termination – The web server will be optimized to handle HTTPS requests with only a little configuration. Don’t “roll your own” in Python which is probably very insecure in comparison.
  • Security – Opening a port to the internet requires careful consideration of security. Flask’s development server is not designed for this and could have open bugs or security issues in comparison to a web server designed for this purpose. Note that a badly configured web server can also be insecure!
  • Static File Handling – It is possible for the builtin Flask web server to handle static files however this is not recommended; Nginx/Apache are much more efficient at handling static files like images, CSS, Javascript files and will only pass “dynamic” requests (those where the content is often read from a database or the content changes) to be handled by the Python code.
  • +more. This is bordering on scope for this question. If you want more info do some research into this area.

回答 1

1-停止使用端口80的其他应用程序。2-使用端口80运行应用程序:

if __name__ == '__main__':
      app.run(host='0.0.0.0', port=80)

1- Stop other applications that are using port 80. 2- run application with port 80 :

if __name__ == '__main__':
      app.run(host='0.0.0.0', port=80)

回答 2

对于外部可见的服务器,您不使用apache或其他Web服务器,只需键入

flask run --host=0.0.0.0 --port=80

For externally visible server, where you don’t use apache or other web server you just type

flask run --host=0.0.0.0 --port=80

回答 3

如果使用以下命令更改端口或主机:

if __name__ == '__main__':
  app.run(host='0.0.0.0', port=80)

使用以下代码启动服务器(我的flask的主入口是app.py):

python app.py

而不是使用:

flask run

If you use the following to change the port or host:

if __name__ == '__main__':
  app.run(host='0.0.0.0', port=80)

use the following code to start the server (my main entrance for flask is app.py):

python app.py

instead of using:

flask run

回答 4

如果要将应用程序放在相同的端口(即port = 5000)上,则只需在终端中运行以下命令:

fuser -k 5000/tcp

然后运行:

python app.py

如果要在指定端口上运行,例如,如果要在port = 80上运行,请在主文件中提及:

if __name__ == '__main__':  
    app.run(host='0.0.0.0', port=80)

If you want your application on same port i.e port=5000 then just in your terminal run this command:

fuser -k 5000/tcp

and then run:

python app.py

If you want to run on a specified port, e.g. if you want to run on port=80, in your main file just mention this:

if __name__ == '__main__':  
    app.run(host='0.0.0.0', port=80)

回答 5

一种方便的方式是使用软件包python-dotenv:它读取一个.flaskenv文件,您可以在其中存储flask的环境变量。

  • pip install python-dotenv
  • .flaskenv在应用程序的根目录中创建文件

在您指定的文件内:

FLASK_APP=application.py
FLASK_RUN_HOST=localhost
FLASK_RUN_PORT=80

之后,您只需要运行 flask run即可在该端口访问您的应用程序。

请注意,FLASK_RUN_HOST默认为127.0.0.1FLASK_RUN_PORT默认为5000

A convinient way is using the package python-dotenv: It reads out a .flaskenv file where you can store environment variables for flask.

  • pip install python-dotenv
  • create a file .flaskenv in the root directory of your app

Inside the file you specify:

FLASK_APP=application.py
FLASK_RUN_HOST=localhost
FLASK_RUN_PORT=80

After that you just have to run your app with flask run and can access your app at that port.

Please note that FLASK_RUN_HOST defaults to 127.0.0.1 and FLASK_RUN_PORT defaults to 5000.


回答 6

这是在Ubuntu-18上对我有用的唯一解决方案。

在文件中app.py,使用:

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)

除非sudo用于运行它,否则上面的代码将给出相同的权限错误:

sudo python3 app.py

This is the only solution that worked for me on Ubuntu-18.

Inside the file app.py , use:

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)

The code above will give the same permission error unless sudo is used to run it:

sudo python3 app.py

回答 7

您的问题是,已经有一个正在使用端口80的apache网络服务器正在运行。因此,您可以:

  1. 杀死apache:您可能应该通过这样做/etc/init.d/apache2 stop,而不是简单地杀死它们。

  2. 如apache中的flask所述,在apache进程中部署flask应用程序。

Your issue is, that you have an apache webserver already running that is already using port 80. So, you can either:

  1. Kill apache: You should probably do this via /etc/init.d/apache2 stop, rather than simply killing them.

  2. Deploy your flask app in your apache process, as flask in apache describes.


回答 8

我必须FLASK_RUN_PORT在我的环境中将其设置为指定的端口号。下次启动应用程序时,Flask将使用您选择的端口号加载该环境变量。

I had to set FLASK_RUN_PORT in my environment to the specified port number. Next time you start your app, Flask will load that environment variable with the port number you selected.


回答 9

您无需更改应用程序的端口号,只需配置www服务器(nginx或apache)即可将查询代理到flask端口。支付的减免费用uWSGI

You don’t need to change port number for your application, just configure your www server (nginx or apache) to proxy queries to flask port. Pay attantion on uWSGI.


回答 10

设置端口,app.run(port=80,debug=True) 在开发时应将debug设置为true

set the port with app.run(port=80,debug=True) you should set debug to true when on dev


回答 11

最简单,最好的解决方案

将.py文件保存在文件夹中。这种情况下我的文件夹名称是test。在命令提示符下运行以下命令

c:\test> set FLASK_APP=application.py
c:\test> set FLASK_RUN_PORT=8000
c:\test> flask run

—————–将返回以下—————-

 * Serving Flask app "application.py"
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:8000/ (Press CTRL+C to quit)
127.0.0.1 - - [23/Aug/2019 09:40:04] "[37mGET / HTTP/1.1[0m" 200 -
127.0.0.1 - - [23/Aug/2019 09:40:04] "[33mGET /favicon.ico HTTP/1.1[0m" 404 -

现在,在浏览器上输入:http : //127.0.0.1 : 8000。谢谢

Easiest and Best Solution

Save your .py file in a folder. This case my folder name is test. In the command prompt run the following

c:\test> set FLASK_APP=application.py
c:\test> set FLASK_RUN_PORT=8000
c:\test> flask run

—————– Following will be returned —————-

 * Serving Flask app "application.py"
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:8000/ (Press CTRL+C to quit)
127.0.0.1 - - [23/Aug/2019 09:40:04] "[37mGET / HTTP/1.1[0m" 200 -
127.0.0.1 - - [23/Aug/2019 09:40:04] "[33mGET /favicon.ico HTTP/1.1[0m" 404 -

Now on your browser type: http://127.0.0.1:8000. Thanks


回答 12

在我的方案中,以下步骤非常有用:

  • 安装软件包:

    pip install --upgrade pip
    pip install python-dotenv
  • 在我的应用程序目录“ flaskr / .flaskenv”中创建隐藏文件

  • 添加以下内容:

    FLASK_APP=flaskr
    FLASK_RUN_HOST=localhost
    FLASK_RUN_PORT=8000
  • 最后,再次运行flask命令:

    flask run
  • 我正在处理的版本是:

    pip freeze |grep -i flask
    Flask==1.1.1

On my scenario the following steps worked like a charm:

  • Installing the package:

    pip install --upgrade pip
    pip install python-dotenv
    
  • Creating a hidden file in my app directory “flaskr/.flaskenv”

  • Adding the following content:

    FLASK_APP=flaskr
    FLASK_RUN_HOST=localhost
    FLASK_RUN_PORT=8000
    
  • Finally, run the flask command one more time:

    flask run
    
  • The version which I am working on is:

    pip freeze |grep -i flask
    Flask==1.1.1
    

代码更改后自动重新加载python Flask应用

问题:代码更改后自动重新加载python Flask应用

我正在研究如何使用Python开发像样的Web应用程序。由于我不希望遇到一些高级结构,因此我选择了轻量级的Flask框架。时间会证明这是否是正确的选择。

因此,现在我已经使用mod_wsgi设置了Apache服务器,并且我的测试站点运行正常。但是,我想通过使我对py或模板文件进行的任何更改自动重新加载网站,从而加快开发流程。我看到站点的.wsgi文件中的任何更改都会导致重新加载(即使在apache配置文件中没有WSGIScriptReloading On的情况下),但我仍然必须手动进行操作(即,插入额外的换行符,保存)。编辑某些应用的py文件时,有什么方法可以引起重新加载?还是希望我使用IDE来刷新.wsgi文件?

I’m investigating how to develop a decent web app with Python. Since I don’t want some high-order structures to get in my way, my choice fell on the lightweight Flask framework. Time will tell if this was the right choice.

So, now I’ve set up an Apache server with mod_wsgi, and my test site is running fine. However, I’d like to speed up the development routine by making the site automatically reload upon any changes in py or template files I make. I see that any changes in site’s .wsgi file causes reloading (even without WSGIScriptReloading On in the apache config file), but I still have to prod it manually (ie, insert extra linebreak, save). Is there some way how to cause reload when I edit some of the app’s py files? Or, I am expected to use IDE that refreshes the .wsgi file for me?


回答 0

当前推荐的方法是使用flask命令行实用程序。

https://flask.palletsprojects.com/zh-CN/1.1.x/quickstart/#debug-mode

例:

$ export FLASK_APP=main.py
$ export FLASK_ENV=development
$ flask run

或在一个命令中:

$ FLASK_APP=main.py FLASK_ENV=development flask run

如果您想要的端口与默认(5000)添加--port选项不同。

例:

$ FLASK_APP=main.py FLASK_ENV=development flask run --port 8080

更多选项可用于:

$ flask run --help

The current recommended way is with the flask command line utility.

https://flask.palletsprojects.com/en/1.1.x/quickstart/#debug-mode

Example:

$ export FLASK_APP=main.py
$ export FLASK_ENV=development
$ flask run

or in one command:

$ FLASK_APP=main.py FLASK_ENV=development flask run

If you want different port than the default (5000) add --port option.

Example:

$ FLASK_APP=main.py FLASK_ENV=development flask run --port 8080

More options are available with:

$ flask run --help

回答 1

如果您在谈论测试/开发环境,则只需使用debug选项。发生代码更改时,它将自动重新加载flask应用程序。

app.run(debug=True)

或者,从外壳:

$ export FLASK_DEBUG=1
$ flask run

http://flask.pocoo.org/docs/quickstart/#debug-mode

If you are talking about test/dev environments, then just use the debug option. It will auto-reload the flask app when a code change happens.

app.run(debug=True)

Or, from the shell:

$ export FLASK_DEBUG=1
$ flask run

http://flask.pocoo.org/docs/quickstart/#debug-mode


回答 2

在测试/开发环境中

werkzeug调试器已经具有“自动重新加载”功能,可以通过执行以下任一操作来启用该功能:

app.run(debug=True)

要么

app.debug = True

如果需要,还可以使用单独的配置文件来管理所有设置。例如,我将’settings.py’与’DEBUG = True’选项一起使用。导入该文件也很容易。

app.config.from_object('application.settings')

但是,这不适用于生产环境。

生产环境

我个人选择Nginx + uWSGI而不是Apache + mod_wsgi是出于一些性能原因以及配置选项。该触摸重装选项允许你指定一个文件/文件夹会导致uWSGI应用程序重新加载新部署的烧瓶应用。

例如,您的更新脚本会下拉您的最新更改并触摸’reload_me.txt’文件。您的uWSGI ini脚本(由Supervisord保留-显然)在某处包含以下行:

touch-reload = '/opt/virtual_environments/application/reload_me.txt'

我希望这有帮助!

In test/development environments

The werkzeug debugger already has an ‘auto reload’ function available that can be enabled by doing one of the following:

app.run(debug=True)

or

app.debug = True

You can also use a separate configuration file to manage all your setup if you need be. For example I use ‘settings.py’ with a ‘DEBUG = True’ option. Importing this file is easy too;

app.config.from_object('application.settings')

However this is not suitable for a production environment.

Production environment

Personally I chose Nginx + uWSGI over Apache + mod_wsgi for a few performance reasons but also the configuration options. The touch-reload option allows you to specify a file/folder that will cause the uWSGI application to reload your newly deployed flask app.

For example, your update script pulls your newest changes down and touches ‘reload_me.txt’ file. Your uWSGI ini script (which is kept up by Supervisord – obviously) has this line in it somewhere:

touch-reload = '/opt/virtual_environments/application/reload_me.txt'

I hope this helps!


回答 3

如果您正在使用uwsgi运行,请查看python自动重载选项:

uwsgi --py-autoreload 1

示例uwsgi-dev-example.ini:

[uwsgi]
socket = 127.0.0.1:5000
master = true
virtualenv = /Users/xxxx/.virtualenvs/sites_env
chdir = /Users/xxx/site_root
module = site_module:register_debug_server()
callable = app
uid = myuser
chmod-socket = 660
log-date = true
workers = 1
py-autoreload = 1

site_root / __ init__.py

def register_debug_server():
    from werkzeug.debug import DebuggedApplication

    app = Flask(__name__)
    app.debug = True
    app = DebuggedApplication(app, evalex=True)
    return app

然后运行:

uwsgi --ini uwsgi-dev-example.ini

注意:此示例还启用调试器。

我通过Nginx设置尽可能地模仿生产。仅在Nginx后面的内置Web服务器中运行flask应用程序时,就会导致严重的网关错误。

If you’re running using uwsgi look at the python auto reload option:

uwsgi --py-autoreload 1

Example uwsgi-dev-example.ini:

[uwsgi]
socket = 127.0.0.1:5000
master = true
virtualenv = /Users/xxxx/.virtualenvs/sites_env
chdir = /Users/xxx/site_root
module = site_module:register_debug_server()
callable = app
uid = myuser
chmod-socket = 660
log-date = true
workers = 1
py-autoreload = 1

site_root/__init__.py

def register_debug_server():
    from werkzeug.debug import DebuggedApplication

    app = Flask(__name__)
    app.debug = True
    app = DebuggedApplication(app, evalex=True)
    return app

Then run:

uwsgi --ini uwsgi-dev-example.ini

Note: This example also enables the debugger.

I went this route to mimic production as close as possible with my nginx setup. Simply running the flask app with it’s built in web server behind nginx it would result in a bad gateway error.


回答 4

Flask 1.0及更高版本的一些更新

热重装的基本方法是:

$ export FLASK_APP=my_application
$ export FLASK_ENV=development
$ flask run
  • 您应该使用FLASK_ENV=development(不是FLASK_DEBUG=1
  • 作为安全检查,您可以运行 flask run --debugger以确保已将其打开
  • Flask CLI现在会自动读取以下内容FLASK_APPFLASK_ENV如果.env项目根目录中文件并且安装了python-dotenv

A few updates for Flask 1.0 and above

the basic approach to hot re-loading is:

$ export FLASK_APP=my_application
$ export FLASK_ENV=development
$ flask run
  • you should use FLASK_ENV=development (not FLASK_DEBUG=1)
  • as a safety check, you can run flask run --debugger just to make sure it’s turned on
  • the Flask CLI will now automatically read things like FLASK_APP and FLASK_ENV if you have an .env file in the project root and have python-dotenv installed

回答 5

我有一个不同的主意:

第一:

pip install python-dotenv

安装python-dotenv模块,该模块将读取您的项目环境的本地首选项。

第二:

.flaskenv在您的项目目录中添加文件。添加以下代码:

FLASK_ENV=development

完成!

使用Flask项目的此配置,当您运行时flask run,您将在终端中看到以下输出:

当您编辑文件时,只需保存更改即可。您会看到自动重新加载在那里:

详细说明:

当然,您可以export FLASK_ENV=development在需要时手动点击。但是使用不同的配置文件来处理实际的工作环境似乎是一个更好的解决方案,因此我强烈建议我使用此方法。

I got a different idea:

First:

pip install python-dotenv

Install the python-dotenv module, which will read local preference for your project environment.

Second:

Add .flaskenv file in your project directory. Add following code:

FLASK_ENV=development

It’s done!

With this config for your Flask project, when you run flask run and you will see this output in your terminal:

And when you edit your file, just save the change. You will see auto-reload is there for you:

With more explanation:

Of course you can manually hit export FLASK_ENV=development every time you need. But using different configuration file to handle the actual working environment seems like a better solution, so I strongly recommend this method I use.


回答 6

Flask应用程序可以选择在调试模式下执行。在这种模式下,默认情况下启用了开发服务器的两个非常方便的模块,分别称为重载调试器。启用重新加载器后,Flask会监视项目的所有源代码文件,并在修改任何文件时自动重新启动服务器。

默认情况下,调试模式是禁用的。要启用它,FLASK_DEBUG=1在调用flask之前设置一个环境变量run

(venv) $ export FLASK_APP=hello.py for Windows use > set FLASK_APP=hello.py

(venv) $ export FLASK_DEBUG=1 for Windows use > set FLASK_DEBUG=1

(venv) $ flask run

* Serving Flask app "hello"
* Forcing debug mode on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 273-181-528

在开发过程中,启用启用重新加载程序的服务器非常有用,因为每次修改和保存源文件时,服务器都会自动重新启动并获取更改。

Flask applications can optionally be executed in debug mode. In this mode, two very convenient modules of the development server called the reloader and the debugger are enabled by default. When the reloader is enabled, Flask watches all the source code files of your project and automatically restarts the server when any of the files are modified.

By default, debug mode is disabled. To enable it, set a FLASK_DEBUG=1 environment variable before invoking flask run:

(venv) $ export FLASK_APP=hello.py for Windows use > set FLASK_APP=hello.py

(venv) $ export FLASK_DEBUG=1 for Windows use > set FLASK_DEBUG=1

(venv) $ flask run

* Serving Flask app "hello"
* Forcing debug mode on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 273-181-528

Having a server running with the reloader enabled is extremely useful during development, because every time you modify and save a source file, the server automatically restarts and picks up the change.


回答 7

要在PyCharm中实现这一目标,请将“环境变量”部分设置为:

PYTHONUNBUFFERED=1;
FLASK_DEBUG=1

对于Flask的“运行/调试配置”。

To achieve this in PyCharm set ‘Environment Variables’ section to:

PYTHONUNBUFFERED=1;
FLASK_DEBUG=1

For Flask ‘run / debug configurations’.


我可以单独使用Flask app.run()服务多个客户端吗?

问题:我可以单独使用Flask app.run()服务多个客户端吗?

我知道我可以将Flask与Apache或其他Web服务器链接。但是,我当时正在考虑将Flask作为独立的服务器运行,同时为多个客户端提供服务。

这可能吗?我是否需要处理产生多个线程并进行管理?

I know I can link Flask with Apache or other web servers. But, I was thinking of running Flask as a standalone server serving multiple clients simultaneously.

Is this possible? Do I have to handle spawning multiple threads and managing them?


回答 0

flask.Flask.run接受**options转发给它的其他关键字参数()werkzeug.serving.run_simple-其中两个参数是threaded(布尔值)和processes(您可以将其设置为大于1的数字以使werkzeug产生多个进程来处理请求)。

threaded默认True版本自Flask 1.0起,因此对于最新版本的Flask,默认情况下默认开发服务器将能够同时为多个客户端提供服务。对于较旧版本的Flask,您可以显式传递threaded=True以启用此行为。

例如,您可以

if __name__ == '__main__':
    app.run(threaded=True)

以与旧Flask版本兼容的方式使用线程处理多个客户端,或者

if __name__ == '__main__':
    app.run(threaded=False, processes=3)

告诉Werkzeug生成三个进程来处理传入的请求,或者只是

if __name__ == '__main__':
    app.run()

如果您知道将使用Flask 1.0或更高版本,则可以使用线程来处理多个客户端。

话虽如此,Werkzeug的serving.run_simple包装了标准库的wsgiref软件包-该软件包包含WSGI的参考实现,而不是可用于生产的Web服务器。如果您要在生产环境中使用Flask(假设“生产环境”不是低流量的内部应用程序,并发用户不超过10个),请确保将其支撑在真实的Web服务器后面(请参阅Flask文档标题为“ 一些建议方法的部署选项)。

flask.Flask.run accepts additional keyword arguments (**options) that it forwards to werkzeug.serving.run_simple – two of those arguments are threaded (a boolean) and processes (which you can set to a number greater than one to have werkzeug spawn more than one process to handle requests).

threaded defaults to True as of Flask 1.0, so for the latest versions of Flask, the default development server will be able to serve multiple clients simultaneously by default. For older versions of Flask, you can explicitly pass threaded=True to enable this behaviour.

For example, you can do

if __name__ == '__main__':
    app.run(threaded=True)

to handle multiple clients using threads in a way compatible with old Flask versions, or

if __name__ == '__main__':
    app.run(threaded=False, processes=3)

to tell Werkzeug to spawn three processes to handle incoming requests, or just

if __name__ == '__main__':
    app.run()

to handle multiple clients using threads if you know that you will be using Flask 1.0 or later.

That being said, Werkzeug’s serving.run_simple wraps the standard library’s wsgiref package – and that package contains a reference implementation of WSGI, not a production-ready web server. If you are going to use Flask in production (assuming that “production” is not a low-traffic internal application with no more than 10 concurrent users) make sure to stand it up behind a real web server (see the section of Flask’s docs entitled Deployment Options for some suggested methods).


回答 1

app.run()在Flask中使用simple from在单个线程上创建单个同步服务器,该服务器一次只能服务一个客户端。正是出于这个原因,它旨在用于需求较低的受控环境(即开发,调试)中。

由于Python GIL,因此自行生成线程并自行管理它们也不会使您走得太远。

也就是说,您仍然有一些不错的选择。Gunicorn是一个坚固且易于使用的WSGI服务器,它使您可以产生多个工作程序(独立的进程,因此无需担心GIL),甚至还带有异步工作程序,这些工作程序可以在不增加成本的情况下加快您的应用程序(并使其更安全)。无需您做任何事情(尤其是使用Flask)。

不过,即使Gunicorn也可能不应该直接公开曝光。在生产中,应在功能更强大的HTTP服务器之后使用它。Nginx倾向于与Gunicorn和Flask搭配使用。

Using the simple app.run() from within Flask creates a single synchronous server on a single thread capable of serving only one client at a time. It is intended for use in controlled environments with low demand (i.e. development, debugging) for exactly this reason.

Spawning threads and managing them yourself is probably not going to get you very far either, because of the Python GIL.

That said, you do still have some good options. Gunicorn is a solid, easy-to-use WSGI server that will let you spawn multiple workers (separate processes, so no GIL worries), and even comes with asynchronous workers that will speed up your app (and make it more secure) with little to no work on your part (especially with Flask).

Still, even Gunicorn should probably not be directly publicly exposed. In production, it should be used behind a more robust HTTP server; nginx tends to go well with Gunicorn and Flask.


如何在Flask中获取HTTP标头?

问题:如何在Flask中获取HTTP标头?

我是python的新手,使用Python Flask并生成REST API服务。

我想检查发送给客户端的授权标头。

但是我找不到在flask中获取HTTP标头的方法。

感谢获得HTTP标头授权的任何帮助。

I am newbie to python and using Python Flask and generating REST API service.

I want to check authorization header which is sent the client.

But I can’t find way to get HTTP header in flask.

Any help for getting HTTP header authorization is appreciated.


回答 0

from flask import request
request.headers.get('your-header-name')

request.headers 行为就像字典,因此您也可以像使用任何字典一样获取标头:

request.headers['your-header-name']
from flask import request
request.headers.get('your-header-name')

request.headers behaves like a dictionary, so you can also get your header like you would with any dictionary:

request.headers['your-header-name']

回答 1

请注意,如果标头不存在,则方法之间的区别是

request.headers.get('your-header-name')

将返回None或没有异常,因此您可以像使用它

if request.headers.get('your-header-name'):
    ....

但是以下内容将引发错误

if request.headers['your-header-name'] # KeyError: 'your-header-name'
    ....

你可以通过

if 'your-header-name' in request.headers:
   customHeader = request.headers['your-header-name']
   ....

just note, The different between the methods are, if the header is not exist

request.headers.get('your-header-name')

will return None or no exception, so you can use it like

if request.headers.get('your-header-name'):
    ....

but the following will throw an error

if request.headers['your-header-name'] # KeyError: 'your-header-name'
    ....

You can handle it by

if 'your-header-name' in request.headers:
   customHeader = request.headers['your-header-name']
   ....

回答 2

如果有人试图获取所有已传递的标头,则只需使用:

dict(request.headers)

它为您提供了dict中的所有标头,您实际上可以从中执行任何想要的操作。在我的用例中,由于python API是代理,因此我不得不将所有标头转发到另一个API

If any one’s trying to fetch all headers that were passed then just simply use:

dict(request.headers)

it gives you all the headers in a dict from which you can actually do whatever ops you want to. In my use case I had to forward all headers to another API since the python API was a proxy


回答 3

让我们看看如何在Flask中获取参数,标题和正文。我要在邮递员的帮助下进行解释。

参数项和值反映在API端点中。例如端点中的key1和key2:https : //127.0.0.1/uploadkey1 = value1&key2 = value2

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

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

  key_1 = request.args.get('key1')
  key_2 = request.args.get('key2')
  print(key_1)
  #--> value1
  print(key_2)
  #--> value2

在参数之后,让我们看看如何获​​取标题

  header_1 = request.headers.get('header1')
  header_2 = request.headers.get('header2')
  print(header_1)
  #--> header_value1
  print(header_2)
  #--> header_value2

现在让我们看看如何获​​得身体

  file_name = request.files['file'].filename
  ref_id = request.form['referenceId']
  print(ref_id)
  #--> WWB9838yb3r47484

因此我们使用request.files获取上传的文件,并使用request.form获取文本

Let’s see how we get the params, headers and body in Flask. I’m gonna explain with the help of postman.

The params keys and values are reflected in the API endpoint. for example key1 and key2 in the endpoint : https://127.0.0.1/upload?key1=value1&key2=value2

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

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

  key_1 = request.args.get('key1')
  key_2 = request.args.get('key2')
  print(key_1)
  #--> value1
  print(key_2)
  #--> value2

After params, let’s now see how to get the headers:

  header_1 = request.headers.get('header1')
  header_2 = request.headers.get('header2')
  print(header_1)
  #--> header_value1
  print(header_2)
  #--> header_value2

Now let’s see how to get the body

  file_name = request.files['file'].filename
  ref_id = request.form['referenceId']
  print(ref_id)
  #--> WWB9838yb3r47484

so we fetch the uploaded files with request.files and text with request.form


使用url_for()在Flask中创建动态URL

问题:使用url_for()在Flask中创建动态URL

我的Flask路线中有一半需要使用变量say /<variable>/add/<variable>/remove。如何创建到这些位置的链接?

url_for() 需要一个参数传递给函数,但是我不能添加参数?

Half of my Flask routes requires a variable say, /<variable>/add or /<variable>/remove. How do I create links to those locations?

url_for() takes one argument for the function to route to but I can’t add arguments?


回答 0

它使用关键字参数作为变量:

url_for('add', variable=foo)

It takes keyword arguments for the variables:

url_for('add', variable=foo)

回答 1

url_forFlask中的ins用于创建URL,以防止必须在整个应用程序(包括模板)中更改URL的开销。如果不使用url_for,则如果您的应用程序的根URL发生更改,则必须在存在该链接的每个页面中进行更改。

句法: url_for('name of the function of the route','parameters (if required)')

它可以用作:

@app.route('/index')
@app.route('/')
def index():
    return 'you are in the index page'

现在,如果您有索引页的链接,则可以使用此页面:

<a href={{ url_for('index') }}>Index</a>

您可以用它做很多事情,例如:

@app.route('/questions/<int:question_id>'):    #int has been used as a filter that only integer will be passed in the url otherwise it will give a 404 error
def find_question(question_id):  
    return ('you asked for question{0}'.format(question_id))

对于以上内容,我们可以使用:

<a href = {{ url_for('find_question' ,question_id=1) }}>Question 1</a>

这样,您可以简单地传递参数!

url_for in Flask is used for creating a URL to prevent the overhead of having to change URLs throughout an application (including in templates). Without url_for, if there is a change in the root URL of your app then you have to change it in every page where the link is present.

Syntax: url_for('name of the function of the route','parameters (if required)')

It can be used as:

@app.route('/index')
@app.route('/')
def index():
    return 'you are in the index page'

Now if you have a link the index page:you can use this:

<a href={{ url_for('index') }}>Index</a>

You can do a lot o stuff with it, for example:

@app.route('/questions/<int:question_id>'):    #int has been used as a filter that only integer will be passed in the url otherwise it will give a 404 error
def find_question(question_id):  
    return ('you asked for question{0}'.format(question_id))

For the above we can use:

<a href = {{ url_for('find_question' ,question_id=1) }}>Question 1</a>

Like this you can simply pass the parameters!


回答 2

请参阅Flask API文档以获取flask.url_for()

下面是用于将js或css链接到模板的其他用法示例片段。

<script src="{{ url_for('static', filename='jquery.min.js') }}"></script>

<link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">

Refer to the Flask API document for flask.url_for()

Other sample snippets of usage for linking js or css to your template are below.

<script src="{{ url_for('static', filename='jquery.min.js') }}"></script>

<link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">

回答 3

范本:

传递函数名称和参数。

<a href="{{ url_for('get_blog_post',id = blog.id)}}">{{blog.title}}</a>

查看功能

@app.route('/blog/post/<string:id>',methods=['GET'])
def get_blog_post(id):
    return id

Templates:

Pass function name and argument.

<a href="{{ url_for('get_blog_post',id = blog.id)}}">{{blog.title}}</a>

View,function

@app.route('/blog/post/<string:id>',methods=['GET'])
def get_blog_post(id):
    return id

究竟什么是烧瓶蓝图?

问题:究竟什么是烧瓶蓝图?

阅读官方瓶文档的蓝图,甚至一个2上使用他们的博客文章。

我什至在我的Web应用程序中使用了它们,但是我不完全了解它们是什么,或者它们如何适合我的整个应用程序。它与我的应用程序实例有何相似之处,但又不太相似?文档虽然很全面,但是我想寻求外行的解释或启发性的类比给我以启发。当一位同事要求我向他们解释我选择在这里询问的Flask蓝图时,我感到非常困惑。

I have read the official Flask documentation on Blueprints and even one or two blog posts on using them.

I’ve even used them in my web app, but I don’t completely understand what they are or how they fit into my app as a whole. How is it similar to an instance of my app but not quite? The documentation is comprehensive but I seek a layman explanation or an enlightening analogy to spark it for me. I was sufficiently perplexed when a colleague asked me to explain a Flask blueprint to them that I elected to ask here.


回答 0

蓝图是用于生成Web应用程序“部分”的模板。您可以将其视为模具:

您可以获取该蓝图,并将其应用于多个位置。每次您应用它时,该蓝图都会在您的应用程序的石膏中创建其结构的新版本。

# An example
from flask import Blueprint

tree_mold = Blueprint("mold", __name__)

@tree_mold.route("/leaves")
def leaves():
    return "This tree has leaves"

@tree_mold.route("/roots")
def roots():
    return "And roots as well"

@tree_mold.route("/rings")
@tree_mold.route("/rings/<int:year>")
def rings(year=None):
    return "Looking at the rings for {year}".format(year=year)

这是处理树木的简单模型-它说与树木打交道的任何应用程序都应提供对其叶子,根和环的访问(按年)。就其本身而言,它是一个中空的外壳-它无法路由,无法响应,直到被应用程序打动为止:

from tree_workshop import tree_mold

app.register_blueprint(tree_mold, url_prefix="/oak")
app.register_blueprint(tree_mold, url_prefix="/fir")
app.register_blueprint(tree_mold, url_prefix="/ash")

一旦创建它,​​就可以通过使用register_blueprint功能将其“打动”在应用程序上-这在所指定的位置“打动”应用程序上的蓝图模具url_prefix

A blueprint is a template for generating a “section” of a web application. You can think of it as a mold:

You can take the blueprint and apply it to your application in several places. Each time you apply it the blueprint will create a new version of its structure in the plaster of your application.

# An example
from flask import Blueprint

tree_mold = Blueprint("mold", __name__)

@tree_mold.route("/leaves")
def leaves():
    return "This tree has leaves"

@tree_mold.route("/roots")
def roots():
    return "And roots as well"

@tree_mold.route("/rings")
@tree_mold.route("/rings/<int:year>")
def rings(year=None):
    return "Looking at the rings for {year}".format(year=year)

This is a simple mold for working with trees – it says that any application that deals with trees should provide access to its leaves, its roots, and its rings (by year). By itself, it is a hollow shell – it cannot route, it cannot respond, until it is impressed upon an application:

from tree_workshop import tree_mold

app.register_blueprint(tree_mold, url_prefix="/oak")
app.register_blueprint(tree_mold, url_prefix="/fir")
app.register_blueprint(tree_mold, url_prefix="/ash")

Once it is created it may be “impressed” on the application by using the register_blueprint function – this “impresses” the mold of the blueprint on the application at the locations specified by url_prefix.


回答 1

正如@Devasish评论中指出的那样,本文提供了一个很好的答案:

http://exploreflask.com/en/latest/blueprints.html

从文章引用:

一个例子就是Facebook。如果Facebook使用Flask,它可能具有静态页面(即,登出的首页,注册,关于等),仪表板(即新闻提要),个人资料(/ robert / about和/ robert / photos)的蓝图,设置(/ settings /安全性和/ settings / privacy)等等。这些组件都具有通用的布局和样式,但是每个组件也都有自己的布局

这是一个很好的解释,尤其是“如果Facebook使用Flask”部分。它为我们提供了一个具体情况,以可视化蓝图的实际工作方式。

As pointed out in a comment by @Devasish, this article provides a good answer:

http://exploreflask.com/en/latest/blueprints.html

Quoting from the article:

An example of this would be Facebook. If Facebook used Flask, it might have blueprints for the static pages (i.e. signed-out home, register, about, etc.), the dashboard (i.e. the news feed), profiles (/robert/about and /robert/photos), settings (/settings/security and /settings/privacy) and many more. These components all share a general layout and styles, but each has its own layout as well

This is a very good interpretation, especially the part “if Facebook used Flask”. It gives us a concrete situation to visualize how Blueprint actually works.


回答 2

我自己也偶然发现了这个问题,在阅读了一些文档资料后感到困惑。起初,我认为它就像C#/ Java实现风格,您可以定义一些东西,而不必担心以后定义它。但是,我偶然发现了该页面,将其置于非常普通的外行(以及当下颇为热闹的当下事件)术语。https://hackersandslackers.com/flask-blueprints/

从本质上讲,链接中提到的一项好处是使我可以有效地逻辑组织/划分,从而使我对它在现实世界中的使用情况有一个清晰的认识。应用程序为几个部分,这些部分只需要关心它自己的事务,就。因此,它提供了一些设计好的封装。

编辑:我目前正在使用它来细分我的webapps代码。这也是一个很好的决定,因为我发现首席设计师希望在Vue.js中成为前端。我还没有使用过,但是查看它的项目文件看起来会更加混乱,并且可能提供很多命名冲突的倾向。

I too just stumbled up this myself and was confused after reading a few of the documentation sources. At first I thought it was like C#/Java Implementation style where you define some stuff but dont have to worry about it defining it til later. However, I stumbled up this page which puts it in very very laymens (and quite hilarious current day events) terms. https://hackersandslackers.com/flask-blueprints/

Essentially one benefit that is mentioned in the link and provides me a clear idea of it’s real world usage is that I can effectively logically organize/divide the app into several parts that only need to be concerned with it’s own affairs. So it provides some designed encapsulation.

Edit: I’m currently using it to segment out my webapps code. It was good decision too because I found the lead designer wants to make the frontend in Vue.js. Which I havent used yet but looking at it’s project files would look far more messy and probably provide many naming collision prone.


回答 3

对于较大的项目,您的所有代码都不应位于同一文件中。相反,您可以根据功能将较大的代码分段或拆分为单独的文件。就像砖砌墙一样。

希望这会有所帮助。由于这是一个理论性的问题,因此请不要发布任何代码。

For bigger projects, all your code shouldn’t be in the same file. Instead you can segment or split bigger codes into separate file, mostly based on functionality. Like bricks forming a wall.

Hope this helped. Since this is a theoretical question, posting no codes.