猎鹰框架简介

Falcon是一个轻量级的Python Web API框架,专注于构建高性能的微服务和应用后端。本教程将引导读者了解Falcon的主要特性,并通过实例展示如何安装和创建一个简单的RESTful API。
摘要由CSDN通过智能技术生成

Falcon is a light-weight Python web API framework for building high-performance microservices, app backends, and higher-level frameworks. This tutorial will give an introduction to Falcon, its major features, and how to install Falcon. We’ll also build a simple RESTful API with Falcon.

Falcon是一个轻量级的Python Web API框架,用于构建高性能微服务,应用程序后端和更高级别的框架。 本教程将介绍Falcon,其主要功能以及如何安装Falcon。 我们还将使用Falcon构建一个简单的RESTful API。

Falcon与其他框架相比的优势 (Advantages of Falcon Compared to Other Frameworks)

According to the documentation, some of the features of Falcon that make it superior to other Python frameworks include:

根据文档 ,Falcon使其优于其他Python框架的一些功能包括:

Speed Falcon requests work several times faster than most other Python frameworks. Additionally, Falcon works well when combined with Cython, giving it an extra speed boost; it also works well with PyPy.

速度 Falcon请求的工作速度比大多数其他Python框架快几倍。 此外,Falcon与Cython结合使用时效果很好,从而可以额外提高速度。 它也可以与PyPy一起使用

Flexibility — Falcon leaves a lot of the implementation details to you, the developer; hence there’s freedom to customize your implementation.

灵活性 -猎鹰向开发人员留下了许多实施细节; 因此,可以自由定制您的实现。

Ease of debugging — In Falcon, logic paths are understandable and straightforward, which makes it easier to reason with the code and perform code debugging.

易于调试 -在Falcon中,逻辑路径是易于理解和直接的,这使得对代码进行推理和执行代码调试更加容易。

特征 (Features)

  • Highly-optimized code base

    高度优化的代码库
  • Intuitive routing via URI templates and REST-inspired resource classes

    通过URI模板和受REST启发的资源类进行直观的路由
  • Easy access to headers and bodies through request and response classes

    通过请求和响应类轻松访问标头和正文
  • DRY request processing via middleware components and hooks

    通过中间件组件和挂钩进行DRY请求处理
  • Idiomatic HTTP error responses

    惯用的HTTP错误响应
  • Straightforward exception handling

    简单的异常处理

使用Falcon构建RESTful API (Building a RESTful API With Falcon)

In this example, you will build a bucket list API. A bucket list is simply a list of things you’d like to do before you die. Let’s get started. Create the project directory and set up a virtual environment.

在此示例中,您将构建存储桶列表API。 遗愿清单只是死亡前您想做的事情的清单。 让我们开始吧。 创建项目目录并设置虚拟环境。

mkdir bucketlist
cd bucketlist
virtualenv .venv
source .venv/bin/activate

安装猎鹰 (Install Falcon)

Installing Falcon is as simple as:

安装Falcon非常简单:

pip install falcon

Create another folder app inside the bucketlist directory and mark it as a Python module by creating an empty __init__.py file in it:

bucketlist目录中创建另一个文件夹app ,并通过在其中创建一个空的__init__.py文件将其标记为Python模块:

mkdir app
touch app/__init__.py

Inside the app folder, create a file main.py and add the following code.

在app文件夹中,创建文件main.py并添加以下代码。

import falcon
application = falcon.API()
if __name__ == "__main__":
  application.run(host="0.0.0.0", debug=True)

Falcon framework uses the concept of a resource. Resources are things that can be accessed by a URL. We will discuss this further when we start building the views for our application.

Falcon框架使用资源的概念。 资源是可以通过URL访问的东西。 当我们开始为应用程序构建视图时,我们将进一步讨论。

Edit main.py file to look something like this:

编辑main.py文件,如下所示:

import falcon
import json


class IndexResource(object):
  def on_get(self, req, res):
    res.status = falcon.HTTP_200
    res.body = json.dumps({"success": "My first falcon app"})




application = falcon.API()
application.add_route('/', IndexResource())




if __name__ == "__main__":
  application.run(host="0.0.0.0", debug=True)

Falcon speaks WSGI, and so to serve a Falcon app, you will need a WSGI server. In this tutorial, we will be using Gunicorn to serve our app, so let’s install Gunicorn.

Falcon说WSGI,因此要提供Falcon应用程序,您将需要WSGI服务器。 在本教程中,我们将使用Gunicorn服务我们的应用程序,因此让我们安装Gunicorn。

pip install gunicorn

Now run your application by issuing gunicorn -b 0.0.0.0:8000 — reload main:application. Navigate to http://127.0.0.1, and you should see your representation of the IndexResource.

现在,通过发出gunicorn -b 0.0.0.0:8000 — reload main:application运行您的应用gunicorn -b 0.0.0.0:8000 — reload main:application 。 导航到http://127.0.0.1 您应该看到IndexResource的表示IndexResource

Image for post

Let’s now get started on creating the blocks for our application:

现在让我们开始为我们的应用程序创建块:

配置数据库 (Configure database)

We will use the PostgreSQL database because it’s robust and stable.

我们将使用PostgreSQL数据库,因为它既健壮又稳定。

PostgreSQL should be installed on your machine. Install the psycopg2 driver library in our application

PostgreSQL应该安装在您的机器上。 在我们的应用程序中安装psycopg2驱动程序库

pip install psycopg2

创建数据库和用户 (Create database and user)

Create a database “bucketlist” and assign a user.

创建一个数据库“ bucketlist”并分配一个用户。

Switch over to the Postgres account on your machine by typing:

通过输入以下命令切换到计算机上的Postgres帐户:

sudo su postgres

Access a Postgres prompt:

访问Postgres提示:

psql

Create bucketlist database:

创建存储桶列表数据库:

CREATE DATABASE bucketlist;

Create role:

创建角色:

CREATE ROLE pat WITH LOGIN PASSWORD ‘my_password’;

Grant access to the user:

向用户授予访问权限:

GRANT ALL PRIVILEGES ON DATABASE bucketlist TO pat;

We will use the SQLAlchemy extension to manage our application. This extension provides an ORM wrapper for the SQLAlchemy project.

我们将使用SQLAlchemy扩展来管理我们的应用程序。 该扩展为SQLAlchemy项目提供了一个ORM包装器。

Create a file config.py in the app directory and add the configurations you set up for the database above. The config file should look something like this.

在app目录中创建一个文件config.py ,并在上面添加您为数据库设置的配置。 配置文件应如下所示。

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, scoped_session
import logging


DATABASE_URL = 'postgresql+psycopg2://pat:my_password@localhost/bucketlist'
DB_ECHO = False
DB_AUTOCOMMIT = True




def get_engine(uri):
    logging.info('Connecting to database..')
    options = {
        'echo': DB_ECHO,
        'execution_options': {
            'autocommit': DB_AUTOCOMMIT
        }
    }
    return create_engine(uri, **options)




db_session = scoped_session(sessionmaker())
engine = get_engine(DATABASE_URL)

建立模型 (Create models)

Create a file models.py in the app directory and write the following code.

在应用目录中创建一个文件models.py并编写以下代码。

from sqlalchemy import Column, Integer, String
from sqlalchemy import DateTime, func
from sqlalchemy.ext.declarative import declarative_base, declared_attr
import datetime




class BaseModel(object):
  @declared_attr
  def __tablename__(self):
        return self.__name__.lower()




  def to_dict(self):
      intersection = set(self.__table__.columns.keys()) & set(self.FIELDS)
      return dict(map(
          lambda key:
              (key,
                  (lambda value: self.FIELDS[key](value) if value else None)
                  (getattr(self, key))),
              intersection))




  FIELDS = {}


Base = declarative_base(cls=BaseModel)








class Task(Base):
  id = Column(Integer, primary_key=True)
  task_name = Column(String(50), nullable=False)
  created = Column(DateTime,  default=datetime.datetime.utcnow)
  modified = Column(DateTime,  default=datetime.datetime.utcnow)




  def __repr__(self):
      return "<Task(task_name='%s',is_finished='%s')>" % \
          (self.task_name, self.is_finished)




  FIELDS = {
      'task_name': str,
  }




  FIELDS.update(Base.FIELDS)

Here we declare a base class that all schema objects will inherit from. The to_dict function will manage our queries by returning results in dictionary form.

在这里,我们声明所有模式对象都将继承的基类。 to_dict函数将通过以字典形式返回结果来管理我们的查询。

The declarative_base() returns a new base class from which all mapped classes should inherit.

declarative_base()返回一个新的基类,所有映射的类都应从该基类继承。

In config.py, update the file to use our models. Here we use the base class from our models to declare metadata that will be used to issue CREATE statements for all tables in our models.

config.py ,更新文件以使用我们的模型。 在这里,我们使用模型中的基类声明元数据,该元数据将用于为模型中的所有表发出CREATE语句。

#app/config.py
    .....
def init_session():
  db_session.configure(bind=engine)
  from app.models import Base
  Base.metadata.create_all(engine)

请求和回应 (Requests and responses)

Each responder in a resource receives a Request object that can be used to read the headers, query parameters, and body of the request.

资源中的每个响应者都会收到一个Request对象,该对象可用于读取标头,查询参数和请求的正文。

HTTP request and HTTP response are represented by req and resp, respectively.

HTTP请求和HTTP响应分别由reqresp表示。

创建用于管理请求和响应的中间件 (Create middleware for managing requests and responses)

A middleware is a Python class that hooks into the request/response lifecycle.

中间件是连接到请求/响应生命周期的Python类。

Create a new file middleware.py in the app directory and add the following middleware class:

创建一个新文件middleware.py 在app目录中,并添加以下中间件类:

# app/middleware.py


import json
class JSONTranslator(object):
    def process_request(self, req, resp):
        if req.content_length in (None, 0):
        # Nothing to do
        return


        body = req.stream.read()


        if not body:
            raise falcon.HTTPBadRequest('Empty request body',
                                        'A valid JSON is required.')




        try:
            req.context['doc'] = json.loads(body.decode('utf-8'))




        except (ValueError, UnicodeDecodeError):
            raise falcon.HTTPError(falcon.HTTP_753,
                                   'Malformed JSON',
                                   'Could not decode the request body.')




    def process_response(self, req, resp, resource):
        if 'result' not in resp.context:
            return


        resp.body = json.dumps(resp.context['result'])

The class above demonstrates how to read headers and query parameters, handle errors, and how to work with request and response bodies.

上面的类演示了如何读取标头和查询参数,如何处理错误以及如何使用请求和响应主体。

配置WSGI服务器以加载中间件并初始化数据库 (Configure WSGI server to load the middleware and initialize the database)

Edit the main.py file to include the middleware, and initialize the database as shown below.

编辑main.py 文件以包含中间件,并如下所示初始化数据库。

import falcon
from app.config import db_session, init_session
from app.views import JSONTranslator


application = falcon.API(middleware=[
    JSONTranslator()
])


init_session()
if __name__ == "__main__":
    application.run(host="127.0.0.1", debug=True)

创建资源 (Create resources)

As we mentioned at the beginning of this tutorial, Falcon uses the concept of a resource, and Python classes usually represent these resources. They convert the incoming response into an action and deliver a response back to the client.

正如我们在本教程开始时提到的那样,Falcon使用资源的概念,Python类通常表示这些资源。 他们将传入的响应转换为操作,然后将响应传递回客户端。

For a resource to provide support for any HTTP method, you add an on_*() method to the class, where * is any one of the common HTTP methods, in lowercase, i.e., on_get(), on_put(), etc.

为了使资源支持任何HTTP方法,请将on_*()方法添加到类中,其中*是常用的HTTP方法中的任何一种,均使用小写形式,即on_get()on_put()等。

Although resources are just regular classes, we are going to create a custom base class, BaseResource, from which we will inherit when we start creating our resources.

尽管资源只是常规类,但我们将创建一个自定义基类BaseResource ,当我们开始创建资源时,将从该基类继承。

Let’s start by creating a tasks resource. In app/views.py add the following code to:

让我们从创建任务开始 资源。 在app/views.py将以下代码添加到:

import falcon
from app.models import Task
from app.config import db_session


try:
    from collections import OrderedDict
except ImportError:
    OrderedDict = dict


class BaseResource(object):
    def success(self, resp, data=None):
        resp.status = falcon.HTTP_200
        obj = OrderedDict()
        obj['status'] = 200
        obj['data'] = data
        obj['message'] = 'OK'
        resp.body = json.dumps(obj)




class TaskResource(BaseResource):


    def on_get(self, req, resp):
        tasks = db_session.query(Task).all()
        obj = [task.to_dict() for task in tasks]
        self.success(resp, obj)


    def on_post(self, req, resp):
        task_details = req.context['doc']
        task = Task(task_name=task_details['task_name'])
        db_session.add(task)
        self.success(resp, "Task created successfullly")

The TaskResource defines two methods, on_get() for obtaining all the recorded tasks and on_post() for adding a new task.

TaskResource定义了两种方法, on_get()用于获取所有记录的任务,以及 on_post()用于添加新任务。

建立网址 (Create URLs)

URLs provide a way for the client to identify resources uniquely.

URL为客户端提供了一种唯一标识资源的方法。

Edit the main.py file to include the URL for the TaskResource as follows:

编辑main.py文件以包括网址TaskResource如下:

from app import views
application.add_route(‘/tasks/’, views.TaskResource())

Now, when a request comes in for /tasks, Falcon will call the responder on the task’s resource that corresponds to the requested HTTP method.

现在,当请求/tasks ,Falcon将在与请求的HTTP方法相对应的任务资源上调用响应者。

The project’s structure should now look like this:

该项目的结构现在应如下所示:

Image for post

Navigate to http://localhost:8000/tasks and see your resource in action.

导航到http://localhost:8000/tasks并查看正在使用的资源。

添加任务 (Add a task)

Image for post

查看任务 (View tasks)

Image for post

钩子 (Hooks)

Hooks in Falcon are similar to Python decorators.

Falcon中的钩子类似于Python装饰器。

Suppose our application required the user to be logged in before they could add or view tasks. We would implement this with a before hook.

假设我们的应用程序要求用户先登录,然后才能添加或查看任务。 我们将使用一个before钩子实现它。

Let’s create a hook that will run before each request to view or add a task.

让我们创建一个挂钩,该挂钩将在每个查看或添加任务的请求之前运行。

Next, we attach the hook to the on_post() responder and on_get() responders, as shown below.

接下来,我们将钩子附加到on_post()响应程序和on_get() 响应者,如下所示。

class TaskResource(BaseResource):
  @falcon.before(login_required)
  def on_get(self, req, resp):...




  @falcon.before(login_required)
  def on_post(self, req, resp):...

Now, before every call to that responder, Falcon will first invoke login_required, giving the following response.

现在,在每次调用该响应者之前,Falcon将首先调用login_required ,并给出以下响应。

{
“title”: “401 Unauthorized”
}

错误处理 (Error handling)

Falcon provides a set of error classes you can raise when something goes wrong, hence making it easier to detect and log errors.

Falcon提供了一组错误类别,您可以在出现问题时引发这些错误类别,从而使其更易于检测和记录错误。

These error classes include:

这些错误类别包括:

  • falcon.HTTPBadRequest

    falcon.HTTPBadRequest

  • falcon.HTTPInvalidHeader

    falcon.HTTPInvalidHeader

  • HTTPMissingHeader

    HTTPMissingHeader

  • HTTPInvalidParam

    HTTPInvalidParam

We have already been able to use the falcon.HTTPUnauthorized error in the login_required hook.

我们已经能够在login_required挂钩中使用falcon.HTTPUnauthorized错误。

结论 (Conclusion)

This tutorial has covered most of what is required to be able to build a REST API with Falcon successfully. For more information, see Falcon docs.

本教程介绍了成功使用Falcon构建REST API所需的大部分内容。 有关更多信息,请参阅Falcon docs

翻译自: https://medium.com/better-programming/an-introduction-to-the-falcon-framework-a787ceea098

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值