为学习目的而构建的python web框架。

alcazar-web-framework的Python项目详细描述



purposetravis

阿尔卡扎尔

alcazar是一个用于学习的python web框架。计划是通过实现框架的特性来学习如何构建框架, 写关于它们的博客文章并尽可能简单地保持代码库。

它是一个wsgi框架,可以与任何wsgi应用服务器(如gunicorn)一起使用。

灵感

在阅读了Florimond Moncablog post之后,我被启发去制作一个web框架。 关于他如何构建一个web框架并成为一个开源维护者。他写了这段经历对他来说是多么的激动人心,所以我决定也试试看。 谢谢,Florimond当然还有Kenneth Reitz他反过来启发了Florimond用 他自己的框架。去看看Bocadillo by Florimond MoncaResponder by Kenneth Reitz。 如果你喜欢他们,就盯着他们的照片来表达你的爱。

博客文章

快速启动

安装:

pip install alcazar-web-framework

基本用法:

# app.pyfromalcazarimportAlcazarapp=Alcazar()@app.route("/")defhome(req,resp):resp.text="Hello, this is a home page."@app.route("/about")defabout_page(req,resp):resp.text="Hello, this is an about page."@app.route("/{age:d}")deftell_age(req,resp,age):resp.text=f"Your age is {age}"@app.route("/{name:l}")classGreetingHandler:defget(self,req,resp,name):resp.text=f"Hello, {name}"@app.route("/show/template")defhandler_with_template(req,resp):resp.html=app.template("example.html",context={"title":"Awesome Framework","body":"welcome to the future!"})@app.route("/json")defjson_handler(req,resp):resp.json={"this":"is JSON"}@app.route("/custom")defcustom_response(req,resp):resp.body=b'any other body'resp.content_type="text/plain"

开始时间:

gunicorn app:app

处理程序

如果使用基于类的处理程序,则只允许您实现的方法:

@app.route("/{name:l}")classGreetingHandler:defget(self,req,resp,name):resp.text=f"Hello, {name}"

此处理程序只允许GET请求。也就是说,POST和其他的将被拒绝。同样的事情也可以用 按以下方式基于函数的处理程序:

@app.route("/",methods=["get"])defhome(req,resp):resp.text="Hello, this is a home page."

注意,如果为基于类的处理程序指定methods,它们将被忽略。

单元测试

编写单元测试的推荐方法是使用pytest。有两个内置装置 使用alcazar编写单元测试时可能要使用的。第一个是app,它是主Alcazar类的一个实例:

deftest_route_overlap_throws_exception(app):@app.route("/")defhome(req,resp):resp.text="Welcome Home."withpytest.raises(AssertionError):@app.route("/")defhome2(req,resp):resp.text="Welcome Home2."

另一个是client,您可以使用它向处理程序发送http请求。它是根据著名的requests改编的,应该会让人感觉非常熟悉:

deftest_parameterized_route(app,client):@app.route("/{name}")defhello(req,resp,name):resp.text=f"hey {name}"assertclient.get(url("/matthew")).text=="hey matthew"

注意,使用了一个url()函数。它用于生成给定相对url的请求的绝对url。使用前导入:

fromalcazar.utils.testsimporturl

模板

模板的默认文件夹是templates。您可以在初始化主Alcazar()类时更改它:

app=Alcazar(templates_dir="templates_dir_name")

然后您可以像在处理程序中那样使用该文件夹中的HTML文件:

@app.route("/show/template")defhandler_with_template(req,resp):resp.html=app.template("example.html",context={"title":"Awesome Framework","body":"welcome to the future!"})

静态文件

与模板一样,静态文件的默认文件夹是static,您可以覆盖它:

app=Alcazar(static_dir="static_dir_name")

然后您可以在HTML文件中使用此文件夹中的文件:

<!DOCTYPE html><htmllang="en"><head><metacharset="UTF-8"><title>{{title}}</title><linkhref="/static/main.css"rel="stylesheet"type="text/css"></head><body><h1>{{body}}</h1><p>This is a paragraph</p></body></html>

自定义异常处理程序

有时,根据引发的异常,您可能需要执行特定操作。对于这种情况,您可以注册异常处理程序:

defon_exception(req,resp,exception):ifisinstance(exception,HTTPError):ifexception.status==404:resp.text="Unfortunately the thing you were looking for was not found"else:resp.text=str(exception)else:# unexpected exceptionsifapp.debug:debug_exception_handler(req,resp,exception)else:print("These unexpected exceptions should be logged.")app=Alcazar(debug=False)app.add_exception_handler(on_exception)

此异常处理程序将捕获404个httperrors并将文本更改为"Unfortunately the thing you were looking for was not found"。对于其他httperrors,它将 显示异常消息。如果引发的异常不是httperror,并且debug设置为true,则它将显示异常及其回溯。否则,它会记录下来。

中间件

通过继承alcazar.middleware.Middleware类并重写其两个方法,可以创建自定义中间件类 在每个请求之前和之后调用:

fromalcazarimportAlcazarfromalcazar.middlewareimportMiddlewareapp=Alcazar()classSimpleCustomMiddleware(Middleware):defprocess_request(self,req):print("Before dispatch",req.url)defprocess_response(self,req,res):print("After dispatch",req.url)app.add_middleware(SimpleCustomMiddleware)

功能

  • 与wsgi兼容
  • 基本和参数化布线
  • 基于类的处理程序
  • 测试客户端
  • 支持模板
  • 支持静态文件
  • 自定义异常处理程序
  • 中间件

这是非常原始的,希望会继续改进。如果您有兴趣了解如何在其他 框架,请打开一个问题,我们将希望实现和解释它在博客文章。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
Java类之间并发性不一致的HashMap   插件如何在JavaSwing中使用UIManager和Classloader从外部jar安装外观?   java JasperReports:找不到子报表   在项目中找不到java生成的Javadoc文件   java BigDecimal。multiply()和divide()方法返回十六进制数。为什么?   java统计出现次数并从字符串中删除重复项   调用运算符时发生java NullPointerException   Spring和Hibernate之间的java配置错误   JavaZK将用户重定向回上一页   Javasocket为传出连接指定特定的网络接口   如果拖动到某个区域外,java Make按钮操作将被取消   如何在Eclipse for selenium 3.141.59中添加Java文档链接   java从匹配条件的数组中获取所有索引   docker未连接到RemoteWebDriver的java Gitlab ci selenium测试   java重写run方法   utf 8如何使用java解码UTF8编码的字符串?   java如何从eclipse调试部署在tomcat上的web应用程序?   将字母字符与前面没有百分号的Java正则表达式匹配