jjzjj

【Web开发】Python实现Web服务器(Sanic)

爱看书的小沐 2023-03-28 原文

1、简介

https://sanic.dev/zh/ https://github.com/sanic-org/sanic

Sanic 是 Python3.7+ Web 服务器和 Web 框架,旨在提高性能。它允许使用 Python3.5 中添加的 async/await 语法,这使得您的代码有效的避免阻塞从而达到提升响应速度的目的。

  • 目标(Goal) 提供一种简单且快速,集创建和启动于一体的方法,来实现一个易于修改和拓展的 HTTP 服务。

  • 特征(Features) 内置极速 web server 生产准备就绪 极高的拓展性 支持 ASGI 简单直观的 API 设计 社区保障

2、安装

2.1 安装sanic

在我们开始之前,请确保您使用的是 Python3.7 或更高版本。目前已知可以使用的 Python 版本包括:3.7,3.8 和 3.9。

pip install sanic

2.2 安装sanic拓展

Sanic 致力于构建一个简洁且没有任何偏见的特征表。该项目不想要求您以某种方式构建应用程序,并试图避免指定特定的开发模式。有许多由社区构建和维护的第三方插件,用于添加不符合核心库要求的附加功能。 但是,为了 帮助 API 开发者 ,Sanic 组织维护了一个名为 Sanic Extensions 的项目来提供各种易用的功能,包括:

  • OpenAPI 使用 Redoc 和/或 Swagger 的文档
  • CORS 保护
  • 依赖注入 路由处理程序
  • Request 参数 检查
  • 自动创建 HEAD, OPTIONS, 和 TRACE 响应函数
  • 响应序列化
pip install sanic sanic-ext

2.3 安装ubuntu

  • 安装python
sudo apt-get update sudo apt-get install software-properties-common sudo add-apt-repository ppa:jonathonf/python-3.8 sudo apt-get update sudo apt-get install python3.8
  • 更改python快捷方式 查看python版本
pip --version 查看python命令指代的版本

cd /usr/bin ls -l | grep python 删除python2.7快捷方式

sudo rm python 创建python3.8快捷方式,安装pip3

sudo ln -s python3.6m python sudo apt-get install python-pip 创建python虚拟环境 安装Virtualenv

sudo pip install virtualenv 创建项目,修改权限

sudo mkdir /root/flowerdance sudo chmod 777 /root/flowerdance 创建虚拟环境venv

mkvirtualenv -p python3 venv virtualenv venv 进入虚拟环境

source venv/bin/activate 安装必要的库

pip install -r requirements.txt 运行测试程序:

sanic test_sanic.app

<font color=red>有可能在用pip下载的时候出现错误: ModuleNotFoundError: No module named 'pip._internal',有可能是与旧版冲突,所以可能事先卸载旧版。</font>

python -m ensurepip python -m pip install --upgrade pip sudo apt install --fix-missing python3-pip curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py python3 get-pip.py --force-reinstall

pip3 install sanic or pip install sanic

3、示例测试

3.1 Hello, world

  • test_sanic.py
from sanic import Sanic from sanic.response import text app = Sanic("MyHelloWorldApp") @app.get("/") async def hello_world(request): return text("Hello, world. 爱看书的小沐!")
  • 命令行执行命令:
sanic test_sanic.app <font color=blue>这是 另一个 重要的区别。其他框架带有一个内置的开发服务器,并明确表示它只用于开发。而 Sanic 的情况恰好相反。可以用于生产环境的服务器已经准备就绪。</font>

#!/usr/bin/env python from sanic import Sanic from sanic.response import text app = Sanic("MyHelloWorldApp") @app.get("/") async def hello_world(request): return text("Hello, world. 爱看书的小沐!") ## python -m sanic server.app --host=0.0.0.0 --port=1337 --workers=4 ## sanic server:app --host=0.0.0.0 --port=1337 --fast ## sanic ./path/to/dir --simple ## sanic ./path/to/dir --simple --reload --reload-dir=./path/to/dir app.run(host='0.0.0.0', port=1337, access_log=False) # app.run(host='0.0.0.0', port=1337, workers=4) # app.run(host='0.0.0.0', port=1337, fast=True)

3.2 配置(Configuration)

Sanic 将配置保存在 Sanic 对象的 config 属性中。可以使用 属性操作 或 字典操作 的方式来修改配置。

app = Sanic('myapp') app.config.DB_NAME = 'appdb' app.config['DB_USER'] = 'appuser' db_settings = { 'DB_HOST': 'localhost', 'DB_NAME': 'appdb', 'DB_USER': 'appuser' } app.config.update(db_settings) 如果您使用了自定义配置对象类,强烈建议 您将自定义类继承 Sanic 的 Config 类,以保持与父类行为一致。

from sanic.config import Config class MyConfig(Config): FOO = "bar" app = Sanic(..., config=MyConfig())

3.3 响应函数(Handlers)

第二个重要的组件就是响应函数(Handlers),也就是我们通常所说的视图(views)。

在 Sanic 中,响应函数可以是任何一个可调用程序,它至少以一个 request 实例作为参数,并返回一个 HTTPResponse 实例或一个执行其他操作的协同程序作为响应。

def i_am_a_handler(request): return HTTPResponse() async def i_am_ALSO_a_handler(request): return HTTPResponse() from sanic.response import text @app.get("/foo") async def foo_handler(request): return text("I said foo!") @app.get("/sync") def sync_handler(request): time.sleep(0.1) return text("Done.") @app.get("/async") async def async_handler(request): await asyncio.sleep(0.1) return text("Done.")

3.4 请求(Request)

Request 实例包含许多有关其参数的有用信息。

>>> print(request.args) {'key1': ['val1', 'val3'], 'key2': ['val2']} >>> print(request.args.get("key1")) val1 >>> print(request.args.getlist("key1")) ['val1', 'val3'] >>> print(request.query_args) [('key1', 'val1'), ('key2', 'val2'), ('key1', 'val3')] >>> print(request.query_string) key1=val1&key2=val2&key1=val3

3.5 响应(Response)

所有的 响应函数 都必须返回一个 response 对象,中间件 可以自由选择是否返回 response 对象。 Sanic 内置了 9 种常用的返回类型,您可以通过以下方式中的任意一种快速生成返回对象。

from sanic.response import text @app.route("/") async def handler(request): return text("Hi ?")

3.6 路由(Routing)

每一个标准的 HTTP 请求方式都对应封装了一个简单易用的装饰器:

3.7 监听器(Listeners)

在 Sanic 应用程序的生命周期中 8 个切入点,在这些关键节点上设置监听器可以让您可以完成一些注入操作。但是这里并不包括信号,信号允许进一步的注入定制。

@app.reload_process_start async def reload_start(*_): print(">>>>>> reload_start <<<<<<") @app.main_process_start async def main_start(*_): print(">>>>>> main_start <<<<<<")

3.8 中间件(Middleware)

监听器允许您将功能挂载到工作进程的生命周期,而中间件允许您将功能挂载到 HTTP 流的生命周期。

您可以在执行响应函数之前或者响应函数之后执行中间件。

3.9 标头(Headers)

请求头和响应头仅在对应的 Request 对象和 HTTPResponse 对象中起作用。它们使用 multidict 包(opens new window) 进行构建,这意味着它们允许一个键名具有多个对应值。

app.config.SERVER_NAME = "https://example.com" @app.route("/hosts", name="foo") async def handler(request): return json( { "effective host": request.host, "host header": request.headers.get("host"), "forwarded host": request.forwarded.get("host"), "you are here": request.url_for("foo"), } )

3.10 Cookies

response 的 cookies 可以通过和字典类型一样的操作方法来进行设置,而且它可以使用以下参数:

@app.route("/cookie") async def test(request): response = text("There's a cookie up in this response") response.cookies["test"] = "It worked!" response.cookies["test"]["domain"] = ".yummy-yummy-cookie.com" response.cookies["test"]["httponly"] = True return response

3.11 后台任务(Background tasks)

在异步 Python 里使用 任务(opens new window) 是非常简单方便的,Sanic 提供了一种简单的方法来将任务添加到当前运行的 loop 当中, 它有点类似于 asyncio.create_task。

async def slow_work(...): ... app = Sanic(...) app.add_task(slow_work) # Note: we are passing the callable and not coroutine object `slow_work(...)` app.run(...)

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭ 如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O??? 如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡) 感谢各位大佬童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

有关【Web开发】Python实现Web服务器(Sanic)的更多相关文章

  1. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  2. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  3. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  4. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  5. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  6. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  7. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  8. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  9. ruby - 是否可以覆盖 gemfile 进行本地开发? - 2

    我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI

  10. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

随机推荐