AppLoader exception

Hi thanks for the great work.

I’m new to Sanic and I am trying to invoke the application directly from the command line using the -m flag:

|-- my-project (cwd)
    |-- new_api
        |-- __init__.py
        |-- __main__.py

__main__.py contains the following code:

import sys

from sanic import Request, Sanic, json, HTTPResponse
from sanic.worker.loader import AppLoader


def attach_endpoints(app: Sanic):
    @app.get("/")
    async def handler(request: Request) -> HTTPResponse:
        return json({"app_name": request.app.name})


def create_app() -> Sanic:
    app = Sanic("MyTestAppName")
    attach_endpoints(app)
    return app


if __name__ == "__main__":
    loader = AppLoader(factory=create_app)
    app = loader.load()
    app.prepare(port=9999, dev=True)
    Sanic.serve(primary=app, app_loader=loader)

When the new_api package is invoked the following exception occurs:

[my-project]$ python3 -m new_api


[2023-06-03 23:49:58 +0200] [2337511] [DEBUG] Creating multiprocessing context using 'spawn'
[2023-06-03 23:49:58 +0200] [2337511] [DEBUG] Starting a process: Sanic-Server-0-0
[2023-06-03 23:49:58 +0200] [2337511] [DEBUG] Starting a process: Sanic-Reloader-0
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib64/python3.11/multiprocessing/spawn.py", line 120, in spawn_main
    exitcode = _main(fd, parent_sentinel)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/multiprocessing/spawn.py", line 130, in _main
    self = reduction.pickle.load(from_parent)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: Can't get attribute 'create_app' on <module '__main__' (built-in)>
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib64/python3.11/multiprocessing/spawn.py", line 120, in spawn_main
    exitcode = _main(fd, parent_sentinel)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/multiprocessing/spawn.py", line 130, in _main
    self = reduction.pickle.load(from_parent)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: Can't get attribute 'create_app' on <module '__main__' (built-in)>

[2023-06-03 23:50:28 +0200] [2337511] [ERROR] Not all workers acknowledged a successful startup. Shutting down.

It seems that one or more of your workers failed to come online in the allowed time. Sanic is shutting down to avoid a deadlock. The current threshold is 30.0s. If this problem persists, please check out the documentation https://sanic.dev/en/guide/deployment/manager.html#worker-ack.
[2023-06-03 23:50:28 +0200] [2337511] [INFO] Killing Sanic-Server-0-0 [2337520]
[2023-06-03 23:50:28 +0200] [2337511] [INFO] Killing Sanic-Reloader-0 [2337521]
[2023-06-03 23:50:28 +0200] [2337511] [INFO] Server Stopped

Is there something wrong with my code? Thanks for the help.

Operating System: Linux (Fedora, Python:3.11)
Sanic Version: 23.3

Why are you trying this method and not the more traditional pattern? I’m trying to understand the underlying goal.

I would assume it is because you placed the factory in __main__.py and not somewhere inside the module, like __init__.py, or some other importable location.

Thanks for the help, it works more better by placing the factory code in a separate app.py file.

1 Like