Flask快速搭建接口-python库

Flask 是一个基于 Python 的轻量级 Web 框架,用于构建 Web 应用程序和 RESTful API。它被设计为简单、易用、灵活,并且具有良好的扩展性。Flask 是一个微型框架,提供了一些基本功能,但也允许开发者根据需要选择并添加扩展。

Flask 构成

  1. 路由(Routing):Flask 使用路由来定义 URL 和对应的处理函数。通过装饰器 @app.route(),可以将一个 URL 映射到相应的处理函数上,从而实现请求的路由和处理。

  2. 视图函数(View Functions):视图函数是 Flask 中处理请求的核心组件,它接收请求并返回响应。视图函数通常被装饰器绑定到特定的 URL 路由上。

  3. 请求上下文(Request Context):Flask 在处理请求时会创建一个请求上下文,其中包含了请求的信息,例如请求的方法、URL 参数、表单数据等。视图函数可以通过 request 对象来访问请求上下文中的数据。

  4. 响应对象(Response Object):视图函数需要返回一个响应对象,用于向客户端返回数据。Flask 提供了 make_response() 函数和 Response 类来构造响应对象,也可以直接返回字符串、模板渲染结果等。

  5. 模板引擎(Template Engine):Flask 默认使用 Jinja2 模板引擎来渲染 HTML 页面。模板引擎允许开发者在模板中嵌入动态内容,从而将数据和视图分离,使页面更加灵活和易于维护。

  6. 上下文全局变量(Context Globals):Flask 提供了一些上下文全局变量,例如 current_appg,可以在视图函数中使用。current_app 表示当前应用的实例,g 是一个全局变量字典,可以在同一请求中共享数据。

  7. 扩展(Extensions):Flask 的功能可以通过扩展来增强,例如数据库支持、表单验证、用户认证等。Flask 社区提供了大量的扩展,使开发者能够更方便地添加功能。

  8. 蓝图(Blueprint):蓝图是一种将 Flask 应用分割为小模块的方式,可以将相关的路由和视图函数组织在一个蓝图中,使应用更加结构化和易于管理。

优势

  1. 简单易用:Flask 的设计理念是保持简单和直观,它的 API 非常易于学习和使用,使得开发者可以快速上手开发 Web 应用。

  2. 轻量级:Flask 是一个微型框架,提供了一些基本的功能,没有过多的依赖,因此加载速度快,适合构建小型和中小型的 Web 应用。

  3. 灵活可扩展:尽管 Flask 是轻量级的,但它允许开发者根据需要选择和添加扩展,以增加更多功能,例如数据库支持、表单验证、用户认证等。

  4. RESTful 支持:Flask 提供了良好的支持来构建 RESTful 风格的 API,使开发者可以轻松地构建基于 Web 的服务端应用。

  5. Jinja2 模板引擎:Flask 使用 Jinja2 模板引擎来渲染 HTML 页面,使页面构建更加灵活和易于维护。

  6. 开放性和活跃社区:Flask 是一个开源项目,有一个活跃的社区,拥有大量的第三方库和扩展可供选择,帮助开发者更快地构建功能丰富的 Web 应用。

劣势

  1. 功能有限:Flask 是一个微型框架,相对于一些全功能的 Web 框架,它提供的功能相对较少。对于复杂的大型 Web 应用,可能需要结合一些扩展或其他库来满足需求。

  2. 缺少内置功能:由于 Flask 是一个轻量级框架,它并不包含一些高级的功能,例如数据库迁移、用户认证等。这些功能需要使用扩展或手动实现。

  3. 依赖于扩展:为了增加功能,开发者需要依赖一些扩展,而不是直接内置在框架中。这在一定程度上增加了应用的复杂性,需要管理更多的依赖关系。

  4. 相对较小的社区:虽然 Flask 有一个活跃的社区,但相对于一些大型框架,其社区规模可能较小,这可能会影响到获取支持和解决问题的速度。

总体来说,Flask 是一个非常优秀和受欢迎的 Web 框架,它的简单性和灵活性使得它适用于快速开发小型和中小型的 Web 应用和 API。但对于复杂的大型 Web 应用,可能需要权衡其功能限制并结合其他工具来满足需求。

 

示例

from flask import Flask

app = Flask(__name__)

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

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

浏览器中访问 http://127.0.0.1:5000/ 来查看输出,会返回 Hello, World!

 

Flask 使用 Jinja2 模板引擎来渲染 HTML 页面,有没有简单的例子:

当使用 Flask 渲染 HTML 页面时,通常需要使用模板引擎来动态生成页面内容。 Flask 默认使用 Jinja2 模板引擎,以下是一个简单的示例:

 

1.首先,在项目目录下创建一个名为 "templates" 的文件夹,用于存放 HTML 模板文件。

 

 

2.在 "templates" 文件夹中创建一个名为 "index.html" 的模板文件,内容如下:

<!DOCTYPE html>
<html>
<head>
    <title>Hello Flask</title>
</head>
<body>
    <h1>Hello, {{ name }}!</h1>
    <p>This is a simple example of Flask template rendering.</p>
</body>
</html>

在上述模板中,我们使用了 {{ name }} 这样的占位符,它将在渲染页面时被动态替换成具体的值。

 

3.创建 Flask 应用并添加视图函数,将模板渲染并返回给客户端:

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    name = 'John'  # 假设这个名字是从数据库或其他地方获取的
    return render_template('index.html', name=name)

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

在上述代码中,我们定义了一个名为 index 的视图函数,它会渲染模板 "index.html" 并将变量 name 的值传递给模板。

4.运行应用并在浏览器中访问 http://127.0.0.1:5000/,将会看到渲染后的页面,其中显示了 "Hello, John!" 和一条简单的说明。

在实际应用中,模板引擎的使用非常灵活,您可以在模板中嵌入任意动态数据,并根据实际需求来展示不同的内容。模板引擎让页面和数据的处理分离,使得开发更加便捷和维护更加简单。

 

用Flask能做到前后端分离吗?

是的,Flask 可以做到前后端分离。虽然 Flask 是一个服务器端的 Web 框架,但它可以通过提供 RESTful API 来实现前后端分离的架构。

在 Flask 中,您可以设计和实现一组 API 接口,这些接口定义了前端可以调用的功能和数据。前端开发团队可以使用任何前端框架(如 React、Vue.js、Angular 等)来构建用户界面和交互,然后通过 Fetch、Axios 等工具来调用 Flask 提供的 API。

具体实现前后端分离的步骤如下:

  1. 设计 API 接口:定义一组 RESTful API 接口,包括对资源的 CRUD 操作。这些接口通常使用 HTTP 方法(如 GET、POST、PUT、DELETE)来实现对后端资源的访问和操作。

  2. 后端开发:在 Flask 中实现定义好的 API 接口。可以使用 Flask 的路由和视图函数来处理 API 请求,并进行后端的业务逻辑处理和数据库访问。

  3. 前端开发:前端团队使用所选的前端框架来构建用户界面和交互,并通过 Fetch、Axios 等工具来调用 Flask 提供的 API 接口。前端开发团队可以独立进行开发,无需依赖于后端的实现。

  4. 跨域处理:由于前端和后端运行在不同的域或端口上,可能会涉及到跨域问题。在 Flask 中,您可以通过配置 CORS(跨域资源共享)来允许前端跨域访问后端 API。

通过前后端分离,Flask 可以实现前后端的独立开发和演进,提高开发效率,同时为构建现代化的 Web 应用提供更好的灵活性和扩展性。

跨域处理是啥?

跨域是指浏览器限制在一个域下的网页去请求另一个域下的资源。在前后端分离的架构中,前端通常运行在一个域或端口上,而后端 API 服务可能运行在另一个域或端口上,因此会涉及到跨域问题。

Flask 本身并不自动处理跨域请求,但可以通过配置 CORS(跨域资源共享)来允许跨域访问。CORS 是一种机制,允许服务器告诉浏览器是否允许在不同域之间进行跨域访问。

下面是在 Flask 中处理跨域请求的详细步骤:

安装 Flask-CORS 扩展:首先,需要安装 Flask-CORS 扩展。您可以使用 pip 安装:

pip install flask-cors

导入扩展:在 Flask 应用中,导入 Flask-CORS 扩展,并将其初始化为应用对象。

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

配置 CORS:您可以根据需要配置 CORS,例如指定允许的源(Origin)或请求头。

# 允许所有来源访问
CORS(app, resources={r"/*": {"origins": "*"}})

# 允许特定来源访问
CORS(app, resources={r"/*": {"origins": "http://example.com"}})

# 允许多个来源访问
CORS(app, resources={r"/*": {"origins": ["http://example.com", "http://example2.com"]}})

指定请求方法:默认情况下,CORS 只允许简单请求(如 GET、POST、HEAD)进行跨域访问。如果您的前端需要使用其他请求方法(如 PUT、DELETE 等),您需要在 CORS 配置中指定它们。

CORS(app, resources={r"/*": {"origins": "*", "methods": ["GET", "POST", "PUT", "DELETE"]}})

响应头设置:Flask-CORS 还可以配置其他响应头,如允许凭证(Credentials)和暴露头(Exposed Headers)等。

CORS(app, resources={r"/*": {"origins": "*", "supports_credentials": True, "expose_headers": "Authorization"}})

以上就是在 Flask 中处理跨域请求的基本步骤。通过配置 CORS,您可以允许前端从不同的域或端口访问后端 API,实现前后端分离架构中的跨域请求。

 

博客例子展示:

设计 API 接口

,假设我们正在设计一个博客系统的后端 API:

获取所有博客文章列表:(GET 请求)

Endpoint: /api/posts
Response: [
    {
        "id": 1,
        "title": "Hello World",
        "content": "This is the first blog post."
    },
    {
        "id": 2,
        "title": "Introduction to Flask",
        "content": "A tutorial on using Flask to build web applications."
    },
    ...
]

获取单篇博客文章:(GET 请求)

Endpoint: /api/posts/{id}
Response: {
    "id": 1,
    "title": "Hello World",
    "content": "This is the first blog post."
}

创建新的博客文章:(POST 请求)

Endpoint: /api/posts
Request Body: {
    "title": "New Post",
    "content": "This is a new blog post."
}
Response: {
    "id": 3,
    "title": "New Post",
    "content": "This is a new blog post."
}

更新博客文章:(PUT 请求)

Endpoint: /api/posts/{id}
Request Body: {
    "title": "Updated Post",
    "content": "This is an updated blog post."
}
Response: {
    "id": 3,
    "title": "Updated Post",
    "content": "This is an updated blog post."
}

删除博客文章:(DELETE 请求)

Endpoint: /api/posts/{id}
Response: 204 No Content

在上述例子中,我们定义了一组基本的 RESTful API 接口,用于对博客文章资源进行 CRUD 操作。每个接口都有对应的请求方法(GET、POST、PUT、DELETE)以及响应数据。这样的设计使得前端可以通过调用这些 API 接口来操作博客文章资源,实现与后端的数据交互。注意,实际的 API 设计可能会更复杂和丰富,根据具体的业务需求来定义更多的接口和功能。

实现接口

在后端使用 Flask 编写这些 API 接口非常简单。Flask 提供了装饰器来定义路由和视图函数,使得编写 API 接口变得非常直观和灵活。

以下是一个简单的示例,展示如何在 Flask 中编写这些 API 接口:

from flask import Flask, request, jsonify

app = Flask(__name__)

# 假设博客文章数据存储在一个列表中
posts = [
    {"id": 1, "title": "Hello World", "content": "This is the first blog post."},
    {"id": 2, "title": "Introduction to Flask", "content": "A tutorial on using Flask to build web applications."}
]

# 获取所有博客文章列表
@app.route('/api/posts', methods=['GET'])
def get_posts():
    return jsonify(posts)

# 获取单篇博客文章
@app.route('/api/posts/<int:post_id>', methods=['GET'])
def get_post(post_id):
    post = next((p for p in posts if p["id"] == post_id), None)
    if post:
        return jsonify(post)
    else:
        return jsonify({"message": "Post not found"}), 404

# 创建新的博客文章
@app.route('/api/posts', methods=['POST'])
def create_post():
    data = request.get_json()
    if "title" in data and "content" in data:
        new_post = {
            "id": len(posts) + 1,
            "title": data["title"],
            "content": data["content"]
        }
        posts.append(new_post)
        return jsonify(new_post), 201
    else:
        return jsonify({"message": "Invalid data"}), 400

# 更新博客文章
@app.route('/api/posts/<int:post_id>', methods=['PUT'])
def update_post(post_id):
    post = next((p for p in posts if p["id"] == post_id), None)
    if post:
        data = request.get_json()
        post["title"] = data.get("title", post["title"])
        post["content"] = data.get("content", post["content"])
        return jsonify(post)
    else:
        return jsonify({"message": "Post not found"}), 404

# 删除博客文章
@app.route('/api/posts/<int:post_id>', methods=['DELETE'])
def delete_post(post_id):
    global posts
    posts = [p for p in posts if p["id"] != post_id]
    return '', 204

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

request.get_json()是什么意思?

request.get_json() 是 Flask 中的一个方法,用于从 HTTP 请求中获取 JSON 数据。当客户端通过 POST 或 PUT 请求发送 JSON 数据时,可以使用 request.get_json() 来解析 JSON 数据,并将其转换为 Python 字典格式。

在上述示例中,我们使用 request.get_json() 来获取客户端发送的 JSON 数据,并在创建新的博客文章时使用这些数据。例如,在创建新博客文章的接口中,我们可以通过 request.get_json() 获取客户端发送的 JSON 数据,并将其提取出标题和内容字段,然后用这些字段创建一个新的博客文章,并将其添加到 posts 列表中。

注意,request.get_json() 方法在默认情况下是根据请求头中的 Content-Type 来判断请求是否是 JSON 数据。如果请求头中的 Content-Type 不是 application/json,则 request.get_json() 方法返回 None。为了处理不同类型的请求,我们可以在使用 request.get_json() 方法时添加参数 force=True,以强制解析 JSON 数据,即使 Content-Type 不是 application/json。

data = request.get_json(force=True)  # 强制解析 JSON 数据

jsonify(posts)是什么意思?

jsonify() 是 Flask 提供的一个辅助函数,用于将 Python 数据结构转换为 JSON 格式的响应对象。它会自动设置响应头的 Content-Type 为 application/json,并将 Python 数据结构转换为 JSON 格式的字符串,然后将其作为响应返回给客户端。

在之前的示例中,我们使用 jsonify(posts)posts 列表转换为 JSON 格式的响应对象,并将其返回给客户端。这样客户端收到的响应就是一个 JSON 格式的数据。

jsonify() 的使用非常简单,只需要将要转换的数据作为参数传递给它即可。例如,我们还可以使用 jsonify() 来返回一个字典或其他数据结构的 JSON 格式响应:

from flask import jsonify

# 返回一个字典的 JSON 格式响应
data = {"name": "John", "age": 30}
response = jsonify(data)
# response 的内容为: {"name": "John", "age": 30}

# 返回一个列表的 JSON 格式响应
items = ["apple", "banana", "orange"]
response = jsonify(items)
# response 的内容为: ["apple", "banana", "orange"]

PUT和POST有什么区别?

PUT 和 POST 是 HTTP 请求方法,用于向服务器提交数据。它们在用途和语义上有一些区别:

  1. POST(创建资源):

    • POST 方法用于在服务器上创建一个新的资源。每次使用 POST 请求,都会创建一个新的资源,其 URI 可能是服务器为其指定的,也可能是由服务器生成的唯一标识符。
    • POST 方法通常用于提交表单数据、上传文件等操作,以及创建资源。它是非幂等的,多次提交同样的数据可能会创建多个资源,因此不适合用于更新数据。
  2. PUT(更新资源):

    • PUT 方法用于向服务器更新或替换指定 URI 处的资源。如果 URI 不存在,则会创建一个新的资源;如果 URI 已经存在,那么 PUT 方法会对其进行更新或替换。
    • PUT 方法通常用于更新已有的资源,它是幂等的,多次提交相同的数据只会对资源进行一次更新,因此适合用于更新数据。

总结:

  • POST 用于创建新的资源,是非幂等的;
  • PUT 用于更新已有的资源,是幂等的。

在 RESTful API 设计中,通常使用 POST 方法来创建资源,使用 PUT 方法来更新资源。例如,使用 POST 方法创建一篇新的博客文章,使用 PUT 方法更新博客文章的内容。

 

我想做一个上传的接口:

from flask import Flask, request, jsonify

app = Flask(__name__)

# 配置上传文件保存路径
app.config['UPLOAD_FOLDER'] = 'uploads/'

# 上传文件接口
@app.route('/api/upload', methods=['POST'])
def upload_file():
    # 检查请求中是否包含文件
    if 'file' not in request.files:
        return jsonify({"message": "No file part"}), 400
    
    file = request.files['file']
    
    # 检查是否选择了文件
    if file.filename == '':
        return jsonify({"message": "No selected file"}), 400
    
    # 将文件保存到指定路径
    file.save(app.config['UPLOAD_FOLDER'] + file.filename)
    
    return jsonify({"message": "File uploaded successfully"}), 200

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

在请求中,客户端应该将文件数据作为 file 字段提交,例如使用表单或者 FormData 来提交文件。

import requests

url = 'http://127.0.0.1:5000/api/upload'
files = {'file': open('/path/to/your/file.jpg', 'rb')}
response = requests.post(url, files=files)

print(response.json())

 

posted @ 2023-08-04 13:31  双木玥  阅读(2326)  评论(0编辑  收藏  举报