标签归档:http-server

Httpbin-HTTP请求和响应服务,用Python+Flask编写

Hug 使API开发尽可能简单


Hug的目标是使开发Python驱动的API尽可能简单,但并不简单。因此,它极大地简化了Python API开发

Hug的设计目标:

  • 使开发Python驱动的API与书面定义一样简洁
  • 框架应该鼓励编写自我文档代码
  • 它应该是快的。出于性能原因,开发人员永远不会觉得有必要寻找其他地方。
  • 为在Hug之上编写的API编写测试应该是简单而直观的
  • 在API框架中只做一次比将问题集推给API框架的用户要好
  • 成为下一代Python API的基础,采用最新技术

作为这些目标的结果,Hug仅支持Python3+,并且是在此基础上构建的Falcon’s高性能HTTP库

支持拥抱发展

Get professionally supported hug with the Tidelift Subscription

拥抱的专业支持是作为Tidelift
Subscription
Tidelift为软件开发团队提供了购买和维护软件的单一来源,并由最了解该技术的专家提供专业级别保证,同时与现有工具无缝集成

安装拥抱

安装Hug非常简单,只需:

pip3 install hug --upgrade

理想情况下,在virtual environment

快速入门

只需几行代码即可使用简单端点构建示例API

# filename: happy_birthday.py
"""A basic (single function) API written using hug"""
import hug


@hug.get('/happy_birthday')
def happy_birthday(name, age:hug.types.number=1):
    """Says happy birthday to a user"""
    return "Happy {age} Birthday {name}!".format(**locals())

要运行,请在命令行中键入:

hug -f happy_birthday.py

您可以在浏览器中访问该示例,网址为:localhost:8000/happy_birthday?name=hug&age=1然后在以下位置查看您的API的文档localhost:8000/documentation

参数也可以在URL中编码(签出happy_birthday.py对于整个示例)

@hug.get('/greet/{event}')
def greet(event: str):
    """Greets appropriately (from http://blog.ketchum.com/how-to-write-10-common-holiday-greetings/)  """
    greetings = "Happy"
    if event == "Christmas":
        greetings = "Merry"
    if event == "Kwanzaa":
        greetings = "Joyous"
    if event == "wishes":
        greetings = "Warm"

    return "{greetings} {event}!".format(**locals())

一旦您按照上述方式运行服务器,您就可以通过以下方式使用它:

curl http://localhost:8000/greet/wishes
"Warm wishes!"

拥抱着版本化

# filename: versioning_example.py
"""A simple example of a hug API call with versioning"""
import hug

@hug.get('/echo', versions=1)
def echo(text):
    return text


@hug.get('/echo', versions=range(2, 5))
def echo(text):
    return "Echo: {text}".format(**locals())

要运行示例,请执行以下操作:

hug -f versioning_example.py

然后,您可以从以下位置访问该示例localhost:8000/v1/echo?text=Hi/localhost:8000/v2/echo?text=Hi或从以下地址访问您的API的文档localhost:8000

注意:Hug中的版本控制自动支持版本头和直接基于URL的规范

Hug接口测试

拥抱的http方法装饰器不会修改您的原始函数。这使得测试Hug API与测试任何其他Python函数一样简单。此外,这意味着与其他Python代码中的API函数交互与仅调用Python API函数一样简单。Hug使测试API的完整Python堆栈变得容易,方法是使用hug.test模块:

import hug
import happy_birthday

hug.test.get(happy_birthday, 'happy_birthday', {'name': 'Timothy', 'age': 25}) # Returns a Response object

你可以用这个Response测试断言的对象(签出test_happy_birthday.py):

def tests_happy_birthday():
    response = hug.test.get(happy_birthday, 'happy_birthday', {'name': 'Timothy', 'age': 25})
    assert response.status == HTTP_200
    assert response.data is not None

与其他基于WSGI的服务器运行Hug

拥抱暴露出一种__hug_wsgi__自动在每个API模块上使用魔法方法。在任何标准的WSGI服务器上运行基于Hug的API都应该很简单,只需将其指向module_name__hug_wsgi__

例如:

uwsgi --http 0.0.0.0:8000 --wsgi-file examples/hello_world.py --callable __hug_wsgi__

要运行hello world hug示例API,请执行以下操作

Hug API的构建块

在使用Hug框架构建API时,您将使用以下概念:

方法装饰器getpostupdate等HTTP方法修饰器,在保持Python方法不变的同时将Python函数公开为API

@hug.get() # <- Is the hug METHOD decorator
def hello_world():
    return "Hello"

Hug使用您修饰的函数结构自动为API用户生成文档。Hug始终将请求、响应和API_VERSION变量传递给函数(如果它们是在函数定义中定义的参数

类型批注可选地附加到方法参数的函数,用于指定如何验证参数并将其转换为Python类型

@hug.get()
def math(number_1:int, number_2:int): #The :int after both arguments is the Type Annotation
    return number_1 + number_2

类型批注还会馈送到hug的自动文档生成,让API用户知道要提供什么数据

指令与请求/响应数据一起执行的函数,这些函数基于在API_Function中作为参数被请求。这些仅作为输入参数应用,当前不能作为输出格式或转换应用

@hug.get()
def test_time(hug_timer):
    return {'time_taken': float(hug_timer)}

指令可以通过带有hug_前缀,或使用Python3类型批注。后者是更现代的方法,建议使用。模块中声明的指令可以通过使用它们的完全限定名作为类型注释来访问(例如:module.directive_name)

除了明显的输入转换用例之外,还可以使用指令将数据输送到API函数中,即使它们没有出现在请求查询字符串、POST正文等中。有关如何以这种方式使用指令的示例,请参阅Examples文件夹中的身份验证示例

添加您自己的指令非常简单:

@hug.directive()
def square(value=1, **kwargs):
    '''Returns passed in parameter multiplied by itself'''
    return value * value

@hug.get()
@hug.local()
def tester(value: square=10):
    return value

tester() == 100

为完整起见,下面是通过魔术名称方法访问指令的示例:

@hug.directive()
def multiply(value=1, **kwargs):
    '''Returns passed in parameter multiplied by itself'''
    return value * value

@hug.get()
@hug.local()
def tester(hug_multiply=10):
    return hug_multiply

tester() == 100

输出表单事项获取API函数的输出并对其进行格式化以便传输给API用户的函数

@hug.default_output_format()
def my_output_formatter(data):
    return "STRING:{0}".format(data)

@hug.get(output=hug.output_format.json)
def hello():
    return {'hello': 'world'}

如图所示,您可以轻松地更改整个API和单个API调用的输出格式

输入表事项一个函数,它从API的用户处获取数据体,并对其进行格式化以进行处理

@hug.default_input_format("application/json")
def my_input_formatter(data):
    return ('Results', hug.input_format.json(data))

输入格式化程序基于content_type请求数据,并且仅执行基本解析。更详细的解析应该由您的api_function

中间件Hug API处理的每个请求都会调用的函数

@hug.request_middleware()
def process_data(request, response):
    request.env['SERVER_NAME'] = 'changed'

@hug.response_middleware()
def process_data(request, response, resource):
    response.set_header('MyHeader', 'Value')

您还可以使用以下工具轻松添加任何Falcon样式的中间件:

__hug__.http.add_middleware(MiddlewareObject())

参数映射可用于覆盖推断的参数名称,例如。对于保留关键字:

import marshmallow.fields as fields
...

@hug.get('/foo', map_params={'from': 'from_date'})  # API call uses 'from'
def get_foo_by_date(from_date: fields.DateTime()):
    return find_foo(from_date)

输入格式化程序基于content_type请求数据,并且仅执行基本解析。更详细的解析应该由您的api_function

多文件拆分API

Hug使您能够以任何您认为合适的方式组织大型项目。您可以导入任何包含Hug修饰函数(请求处理、指令、类型处理程序等)的模块,并使用该模块扩展您的基础API

例如:

something.py

import hug

@hug.get('/')
def say_hi():
    return 'hello from something'

可以导入到主API文件中:

__init__.py

import hug
from . import something

@hug.get('/')
def say_hi():
    return "Hi from root"

@hug.extend_api('/something')
def something_api():
    return [something]

或者,对于这样的情况,每个URL路由只包含一个模块:

#alternatively
hug.API(__name__).extend(something, '/something')

配置拥抱404

默认情况下,当用户尝试访问未定义的端点时,Hug返回自动生成的API规范。如果您不想退还此规范,可以关闭404文档:

从命令行应用程序执行以下操作:

hug -nd -f {file} #nd flag tells hug not to generate documentation on 404

此外,您还可以轻松创建自定义404处理程序,方法是使用hug.not_found装饰师:

@hug.not_found()
def not_found_handler():
    return "Not Found"

此修饰器的工作方式与Hug HTTP方法修饰器相同,甚至可以识别版本:

@hug.not_found(versions=1)
def not_found_handler():
    return ""

@hug.not_found(versions=2)
def not_found_handler():
    return "Not Found"

Asyncio支持

在使用getcli协程上的方法修饰器,Hug将调度协程的执行

使用异步协同程序装饰器

@hug.get()
@asyncio.coroutine
def hello_world():
    return "Hello"

使用Python 3.5异步关键字

@hug.get()
async def hello_world():
    return "Hello"

注意:Hug在顶部的Falcon上运行,它不是异步服务器。即使使用Asyncio,仍将同步处理请求

使用Docker

如果您希望在Docker中进行开发并保持系统整洁,您可以这样做,但您需要首先安装Docker Compose

一旦你这样做了,你就需要cd进入到docker目录并运行中指定的Web服务器(Gunicorn./docker/gunicorn/Dockerfile之后,您可以在主机上的浏览器中预览API的输出

$ cd ./docker
# This will run Gunicorn on port 8000 of the Docker container.
$ docker-compose up gunicorn

# From the host machine, find your Dockers IP address.
# For Windows & Mac:
$ docker-machine ip default

# For Linux:
$ ifconfig docker0 | grep 'inet' | cut -d: -f2 | awk '{ print $1}' | head -n1

默认情况下,IP为172.17.0.1。假设这也是您看到的IP,那么您将转到http://172.17.0.1:8000/在您的浏览器中查看您的API

您还可以登录到可以考虑您的工作空间的Docker容器。此工作区安装了Python和Pip,因此您可以在Docker中使用这些工具。例如,如果您需要测试CLI接口,您可以使用以下代码

$ docker-compose run workspace bash

在你的码头上workspace容器中的./docker/templates主计算机上的目录挂载到/src在码头集装箱里。这是在下指定的services>app./docker/docker-compose.yml

bash-4.3# cd /src
bash-4.3# tree
.
├── __init__.py
└── handlers
    ├── birthday.py
    └── hello.py

1 directory, 3 files

安全联系信息

Hug认真对待安全和质量。这就是为什么我们只依赖经过彻底测试的组件并利用静电分析工具(如Banddit和SAFE)来验证我们代码库的安全性的原因。如果您发现或遇到任何潜在的安全问题,请立即通知我们,以便我们解决

若要报告安全漏洞,请使用Tidelift security contactTidelift将协调修复和披露

为什么要拥抱?

拥抱只是希望有用的向导的意思。这代表了该项目的目标,即帮助指导开发人员创建编写良好且直观的API


谢谢,我希望你能找到拥抱对您开发下一个Python API很有帮助!

~蒂莫西·克罗斯利

Uvicorn-闪电般的ASGI服务器。🦄

闪电般的ASGI服务器

文档https://www.uvicorn.org

要求:Python 3.6+(要支持Python 3.5,请安装版本0.8.6。)

Uvicorn是一个闪电般的ASGI服务器实现,使用uvloophttptools

直到最近,Python还缺乏用于异步框架的最低级别的服务器/应用程序接口。这个ASGI specification填补了这一空白,意味着我们现在能够开始构建一组可在所有异步CIO框架中使用的通用工具

Uvicorn目前支持HTTP/1.1和WebSockets。计划支持HTTP/2

快速入门

使用以下方式安装pip

$ pip install uvicorn

这将安装具有最小(纯Python)依赖项的uvicorn

$ pip install uvicorn[standard]

这将安装带有“基于Cython的”依赖项(如果可能)和其他“可选的附加项”的uvicorn。

在此上下文中,“基于Cython”的含义如下:

  • 事件循环uvloop将在可能的情况下安装和使用
  • http协议将由httptools如果可能的话

此外,“自选额外服务”的意思是:

  • WebSocket协议将由websockets(您是否要使用wsproto如果可能,您需要手动安装)
  • 这个--reloader处于开发模式的标志将使用watchgod
  • Windows用户将拥有colorama为彩色原木安装的
  • python-dotenv如果您要使用--env-file选项
  • PyYAML将被安装,以允许您提供.yaml文件到--log-config,如果需要

创建应用程序,在example.py

async def app(scope, receive, send):
    assert scope['type'] == 'http'

    await send({
        'type': 'http.response.start',
        'status': 200,
        'headers': [
            [b'content-type', b'text/plain'],
        ],
    })
    await send({
        'type': 'http.response.body',
        'body': b'Hello, world!',
    })

运行服务器:

$ uvicorn example:app

Uvicorn是BSD licensed代码
在英国布赖顿设计和建造

-🦄-

Guricorn‘Green Unicorn’ 是一款适用于UNIX的WSGI HTTP服务器

Gunicorn‘Green Unicorn’是用于UNIX的Python WSGI HTTP服务器。这是一个从Ruby‘s移植过来的叉前工人模型Unicorn项目。Gunicorn服务器与各种Web框架广泛兼容,实现简单,对服务器资源的使用很少,而且速度相当快

欢迎加入我们的行列#gunicorn在……上面Freenode

文档

文档位于https://docs.gunicorn.org

安装

Gunicorn要求Python 3.x>=3.5

从PyPI安装:

$ pip install gunicorn

用法

基本用法:

$ gunicorn [OPTIONS] APP_MODULE

哪里APP_MODULE是属于这种模式的$(MODULE_NAME):$(VARIABLE_NAME)模块名称可以是完整的虚线路径。变量名引用应在指定模块中找到的WSGI可调用对象

测试应用示例:

$ cd examples
$ gunicorn --workers=2 test:app

贡献

看见our complete contributor’s guide有关更多详细信息,请参阅

许可证

Gunicorn是在麻省理工学院的许可下发布的。请参阅LICENSE有关更多详细信息,请提交文件