# Sanic Application

# 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より前のバージョンのSanicでは、これは通常、属性をアプリケーションインスタンスにアタッチすることによって行われていました。

# Raises a warning as deprecated feature in 21.3
app = Sanic("MyApp")
app.db = Database()

ほとんどのアプリケーションでは、コード・ベースのさまざまな部分でデータやオブジェクトを共有/再利用する必要があります。最も一般的な例はDB接続です。

v21.3より前のバージョンのSanicでは、これは通常、属性をアプリケーションインスタンスにアタッチすることによって行われていました。

# Raises a warning as deprecated feature in 21.3
app = Sanic("MyApp")
app.db = Database()

これにより、名前の競合に関する潜在的な問題が発生したり、要求コンテキストオブジェクトv 21.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インスタンスが1つしか登録されていない場合、引数なしでSanic.get_app ()を呼び出すと、そのインスタンスが返されます。

Sanic("My only app")
app = Sanic.get_app()

# 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)

Heads up

構成キーは大文字でなければなりません。しかし、これは主に規約によるもので、ほとんどの場合小文字で動作します。

app.config.GOOD = "yay!"
app.config.bad = "boo"

設定の詳細については後で説明します。

# Customization

Sanicアプリケーションインスタンスは、インスタンス化時にさまざまな方法でアプリケーションのニーズに合わせてカスタマイズできます。

# Custom configuration

カスタム設定の最も単純な形式は、独自のオブジェクトを直接そのSanicアプリケーションインスタンスに渡すことです。

カスタム設定オブジェクトを作成する場合は、SanicのConfigオプションをサブクラス化して、その動作を継承することを強くお勧めします。このオプションを使用して、プロパティを追加することも、独自のカスタムロジックセットを追加することもできます。

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

この機能の有用な例は、 supportedとは異なる形式の設定ファイルを使用する場合です。

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() (opens new window) であり、必要なプロパティを設定できます。ただし、代わりに任意のオブジェクトを渡すこともできます。

app = Sanic(..., ctx=1)
app = Sanic(..., ctx={})
class MyContext:
    ...
app = Sanic(..., ctx=MyContext())

# Custom requests

独自の 「Request」 クラスを用意し、デフォルトの代わりにそれを使用するようにSanicに指示すると便利な場合があります。たとえば、デフォルトのrequest.idジェネレータを変更する場合です。

Important

クラスのインスタンスではなく、クラスを渡すことを覚えておくことが重要です。

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

詳細については、exception handlingを参照してください。

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())
MIT Licensed
Copyright © 2018-present Sanic Community Organization

~ Made with ❤️ and ☕️ ~