Encapsulación y llamada de la API de Python3

1. Encapsulación de API

API (Interfaz de programación de aplicaciones, interfaz de programación de aplicaciones) son algunas funciones predefinidas, el propósito es proporcionar a las aplicaciones y desarrolladores la capacidad de acceder a un conjunto de rutinas basadas en una pieza de software o hardware, sin tener que acceder al código fuente, o comprender los detalles del mecanismo de funcionamiento interno.

La interfaz de Python3 es WSGI: Web Server Gateway Interface.

La definición de la interfaz WSGI es muy simple, solo requiere que los desarrolladores web implementen una función para responder a las solicitudes HTTP. Echemos un vistazo a la versión web más simple Hello, web!:

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [b'<h1>Hello, web!</h1>']

La función application() anterior es una función de procesamiento HTTP que cumple con el estándar WSGI y recibe dos parámetros:

  • entorno: un objeto dict que contiene toda la información de solicitud HTTP;

  • start_response: una función que envía una respuesta HTTP.

En la función application(), llame a:

start_response('200 OK', [('Content-Type', 'text/html')])

Se envía el encabezado de la respuesta HTTP. Tenga en cuenta que el encabezado solo se puede enviar una vez, es decir, start_response()la función solo se puede llamar una vez. start_response()La función recibe dos parámetros, uno es el código de respuesta HTTP y el otro es un conjunto de encabezados HTTP representados por una lista, y cada encabezado está representado por una tupla que contiene dos cadenas.

Normalmente, el encabezado de tipo de contenido debe enviarse al navegador. También se deben enviar muchos otros encabezados HTTP de uso común.

Luego, el valor de retorno de la función b'<h1>Hello, web!</h1>'se enviará al navegador como el cuerpo de la respuesta HTTP.

Con WSGI, lo que nos importa es cómo obtener la información de la solicitud HTTP del objeto dict del entorno, luego construir HTML, enviar el encabezado a través de start_response() y finalmente devolver el cuerpo.

Toda la función application() en sí misma no involucra ninguna parte del análisis de HTTP, es decir, el código subyacente no necesita ser escrito por nosotros mismos, solo somos responsables de considerar cómo responder a las solicitudes en un nivel superior.

Pero espera, ¿cómo se llama esta función application()? Si lo llamamos nosotros mismos, no podemos proporcionar los dos parámetros environ y start_response, y los bytes devueltos no se pueden enviar al navegador.

Por lo tanto, el servidor WSGI debe llamar a la función application(). Hay muchos servidores que se ajustan a la especificación WSGI y podemos elegir uno para usar. Pero ahora, solo queremos probar lo antes posible que la función application() que escribimos realmente puede generar HTML en el navegador, por lo que debemos encontrar rápidamente el servidor WSGI más simple y ejecutar nuestra aplicación web.

Python3 tiene un servidor WSGI incorporado.Este módulo se llama wsgiref, que es una implementación de referencia de un servidor WSGI escrito en Python puro. La llamada "implementación de referencia" significa que la implementación cumple completamente con el estándar WSGI, pero no considera ninguna eficiencia operativa y solo se usa para desarrollo y prueba.

Ejecute el servicio WSGI

Primero escribamos hello.py para implementar la función de procesamiento WSGI de la aplicación web:

# hello.py

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [b'<h1>Hello, web!</h1>']

Luego, escribe un server.py responsable de iniciar el servidor WSGI y cargar la función application():

# server.py
# 从wsgiref模块导入:
from wsgiref.simple_server import make_server
# 导入我们自己编写的application函数:
from hello import application

# 创建一个服务器,IP地址为空,端口是8080,处理函数是application:
httpd = make_server('', 8080, application)
print('Serving HTTP on port 8080...')
# 开始监听HTTP请求:
httpd.serve_forever()

resultado de la operación:

  • Iniciar WSGI

    Geek-Mac:Downloads zhangyi$ python3 server.py 
    Serving HTTP on port 8080...
  • API de acceso

    Geek-Mac:Downloads zhangyi$ curl "localhost:8080/"
    <h1>Hello, web!</h1>Geek-Mac:Downloads zhangyi$

Esta es la aplicación WSGI más simple y luego escriba un programa simple para probar la API usted mismo en el trabajo diario

ejemplo

api.py

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

import json
# 导入 urllib.parse 模块的 parse_qs 方法
from urllib.parse import parse_qs
from wsgiref.simple_server import make_server


def api(app):

    def application(environ, start_response):

        start_response('200 OK', [('Content-Type', 'text/html')])
        # 获取当前get请求的所有数据,返回是string类型
        parse = parse_qs(environ['QUERY_STRING'])
        data = json.dumps(app(parse))

        # 返回值是 UTF-8
        return [data.encode('utf-8')]

    def run():

        httpd = make_server('', 8080, application)
        print("Serving HTTP on port 8080 ...")
        httpd.serve_forever()

    # 外部模块调用才执行
    if __name__ != "__main__":
        run()

app.py

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

# API 调用实例
# http://127.0.0.1:8080/?name=Geek&user=root

# 导入 api 模块的 api 方法,当然也可以将 api 模块做成一个包,方便调用
from api import api


# 使用装饰器的形式调用函数
@api
def app(parse):

    # 使用 urllib.parse 模块的 parse_qs.get 方法获取 url 中字段的值
    name = parse.get('name', [''])[0]
    user = parse.get('user', [''])[0]

    # 将获取的值写到字典中
    data = {'name': name, 'user': user}

    return data

resultado de la operación:

  • Iniciar WSGI

    Geek-Mac:API zhangyi$ python3 app.py 
    Serving HTTP on port 8080 ...
  • API de acceso

    Geek-Mac:API zhangyi$ curl "http://127.0.0.1:8080/?name=Geek&user=root"
    {"name": "Geek", "user": "root"}Geek-Mac:API zhangyi$

La mayor ventaja de usar un decorador es que reduce la complejidad del programa. Solo debemos preocuparnos por las funciones que escribimos.  app Finalmente, usar uno encima de la función  @api puede hacer que el programa se ejecute directamente, lo que acelera enormemente la eficiencia del desarrollo.

2. Llamada a la API

La llamada API puede usar el módulo que viene con Python 3.  urllibAquí hay un módulo de terceros más útil  requests.

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

# 安装requests ==> sudo pip3 install requests

import requests


# 调用 API 的 GET 请求
URL = "http://127.0.0.1:8080/?name=Geek&user=root"
data = requests.get(url = URL)

# 获取返回状态
print (data.status_code)
# 获取返回URL
print (data.url)
# 获取返回数据
print (data.text)
# 获取返回 json 解析数据
print (data.json())

resultado de la operación:

Geek-Mac:Downloads zhangyi$ python3 API.py 
200
http://127.0.0.1:8080/?name=Geek&user=root
{"name": "Geek", "user": "root"}
{'name': 'Geek', 'user': 'root'}

Este es solo  requestsel uso GET más simple, así como el uso POST, el paso de parámetros de diccionario y otros usos más detallados, visite el sitio web oficial: http://cn.python-requests.org/zh_CN/latest/

3. Especificación de escritura de API REST

Se puede resumir en una oración: REST es el principio rector del diseño arquitectónico que todas las aplicaciones web deben cumplir.

Transferencia de estado representacional, la traducción es "transferencia de estado representacional", Wikipedia tiene una descripción detallada: https://zh.wikipedia.org/wiki/Representational State Transfer. 

Orientado a recursos es la característica más obvia de REST, un conjunto de diferentes operaciones para el mismo recurso. Un recurso es un concepto abstracto que se puede nombrar en el servidor. Los recursos se organizan en torno a sustantivos, y lo primero en lo que hay que centrarse son los sustantivos. REST requiere que varias operaciones en los recursos se realicen a través de una interfaz unificada. Solo se puede realizar un conjunto limitado de operaciones en cada recurso. (7 métodos HTTP: GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS)

¿Qué son las API RESTful?

Una API que se ajusta al diseño de la arquitectura REST.

Resumir

Una API que se ajusta al estándar de diseño REST, es decir, una API RESTful. Los estándares y lineamientos que sigue el diseño de la arquitectura REST son el desempeño del protocolo HTTP, es decir, el protocolo HTTP es un patrón de diseño perteneciente a la arquitectura REST. Por ejemplo, sin estado, solicitud-respuesta.

4. Directrices de diseño de API RESTful

Reimpreso del blog de Ruan Yifeng: http://www.ruanyifeng.com/blog/2014/05/restful_api

La aplicación web se divide en dos partes, el front-end y el back-end. La tendencia de desarrollo actual es que los dispositivos front-end surgen sin cesar (teléfonos móviles, tabletas, computadoras de escritorio, otros dispositivos especiales...).

Por lo tanto, debe haber un mecanismo unificado para facilitar la comunicación entre los diferentes dispositivos front-end y el back-end. Esto ha llevado a la popularidad de la arquitectura API, e incluso a la idea de diseño de "API First". RESTful API es un conjunto relativamente maduro de teoría de diseño de API para aplicaciones de Internet. Escribí un artículo "Comprender la arquitectura RESTful" antes para explorar cómo entender este concepto.

Hoy, presentaré los detalles de diseño de la API RESTful y discutiré cómo diseñar una API razonable y fácil de usar.

1. Acuerdo

El protocolo de comunicación entre la API y el usuario siempre utiliza el protocolo HTTPs.

2. Nombre de dominio

La API debe implementarse bajo un nombre de dominio dedicado tanto como sea posible.

https://api.example.com

Si se determina que la API es muy simple y no habrá más expansión, se puede considerar colocarla bajo el nombre de dominio principal.

https://example.org/api/

3. Versiones

El número de versión de la API se debe poner en la URL.

https://api.example.com/v1/

Otra forma es poner el número de versión en la información del encabezado HTTP, pero no es tan conveniente e intuitivo como ponerlo en la URL. Github adopta esta práctica.

4. Ruta (punto final)

La ruta, también conocida como "punto final", indica la URL específica de la API.

En la arquitectura RESTful, cada URL representa un recurso (recurso), por lo que no puede haber verbos en la URL, solo sustantivos, y los sustantivos utilizados a menudo corresponden a los nombres de las tablas de la base de datos. En términos generales, las tablas de la base de datos son "colecciones" del mismo tipo de registros, por lo que los sustantivos en la API también deben usar plurales.

Por ejemplo, si hay una API que proporciona información del zoológico, incluida información sobre varios animales y empleados, su ruta debe diseñarse de la siguiente manera.

https://api.example.com/v1/zoos
https://api.example.com/v1/animals
https://api.example.com/v1/employees

5. Verbos HTTP

Los tipos de operaciones específicas para los recursos están representados por verbos HTTP.

Los verbos HTTP comúnmente utilizados son los siguientes (los comandos SQL correspondientes están entre paréntesis).

GET(SELECT):从服务器取出资源(一项或多项)。
POST(CREATE):在服务器新建一个资源。
PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
DELETE(DELETE):从服务器删除资源。

También hay dos verbos HTTP que no se usan comúnmente.

HEAD:获取资源的元数据。
OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。
下面是一些例子。
GET /zoos:列出所有动物园
POST /zoos:新建一个动物园
GET /zoos/ID:获取某个指定动物园的信息
PUT /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息)
PATCH /zoos/ID:更新某个指定动物园的信息(提供该动物园的部分信息)
DELETE /zoos/ID:删除某个动物园
GET /zoos/ID/animals:列出某个指定动物园的所有动物
DELETE /zoos/ID/animals/ID:删除某个指定动物园的指定动物

Seis, filtrar información (Filtrar)

Si la cantidad de registros es grande, es imposible que el servidor se los devuelva todos al usuario. La API debe proporcionar parámetros y filtrar los resultados devueltos.

A continuación se muestran algunos parámetros comunes.

?limit=10:指定返回记录的数量
?offset=10:指定返回记录的开始位置。
?page=2&per_page=100:指定第几页,以及每页的记录数。
?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
?animal_type_id=1:指定筛选条件
参数的设计允许存在冗余,即允许API路径和URL参数偶尔有重复。比如,GET /zoo/ID/animals 与 GET /animals?zoo_id=ID 的含义是相同的。

7. Códigos de estado

Los códigos de estado comunes y la información de solicitud que devuelve el servidor al usuario son los siguientes (el verbo HTTP correspondiente al código de estado está entre corchetes).

200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
204 NO CONTENT - [DELETE]:用户删除数据成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

Consulte aquí para obtener una lista completa de códigos de estado: https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

8. Manejo de errores

Si el código de estado es 4xx, se debe devolver un mensaje de error al usuario. En términos generales, el error se usa como el nombre de la clave en la información devuelta y el mensaje de error se usa como el valor de la clave.

{
    error: "Invalid API key"
}

Nueve, devuelve el resultado.

Para diferentes operaciones, los resultados devueltos por el servidor al usuario deben cumplir con las siguientes especificaciones.

GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
PATCH /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档

10. API hipermedia

La API RESTful es mejor para lograr Hypermedia, es decir, para proporcionar enlaces en los resultados devueltos a otros métodos API, para que los usuarios puedan saber qué hacer a continuación sin consultar la documentación.

Por ejemplo, cuando un usuario realiza una solicitud al directorio raíz de api.example.com, obtendrá dicho documento.

{"link": {
  "rel":   "collection https://www.example.com/zoos",
  "href":  "https://api.example.com/zoos",
  "title": "List of zoos",
  "type":  "application/vnd.yourformat+json"
}}

El código anterior indica que hay un atributo de enlace en el documento, y el usuario sabrá a qué API llamar después de leer este atributo. rel indica la relación entre esta API y la URL actual (se proporciona la relación de la colección y la URL de la colección), href indica la ruta de la API, title indica el título de la API y type indica el tipo de retorno.

El diseño de la API Hypermedia se llama HATEOAS. La API de Github está diseñada de esta manera. Al visitar api.github.com obtendrá una lista de URL para todas las API disponibles.

{
  "current_user_url": "https://api.github.com/user",
  "authorizations_url": "https://api.github.com/authorizations",
  // ...
}

Como se puede ver en lo anterior, si desea obtener la información del usuario actual, debe visitar api.github.com/user y luego obtendrá los siguientes resultados.

{
  "message": "Requires authentication",
  "documentation_url": "https://developer.github.com/v3"
}

El código anterior indica que el servidor proporciona la información del aviso y la URL del documento.

11. Otros

(1) La autenticación de API debe usar el marco OAuth 2.0.

(2) El formato de datos devuelto por el servidor debe tratar de usar JSON en lugar de XML.

Supongo que te gusta

Origin blog.csdn.net/onebound_linda/article/details/131914900
Recomendado
Clasificación