实例 Instance
最基本的构建块是Sanic()实例。这不是必需的,但习惯是在一个名为server.py.
# /path/to/server.py
from sanic import Sanic
app = Sanic("My Hello, world app")
应用上下文 Application context
大多数应用程序都需要在代码库的不同部分共享/重用数据或对象。最常见的例子是数据库连接。
在 v21.3 之前的 Sanic 版本中,这通常通过将属性附加到应用程序实例来完成
# Raises a warning as deprecated feature in 21.3
app = Sanic("MyApp")
app.db = Database()
因为这可能会产生名称冲突的潜在问题,并且为了与请求上下文对象保持一致,v21.3 引入了应用程序级上下文对象。
# Correct way to attach objects to the application
app = Sanic("MyApp")
app.ctx.db = Database()
应用注册表App Registry
当您实例化 Sanic 实例时,稍后可以从 Sanic 应用程序注册表中检索该实例。这可能很有用,例如,如果您需要从无法以其他方式访问的位置访问您的 Sanic 实例。
# ./path/to/server.py
from sanic import Sanic
app = Sanic("my_awesome_server")
# ./path/to/somewhere_else.py
from sanic import Sanic
app = Sanic.get_app("my_awesome_server")
如果你调用Sanic.get_app(“non-existing”)一个不存在的应用程序,它会SanicException默认引发。相反,您可以强制该方法返回具有该名称的 Sanic 的新实例。
app = Sanic.get_app(
"non-existing",
force_create=True,
)
如果只注册了一个Sanic 实例,则不Sanic.get_app()带参数调用将返回该实例
Sanic("My only app")
app = Sanic.get_app()
**
配置Configuration
**
Sanic 将配置保存config在Sanic实例的属性中。可以修改配置或者使用点符号或像一本字典。
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)
注意:
配置键应该是大写的。但是,这主要是约定俗成的,大部分时间小写都可以。
app.config.GOOD = "yay!"
app.config.bad = "boo"
自定义Customization
Sanic 应用程序实例可以在实例化时以多种方式根据您的应用程序需求进行定制。
自定义配置Custom configuration
这种最简单的自定义配置形式是将您自己的对象直接传递到该 Sanic 应用程序实例中
from sanic.config import Config
class MyConfig(Config):
FOO = "bar"
app = Sanic(..., config=MyConfig())
如果您创建自定义配置对象,强烈建议您子类化 SanicConfig选项以继承其行为。您可以使用此选项添加属性或您自己的自定义逻辑集。
此功能的一个有用示例是,如果您想以与支持的形式不同的形式使用配置文件。
from sanic import Sanic, text
from sanic.config import Config
class TomlConfig(Config):
def __init__(self, *args, path: str, **kwargs):
super().__init__(*args, **kwargs)
with open(path, "r") as f:
self.apply(toml.load(f))
def apply(self, config):
self.update(self._to_uppercase(config))
def _to_uppercase(self, obj: Dict[str, Any]) -> Dict[str, Any]:
retval: Dict[str, Any] = {}
for key, value in obj.items():
upper_key = key.upper()
if isinstance(value, list):
retval[upper_key] = [
self._to_uppercase(item) for item in value
]
elif isinstance(value, dict):
retval[upper_key] = self._to_uppercase(value)
else:
retval[upper_key] = value
return retval
toml_config = TomlConfig(path="/path/to/config.toml")
app = Sanic(toml_config.APP_NAME, config=toml_config)
自定义上下文Custom context
默认情况下,应用程序上下文是 SimpleNamespace() (打开新窗口)这允许您设置您想要的任何属性。但是,您也可以选择传递任何对象。
# case1
app = Sanic(..., ctx=1)
#case2
app = Sanic(..., ctx={})
#case3
class MyContext:
...
app = Sanic(..., ctx=MyContext())
自定义请求Custom requests
有时拥有自己的Request类会很有帮助,并告诉 Sanic 使用它而不是默认值。一个例子是如果您想修改默认request.id生成器。
import time
from sanic import Request, Sanic, text
class NanoSecondRequest(Request):
@classmethod
def generate_id(*_):
return time.time_ns()
app = Sanic(..., request_class=NanoSecondRequest)
@app.get("/")
async def handler(request):
return text(str(request.id))
注意: 重要的是要记住,您传递的是类而不是类的实例。
自定义错误处理程序 Custom error handler
from sanic.handlers import ErrorHandler
class CustomErrorHandler(ErrorHandler):
def default(self, request, exception):
''' handles errors that have no error handlers assigned '''
# You custom error handling logic...
return super().default(request, exception)
app = Sanic(..., error_handler=CustomErrorHandler())