标签归档:flask

典型的AngularJS工作流程和项目结构(使用Python Flask)

问题:典型的AngularJS工作流程和项目结构(使用Python Flask)

对于整个MV *客户端框架的狂热,我还是一个新手。它不一定是AngularJS,但我选择它是因为它对我来说比淘汰赛,Ember或Backbone更自然。无论如何,工作流程是什么样的?人们是否开始在AngularJS中开发客户端应用程序,然后将其连接到后端?

还是相反,首先在Django,Flask,Rails中构建后端,然后将AngularJS应用附加到该后端?是否有“正确”的方式来做,还是最终只是个人喜好?

我也不确定是否根据Flask或AngularJS构建我的项目?社区实践。

例如,Flask的minitwit应用程序的结构如下:

minitwit
|-- minitwit.py
|-- static
   |-- css, js, images, etc...
`-- templates
   |-- html files and base layout

AngularJS教程应用程序的结构如下:

angular-phonecat
|-- app
    `-- css
    `-- img
    `-- js
    `-- lib
    `-- partials
    `-- index.html
|-- scripts
 `-- node.js server and test server files

我可以单独想象一个Flask应用程序,并且很容易看到像ToDo List这样的AngularJS应用程序,但是当同时使用这两种技术时,我不知道它们是如何协同工作的。当您已经拥有AngularJS时,似乎几乎不需要服务器端Web框架,一个简单的Python Web服务器就足够了。例如,在AngularJS待办应用程序中,他们使用MongoLab通过Restful API与数据库对话。无需在后端使用Web框架。

也许我只是非常困惑,而AngularJS只是一个花哨的jQuery库,所以我应该像在Flask项目中使用jQuery一样使用(假设我将AngularJS模板语法更改为与Jinja2不冲突的语法)。我希望我的问题有道理。我主要在后端工作,这个客户端框架对我来说是未知领域。

I am pretty new to this whole MV* client-side framework frenzy. It doesn’t have to be AngularJS, but I picked it because it feels more natural to me than either Knockout, Ember or Backbone. Anyway what is the workflow like? Do people start with developing a client-side application in AngularJS and then hooking up the back-end to it?

Or the other way around by first building the back-end in Django, Flask, Rails and then attaching an AngularJS app to it? Is there a “right” way of doing it, or is it just a personal preference in the end?

I am also not sure whether to structure my project according to the Flask or AngularJS? community practices.

For example, Flask’s minitwit app is structured like so:

minitwit
|-- minitwit.py
|-- static
   |-- css, js, images, etc...
`-- templates
   |-- html files and base layout

AngularJS tutorial app is structured like this:

angular-phonecat
|-- app
    `-- css
    `-- img
    `-- js
    `-- lib
    `-- partials
    `-- index.html
|-- scripts
 `-- node.js server and test server files

I could picture a Flask app by itself, and it’s fairly easy to see AngularJS app like ToDo List by itself but when it comes to using both of these technologies I don’t understand how they work together. It almost seems like I don’t need a server-side web-framework when you already have AngularJS, a simple Python web server will suffice. In the AngularJS to-do app for example they use MongoLab to talk to the database using Restful API. There was no need having a web framework on the back-end.

Maybe I am just awfully confused, and AngularJS is nothing more than a fancy jQuery library so I should use just like I would use jQuery in my Flask projects (assuming I change the AngularJS template syntax to something that doesn’t conflict with Jinja2). I hope my questions make some sense. I mainly work on the back-end and this client-side framework is an unknown territory for me.


回答 0

首先,我将以标准结构组织Flask应用程序,如下所示:

app
|-- app.py
|-- static
    |-- css
    |-- img
    |-- js
|-- templates

正如btford所提到的,如果您正在开发Angular应用程序,则需要集中精力使用Angular客户端模板,而远离服务器端模板。使用render_template(’index.html’)会使Flask将您的角度模板解释为Jinja模板,因此它们将无法正确渲染。相反,您需要执行以下操作:

@app.route("/")
def index():
    return send_file('templates/index.html')

请注意,使用send_file()意味着文件将被缓存,因此您至少在开发时可能要使用make_response():

    return make_response(open('templates/index.html').read())

然后,构建应用程序的AngularJS部分,修改应用程序结构,使其看起来像这样:

app
|-- app.py
|-- static
    |-- css
    |-- img
    |-- js
        |-- app.js, controllers.js, etc.
    |-- lib
        |-- angular
            |-- angular.js, etc.
    |-- partials
|-- templates
    |-- index.html

确保index.html包含AngularJS以及任何其他文件:

<script src="static/lib/angular/angular.js"></script>

此时,您尚未构建RESTful API,因此可以让js控制器返回预定义的示例数据(仅是临时设置)。准备就绪后,实现RESTful API并使用angular-resource.js将其连接到您的angular应用程序。

编辑:我整理了一个应用程序模板,尽管比我上面描述的要复杂一些,但它说明了如何使用AngularJS + Flask构建应用程序,并完成了AngularJS和简单的Flask API之间的通信。如果您想签出,这里是这里:https : //github.com/rxl/angular-flask

I would start out by organizing the Flask app in the standard structure as follows:

app
|-- app.py
|-- static
    |-- css
    |-- img
    |-- js
|-- templates

And as btford mentioned, if you are doing an Angular app, you’ll want to focus on using Angular client-side templates and stay away from server-side templates. Using render_template(‘index.html’) will cause Flask to interpret your angular templates as jinja templates, so they won’t render correctly. Instead, you’ll want to do the following:

@app.route("/")
def index():
    return send_file('templates/index.html')

Note that using send_file() means that the files will be cached, so you might want to use make_response() instead, at least for development:

    return make_response(open('templates/index.html').read())

Afterwards, build out the AngularJS part of your app, modifying the app structure so that it looks like this:

app
|-- app.py
|-- static
    |-- css
    |-- img
    |-- js
        |-- app.js, controllers.js, etc.
    |-- lib
        |-- angular
            |-- angular.js, etc.
    |-- partials
|-- templates
    |-- index.html

Make sure your index.html includes AngularJS, as well as any other files:

<script src="static/lib/angular/angular.js"></script>

At this point, you haven’t yet constructed your RESTful API, so you can have your js controllers return predefined sample data (only a temporary setup). When you’re ready, implement the RESTful API and hook it up to your angular app with angular-resource.js.

EDIT: I put together an app template that, though a little more complex that what I’ve described above, illustrates how one could build an app with AngularJS + Flask, complete with communication between AngularJS and a simple Flask API. Here it is if you want to check it out: https://github.com/rxl/angular-flask


回答 1

您可以从任一端开始。

没错,AngularJS可能不需要完整的服务器端框架。通常,最好提供静态HTML / CSS / JavaScript文件,并为后端提供RESTful API供客户端使用。您可能应该避免的一件事是将服务器端模板与AngularJS客户端模板混合。

如果您想使用Flask来提供文件(可能有些过头,但仍然可以使用它),则可以将“ app”的内容从“ angular-phonecat”复制到“ minitwit”的“ static”文件夹中。

AngularJS的目标是类似AJAX的应用程序,而flask使您能够执行旧式Web应用程序以及创建RESTful API。每种方法都有优点和缺点,因此它实际上取决于您要执行的操作。如果您给我一些见解,我也许可以提出更多建议。

You can start on either end.

You are right that you probably don’t need a full server-side framework with AngularJS. It’s typically better to serve static HTML/CSS/JavaScript files, and provide a RESTful API for the back end for the client to consume. One thing that you should probably avoid is mixing server-side templates with AngularJS client-side templates.

If you want to use Flask to serve your files (might be overkill, but you can use it nonetheless) you would copy the contents of “app” from “angular-phonecat” into the “static” folder of “minitwit.”

AngularJS is more targeted at AJAX-like applications, whereas flask gives you the ability to do both the older-style web apps as well as create RESTful APIs. There are advantages and disadvantages to each approach, so it really depends what you want to do. If you give me some insights, I might be able to make further recommendations.


回答 2

John Lindquist的这个Jetbrains PyCharm官方视频(angular.js和jetbrains大师)是一个不错的起点,因为它显示了烧瓶中Web服务,数据库和angular.js的相互作用。

他在不到25分钟的时间内使用flask,sqlalchemy,flask-restless和angular.js 构建了一个pinterest克隆

欣赏:http//www.youtube.com/watch?v = 2geC50roans

This official Jetbrains PyCharm video by John Lindquist (angular.js and jetbrains guru) is a nice starting point as it shows the interplay of webservice, database and angular.js within flask.

He builds a pinterest clone with flask, sqlalchemy, flask-restless and angular.js in less than 25 minutes.

Enjoy: http://www.youtube.com/watch?v=2geC50roans


回答 3

编辑:新的Angular2样式指南更详细地建议了一个相似的结构,即使不是相同的结构。

下面的答案针对大型项目。我花了很多时间思考和尝试几种方法,因此我可以将一些用于后端功能的服务器端框架(在我的情况下为Flask和App Engine)与客户端框架(例如Angular)结合起来。这两个答案都很好,但是我想提出一个稍微不同的方法(至少在我看来),以一种更人性化的方式进行扩展。

当您实现TODO示例时,事情就很简单了。当您开始添加功能以及改善用户体验的细微细节时,不难发现样式,javascript等混乱。

我的应用程序开始变得很大,因此我不得不退后一步并重新思考。最初,通过将所有样式和所有JavaScript合并在一起,可以采用上述建议的方法,但是这种方法不是模块化的,也不容易维护。

如果我们按功能而非文件类型组织客户端代码怎么办:

app
|-- server
    |-- controllers
        |-- app.py
    |-- models
        |-- model.py
    |-- templates
        |-- index.html
|-- static
    |-- img
    |-- client
        |-- app.js
        |-- main_style.css
        |-- foo_feature
            |-- controller.js
            |-- directive.js
            |-- service.js
            |-- style.css
            |-- html_file.tpl.html
        |-- bar_feature
            |-- controller.js
            |-- directive.js
            |-- service.js
            |-- style.css
            |-- html_file.tpl.html
    |-- lib
        |-- jquery.js
        |-- angular.js
        |-- ...

等等。

如果我们这样构建它,我们可以将我们的每个目录都包装在angular模块中。而且我们以一种很好的方式拆分了文件,当我们使用特定功能时,我们不必经过不相关的代码。

正确配置了诸如Grunt的任务运行程序,将能够轻松找到并连接和编译文件。

edit: The new Angular2 style guide suggests a similar, if not the same structure in much more detail.

The answer below target large scale projects. I have spend quite some time thinking and experimenting with several approaches so I can combine some server side framework (Flask with App Engine in my case) for back-end functionality along with a client side framework like Angular. Both answers are very good, but I would like to suggest a slightly different approach which (in my mind at least) scales in a more human way.

When you are implementing a TODO example, things are quite straight forward. When you start adding functionality though and small nice details for user experience improvement, its not difficult to get lost in chaos of styles, javascript etc..

My application started to grow quite big, so I had to take a step back and rethink. Initially an approach like suggested above would work, by having all the styles together and all JavaScript together, but its not modular and not easily maintainable.

What if we organized the client code per feature and not per file type:

app
|-- server
    |-- controllers
        |-- app.py
    |-- models
        |-- model.py
    |-- templates
        |-- index.html
|-- static
    |-- img
    |-- client
        |-- app.js
        |-- main_style.css
        |-- foo_feature
            |-- controller.js
            |-- directive.js
            |-- service.js
            |-- style.css
            |-- html_file.tpl.html
        |-- bar_feature
            |-- controller.js
            |-- directive.js
            |-- service.js
            |-- style.css
            |-- html_file.tpl.html
    |-- lib
        |-- jquery.js
        |-- angular.js
        |-- ...

and so on.

If we build it like this, we can wrap every directory of ours in an angular module. And we have split our files in a nice way that we don’t have to go through irrelevant code when we are working with a specific feature.

A task runner like Grunt properly configured, will be able to find and concatenate and compile your files without much hassle.


回答 4

另一种选择是将两者完全分开。

项目
|-服务器
|-客户

与flask相关的文件位于服务器文件夹下,而与angularjs相关的文件位于客户端文件夹下。这样,将更容易更改后端或前端。例如,将来您可能希望从Flask切换到Django或从AngularJS切换到ReactJS。

Another option is to completely separate the two.

project
|-- server
|-- client

Files related to flask goes under the server folder and files related to angularjs goes under the client folder. This way, it will be easier to change the backend or front-end. For example, you might want to switch from Flask to Django or AngularJS to ReactJS in the future.


回答 5

我认为确定大部分数据处理的目标是前端还是后端很重要。
如果是前端,则使用有角度的工作流程,这意味着您的flask应用程序将更多地充当api的角色,在该api中,如flask-restful的扩展将结束。

但是,如果像我一样,您需要在后端完成大部分工作,然后使用flask结构,仅插入有角度的插件(或在我的情况下为vue.js)来构建前端(必要时)

I think it is important to determine at what end you want to do most of your data processing – front end or back end.
If it’s front end, then go with the angular workflow, which means your flask app will function as more of an api where an extension like flask-restful will come end.

But if like me, you are doing most work on the backend, then go with the flask structure and only plug angular ( or in my case vue.js) to build the front end (when neccessary)


json.dumps与flask.jsonify

问题:json.dumps与flask.jsonify

我不确定我是否了解该flask.jsonify方法的目的。我尝试从中制作一个JSON字符串:

data = {"id": str(album.id), "title": album.title}

但是我得到的与我得到的json.dumps有所不同flask.jsonify

json.dumps(data): [{"id": "4ea856fd6506ae0db42702dd", "title": "Business"}]
flask.jsonify(data): {"id":…, "title":…}

显然,我需要得到一个看起来更像json.dumps返回结果的结果。我究竟做错了什么?

I am not sure I understand the purpose of the flask.jsonify method. I try to make a JSON string from this:

data = {"id": str(album.id), "title": album.title}

but what I get with json.dumps differs from what I get with flask.jsonify.

json.dumps(data): [{"id": "4ea856fd6506ae0db42702dd", "title": "Business"}]
flask.jsonify(data): {"id":…, "title":…}

Obviously I need to get a result that looks more like what json.dumps returns. What am I doing wrong?


回答 0

jsonify()flask中的函数返回一个flask.Response()对象,该对象已经具有用于json响应的适当的内容类型标头’application / json’。而该json.dumps()方法将仅返回编码后的字符串,这将需要手动添加MIME类型标头。

查看更多有关该jsonify()功能在这里完全参考。

编辑:另外,我注意到它可以jsonify()处理kwarg或字典,同时json.dumps()还支持列表和其他列表。

The jsonify() function in flask returns a flask.Response() object that already has the appropriate content-type header ‘application/json’ for use with json responses. Whereas, the json.dumps() method will just return an encoded string, which would require manually adding the MIME type header.

See more about the jsonify() function here for full reference.

Edit: Also, I’ve noticed that jsonify() handles kwargs or dictionaries, while json.dumps() additionally supports lists and others.


回答 1

你可以做:

flask.jsonify(**data)

要么

flask.jsonify(id=str(album.id), title=album.title)

You can do:

flask.jsonify(**data)

or

flask.jsonify(id=str(album.id), title=album.title)

回答 2

这是 flask.jsonify()

def jsonify(*args, **kwargs):
    if __debug__:
        _assert_have_json()
    return current_app.response_class(json.dumps(dict(*args, **kwargs),
        indent=None if request.is_xhr else 2), mimetype='application/json')

json使用的模块是simplejsonjson顺序相同。current_app是对Flask()对象(即您的应用程序)的引用。response_class()是对该Response()类的引用。

This is flask.jsonify()

def jsonify(*args, **kwargs):
    if __debug__:
        _assert_have_json()
    return current_app.response_class(json.dumps(dict(*args, **kwargs),
        indent=None if request.is_xhr else 2), mimetype='application/json')

The json module used is either simplejson or json in that order. current_app is a reference to the Flask() object i.e. your application. response_class() is a reference to the Response() class.


回答 3

一个或另一个的选择取决于您打算做什么。据我了解:

  • 当您构建一个有人查询并期望json作为回报的API时,jsonify会很有用。例如:REST github API可以使用此方法来回答您的请求。

  • dumps,更多关于将数据/ python对象格式化为json并在您的应用程序中进行处理。例如,我需要将一个对象传递给我的表示层,其中一些javascript将显示图形。您将使用转储生成的Json喂javascript。

The choice of one or another depends on what you intend to do. From what I do understand:

  • jsonify would be useful when you are building an API someone would query and expect json in return. E.g: The REST github API could use this method to answer your request.

  • dumps, is more about formating data/python object into json and work on it inside your application. For instance, I need to pass an object to my representation layer where some javascript will display graph. You’ll feed javascript with the Json generated by dumps.


回答 4

考虑

data={'fld':'hello'}

现在

jsonify(data)

将产生{‘fld’:’hello’}并且

json.dumps(data)

"<html><body><p>{'fld':'hello'}</p></body></html>"

consider

data={'fld':'hello'}

now

jsonify(data)

will yield {‘fld’:’hello’} and

json.dumps(data)

gives

"<html><body><p>{'fld':'hello'}</p></body></html>"

Flask可以有可选的URL参数吗?

问题:Flask可以有可选的URL参数吗?

是否可以直接声明Flask URL可选参数?

目前,我正在按照以下方式进行:

@user.route('/<userId>')
@user.route('/<userId>/<username>')
def show(userId, username=None):
    pass

我如何直接说这username是可选的?

Is it possible to directly declare a flask URL optional parameter?

Currently I’m proceeding the following way:

@user.route('/<userId>')
@user.route('/<userId>/<username>')
def show(userId, username=None):
    pass

How can I directly say that username is optional?


回答 0

另一种方法是写

@user.route('/<user_id>', defaults={'username': None})
@user.route('/<user_id>/<username>')
def show(user_id, username):
    pass

但是我想您想编写一条路由并将其标记username为可选?如果是这样,我认为不可能。

Another way is to write

@user.route('/<user_id>', defaults={'username': None})
@user.route('/<user_id>/<username>')
def show(user_id, username):
    pass

But I guess that you want to write a single route and mark username as optional? If that’s the case, I don’t think it’s possible.


回答 1

几乎与几个月前完成的Audrius一样,但是您可能会发现它与函数头中的默认设置相比更具可读性-习惯于python:

@app.route('/<user_id>')
@app.route('/<user_id>/<username>')
def show(user_id, username='Anonymous'):
    return user_id + ':' + username

Almost the same as Audrius cooked up some months ago, but you might find it a bit more readable with the defaults in the function head – the way you are used to with python:

@app.route('/<user_id>')
@app.route('/<user_id>/<username>')
def show(user_id, username='Anonymous'):
    return user_id + ':' + username

回答 2

如果您像我一样使用Flask-Restful,也可以这样:

api.add_resource(UserAPI, '/<userId>', '/<userId>/<username>', endpoint = 'user')

然后在您的Resource类中:

class UserAPI(Resource):

  def get(self, userId, username=None):
    pass

If you are using Flask-Restful like me, it is also possible this way:

api.add_resource(UserAPI, '/<userId>', '/<userId>/<username>', endpoint = 'user')

a then in your Resource class:

class UserAPI(Resource):

  def get(self, userId, username=None):
    pass

回答 3

@user.route('/<userId>/')  # NEED '/' AFTER LINK
@user.route('/<userId>/<username>')
def show(userId, username=None):
    pass

https://flask.palletsprojects.com/zh-CN/1.1.x/quickstart/#unique-urls-redirection-behavior

@user.route('/<userId>/')  # NEED '/' AFTER LINK
@user.route('/<userId>/<username>')
def show(userId, username=None):
    pass

https://flask.palletsprojects.com/en/1.1.x/quickstart/#unique-urls-redirection-behavior


回答 4

@app.route('/', defaults={'path': ''})
@app.route('/< path:path >')
def catch_all(path):
    return 'You want path: %s' % path

http://flask.pocoo.org/snippets/57/

@app.route('/', defaults={'path': ''})
@app.route('/< path:path >')
def catch_all(path):
    return 'You want path: %s' % path

http://flask.pocoo.org/snippets/57/


回答 5

@user.route('/<user_id>', defaults={'username': default_value})
@user.route('/<user_id>/<username>')
def show(user_id, username):
   #
   pass
@user.route('/<user_id>', defaults={'username': default_value})
@user.route('/<user_id>/<username>')
def show(user_id, username):
   #
   pass

回答 6

与skornos几乎相同,但具有变量声明以提供更明确的答案。它可以与Flask-RESTful扩展一起使用

from flask import Flask
from flask_restful import Resource, Api

app = Flask(__name__)
api = Api(app)

class UserAPI(Resource):
    def show(userId, username=None):
    pass

api.add_resource(UserAPI, '/<userId>', '/<userId>/<username>', endpoint='user')

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

add_resource方法允许传递多个URL。每个将被路由到您的资源

Almost the same as skornos, but with variable declarations for a more explicit answer. It can work with Flask-RESTful extension:

from flask import Flask
from flask_restful import Resource, Api

app = Flask(__name__)
api = Api(app)

class UserAPI(Resource):
    def show(userId, username=None):
    pass

api.add_resource(UserAPI, '/<userId>', '/<userId>/<username>', endpoint='user')

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

The add_resource method allows pass multiples URLs. Each one will be routed to your Resource.


回答 7

我知道这篇文章确实很老,但是我从事的是一个名为flask_optional_routes的软件包。该代码位于:https : //github.com/sudouser2010/flask_optional_routes

from flask import Flask

from flask_optional_routes import OptionalRoutes


app = Flask(__name__)
optional = OptionalRoutes(app)

@optional.routes('/<user_id>/<user_name>?/')
def foobar(user_id, user_name=None):
    return 'it worked!'

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

I know this post is really old but I worked on a package that does this called flask_optional_routes. The code is located at: https://github.com/sudouser2010/flask_optional_routes.

from flask import Flask

from flask_optional_routes import OptionalRoutes


app = Flask(__name__)
optional = OptionalRoutes(app)

@optional.routes('/<user_id>/<user_name>?/')
def foobar(user_id, user_name=None):
    return 'it worked!'

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

回答 8

您可以按照示例中所示进行编写,但是会遇到构建错误。

要解决此问题:

  1. 在您的root .py中打印app.url_map()
  2. 您会看到类似以下内容的内容:

<Rule '/<userId>/<username>' (HEAD, POST, OPTIONS, GET) -> user.show_0>

<Rule '/<userId>' (HEAD, POST, OPTIONS, GET) -> .show_1>

  1. 比模板,你可以{{ url_for('.show_0', args) }}{{ url_for('.show_1', args) }}

You can write as you show in example, but than you get build-error.

For fix this:

  1. print app.url_map () in you root .py
  2. you see something like:

<Rule '/<userId>/<username>' (HEAD, POST, OPTIONS, GET) -> user.show_0>

and

<Rule '/<userId>' (HEAD, POST, OPTIONS, GET) -> .show_1>

  1. than in template you can {{ url_for('.show_0', args) }} and {{ url_for('.show_1', args) }}

回答 9

从Flask 0.10开始,您无法将多个路由添加到一个端点。但是您可以添加伪造的端点

@user.route('/<userId>')
def show(userId):
   return show_with_username(userId)

@user.route('/<userId>/<username>')
def show_with_username(userId,username=None):
   pass

Since Flask 0.10 you can`t add multiple routes to one endpoint. But you can add fake endpoint

@user.route('/<userId>')
def show(userId):
   return show_with_username(userId)

@user.route('/<userId>/<username>')
def show_with_username(userId,username=None):
   pass

回答 10

我认为您可以使用Blueprint,这将使您的代码看起来更好,更整洁。

例:

from flask import Blueprint

bp = Blueprint(__name__, "example")

@bp.route("/example", methods=["POST"])
def example(self):
   print("example")

I think you can use Blueprint and that’s will make ur code look better and neatly.

example:

from flask import Blueprint

bp = Blueprint(__name__, "example")

@bp.route("/example", methods=["POST"])
def example(self):
   print("example")

如何使用Flask从URL获取命名参数?

问题:如何使用Flask从URL获取命名参数?

当用户访问在我的flask应用程序上运行的URL时,我希望Web服务能够处理问号后指定的参数:

http://10.1.1.1:5000/login?username=alex&password=pw1

#I just want to be able to manipulate the parameters
@app.route('/login', methods=['GET', 'POST'])
def login():
    username = request.form['username']
    print(username)
    password = request.form['password']
    print(password)

When the user accesses this URL running on my flask app, I want the web service to be able to handle the parameters specified after the question mark:

http://10.1.1.1:5000/login?username=alex&password=pw1

#I just want to be able to manipulate the parameters
@app.route('/login', methods=['GET', 'POST'])
def login():
    username = request.form['username']
    print(username)
    password = request.form['password']
    print(password)

回答 0

使用request.args得到解析查询字符串的内容:

from flask import request

@app.route(...)
def login():
    username = request.args.get('username')
    password = request.args.get('password')

Use request.args to get parsed contents of query string:

from flask import request

@app.route(...)
def login():
    username = request.args.get('username')
    password = request.args.get('password')

回答 1

URL参数可在中使用request.args,它是具有方法的ImmutableMultiDict,具有get默认值(default)和类型(type)的可选参数-这是可调用的方法,可将输入值转换为所需的格式。(有关更多详细信息,请参见该方法文档。)

from flask import request

@app.route('/my-route')
def my_route():
  page = request.args.get('page', default = 1, type = int)
  filter = request.args.get('filter', default = '*', type = str)

上面的代码示例:

/my-route?page=34               -> page: 34  filter: '*'
/my-route                       -> page:  1  filter: '*'
/my-route?page=10&filter=test   -> page: 10  filter: 'test'
/my-route?page=10&filter=10     -> page: 10  filter: '10'
/my-route?page=*&filter=*       -> page:  1  filter: '*'

The URL parameters are available in request.args, which is an ImmutableMultiDict that has a get method, with optional parameters for default value (default) and type (type) – which is a callable that converts the input value to the desired format. (See the documentation of the method for more details.)

from flask import request

@app.route('/my-route')
def my_route():
  page = request.args.get('page', default = 1, type = int)
  filter = request.args.get('filter', default = '*', type = str)

Examples with the code above:

/my-route?page=34               -> page: 34  filter: '*'
/my-route                       -> page:  1  filter: '*'
/my-route?page=10&filter=test   -> page: 10  filter: 'test'
/my-route?page=10&filter=10     -> page: 10  filter: '10'
/my-route?page=*&filter=*       -> page:  1  filter: '*'

回答 2

您还可以在视图定义的URL上使用方括号<>,此输入将进入您的视图函数参数

@app.route('/<name>')
def my_view_func(name):
    return name

You can also use brackets <> on the URL of the view definition and this input will go into your view function arguments

@app.route('/<name>')
def my_view_func(name):
    return name

回答 3

如果您在URL中传递了一个参数,则可以按照以下步骤进行操作

from flask import request
#url
http://10.1.1.1:5000/login/alex

from flask import request
@app.route('/login/<username>', methods=['GET'])
def login(username):
    print(username)

如果您有多个参数:

#url
http://10.1.1.1:5000/login?username=alex&password=pw1

from flask import request
@app.route('/login', methods=['GET'])
    def login():
        username = request.args.get('username')
        print(username)
        password= request.args.get('password')
        print(password)

在POST请求的情况下,您尝试执行的操作将参数作为表单参数传递并且不出现在URL中。如果您实际上正在开发登录API,建议您使用POST请求而不是GET,并将数据公开给用户。

如果有职位要求,它将按以下方式工作:

#url
http://10.1.1.1:5000/login

HTML片段:

<form action="http://10.1.1.1:5000/login" method="POST">
  Username : <input type="text" name="username"><br>
  Password : <input type="password" name="password"><br>
  <input type="submit" value="submit">
</form>

路线:

from flask import request
@app.route('/login', methods=['POST'])
    def login():
        username = request.form.get('username')
        print(username)
        password= request.form.get('password')
        print(password)

If you have a single argument passed in the URL you can do it as follows

from flask import request
#url
http://10.1.1.1:5000/login/alex

from flask import request
@app.route('/login/<username>', methods=['GET'])
def login(username):
    print(username)

In case you have multiple parameters:

#url
http://10.1.1.1:5000/login?username=alex&password=pw1

from flask import request
@app.route('/login', methods=['GET'])
    def login():
        username = request.args.get('username')
        print(username)
        password= request.args.get('password')
        print(password)

What you were trying to do works in case of POST requests where parameters are passed as form parameters and do not appear in the URL. In case you are actually developing a login API, it is advisable you use POST request rather than GET and expose the data to the user.

In case of post request, it would work as follows:

#url
http://10.1.1.1:5000/login

HTML snippet:

<form action="http://10.1.1.1:5000/login" method="POST">
  Username : <input type="text" name="username"><br>
  Password : <input type="password" name="password"><br>
  <input type="submit" value="submit">
</form>

Route:

from flask import request
@app.route('/login', methods=['POST'])
    def login():
        username = request.form.get('username')
        print(username)
        password= request.form.get('password')
        print(password)

回答 4

网址:

http://0.0.0.0:5000/user/name/

码:

@app.route('/user/<string:name>/', methods=['GET', 'POST'])
def user_view(name):
    print(name)

(编辑:删除格式字符串中的空格)

url:

http://0.0.0.0:5000/user/name/

code:

@app.route('/user/<string:name>/', methods=['GET', 'POST'])
def user_view(name):
    print(name)

(Edit: removed spaces in format string)


回答 5

真的很简单。让我将此过程分为两个简单步骤。

  1. 在html模板上,您将用户名和密码的名称标签声明为

    <form method="POST">
    <input type="text" name="user_name"></input>
    <input type="text" name="password"></input>
    </form>
  2. 然后,将代码修改为:

    from flask import request
    
    @app.route('/my-route', methods=['POST']) #you should always parse username and 
    # password in a POST method not GET
    def my_route():
      username = request.form.get("user_name")
      print(username)
      password = request.form.get("password")
      print(password)
    #now manipulate the username and password variables as you wish
    #Tip: define another method instead of methods=['GET','POST'], if you want to  
    # render the same template with a GET request too

It’s really simple. Let me divide this process into two simple steps.

  1. On the html template you will declare name tag for username and password as

    <form method="POST">
    <input type="text" name="user_name"></input>
    <input type="text" name="password"></input>
    </form>
    
  2. Then, modify your code as:

    from flask import request
    
    @app.route('/my-route', methods=['POST']) #you should always parse username and 
    # password in a POST method not GET
    def my_route():
      username = request.form.get("user_name")
      print(username)
      password = request.form.get("password")
      print(password)
    #now manipulate the username and password variables as you wish
    #Tip: define another method instead of methods=['GET','POST'], if you want to  
    # render the same template with a GET request too
    

回答 6

使用request.args.get(param),例如:

http://10.1.1.1:5000/login?username=alex&password=pw1
@app.route('/login', methods=['GET', 'POST'])
def login():
    username = request.args.get('username')
    print(username)
    password = request.args.get('password')
    print(password)

这是代码的引用链接。

Use request.args.get(param), for example:

http://10.1.1.1:5000/login?username=alex&password=pw1
@app.route('/login', methods=['GET', 'POST'])
def login():
    username = request.args.get('username')
    print(username)
    password = request.args.get('password')
    print(password)

Here is the referenced link to the code.


如何在Flask中获取POST JSON?

问题:如何在Flask中获取POST JSON?

我正在尝试使用Flask构建一个简单的API,现在我想在其中读取一些POSTed JSON。我使用Postman Chrome扩展程序执行POST,而我发布的JSON就是{"text":"lalala"}。我尝试使用以下方法读取JSON:

@app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
    content = request.json
    print content
    return uuid

在浏览器上,它可以正确返回我放入GET中的UUID,但是在控制台上,它只是打印出来None(我希望它可以在其中打印出来{"text":"lalala"}。有人知道我如何从Flask方法中获取发布的JSON吗?

I’m trying to build a simple API using Flask, in which I now want to read some POSTed JSON. I do the POST with the Postman Chrome extension, and the JSON I POST is simply {"text":"lalala"}. I try to read the JSON using the following method:

@app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
    content = request.json
    print content
    return uuid

On the browser it correctly returns the UUID I put in the GET, but on the console, it just prints out None (where I expect it to print out the {"text":"lalala"}. Does anybody know how I can get the posted JSON from within the Flask method?


回答 0

首先,该.json属性是一个委托给request.get_json()method的属性,该属性记录了为什么None在此处看到。

您需要将请求内容类型设置为,application/json以使.json属性和.get_json()方法(不带参数)起作用,None否则两者都会产生这种情况。请参阅Flask Request文档

如果mimetype表示JSON(包含application / json,请参见is_json()),则它将包含已解析的JSON数据,否则为None

您可以request.get_json()通过向其传递force=True关键字参数来告知跳过内容类型要求。

请注意,如果此时引发异常(可能导致400 Bad Request响应),则您的JSON 数据无效。它在某种程度上畸形;您可能需要使用JSON验证程序进行检查。

First of all, the .json attribute is a property that delegates to the request.get_json() method, which documents why you see None here.

You need to set the request content type to application/json for the .json property and .get_json() method (with no arguments) to work as either will produce None otherwise. See the Flask Request documentation:

This will contain the parsed JSON data if the mimetype indicates JSON (application/json, see is_json()), otherwise it will be None.

You can tell request.get_json() to skip the content type requirement by passing it the force=True keyword argument.

Note that if an exception is raised at this point (possibly resulting in a 400 Bad Request response), your JSON data is invalid. It is in some way malformed; you may want to check it with a JSON validator.


回答 1

作为参考,以下是有关如何从Python客户端发送json的完整代码:

import requests
res = requests.post('http://localhost:5000/api/add_message/1234', json={"mytext":"lalala"})
if res.ok:
    print res.json()

“ json =“输入将自动设置内容类型,如下所述:使用Python请求发布JSON

以上客户端将使用此服务器端代码:

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

@app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
    content = request.json
    print content['mytext']
    return jsonify({"uuid":uuid})

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

For reference, here’s complete code for how to send json from a Python client:

import requests
res = requests.post('http://localhost:5000/api/add_message/1234', json={"mytext":"lalala"})
if res.ok:
    print res.json()

The “json=” input will automatically set the content-type, as discussed here: Post JSON using Python Requests

And the above client will work with this server-side code:

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

@app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
    content = request.json
    print content['mytext']
    return jsonify({"uuid":uuid})

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

回答 2

这就是我要做的方法,应该是

@app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
    content = request.get_json(silent=True)
    # print(content) # Do your processing
    return uuid

随着silent=True集,该get_json功能将尝试检索JSON的身体的时候默默的失败。默认情况下,此设置为False。如果您始终希望使用json正文(而不是可选),请将其保留为silent=False

设置force=True将忽略request.headers.get('Content-Type') == 'application/json'烧瓶对您的 检查。默认情况下,它也设置为False

请参见烧瓶文档

我强烈建议您离开force=False并让客户端发送Content-Type标头以使其更加明确。

希望这可以帮助!

This is the way I would do it and it should be

@app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
    content = request.get_json(silent=True)
    # print(content) # Do your processing
    return uuid

With silent=True set, the get_json function will fail silently when trying to retrieve the json body. By default this is set to False. If you are always expecting a json body (not optionally), leave it as silent=False.

Setting force=True will ignore the request.headers.get('Content-Type') == 'application/json' check that flask does for you. By default this is also set to False.

See flask documentation.

I would strongly recommend leaving force=False and make the client send the Content-Type header to make it more explicit.

Hope this helps!


回答 3

假设您已发布具有application/json内容类型的有效JSON ,request.json将具有已解析的JSON数据。

from flask import Flask, request, jsonify

app = Flask(__name__)


@app.route('/echo', methods=['POST'])
def hello():
   return jsonify(request.json)

Assuming you’ve posted valid JSON with the application/json content type, request.json will have the parsed JSON data.

from flask import Flask, request, jsonify

app = Flask(__name__)


@app.route('/echo', methods=['POST'])
def hello():
   return jsonify(request.json)

回答 4

对于所有问题都是来自ajax调用的人,这里有一个完整的示例:

Ajax调用:这里的关键是使用a dict然后JSON.stringify

    var dict = {username : "username" , password:"password"};

    $.ajax({
        type: "POST", 
        url: "http://127.0.0.1:5000/", //localhost Flask
        data : JSON.stringify(dict),
        contentType: "application/json",
    });

在服务器端:

from flask import Flask
from flask import request
import json

app = Flask(__name__)

@app.route("/",  methods = ['POST'])
def hello():
    print(request.get_json())
    return json.dumps({'success':True}), 200, {'ContentType':'application/json'} 

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

For all those whose issue was from the ajax call, here is a full example :

Ajax call : the key here is to use a dict and then JSON.stringify

    var dict = {username : "username" , password:"password"};

    $.ajax({
        type: "POST", 
        url: "http://127.0.0.1:5000/", //localhost Flask
        data : JSON.stringify(dict),
        contentType: "application/json",
    });

And on server side :

from flask import Flask
from flask import request
import json

app = Flask(__name__)

@app.route("/",  methods = ['POST'])
def hello():
    print(request.get_json())
    return json.dumps({'success':True}), 200, {'ContentType':'application/json'} 

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

回答 5

给出另一种方法。

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

@app.route('/service', methods=['POST'])
def service():
    data = json.loads(request.data)
    text = data.get("text",None)
    if text is None:
        return jsonify({"message":"text not found"})
    else:
        return jsonify(data)

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

To give another approach.

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

@app.route('/service', methods=['POST'])
def service():
    data = json.loads(request.data)
    text = data.get("text",None)
    if text is None:
        return jsonify({"message":"text not found"})
    else:
        return jsonify(data)

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

回答 6

假设您发布了有效的JSON,

@app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
    content = request.json
    print content['uuid']
    # Return data as JSON
    return jsonify(content)

Assuming that you have posted valid JSON,

@app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
    content = request.json
    print content['uuid']
    # Return data as JSON
    return jsonify(content)

回答 7

尝试使用力参数…

request.get_json(force = True)

Try to use force parameter…

request.get_json(force = True)


如何在Flask中提供静态文件

问题:如何在Flask中提供静态文件

所以这很尴尬。我有一个集成在一起的应用程序,Flask现在它只提供一个静态HTML页面,其中包含指向CSS和JS的链接。而且我找不到文档中Flask描述返回静态文件的位置。是的,我可以使用,render_template但是我知道数据没有模板化。我还以为send_file或者url_for是正确的事情,但我不能让这些工作。同时,我正在打开文件,阅读内容,并装配Response具有适当mimetype的:

import os.path

from flask import Flask, Response


app = Flask(__name__)
app.config.from_object(__name__)


def root_dir():  # pragma: no cover
    return os.path.abspath(os.path.dirname(__file__))


def get_file(filename):  # pragma: no cover
    try:
        src = os.path.join(root_dir(), filename)
        # Figure out how flask returns static files
        # Tried:
        # - render_template
        # - send_file
        # This should not be so non-obvious
        return open(src).read()
    except IOError as exc:
        return str(exc)


@app.route('/', methods=['GET'])
def metrics():  # pragma: no cover
    content = get_file('jenkins_analytics.html')
    return Response(content, mimetype="text/html")


@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def get_resource(path):  # pragma: no cover
    mimetypes = {
        ".css": "text/css",
        ".html": "text/html",
        ".js": "application/javascript",
    }
    complete_path = os.path.join(root_dir(), path)
    ext = os.path.splitext(path)[1]
    mimetype = mimetypes.get(ext, "text/html")
    content = get_file(complete_path)
    return Response(content, mimetype=mimetype)


if __name__ == '__main__':  # pragma: no cover
    app.run(port=80)

有人要为此提供代码示例或网址吗?我知道这将变得简单。

So this is embarrassing. I’ve got an application that I threw together in Flask and for now it is just serving up a single static HTML page with some links to CSS and JS. And I can’t find where in the documentation Flask describes returning static files. Yes, I could use render_template but I know the data is not templatized. I’d have thought send_file or url_for was the right thing, but I could not get those to work. In the meantime, I am opening the files, reading content, and rigging up a Response with appropriate mimetype:

import os.path

from flask import Flask, Response


app = Flask(__name__)
app.config.from_object(__name__)


def root_dir():  # pragma: no cover
    return os.path.abspath(os.path.dirname(__file__))


def get_file(filename):  # pragma: no cover
    try:
        src = os.path.join(root_dir(), filename)
        # Figure out how flask returns static files
        # Tried:
        # - render_template
        # - send_file
        # This should not be so non-obvious
        return open(src).read()
    except IOError as exc:
        return str(exc)


@app.route('/', methods=['GET'])
def metrics():  # pragma: no cover
    content = get_file('jenkins_analytics.html')
    return Response(content, mimetype="text/html")


@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def get_resource(path):  # pragma: no cover
    mimetypes = {
        ".css": "text/css",
        ".html": "text/html",
        ".js": "application/javascript",
    }
    complete_path = os.path.join(root_dir(), path)
    ext = os.path.splitext(path)[1]
    mimetype = mimetypes.get(ext, "text/html")
    content = get_file(complete_path)
    return Response(content, mimetype=mimetype)


if __name__ == '__main__':  # pragma: no cover
    app.run(port=80)

Someone want to give a code sample or url for this? I know this is going to be dead simple.


回答 0

首选方法是使用nginx或其他Web服务器提供静态文件。他们将比Flask更有效率。

但是,您可以使用send_from_directory从目录发送文件,这在某些情况下非常方便:

from flask import Flask, request, send_from_directory

# set the project root directory as the static folder, you can set others.
app = Flask(__name__, static_url_path='')

@app.route('/js/<path:path>')
def send_js(path):
    return send_from_directory('js', path)

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

千万不能使用send_filesend_static_file与用户提供的路径。

send_static_file 例:

from flask import Flask, request
# set the project root directory as the static folder, you can set others.
app = Flask(__name__, static_url_path='')

@app.route('/')
def root():
    return app.send_static_file('index.html')

The preferred method is to use nginx or another web server to serve static files; they’ll be able to do it more efficiently than Flask.

However, you can use send_from_directory to send files from a directory, which can be pretty convenient in some situations:

from flask import Flask, request, send_from_directory

# set the project root directory as the static folder, you can set others.
app = Flask(__name__, static_url_path='')

@app.route('/js/<path:path>')
def send_js(path):
    return send_from_directory('js', path)

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

Do not use send_file or send_static_file with a user-supplied path.

send_static_file example:

from flask import Flask, request
# set the project root directory as the static folder, you can set others.
app = Flask(__name__, static_url_path='')

@app.route('/')
def root():
    return app.send_static_file('index.html')

回答 1

如果只想移动静态文件的位置,则最简单的方法是在构造函数中声明路径。在下面的示例中,我将模板和静态文件移动到了名为的子文件夹中web

app = Flask(__name__,
            static_url_path='', 
            static_folder='web/static',
            template_folder='web/templates')
  • static_url_path=''从URL中删除任何前面的路径(即默认值/static)。
  • static_folder='web/static'将在文件夹中找到的所有文件 web/static作为静态文件提供。
  • template_folder='web/templates' 同样,这会更改模板文件夹。

使用此方法,以下URL将返回CSS文件:

<link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css">

最后,这是文件夹结构的快照,flask_server.pyFlask实例在哪里:

If you just want to move the location of your static files, then the simplest method is to declare the paths in the constructor. In the example below, I have moved my templates and static files into a sub-folder called web.

app = Flask(__name__,
            static_url_path='', 
            static_folder='web/static',
            template_folder='web/templates')
  • static_url_path='' removes any preceding path from the URL (i.e. the default /static).
  • static_folder='web/static' to serve any files found in the folder web/static as static files.
  • template_folder='web/templates' similarly, this changes the templates folder.

Using this method, the following URL will return a CSS file:

<link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css">

And finally, here’s a snap of the folder structure, where flask_server.py is the Flask instance:


回答 2

您也可以(这是我的最爱)将文件夹设置为静态路径,以便每个人都可以访问其中的文件。

app = Flask(__name__, static_url_path='/static')

通过该设置,您可以使用标准HTML:

<link rel="stylesheet" type="text/css" href="/static/style.css">

You can also, and this is my favorite, set a folder as static path so that the files inside are reachable for everyone.

app = Flask(__name__, static_url_path='/static')

With that set you can use the standard HTML:

<link rel="stylesheet" type="text/css" href="/static/style.css">

回答 3

我确定您会在这里找到所需的资源:http : //flask.pocoo.org/docs/quickstart/#static-files

基本上,您只需要在软件包根目录中添加一个“静态”文件夹,然后就可以url_for('static', filename='foo.bar')通过http://example.com/static/foo.bar使用或直接链接到您的文件。

编辑:如评论中所建议,您可以直接使用'/static/foo.bar'URL路径, url_for()开销(在性能方面)非常低,并且使用它意味着您以后可以轻松自定义行为(更改文件夹,更改URL路径,将您的静态文件移至S3等)。

I’m sure you’ll find what you need there: http://flask.pocoo.org/docs/quickstart/#static-files

Basically you just need a “static” folder at the root of your package, and then you can use url_for('static', filename='foo.bar') or directly link to your files with http://example.com/static/foo.bar.

EDIT: As suggested in the comments you could directly use the '/static/foo.bar' URL path BUT url_for() overhead (performance wise) is quite low, and using it means that you’ll be able to easily customise the behaviour afterwards (change the folder, change the URL path, move your static files to S3, etc).


回答 4

您可以使用此功能:

send_static_file(filename)
内部使用的功能,用于将静态文件从静态文件夹发送到浏览器。

app = Flask(__name__)
@app.route('/<path:path>')
def static_file(path):
    return app.send_static_file(path)

You can use this function :

send_static_file(filename)
Function used internally to send static files from the static folder to the browser.

app = Flask(__name__)
@app.route('/<path:path>')
def static_file(path):
    return app.send_static_file(path)

回答 5

我使用的(并且运行良好)是“模板”目录和“静态”目录。我将所有.html文件/ Flask模板放在模板目录中,而static包含CSS / JS。据我所知,无论您使用Flask的模板语法的程度如何,render_template都能很好地适用于通用html文件。以下是我的views.py文件中的示例调用。

@app.route('/projects')
def projects():
    return render_template("projects.html", title = 'Projects')

只要确实要在单独的静态目录中引用某些静态文件时确保使用url_for()即可。无论如何,您可能最终都会在HTML的CSS / JS文件链接中执行此操作。例如…

<script src="{{ url_for('static', filename='styles/dist/js/bootstrap.js') }}"></script>

这是“规范”非正式Flask教程的链接-此处有许多很棒的技巧可帮助您快速入门。

http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world

What I use (and it’s been working great) is a “templates” directory and a “static” directory. I place all my .html files/Flask templates inside the templates directory, and static contains CSS/JS. render_template works fine for generic html files to my knowledge, regardless of the extent at which you used Flask’s templating syntax. Below is a sample call in my views.py file.

@app.route('/projects')
def projects():
    return render_template("projects.html", title = 'Projects')

Just make sure you use url_for() when you do want to reference some static file in the separate static directory. You’ll probably end up doing this anyways in your CSS/JS file links in html. For instance…

<script src="{{ url_for('static', filename='styles/dist/js/bootstrap.js') }}"></script>

Here’s a link to the “canonical” informal Flask tutorial – lots of great tips in here to help you hit the ground running.

http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world


回答 6

基于其他答案的最简单的工作示例如下:

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

@app.route('/index/')
def root():
    return app.send_static_file('index.html')

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

使用名为index.html的HTML

<!DOCTYPE html>
<html>
<head>
    <title>Hello World!</title>
</head>
<body>
    <div>
         <p>
            This is a test.
         </p>
    </div>
</body>
</html>

重要提示:而且index.html的是一个文件夹,名为在静态,这意味着<projectpath>.py文件,<projectpath>\statichtml文件。

如果希望服务器在网络上可见,请使用 app.run(debug=True, host='0.0.0.0')

编辑:如果需要显示文件夹中的所有文件,请使用此

@app.route('/<path:path>')
def static_file(path):
    return app.send_static_file(path)

从本质BlackMamba上讲,这是答案,所以给他们投票。

A simplest working example based on the other answers is the following:

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

@app.route('/index/')
def root():
    return app.send_static_file('index.html')

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

With the HTML called index.html:

<!DOCTYPE html>
<html>
<head>
    <title>Hello World!</title>
</head>
<body>
    <div>
         <p>
            This is a test.
         </p>
    </div>
</body>
</html>

IMPORTANT: And index.html is in a folder called static, meaning <projectpath> has the .py file, and <projectpath>\static has the html file.

If you want the server to be visible on the network, use app.run(debug=True, host='0.0.0.0')

EDIT: For showing all files in the folder if requested, use this

@app.route('/<path:path>')
def static_file(path):
    return app.send_static_file(path)

Which is essentially BlackMamba‘s answer, so give them an upvote.


回答 7

对于创建下一个文件夹树的角度+样板流:

backend/
|
|------ui/
|      |------------------build/          <--'static' folder, constructed by Grunt
|      |--<proj           |----vendors/   <-- angular.js and others here
|      |--     folders>   |----src/       <-- your js
|                         |----index.html <-- your SPA entrypoint 
|------<proj
|------     folders>
|
|------view.py  <-- Flask app here

我使用以下解决方案:

...
root = os.path.join(os.path.dirname(os.path.abspath(__file__)), "ui", "build")

@app.route('/<path:path>', methods=['GET'])
def static_proxy(path):
    return send_from_directory(root, path)


@app.route('/', methods=['GET'])
def redirect_to_index():
    return send_from_directory(root, 'index.html')
...

它有助于将“静态”文件夹重新定义为自定义。

For angular+boilerplate flow which creates next folders tree:

backend/
|
|------ui/
|      |------------------build/          <--'static' folder, constructed by Grunt
|      |--<proj           |----vendors/   <-- angular.js and others here
|      |--     folders>   |----src/       <-- your js
|                         |----index.html <-- your SPA entrypoint 
|------<proj
|------     folders>
|
|------view.py  <-- Flask app here

I use following solution:

...
root = os.path.join(os.path.dirname(os.path.abspath(__file__)), "ui", "build")

@app.route('/<path:path>', methods=['GET'])
def static_proxy(path):
    return send_from_directory(root, path)


@app.route('/', methods=['GET'])
def redirect_to_index():
    return send_from_directory(root, 'index.html')
...

It helps to redefine ‘static’ folder to custom.


回答 8

因此,我开始工作(基于@ user1671599答案),并希望与大家分享。

(我希望我做对了,因为这是我的第一个Python应用程序)

我做到了-

项目结构:

server.py:

from server.AppStarter import AppStarter
import os

static_folder_root = os.path.join(os.path.dirname(os.path.abspath(__file__)), "client")

app = AppStarter()
app.register_routes_to_resources(static_folder_root)
app.run(__name__)

AppStarter.py:

from flask import Flask, send_from_directory
from flask_restful import Api, Resource
from server.ApiResources.TodoList import TodoList
from server.ApiResources.Todo import Todo


class AppStarter(Resource):
    def __init__(self):
        self._static_files_root_folder_path = ''  # Default is current folder
        self._app = Flask(__name__)  # , static_folder='client', static_url_path='')
        self._api = Api(self._app)

    def _register_static_server(self, static_files_root_folder_path):
        self._static_files_root_folder_path = static_files_root_folder_path
        self._app.add_url_rule('/<path:file_relative_path_to_root>', 'serve_page', self._serve_page, methods=['GET'])
        self._app.add_url_rule('/', 'index', self._goto_index, methods=['GET'])

    def register_routes_to_resources(self, static_files_root_folder_path):

        self._register_static_server(static_files_root_folder_path)
        self._api.add_resource(TodoList, '/todos')
        self._api.add_resource(Todo, '/todos/<todo_id>')

    def _goto_index(self):
        return self._serve_page("index.html")

    def _serve_page(self, file_relative_path_to_root):
        return send_from_directory(self._static_files_root_folder_path, file_relative_path_to_root)

    def run(self, module_name):
        if module_name == '__main__':
            self._app.run(debug=True)

So I got things working (based on @user1671599 answer) and wanted to share it with you guys.

(I hope I’m doing it right since it’s my first app in Python)

I did this –

Project structure:

server.py:

from server.AppStarter import AppStarter
import os

static_folder_root = os.path.join(os.path.dirname(os.path.abspath(__file__)), "client")

app = AppStarter()
app.register_routes_to_resources(static_folder_root)
app.run(__name__)

AppStarter.py:

from flask import Flask, send_from_directory
from flask_restful import Api, Resource
from server.ApiResources.TodoList import TodoList
from server.ApiResources.Todo import Todo


class AppStarter(Resource):
    def __init__(self):
        self._static_files_root_folder_path = ''  # Default is current folder
        self._app = Flask(__name__)  # , static_folder='client', static_url_path='')
        self._api = Api(self._app)

    def _register_static_server(self, static_files_root_folder_path):
        self._static_files_root_folder_path = static_files_root_folder_path
        self._app.add_url_rule('/<path:file_relative_path_to_root>', 'serve_page', self._serve_page, methods=['GET'])
        self._app.add_url_rule('/', 'index', self._goto_index, methods=['GET'])

    def register_routes_to_resources(self, static_files_root_folder_path):

        self._register_static_server(static_files_root_folder_path)
        self._api.add_resource(TodoList, '/todos')
        self._api.add_resource(Todo, '/todos/<todo_id>')

    def _goto_index(self):
        return self._serve_page("index.html")

    def _serve_page(self, file_relative_path_to_root):
        return send_from_directory(self._static_files_root_folder_path, file_relative_path_to_root)

    def run(self, module_name):
        if module_name == '__main__':
            self._app.run(debug=True)

回答 9

一种简单的方法。 干杯!

演示

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

@app.route("/")
def index():
   return render_template("index.html")

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

现在创建名为模板的文件夹名称。将您的index.html文件添加到模板文件夹中

index.html

<!DOCTYPE html>
<html>
<head>
    <title>Python Web Application</title>
</head>
<body>
    <div>
         <p>
            Welcomes You!!
         </p>
    </div>
</body>
</html>

项目结构

-demo.py
-templates/index.html

One of the simple way to do. Cheers!

demo.py

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

@app.route("/")
def index():
   return render_template("index.html")

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

Now create folder name called templates. Add your index.html file inside of templates folder

index.html

<!DOCTYPE html>
<html>
<head>
    <title>Python Web Application</title>
</head>
<body>
    <div>
         <p>
            Welcomes You!!
         </p>
    </div>
</body>
</html>

Project Structure

-demo.py
-templates/index.html

回答 10

想共享…这个例子。

from flask import Flask
app = Flask(__name__)

@app.route('/loading/')
def hello_world():
    data = open('sample.html').read()    
    return data

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

这样效果更好,更简单。

Thought of sharing…. this example.

from flask import Flask
app = Flask(__name__)

@app.route('/loading/')
def hello_world():
    data = open('sample.html').read()    
    return data

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

This works better and simple.


回答 11

使用redirecturl_for

from flask import redirect, url_for

@app.route('/', methods=['GET'])
def metrics():
    return redirect(url_for('static', filename='jenkins_analytics.html'))

这将处理您html中引用的所有文件(css和js …)。

Use redirect and url_for

from flask import redirect, url_for

@app.route('/', methods=['GET'])
def metrics():
    return redirect(url_for('static', filename='jenkins_analytics.html'))

This servers all files (css & js…) referenced in your html.


回答 12

最简单的方法是在主项目文件夹中创建一个静态文件夹。包含.css文件的静态文件夹。

主文件夹

/Main Folder
/Main Folder/templates/foo.html
/Main Folder/static/foo.css
/Main Folder/application.py(flask script)

包含静态和模板文件夹以及flask脚本的主文件夹的图像

烧瓶

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def login():
    return render_template("login.html")

html(布局)

<!DOCTYPE html>
<html>
    <head>
        <title>Project(1)</title>
        <link rel="stylesheet" href="/static/styles.css">
     </head>
    <body>
        <header>
            <div class="container">
                <nav>
                    <a class="title" href="">Kamook</a>
                    <a class="text" href="">Sign Up</a>
                    <a class="text" href="">Log In</a>
                </nav>
            </div>
        </header>  
        {% block body %}
        {% endblock %}
    </body>
</html>

html

{% extends "layout.html" %}

{% block body %}
    <div class="col">
        <input type="text" name="username" placeholder="Username" required>
        <input type="password" name="password" placeholder="Password" required>
        <input type="submit" value="Login">
    </div>
{% endblock %}

The simplest way is create a static folder inside the main project folder. Static folder containing .css files.

main folder

/Main Folder
/Main Folder/templates/foo.html
/Main Folder/static/foo.css
/Main Folder/application.py(flask script)

Image of main folder containing static and templates folders and flask script

flask

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def login():
    return render_template("login.html")

html (layout)

<!DOCTYPE html>
<html>
    <head>
        <title>Project(1)</title>
        <link rel="stylesheet" href="/static/styles.css">
     </head>
    <body>
        <header>
            <div class="container">
                <nav>
                    <a class="title" href="">Kamook</a>
                    <a class="text" href="">Sign Up</a>
                    <a class="text" href="">Log In</a>
                </nav>
            </div>
        </header>  
        {% block body %}
        {% endblock %}
    </body>
</html>

html

{% extends "layout.html" %}

{% block body %}
    <div class="col">
        <input type="text" name="username" placeholder="Username" required>
        <input type="password" name="password" placeholder="Password" required>
        <input type="submit" value="Login">
    </div>
{% endblock %}

回答 13

app = Flask(__name__, static_folder="your path to static")

如果您的根目录中有模板,则如果包含app_Flask(name)的文件也位于同一位置,则放置app = Flask(name)将起作用,如果该文件位于其他位置,则必须指定模板位置才​​能启用烧瓶指向该位置

app = Flask(__name__, static_folder="your path to static")

If you have templates in your root directory, placing the app=Flask(name) will work if the file that contains this also is in the same location, if this file is in another location, you will have to specify the template location to enable Flask to point to the location


回答 14

所有的答案都不错,但是对我来说,行之有效的只是使用send_fileFlask 的简单功能。当host:port / ApiName将在浏览器中显示文件的输出时,当您只需要发送一个HTML文件作为响应时,此方法很好用


@app.route('/ApiName')
def ApiFunc():
    try:
        return send_file('some-other-directory-than-root/your-file.extension')
    except Exception as e:
        logging.info(e.args[0])```

All the answers are good but what worked well for me is just using the simple function send_file from Flask. This works well when you just need to send an html file as response when host:port/ApiName will show the output of the file in browser


@app.route('/ApiName')
def ApiFunc():
    try:
        return send_file('some-other-directory-than-root/your-file.extension')
    except Exception as e:
        logging.info(e.args[0])```


回答 15

   默认情况下,flask使用“模板”文件夹包含所有模板文件(任何纯文本文件,但通常是.html某种模板语言,例如jinja2),并使用“静态”文件夹包含所有静态文件(即.js .css和您的图片)。
   在您的中routes,您可以使用render_template()呈现模板文件(如上所述,默认情况下将其放置在templates文件夹中)作为您请求的响应。并且在模板文件(通常是类似.html的文件)中,您可能会使用某些.js和/或`.css’文件,所以我想您的问题是如何将这些静态文件链接到当前模板文件。

   By default, flask use a “templates” folder to contain all your template files(any plain-text file, but usually .html or some kind of template language such as jinja2 ) & a “static” folder to contain all your static files(i.e. .js .css and your images).
   In your routes, u can use render_template() to render a template file (as I say above, by default it is placed in the templates folder) as the response for your request. And in the template file (it’s usually a .html-like file), u may use some .js and/or `.css’ files, so I guess your question is how u link these static files to the current template file.


回答 16

如果您只是尝试打开文件,则可以使用 app.open_resource()。所以读取文件看起来像

with app.open_resource('/static/path/yourfile'):
      #code to read the file and do something

If you are just trying to open a file, you could use app.open_resource(). So reading a file would look something like

with app.open_resource('/static/path/yourfile'):
      #code to read the file and do something

从Flask视图返回JSON响应

问题:从Flask视图返回JSON响应

我有一个函数,可使用Pandas分析CSV文件并生成带有摘要信息的字典。我想从Flask视图返回结果作为响应。如何返回JSON响应?

@app.route("/summary")
def summary():
    d = make_summary()
    # send it back as json

I have a function that analyzes a CSV file with Pandas and produces a dict with summary information. I want to return the results as a response from a Flask view. How do I return a JSON response?

@app.route("/summary")
def summary():
    d = make_summary()
    # send it back as json

回答 0

将摘要数据传递给该jsonify函数,该函数返回JSON响应。

from flask import jsonify

@app.route('/summary')
def summary():
    d = make_summary()
    return jsonify(d)

从Flask 0.11开始,您可以将任何JSON可序列化的类型(不仅是dict)传递为顶级对象。

Pass the summary data to the jsonify function, which returns a JSON response.

from flask import jsonify

@app.route('/summary')
def summary():
    d = make_summary()
    return jsonify(d)

As of Flask 0.11, you can pass any JSON-serializable type, not just dict, as the top level object.


回答 1

jsonify序列化您传递给JSON的数据。如果您想自己序列化数据,请jsonify使用status=200和构建响应以执行操作mimetype='application/json'

from flask import json

@app.route('/summary')
def summary():
    data = make_summary()
    response = app.response_class(
        response=json.dumps(data),
        status=200,
        mimetype='application/json'
    )
    return response

jsonify serializes the data you pass it to JSON. If you want to serialize the data yourself, do what jsonify does by building a response with status=200 and mimetype='application/json'.

from flask import json

@app.route('/summary')
def summary():
    data = make_summary()
    response = app.response_class(
        response=json.dumps(data),
        status=200,
        mimetype='application/json'
    )
    return response

回答 2

将关键字参数传递给flask.jsonify,它们将作为JSON对象输出。

@app.route('/_get_current_user')
def get_current_user():
    return jsonify(
        username=g.user.username,
        email=g.user.email,
        id=g.user.id
    )
{
    "username": "admin",
    "email": "admin@localhost",
    "id": 42
}

如果您已有字典,则可以将其直接传递为jsonify(d)

Pass keyword arguments to flask.jsonify and they will be output as a JSON object.

@app.route('/_get_current_user')
def get_current_user():
    return jsonify(
        username=g.user.username,
        email=g.user.email,
        id=g.user.id
    )
{
    "username": "admin",
    "email": "admin@localhost",
    "id": 42
}

If you already have a dict, you can pass it directly as jsonify(d).


回答 3

如果jsonify由于某种原因不想使用,则可以手动执行。调用flask.json.dumps以创建JSON数据,然后返回application/json内容类型的响应。

from flask import json

@app.route('/summary')
def summary():
    data = make_summary()
    response = app.response_class(
        response=json.dumps(data),
        mimetype='application/json'
    )
    return response

flask.json与内置json模块不同。simplejson如果可用,它将使用速度更快的模块,并与Flask应用进行各种集成。

If you don’t want to use jsonify for some reason, you can do what it does manually. Call flask.json.dumps to create JSON data, then return a response with the application/json content type.

from flask import json

@app.route('/summary')
def summary():
    data = make_summary()
    response = app.response_class(
        response=json.dumps(data),
        mimetype='application/json'
    )
    return response

flask.json is distinct from the built-in json module. It will use the faster simplejson module if available, and enables various integrations with your Flask app.


回答 4

如果您要分析用户上传的文件,则Flask 快速入门会显示如何从用户那里获取文件并进行访问。从中获取文件request.files并将其传递给摘要函数。

from flask import request, jsonify
from werkzeug import secure_filename

@app.route('/summary', methods=['GET', 'POST'])
def summary():
    if request.method == 'POST':
        csv = request.files['data']
        return jsonify(
            summary=make_summary(csv),
            csv_name=secure_filename(csv.filename)
        )

    return render_template('submit_data.html')

'data'键替换为request.filesHTML表单中输入的文件名。

If you want to analyze a file uploaded by the user, the Flask quickstart shows how to get files from users and access them. Get the file from request.files and pass it to the summary function.

from flask import request, jsonify
from werkzeug import secure_filename

@app.route('/summary', methods=['GET', 'POST'])
def summary():
    if request.method == 'POST':
        csv = request.files['data']
        return jsonify(
            summary=make_summary(csv),
            csv_name=secure_filename(csv.filename)
        )

    return render_template('submit_data.html')

Replace the 'data' key for request.files with the name of the file input in your HTML form.


回答 5

要返回JSON响应并设置状态代码,您可以使用make_response

from flask import jsonify, make_response

@app.route('/summary')
def summary():
    d = make_summary()
    return make_response(jsonify(d), 200)

Flask问题跟踪器中此注释的启发。

To return a JSON response and set a status code you can use make_response:

from flask import jsonify, make_response

@app.route('/summary')
def summary():
    d = make_summary()
    return make_response(jsonify(d), 200)

Inspiration taken from this comment in the Flask issue tracker.


回答 6

从版本1.1.0 Flask开始,如果视图返回dict,它将被转换为JSON response

@app.route("/users", methods=['GET'])
def get_user():
    return {
        "user": "John Doe",
    }

As of version 1.1.0 Flask, if a view returns a dict it will be turned into a JSON response.

@app.route("/users", methods=['GET'])
def get_user():
    return {
        "user": "John Doe",
    }

回答 7

我使用装饰器返回的结果jsonfiy。我认为当视图具有多个返回值时,它更具可读性。这不支持返回类似的元组content, status,但是我将使用返回app.errorhandler来处理错误状态。

import functools
from flask import jsonify

def return_json(f):
    @functools.wraps(f)
    def inner(**kwargs):
        return jsonify(f(**kwargs))

    return inner

@app.route('/test/<arg>')
@return_json
def test(arg):
    if arg == 'list':
        return [1, 2, 3]
    elif arg == 'dict':
        return {'a': 1, 'b': 2}
    elif arg == 'bool':
        return True
    return 'none of them'

I use a decorator to return the result of jsonfiy. I think it is more readable when a view has multiple returns. This does not support returning a tuple like content, status, but I handle returning error statuses with app.errorhandler instead.

import functools
from flask import jsonify

def return_json(f):
    @functools.wraps(f)
    def inner(**kwargs):
        return jsonify(f(**kwargs))

    return inner

@app.route('/test/<arg>')
@return_json
def test(arg):
    if arg == 'list':
        return [1, 2, 3]
    elif arg == 'dict':
        return {'a': 1, 'b': 2}
    elif arg == 'bool':
        return True
    return 'none of them'

回答 8

在Flask 0.11之前,jsonfiy不允许直接返回数组。而是将列表作为关键字参数传递。

@app.route('/get_records')
def get_records():
    results = [
        {
          "rec_create_date": "12 Jun 2016",
          "rec_dietary_info": "nothing",
          "rec_dob": "01 Apr 1988",
          "rec_first_name": "New",
          "rec_last_name": "Guy",
        },
        {
          "rec_create_date": "1 Apr 2016",
          "rec_dietary_info": "Nut allergy",
          "rec_dob": "01 Feb 1988",
          "rec_first_name": "Old",
          "rec_last_name": "Guy",
        },
    ]
    return jsonify(results=list)

Prior to Flask 0.11, jsonfiy would not allow returning an array directly. Instead, pass the list as a keyword argument.

@app.route('/get_records')
def get_records():
    results = [
        {
          "rec_create_date": "12 Jun 2016",
          "rec_dietary_info": "nothing",
          "rec_dob": "01 Apr 1988",
          "rec_first_name": "New",
          "rec_last_name": "Guy",
        },
        {
          "rec_create_date": "1 Apr 2016",
          "rec_dietary_info": "Nut allergy",
          "rec_dob": "01 Feb 1988",
          "rec_first_name": "Old",
          "rec_last_name": "Guy",
        },
    ]
    return jsonify(results=list)

回答 9

在Flask 1.1中,如果返回字典,它将自动转换为JSON。因此,如果make_summary()返回字典,您可以

from flask import Flask

app = Flask(__name__)

@app.route('/summary')
def summary():
    d = make_summary()
    return d

要求包含状态码SO已作为与此副本的副本被关闭。因此,要回答该问题,您可以通过返回形式的元组来包含状态代码(dict, int)。将dict转换为JSON,int将HTTP状态代码。没有任何输入,状态是默认的200。因此在上面的示例中,代码将是200。在下面的示例中,其代码更改为201。

from flask import Flask

app = Flask(__name__)

@app.route('/summary')
def summary():
    d = make_summary()
    return d, 201  # 200 is the default

您可以使用以下方法检查状态码

curl --request GET "http://127.0.0.1:5000/summary" -w "\ncode: %{http_code}\n\n"

In Flask 1.1, if you return a dictionary and it will automatically be converted into JSON. So if make_summary() returns a dictionary, you can

from flask import Flask

app = Flask(__name__)

@app.route('/summary')
def summary():
    d = make_summary()
    return d

The SO that asks about including the status code was closed as a duplicate to this one. So to also answer that question, you can include the status code by returning a tuple of the form (dict, int). The dict is converted to JSON and the int will be the HTTP Status Code. Without any input, the Status is the default 200. So in the above example the code would be 200. In the example below it is changed to 201.

from flask import Flask

app = Flask(__name__)

@app.route('/summary')
def summary():
    d = make_summary()
    return d, 201  # 200 is the default

You can check the status code using

curl --request GET "http://127.0.0.1:5000/summary" -w "\ncode: %{http_code}\n\n"

回答 10

如果是字典,则flask可以直接将其返回(版本1.0.2)

def summary():
    d = make_summary()
    return d, 200

if its a dict, flask can return it directly (Version 1.0.2)

def summary():
    d = make_summary()
    return d, 200

回答 11

“”“ 使用Flask基于类的视图 ”“”

from flask import Flask, request, jsonify

from flask.views import MethodView

app = Flask(**__name__**)

app.add_url_rule('/summary/', view_func=Summary.as_view('summary'))

class Summary(MethodView):

    def __init__(self):
        self.response = dict()

    def get(self):
        self.response['summary'] = make_summary()  # make_summary is a method to calculate the summary.
        return jsonify(self.response)

“”” Using Flask Class-base View “””

from flask import Flask, request, jsonify

from flask.views import MethodView

app = Flask(**__name__**)

app.add_url_rule('/summary/', view_func=Summary.as_view('summary'))

class Summary(MethodView):

    def __init__(self):
        self.response = dict()

    def get(self):
        self.response['summary'] = make_summary()  # make_summary is a method to calculate the summary.
        return jsonify(self.response)

回答 12

烧瓶1.1.x

现在Flask支持请求直接通过json返回,不再需要jsonify

@app.route("/")
def index():
    return {
        "api_stuff": "values",
    }

相当于

@app.route("/")
def index():
    return jsonify({
        "api_stuff": "values",
    })

有关更多信息,请在此处阅读https://medium.com/octopus-wealth/returning-json-from-flask-cf4ce6fe9aebhttps://github.com/pallets/flask/pull/3111

Flask 1.1.x

now Flask support request return with json directly, jsonify not required anymore

@app.route("/")
def index():
    return {
        "api_stuff": "values",
    }

is equivalent to

@app.route("/")
def index():
    return jsonify({
        "api_stuff": "values",
    })

for more information read here https://medium.com/octopus-wealth/returning-json-from-flask-cf4ce6fe9aeb and https://github.com/pallets/flask/pull/3111


将Flask开发服务器配置为在网络上可见

问题:将Flask开发服务器配置为在网络上可见

我不确定这是否是Flask专用的,但是当我在开发模式(http://localhost:5000)下运行应用程序时,无法从网络上的其他计算机(使用http://[dev-host-ip]:5000)访问它。例如,在开发模式下使用Rails时,它可以正常工作。我找不到有关Flask开发服务器配置的任何文档。任何想法应该配置为启用此功能吗?

I’m not sure if this is Flask specific, but when I run an app in dev mode (http://localhost:5000), I cannot access it from other machines on the network (with http://[dev-host-ip]:5000). With Rails in dev mode, for example, it works fine. I couldn’t find any docs regarding the Flask dev server configuration. Any idea what should be configured to enable this?


回答 0

尽管这是可行的,但您不应在生产中使用Flask dev服务器。Flask开发服务器的设计并非特别安全,稳定或高效。有关正确的解决方案,请参阅有关部署的文档。


将参数添加到中app.run()。默认情况下,它在本地主机上运行,​​将其更改app.run(host= '0.0.0.0')为在您的计算机IP地址上运行。

快速入门页上的“外部可见的服务器”下的Flask网站上记录

外部可见服务器

如果运行服务器,您会注意到该服务器仅可用于您自己的计算机,而不能用于网络中的任何其他服务器。这是默认设置,因为在调试模式下,应用程序的用户可以在计算机上执行任意Python代码。如果禁用了调试或信任网络上的用户,则可以使服务器公开可用。

只需将run()方法的调用更改为如下所示:

app.run(host='0.0.0.0')

这告诉您的操作系统侦听公共IP。

While this is possible, you should not use the Flask dev server in production. The Flask dev server is not designed to be particularly secure, stable, or efficient. See the docs on deploying for correct solutions.


Add a parameter to your app.run(). By default it runs on localhost, change it to app.run(host= '0.0.0.0') to run on your machines IP address.

Documented on the Flask site under “Externally Visible Server” on the Quickstart page:

Externally Visible Server

If you run the server you will notice that the server is only available from your own computer, not from any other in the network. This is the default because in debugging mode a user of the application can execute arbitrary Python code on your computer. If you have debug disabled or trust the users on your network, you can make the server publicly available.

Just change the call of the run() method to look like this:

app.run(host='0.0.0.0')

This tells your operating system to listen on a public IP.


回答 1

如果使用flask可执行文件启动服务器,则可以使用flask run --host=0.0.0.0更改默认值,从127.0.0.1并将其打开到非本地连接。其他答案描述的config和app.run方法可能是更好的做法,但这也很方便。

外部可见服务器如果运行服务器,您将注意到只能从您自己的计算机访问该服务器,而不能从网络中的任何其他服务器访问该服务器。这是默认设置,因为在调试模式下,应用程序的用户可以在计算机上执行任意Python代码。

如果禁用了调试器或信任网络上的用户,则只需在命令行中添加–host = 0.0.0.0,即可使服务器公开可用:

flask run –host = 0.0.0.0这告诉您的操作系统侦听所有公用IP。

参考:http//flask.pocoo.org/docs/0.11/quickstart/

If you use the flask executable to start your server, you can use flask run --host=0.0.0.0 to change the default from 127.0.0.1 and open it up to non local connections. The config and app.run methods that the other answers describe are probably better practice but this can be handy as well.

Externally Visible Server If you run the server you will notice that the server is only accessible from your own computer, not from any other in the network. This is the default because in debugging mode a user of the application can execute arbitrary Python code on your computer.

If you have the debugger disabled or trust the users on your network, you can make the server publicly available simply by adding –host=0.0.0.0 to the command line:

flask run –host=0.0.0.0 This tells your operating system to listen on all public IPs.

Reference: http://flask.pocoo.org/docs/0.11/quickstart/


回答 2

如果0.0.0.0方法不起作用,请尝试此操作

无聊的东西

我亲自进行了很多努力,以使我的应用可以通过本地服务器访问其他设备(笔记本电脑和手机)。我尝试了0.0.0.0方法,但是没有运气。然后,我尝试更改端口,但没有成功。因此,在尝试了一堆不同的组合之后,我找到了这个组合,它解决了我在本地服务器上部署应用程序的问题。

脚步

  1. 获取计算机的本地IPv4地址。这可以通过ipconfig在Windows以及ifconfiglinux和Mac上键入来完成。

请注意:以上步骤将在提供该应用程序的计算机上执行,而不是在您正在访问该应用程序的计算机上执行。另请注意,如果断开连接并重新连接到网络,IPv4地址可能会更改。

  1. 现在,只需使用获取的IPv4地址运行flask应用程序即可。

    flask run -h 192.168.X.X

    例如,就我而言(参见图片),我将其运行为:

    flask run -h 192.168.1.100

在我的移动设备上

可选的东西

如果您正在Windows上执行此过程,并使用Power Shell作为CLI,但仍然无法访问该网站,请在运行该应用程序的Shell中尝试使用CTRL + C命令。Power Shell有时会冻结,因此需要一点点恢复。这样做甚至可能终止服务器,但有时可以解决问题。

而已。如果您觉得有帮助,请竖起大拇指。😉

一些其他可选的东西

我创建了一个简短的Powershell脚本,可以在需要时为您提供IP地址:

$env:getIp = ipconfig
if ($env:getIp -match '(IPv4[\sa-zA-Z.]+:\s[0-9.]+)') {
    if ($matches[1] -match '([^a-z\s][\d]+[.\d]+)'){
        $ipv4 = $matches[1]
    }
}
echo $ipv4

将其保存到扩展名为.ps1的文件中(对于PowerShell),然后在启动您的应用程序之前对其运行。您可以将其保存在项目文件夹中,并以以下方式运行:

.\getIP.ps1; flask run -h $ipv4

注意:我将上面的shell代码保存在getIP.ps1中。

酷👌

Try this if the 0.0.0.0 method doesn’t work

Boring Stuff

I personally battled a lot to get my app accessible to other devices(laptops and mobile phones) through a local-server. I tried the 0.0.0.0 method, but no luck. Then I tried changing the port, but it just didn’t work. So, after trying a bunch of different combinations, I arrived to this one, and it solved my problem of deploying my app on a local-server.

Steps

  1. Get the local IPv4 address of your computer. This can be done by typing ipconfig on Windows and ifconfig on linux and Mac.

Please note: The above step is to be performed on the machine you are serving the app on, and on not the machine on which you are accessing it. Also note, that the IPv4 address might change if you disconnect and reconnect to the network.

  1. Now, simply run the flask app with the acquired IPv4 address.

    flask run -h 192.168.X.X

    E.g. In my case (see the image), I ran it as:

    flask run -h 192.168.1.100

On my mobile device

Optional Stuff

If you are performing this procedure on Windows, and using Power Shell as the CLI, and you still aren’t able to access the website, try a CTRL + C command in the shell that’s running the app. Power Shell get frozen up sometimes and it needs a pinch to revive. Doing this might even terminate the server, but it sometimes does the trick.

That’s it. Give a thumbs up if you found this helpful.😉

Some more optional stuff

I have created a short Powershell script that will get you your IP address whenever you need one:

$env:getIp = ipconfig
if ($env:getIp -match '(IPv4[\sa-zA-Z.]+:\s[0-9.]+)') {
    if ($matches[1] -match '([^a-z\s][\d]+[.\d]+)'){
        $ipv4 = $matches[1]
    }
}
echo $ipv4

Save it to a file with .ps1 extenstion (for PowerShell), and run it on before starting your app. You can save it in your project folder and run it as:

.\getIP.ps1; flask run -h $ipv4

Note: I saved the above shell code in getIP.ps1.

Cool.👌


回答 3

如果您的cool应用程序的配置是从外部文件加载的,如以下示例所示,请不要忘记使用HOST =“ 0.0.0.0”更新相应的配置文件

cool.app.run(
    host=cool.app.config.get("HOST", "localhost"),
    port=cool.app.config.get("PORT", 9000)
)            

If your cool app has it’s configuration loaded from an external file, like in the following example, then don’t forget to update the corresponding config file with HOST=”0.0.0.0″

cool.app.run(
    host=cool.app.config.get("HOST", "localhost"),
    port=cool.app.config.get("PORT", 9000)
)            

回答 4

在您的项目中添加以下几行

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

Add below lines to your project

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

回答 5

检查服务器上是否打开了特定端口以服务于客户端?

在Ubuntu或Linux发行版中

sudo ufw enable
sudo ufw allow 5000/tcp //allow the server to handle the request on port 5000

配置应用程序以处理远程请求

app.run(host='0.0.0.0' , port=5000)


python3 app.py & #run application in background

Check whether the particular port is open on the server to serve the client or not?

in Ubuntu or Linux distro

sudo ufw enable
sudo ufw allow 5000/tcp //allow the server to handle the request on port 5000

Configure the application to handle remote requests

app.run(host='0.0.0.0' , port=5000)


python3 app.py & #run application in background

回答 6

转到CMD(命令提示符)上的项目路径,然后执行以下命令:

设置FLASK_APP = ABC.py

SET FLASK_ENV =开发

烧瓶运行-h [yourIP] -p 8080

您将在CMD上获得以下o / p:-

  • 正在投放Flask应用“ expirement.py”(延迟加载)

现在,您可以使用http:// [yourIP]:8080 / url 在另一台计算机上访问flask应用程序

Go to your project path on CMD(command Prompt) and execute the following command:-

set FLASK_APP=ABC.py

SET FLASK_ENV=development

flask run -h [yourIP] -p 8080

you will get following o/p on CMD:-

  • Serving Flask app “expirement.py” (lazy loading)
    • Environment: development
    • Debug mode: on
    • Restarting with stat
    • Debugger is active!
    • Debugger PIN: 199-519-700
    • Running on http://[yourIP]:8080/ (Press CTRL+C to quit)

Now you can access your flask app on another machine using http://[yourIP]:8080/ url


回答 7

如果您在访问使用PyCharm部署的Flask服务器时遇到问题,请考虑以下因素:

PyCharm不会直接运行您的主.py文件,因此if __name__ == '__main__':不会执行其中的任何代码,并且任何更改(例如app.run(host='0.0.0.0', port=5000))都不会生效。

相反,您应该使用“运行配置”配置Flask服务器,尤其是将其放置--host 0.0.0.0 --port 5000在“ 其他选项”字段中。

有关在PyCharm中配置Flask服务器的更多信息

If you’re having troubles accessing your Flask server, deployed using PyCharm, take the following into account:

PyCharm doesn’t run your main .py file directly, so any code in if __name__ == '__main__': won’t be executed, and any changes (like app.run(host='0.0.0.0', port=5000)) won’t take effect.

Instead, you should configure the Flask server using Run Configurations, in particular, placing --host 0.0.0.0 --port 5000 into Additional options field.

More about configuring Flask server in PyCharm


回答 8

我遇到了同样的问题,我使用PyCharm作为编辑器,并且在创建项目时,PyCharm创建了Flask Server。我所做的就是通过以下方式用Python创建服务器;

基本上我所做的是创建一个新服务器,但如果不是python,则使用flask

希望对您有帮助

I had the same problem, I use PyCharm as an editor and when I created the project, PyCharm created a Flask Server. What I did was create a server with Python in the following way;

basically what I did was create a new server but flask if not python

I hope it helps you


回答 9

这个答案不仅与flask有关,而且应适用于所有无法连接来自另一个主机的服务

  1. 用于netstat -ano | grep <port>查看地址是0.0.0.0还是::。如果是127.0.0.1,则仅适用于本地请求。
  2. 使用tcpdump查看是否有任何数据包丢失。如果显示明显的不平衡,请通过iptables检查路由规则。

今天,我像往常一样运行烧瓶应用程序,但是我发现它无法从其他服务器连接。然后运行netstat -ano | grep <port>,本地地址为::or 0.0.0.0(我都尝试过,并且我知道127.0.0.1仅允许来自本地主机的连接)。然后我用了telnet host port,结果就像connect to ...。这很奇怪。然后我想我最好跟查一下tcpdump -i any port <port> -w w.pcap。我注意到这一切都是这样的:

然后通过检查iptables --listOUTPUT部分,我可以看到一些规则:

这些规则禁止握手时输出tcp重要数据包。通过删除它们,问题消失了。

This answer is not solely related with flask, but should be applicable for all cannot connect service from another host issue.

  1. use netstat -ano | grep <port> to see if the address is 0.0.0.0 or ::. If it is 127.0.0.1 then it is only for the local requests.
  2. use tcpdump to see if any packet is missing. If it shows obvious imbalance, check routing rules by iptables.

Today I run my flask app as usual, but I noticed it cannot connect from other server. Then I run netstat -ano | grep <port>, and the local address is :: or 0.0.0.0 (I tried both, and I know 127.0.0.1 only allows connection from the local host). Then I used telnet host port, the result is like connect to .... This is very odd. Then I thought I would better check it with tcpdump -i any port <port> -w w.pcap. And I noticed it is all like this:

Then by checking iptables --list OUTPUT section, I could see several rules:

these rules forbid output tcp vital packets in handshaking. By deleting them, the problem is gone.


回答 10

对我来说,我遵循上面的答案并对其进行了一些修改:

  1. 只需在命令提示符下使用ipconfig来获取您的ipv4地址
  2. 转到存在烧瓶代码的文件
  3. 在主函数中编写app.run(host =’您的ipv4地址’)

例如:

For me i followed the above answer and modified it a bit:

  1. Just grab your ipv4 address using ipconfig on command prompt
  2. Go to the file in which flask code is present
  3. In main function write app.run(host= ‘your ipv4 address’)

Eg:


回答 11

转到项目路径set FLASK_APP = ABC.py SET FLASK_ENV = development

flask run -h [yourIP] -p 8080,您将在CMD上遵循o / p:-*正在服务的Flask应用程序“ expirement.py”(延迟加载)*环境:开发*调试模式:on *以stat重新启动*调试器处于活动状态!*调试器PIN:199-519-700 *在http:// [yourIP]:8080 /上运行(按CTRL + C退出)

go to project path set FLASK_APP=ABC.py SET FLASK_ENV=development

flask run -h [yourIP] -p 8080 you will following o/p on CMD:- * Serving Flask app “expirement.py” (lazy loading) * Environment: development * Debug mode: on * Restarting with stat * Debugger is active! * Debugger PIN: 199-519-700 * Running on http://[yourIP]:8080/ (Press CTRL+C to quit)


回答 12

您还可以通过环境变量设置主机(将其暴露在面向IP地址的网络上)和端口。

$ export FLASK_APP=app.py
$ export FLASK_ENV=development
$ export FLASK_RUN_PORT=8000
$ export FLASK_RUN_HOST=0.0.0.0

$ flask run
 * Serving Flask app "app.py" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Running on https://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 329-665-000

请参见如何获取所有可用的命令选项来设置环境变量?

You can also set the host (to expose it on a network facing IP address) and port via environment variables.

$ export FLASK_APP=app.py
$ export FLASK_ENV=development
$ export FLASK_RUN_PORT=8000
$ export FLASK_RUN_HOST=0.0.0.0

$ flask run
 * Serving Flask app "app.py" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Running on https://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 329-665-000

See How to get all available Command Options to set environment variables?


回答 13

.flaskenv在项目根目录中创建文件。

该文件中的参数通常为:

FLASK_APP=app.py
FLASK_ENV=development
FLASK_RUN_HOST=[dev-host-ip]
FLASK_RUN_PORT=5000

如果您有虚拟环境,请激活它并执行pip install python-dotenv

该软件包将使用该.flaskenv文件,并且其中的声明将在终端会话之间自动导入。

那你可以做 flask run

Create file .flaskenv in the project root directory.

The parameters in this file are typically:

FLASK_APP=app.py
FLASK_ENV=development
FLASK_RUN_HOST=[dev-host-ip]
FLASK_RUN_PORT=5000

If you have a virtual environment, activate it and do a pip install python-dotenv .

This package is going to use the .flaskenv file, and declarations inside it will be automatically imported across terminal sessions.

Then you can do flask run


如何在Flask上获取查询字符串?

问题:如何在Flask上获取查询字符串?

从烧瓶文档中关于如何获取查询字符串的知识并不明显。我是新手,看了看文档,找不到!

所以

@app.route('/')
@app.route('/data')
def data():
    query_string=??????
    return render_template("data.html")

Not obvious from the flask documention on how to get the query string. I am new, looked at the docs, could not find!

So

@app.route('/')
@app.route('/data')
def data():
    query_string=??????
    return render_template("data.html")

回答 0

from flask import request

@app.route('/data')
def data():
    # here we want to get the value of user (i.e. ?user=some-value)
    user = request.args.get('user')
from flask import request

@app.route('/data')
def data():
    # here we want to get the value of user (i.e. ?user=some-value)
    user = request.args.get('user')

回答 1

完整URL可用request.url,而查询字符串可用request.query_string

这是一个例子:

from flask import request

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

    return request.query_string

要访问在查询字符串中传递的单个已知参数,可以使用request.args.get('param')。据我所知,这是“正确”的方法。

ETA:在继续之前,您应该问自己为什么要查询字符串。我从来没有拉过原始字符串-Flask具有以抽象方式访问它的机制。除非您有令人信服的理由不使用,否则应使用它们。

The full URL is available as request.url, and the query string is available as request.query_string.

Here’s an example:

from flask import request

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

    return request.query_string

To access an individual known param passed in the query string, you can use request.args.get('param'). This is the “right” way to do it, as far as I know.

ETA: Before you go further, you should ask yourself why you want the query string. I’ve never had to pull in the raw string – Flask has mechanisms for accessing it in an abstracted way. You should use those unless you have a compelling reason not to.


回答 2

Werkzeug / Flask已经为您解析了所有内容。无需使用urlparse再次执行相同的工作:

from flask import request

@app.route('/')
@app.route('/data')
def data():
    query_string = request.query_string  ## There is it
    return render_template("data.html")

有关请求和响应对象的完整文档,请参见Werkzeug:http : //werkzeug.pocoo.org/docs/wrappers/

Werkzeug/Flask as already parsed everything for you. No need to do the same work again with urlparse:

from flask import request

@app.route('/')
@app.route('/data')
def data():
    query_string = request.query_string  ## There is it
    return render_template("data.html")

The full documentation for the request and response objects is in Werkzeug: http://werkzeug.pocoo.org/docs/wrappers/


回答 3

我们可以使用request.query_string做到这一点。

例:

让我们考虑view.py

from my_script import get_url_params

@app.route('/web_url/', methods=('get', 'post'))
def get_url_params_index():
    return Response(get_url_params())

您还可以通过使用Flask蓝图使它更具模块化-http: //flask.pocoo.org/docs/0.10/blueprints/

让我们考虑将名字作为查询字符串/ web_url /?first_name = john的一部分进行传递

## here is my_script.py

## import required flask packages
from flask import request
def get_url_params():
    ## you might further need to format the URL params through escape.    
    firstName = request.args.get('first_name') 
    return firstName

如您所见,这只是一个小例子-您可以获取多个值+为其赋值,然后使用它或将其传递到模板文件中。

We can do this by using request.query_string.

Example:

Lets consider view.py

from my_script import get_url_params

@app.route('/web_url/', methods=('get', 'post'))
def get_url_params_index():
    return Response(get_url_params())

You also make it more modular by using Flask Blueprints – http://flask.pocoo.org/docs/0.10/blueprints/

Lets consider first name is being passed as a part of query string /web_url/?first_name=john

## here is my_script.py

## import required flask packages
from flask import request
def get_url_params():
    ## you might further need to format the URL params through escape.    
    firstName = request.args.get('first_name') 
    return firstName

As you see this is just a small example – you can fetch multiple values + formate those and use it or pass it onto the template file.


回答 4

我来这里是在寻找查询字符串,而不是如何从查询字符串获取值。

request.query_string 返回URL参数作为原始字节字符串(参考文献1)。

使用示例request.query_string

from flask import Flask, request

app = Flask(__name__)

@app.route('/data', methods=['GET'])
def get_query_string():
    return request.query_string

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

输出:

参考文献:

  1. 有关query_string的官方API文档

I came here looking for the query string, not how to get values from the query string.

request.query_string returns the URL parameters as raw byte string (Ref 1).

Example of using request.query_string:

from flask import Flask, request

app = Flask(__name__)

@app.route('/data', methods=['GET'])
def get_query_string():
    return request.query_string

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

Output:

References:

  1. Official API documentation on query_string

回答 5

像这样尝试查询字符串:

from flask import Flask, request

app = Flask(__name__)

@app.route('/parameters', methods=['GET'])
def query_strings():

    args1 = request.args['args1']
    args2 = request.args['args2']
    args3 = request.args['args3']

    return '''<h1>The Query String are...{}:{}:{}</h1>''' .format(args1,args2,args3)


if __name__ == '__main__':

    app.run(debug=True)

输出:

Try like this for query string:

from flask import Flask, request

app = Flask(__name__)

@app.route('/parameters', methods=['GET'])
def query_strings():

    args1 = request.args['args1']
    args2 = request.args['args2']
    args3 = request.args['args3']

    return '''<h1>The Query String are...{}:{}:{}</h1>''' .format(args1,args2,args3)


if __name__ == '__main__':

    app.run(debug=True)

Output:


回答 6

O’Reilly Flask Web开发中所述,可以从烧瓶请求对象中检索每种形式的查询字符串:

O’Reilly Flask Web开发,如Manan Gouhari先前所述,首先,您需要导入请求:

from flask import request

request是Flask公开的对象,它是一个名为(您猜对了)的上下文变量request。顾名思义,它包含客户端包含在HTTP请求中的所有信息。该对象具有许多可以分别检索和调用的属性和方法。

您有很多request属性,其中包含要选择的查询字符串。在这里,我将列出以任何方式包含查询字符串的每个属性,以及O’Reilly对该书的描述。

首先args是“字典,其中所有参数都在URL的查询字符串中传递”。因此,如果要将查询字符串解析为字典,则可以执行以下操作:

from flask import request

@app.route('/'):
    queryStringDict = request.args

(正如其他人指出的,您也可以使用.get('<arg_name>')从字典中获取特定值)

然后,有form属性,它确实包含查询字符串,但它包含在另一个属性的部分包括查询字符串,我将立即上市。不过,首先form是“具有随请求一起提交的所有表单字段的字典”。我这么说是:烧瓶请求对象中还有另一个字典属性可用valuesvalues是“结合了form和中的值的字典args。” 检索将类似于以下内容:

from flask import request

@app.route('/'):
    formFieldsAndQueryStringDict = request.values

(再次,用于.get('<arg_name>')从字典中获取特定项目)

另一个选项是query_string“ URL的查询字符串部分,作为原始二进制值”。例子:

from flask import request

@app.route('/'):
    queryStringRaw = request.query_string

然后,还有一个额外的好处full_path是“ URL的路径和查询字符串部分”。通过ejemplo:

from flask import request

@app.route('/'):
    pathWithQueryString = request.full_path

最后,url“客户端请求的完整URL”(包括查询字符串):

from flask import request

@app.route('/'):
    pathWithQueryString = request.url

快乐黑客:)

Every form of the query string retrievable from flask request object as described in O’Reilly Flask Web Devleopment:

From O’Reilly Flask Web Development, and as stated by Manan Gouhari earlier, first you need to import request:

from flask import request

request is an object exposed by Flask as a context variable named (you guessed it) request. As its name suggests, it contains all the information that the client included in the HTTP request. This object has many attributes and methods that you can retrieve and call, respectively.

You have quite a few request attributes which contain the query string from which to choose. Here I will list every attribute that contains in any way the query string, as well as a description from the O’Reilly book of that attribute.

First there is args which is “a dictionary with all the arguments passed in the query string of the URL.” So if you want the query string parsed into a dictionary, you’d do something like this:

from flask import request

@app.route('/'):
    queryStringDict = request.args

(As others have pointed out, you can also use .get('<arg_name>') to get a specific value from the dictionary)

Then, there is the form attribute, which does not contain the query string, but which is included in part of another attribute that does include the query string which I will list momentarily. First, though, form is “A dictionary with all the form fields submitted with the request.” I say that to say this: there is another dictionary attribute available in the flask request object called values. values is “A dictionary that combines the values in form and args.” Retrieving that would look something like this:

from flask import request

@app.route('/'):
    formFieldsAndQueryStringDict = request.values

(Again, use .get('<arg_name>') to get a specific item out of the dictionary)

Another option is query_string which is “The query string portion of the URL, as a raw binary value.” Example of that:

from flask import request

@app.route('/'):
    queryStringRaw = request.query_string

Then as an added bonus there is full_path which is “The path and query string portions of the URL.” Por ejemplo:

from flask import request

@app.route('/'):
    pathWithQueryString = request.full_path

And finally, url, “The complete URL requested by the client” (which includes the query string):

from flask import request

@app.route('/'):
    pathWithQueryString = request.url

Happy hacking :)


回答 7

可以使用来完成request.args.get()。例如,如果您的查询字符串包含字段date,则可以使用进行访问

date = request.args.get('date')

别忘了request在烧瓶的导入列表中添加“ ”,即

from flask import request

This can be done using request.args.get(). For example if your query string has a field date, it can be accessed using

date = request.args.get('date')

Don’t forget to add “request” to list of imports from flask, i.e.

from flask import request

回答 8

如果请求为GET并且我们传递了一些查询参数,

fro`enter code here`m flask import request
@app.route('/')
@app.route('/data')
def data():
   if request.method == 'GET':
      # Get the parameters by key
      arg1 = request.args.get('arg1')
      arg2 = request.args.get('arg2')
      # Generate the query string
      query_string="?arg1={0}&arg2={1}".format(arg1, arg2)
      return render_template("data.html", query_string=query_string)

If the request if GET and we passed some query parameters then,

fro`enter code here`m flask import request
@app.route('/')
@app.route('/data')
def data():
   if request.method == 'GET':
      # Get the parameters by key
      arg1 = request.args.get('arg1')
      arg2 = request.args.get('arg2')
      # Generate the query string
      query_string="?arg1={0}&arg2={1}".format(arg1, arg2)
      return render_template("data.html", query_string=query_string)

获取烧瓶请求中收到的数据

问题:获取烧瓶请求中收到的数据

我希望能够将数据发送到我的Flask应用。我尝试访问,request.data但它是一个空字符串。您如何访问请求数据?

from flask import request

@app.route('/', methods=['GET', 'POST'])
def parse_request():
    data = request.data  # data is empty
    # need posted data here

这个问题的答案使我提出了在Python Flask中获取原始POST正文的问题,而不管接下来的Content-Type标头如何,这都是关于获取原始数据而不是已解析数据的问题。

I want to be able to get the data sent to my Flask app. I’ve tried accessing request.data but it is an empty string. How do you access request data?

from flask import request

@app.route('/', methods=['GET', 'POST'])
def parse_request():
    data = request.data  # data is empty
    # need posted data here

The answer to this question led me to ask Get raw POST body in Python Flask regardless of Content-Type header next, which is about getting the raw data rather than the parsed data.


回答 0

文档描述的要求提供的属性。在大多数情况下,request.data由于它用作后备广告,因此将为空:

request.data 如果传入的请求数据带有mimetype Flask无法处理,则将其包含为字符串。

  • request.args:URL查询字符串中的键/值对
  • request.form:正文中的键/值对,来自HTML帖子形式或非JSON编码的JavaScript请求
  • request.files:Flask与正文分开的正文文件form。必须使用HTML表单,enctype=multipart/form-data否则将不会上传文件。
  • request.values:组合argsformargs如果键重叠则首选
  • request.json:解析的JSON数据。该请求必须具有application/json内容类型,或用于request.get_json(force=True)忽略内容类型。

所有这些都是MultiDict实例(除外json)。您可以使用以下方法访问值:

  • request.form['name']:如果您知道密钥存在,请使用索引
  • request.form.get('name')get如果密钥可能不存在,则使用
  • request.form.getlist('name')getlist如果键被多次发送并且需要值列表,则使用该键。get仅返回第一个值。

The docs describe the attributes available on the request. In most common cases request.data will be empty because it’s used as a fallback:

request.data Contains the incoming request data as string in case it came with a mimetype Flask does not handle.

  • request.args: the key/value pairs in the URL query string
  • request.form: the key/value pairs in the body, from a HTML post form, or JavaScript request that isn’t JSON encoded
  • request.files: the files in the body, which Flask keeps separate from form. HTML forms must use enctype=multipart/form-data or files will not be uploaded.
  • request.values: combined args and form, preferring args if keys overlap
  • request.json: parsed JSON data. The request must have the application/json content type, or use request.get_json(force=True) to ignore the content type.

All of these are MultiDict instances (except for json). You can access values using:

  • request.form['name']: use indexing if you know the key exists
  • request.form.get('name'): use get if the key might not exist
  • request.form.getlist('name'): use getlist if the key is sent multiple times and you want a list of values. get only returns the first value.

回答 1

要获取原始数据,请使用request.data。这仅在无法将其解析为表单数据时才有效,否则它将为空request.form并将具有解析后的数据。

from flask import request
request.data

To get the raw data, use request.data. This only works if it couldn’t be parsed as form data, otherwise it will be empty and request.form will have the parsed data.

from flask import request
request.data

回答 2

对于URL查询参数,请使用request.args

search = request.args.get("search")
page = request.args.get("page")

对于张贴的表单输入,请使用request.form

email = request.form.get('email')
password = request.form.get('password')

对于以内容类型发布的JSON application/json,请使用request.get_json()

data = request.get_json()

For URL query parameters, use request.args.

search = request.args.get("search")
page = request.args.get("page")

For posted form input, use request.form.

email = request.form.get('email')
password = request.form.get('password')

For JSON posted with content type application/json, use request.get_json().

data = request.get_json()

回答 3

这是解析发布的JSON数据并将其回显的示例。

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/foo', methods=['POST']) 
def foo():
    data = request.json
    return jsonify(data)

要使用curl发布JSON:

curl -i -H "Content-Type: application/json" -X POST -d '{"userId":"1", "username": "fizz bizz"}' http://localhost:5000/foo

或使用邮递员:

Here’s an example of parsing posted JSON data and echoing it back.

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/foo', methods=['POST']) 
def foo():
    data = request.json
    return jsonify(data)

To post JSON with curl:

curl -i -H "Content-Type: application/json" -X POST -d '{"userId":"1", "username": "fizz bizz"}' http://localhost:5000/foo

Or to use Postman:


回答 4

如果您发布内容类型为的JSON,请在Flask中application/json使用request.get_json()它。如果内容类型不正确,None则返回。如果数据不是JSON,则会引发错误。

@app.route("/something", methods=["POST"])
def do_something():
    data = request.get_json()

If you post JSON with content type application/json, use request.get_json() to get it in Flask. If the content type is not correct, None is returned. If the data is not JSON, an error is raised.

@app.route("/something", methods=["POST"])
def do_something():
    data = request.get_json()

回答 5

要获取原始帖子正文,而不管内容类型如何,请使用request.get_data()。如果使用request.data,它将调用request.get_data(parse_form_data=True),它将填充request.form MultiDictdata留空。

To get the raw post body regardless of the content type, use request.get_data(). If you use request.data, it calls request.get_data(parse_form_data=True), which will populate the request.form MultiDict and leave data empty.


回答 6

request.form使用普通字典,请使用request.form.to_dict(flat=False)

要返回API的JSON数据,请将其传递给jsonify

本示例将表单数据作为JSON数据返回。

@app.route('/form_to_json', methods=['POST'])
def form_to_json():
    data = request.form.to_dict(flat=False)
    return jsonify(data)

这是带有curl的POST表单数据的示例,返回为JSON:

$ curl http://127.0.0.1:5000/data -d "name=ivanleoncz&role=Software Developer"
{
  "name": "ivanleoncz", 
  "role": "Software Developer"
}

To get request.form as a normal dictionary , use request.form.to_dict(flat=False).

To return JSON data for an API, pass it to jsonify.

This example returns form data as JSON data.

@app.route('/form_to_json', methods=['POST'])
def form_to_json():
    data = request.form.to_dict(flat=False)
    return jsonify(data)

Here’s an example of POST form data with curl, returning as JSON:

$ curl http://127.0.0.1:5000/data -d "name=ivanleoncz&role=Software Developer"
{
  "name": "ivanleoncz", 
  "role": "Software Developer"
}

回答 7

使用request.get_json()得到张贴JSON数据。

data = request.get_json()
name = data.get('name', '')

使用request.formPOST方法提交表单时用于获取数据。

name = request.form.get('name', '')

使用request.args得到的网址,用GET方法提交表单的时候喜欢的查询字符串传递的数据。

request.args.get("name", "")

request.form等类似dict,get如果未通过默认值,请使用方法获取值。

Use request.get_json() to get posted JSON data.

data = request.get_json()
name = data.get('name', '')

Use request.form to get data when submitting a form with the POST method.

name = request.form.get('name', '')

Use request.args to get data passed in the query string of the URL, like when submitting a form with the GET method.

request.args.get("name", "")

request.form etc. are dict-like, use the get method to get a value with a default if it wasn’t passed.


回答 8

要发布不包含application/json内容类型的JSON ,请使用request.get_json(force=True)

@app.route('/process_data', methods=['POST'])
def process_data():
    req_data = request.get_json(force=True)
    language = req_data['language']
    return 'The language value is: {}'.format(language)

To get JSON posted without the application/json content type, use request.get_json(force=True).

@app.route('/process_data', methods=['POST'])
def process_data():
    req_data = request.get_json(force=True)
    language = req_data['language']
    return 'The language value is: {}'.format(language)

回答 9

原始数据从WSGI服务器传递到Flask应用程序request.stream。流的长度在Content-Length标题中。

length = request.headers["Content-Length"]
data = request.stream.read(length)

通常,使用它更安全request.get_data()

The raw data is passed in to the Flask application from the WSGI server as request.stream. The length of the stream is in the Content-Length header.

length = request.headers["Content-Length"]
data = request.stream.read(length)

It is usually safer to use request.get_data() instead.


回答 10

要在JavaScript中使用jQuery发布JSON,请使用JSON.stringify转储数据并将内容类型设置为application/json

var value_data = [1, 2, 3, 4];

$.ajax({
    type: 'POST',
    url: '/process',
    data: JSON.stringify(value_data),
    contentType: 'application/json',
    success: function (response_data) {
        alert("success");
    }   
});

使用解析在Flask中request.get_json()

data = request.get_json()

To post JSON with jQuery in JavaScript, use JSON.stringify to dump the data, and set the content type to application/json.

var value_data = [1, 2, 3, 4];

$.ajax({
    type: 'POST',
    url: '/process',
    data: JSON.stringify(value_data),
    contentType: 'application/json',
    success: function (response_data) {
        alert("success");
    }   
});

Parse it in Flask with request.get_json().

data = request.get_json()

回答 11

要解析JSON,请使用request.get_json()

@app.route("/something", methods=["POST"])
def do_something():
    result = handle(request.get_json())
    return jsonify(data=result)

To parse JSON, use request.get_json().

@app.route("/something", methods=["POST"])
def do_something():
    result = handle(request.get_json())
    return jsonify(data=result)

回答 12

这是一个发布表单数据以将用户添加到数据库的示例。检查request.method == "POST"表单是否已提交。使用键request.form来获取表单数据。使用<form>其他方式呈现HTML模板。表单中的字段应具有name与中的键匹配的属性request.form

from flask import Flask, request, render_template

app = Flask(__name__)

@app.route("/user/add", methods=["GET", "POST"])
def add_user():
    if request.method == "POST":
        user = User(
            username=request.form["username"],
            email=request.form["email"],
        )
        db.session.add(user)
        db.session.commit()
        return redirect(url_for("index"))

    return render_template("add_user.html")
<form method="post">
    <label for="username">Username</label>
    <input type="text" name="username" id="username">
    <label for="email">Email</label>
    <input type="email" name="email" id="email">
    <input type="submit">
</form>

Here’s an example of posting form data to add a user to a database. Check request.method == "POST" to check if the form was submitted. Use keys from request.form to get the form data. Render an HTML template with a <form> otherwise. The fields in the form should have name attributes that match the keys in request.form.

from flask import Flask, request, render_template

app = Flask(__name__)

@app.route("/user/add", methods=["GET", "POST"])
def add_user():
    if request.method == "POST":
        user = User(
            username=request.form["username"],
            email=request.form["email"],
        )
        db.session.add(user)
        db.session.commit()
        return redirect(url_for("index"))

    return render_template("add_user.html")
<form method="post">
    <label for="username">Username</label>
    <input type="text" name="username" id="username">
    <label for="email">Email</label>
    <input type="email" name="email" id="email">
    <input type="submit">
</form>

回答 13

如果内容类型被识别为表单数据,request.data则将其解析为表单request.form并返回一个空字符串。

要获取原始数据,而不管内容类型如何,请调用request.get_data()request.data直接调用get_data(parse_form_data=True),而默认值为False直接调用。

If the content type is recognized as form data, request.data will parse that into request.form and return an empty string.

To get the raw data regardless of content type, call request.get_data(). request.data calls get_data(parse_form_data=True), while the default is False if you call it directly.


回答 14

如果将正文识别为表单数据,它将在中request.form。如果是JSON,它将位于中request.get_json()。否则,原始数据将在中request.data。如果不确定如何提交数据,可以使用or链来获取第一个包含数据的链。

def get_request_data():
    return (
        request.args
        or request.form
        or request.get_json(force=True, silent=True)
        or request.data
    )

request.args包含从查询字符串中解析出的args,无论主体是什么,因此get_request_data()如果它和主体都应同时进行数据处理,则可以将其删除。

If the body is recognized as form data, it will be in request.form. If it’s JSON, it will be in request.get_json(). Otherwise the raw data will be in request.data. If you’re not sure how data will be submitted, you can use an or chain to get the first one with data.

def get_request_data():
    return (
        request.args
        or request.form
        or request.get_json(force=True, silent=True)
        or request.data
    )

request.args contains args parsed from the query string, regardless of what was in the body, so you would remove that from get_request_data() if both it and a body should data at the same time.


回答 15

使用HTML表单发布表单数据时,请确保input标签具有name属性,否则它们将不会出现在中request.form

@app.route('/', methods=['GET', 'POST'])
def index():
    print(request.form)
    return """
<form method="post">
    <input type="text">
    <input type="text" id="txt2">
    <input type="text" name="txt3" id="txt3">  
    <input type="submit">
</form>
"""
ImmutableMultiDict([('txt3', 'text 3')])

只有txt3输入中有一个name,因此它是中唯一的键request.form

When posting form data with an HTML form, be sure the input tags have name attributes, otherwise they won’t be present in request.form.

@app.route('/', methods=['GET', 'POST'])
def index():
    print(request.form)
    return """
<form method="post">
    <input type="text">
    <input type="text" id="txt2">
    <input type="text" name="txt3" id="txt3">  
    <input type="submit">
</form>
"""
ImmutableMultiDict([('txt3', 'text 3')])

Only the txt3 input had a name, so it’s the only key present in request.form.