Sanic 22.12.0 Unable to use Blueprint
x-haose opened this issue · comments
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
I use sanic 22.12.0 version, but Unable to use Blueprint, 404 appeared when accessing the blueprint url. this is code:
from sanic import Sanic, Blueprint, text
app = Sanic(name="test")
test_bp = Blueprint('test', url_prefix='/test')
@app.get('/')
def index(r):
return text("server")
@test_bp.get("/hello")
def hello(r):
return text("xxx")
def main():
api_blueprint = Blueprint.group(url_prefix="/api")
api_blueprint.append(test_bp)
app.blueprint(api_blueprint)
app.run(port=5277, debug=True)
if __name__ == '__main__':
main()
output:
/home/haose/codes/sanic_test/.venv/bin/python /opt/apps/pycharm-2022.2.2/plugins/python/helpers/pydev/pydevd.py --multiprocess --qt-support=auto --client 127.0.0.1 --port 38525 --file /home/haose/codes/sanic_test/server.py
Connected to pydev debugger (build 222.4345.23)
[2023-01-06 10:38:18 +0800] [5678] [DEBUG]
Sanic
Build Fast. Run Fast.
[2023-01-06 10:38:18 +0800] [5678] [INFO] Sanic v22.12.0
[2023-01-06 10:38:18 +0800] [5678] [INFO] Goin' Fast @ http://127.0.0.1:5277
[2023-01-06 10:38:18 +0800] [5678] [INFO] mode: debug, single worker
[2023-01-06 10:38:18 +0800] [5678] [INFO] server: sanic, HTTP/1.1
[2023-01-06 10:38:18 +0800] [5678] [INFO] python: 3.10.7
[2023-01-06 10:38:18 +0800] [5678] [INFO] platform: Linux-5.10.0-amd64-desktop-x86_64-with-glibc2.28
[2023-01-06 10:38:18 +0800] [5678] [INFO] packages: sanic-routing==22.8.0
[2023-01-06 10:38:19 +0800] [5678] [DEBUG] Creating multiprocessing context using 'spawn'
[2023-01-06 10:38:19 +0800] [5678] [DEBUG] Starting a process: Sanic-Server-0-0
[2023-01-06 10:38:19 +0800] [5708] [DEBUG] Process ack: Sanic-Server-0-0 [5708]
[2023-01-06 10:38:19 +0800] [5708] [INFO] Starting worker [5708]
[2023-01-06 10:38:21 +0800] - (sanic.access)[INFO][127.0.0.1:39886]: GET http://127.0.0.1:5277/api/test/hello 404 740
[2023-01-06 10:38:22 +0800] - (sanic.access)[INFO][127.0.0.1:39886]: GET http://127.0.0.1:5277/api/test/hello 404 740
[2023-01-06 10:38:26 +0800] [5708] [DEBUG] KeepAlive Timeout. Closing connection.
[2023-01-06 10:38:29 +0800] [5708] [DEBUG] KeepAlive Timeout. Closing connection.
[2023-01-06 10:38:54 +0800] - (sanic.access)[INFO][127.0.0.1:40512]: GET http://127.0.0.1:5277/ 200 6
[2023-01-06 10:38:59 +0800] [5708] [DEBUG] KeepAlive Timeout. Closing connection.
[2023-01-06 10:38:59 +0800] [5708] [DEBUG] KeepAlive Timeout. Closing connection.
package:
╭───────────────┬─────────┬──────────╮
│ name │ version │ location │
├───────────────┼─────────┼──────────┤
│ aiofiles │ 22.1.0 │ │
│ httptools │ 0.5.0 │ │
│ uvloop │ 0.17.0 │ │
│ websockets │ 10.4 │ │
│ multidict │ 6.0.4 │ │
│ ujson │ 5.6.0 │ │
│ sanic-routing │ 22.8.0 │ │
│ sanic │ 22.12.0 │ │
╰───────────────┴─────────┴──────────╯
Code snippet
No response
Expected Behavior
No response
How do you run Sanic?
As a script (app.run
or Sanic.serve
)
Operating System
Linux
Sanic Version
22.12.0
Additional context
No response
When I add the parameter single_process=True
in app.run(...)
, I found that the URL of the blueprint can be accessed. Is this caused by Worker Manager
? how do i use it
It is because the "if" block only runs in the main process. So none of your sub processes know that it is attaching. The main block should ONLY be used for running the server.
It is because the "if" block only runs in the main process. So none of your sub processes know that it is attaching. The main block should ONLY be used for running the server.
Thank you very much for your reply, but if I want to run it without adding single_process=True
parameter, what is the correct way to do it?
You have a couple options. I'd suggest you make main
a proper factory. With minimal changes to your code:
from sanic import Blueprint, Sanic, text
app = Sanic(name="test")
test_bp = Blueprint("test", url_prefix="/test")
@app.get("/")
def index(r):
return text("server")
@test_bp.get("/hello")
def hello(r):
return text("xxx")
def main():
api_blueprint = Blueprint.group(url_prefix="/api")
api_blueprint.append(test_bp)
app.blueprint(api_blueprint)
return app
Of course, to make it a TRUE factory, then main
would also create the app instance too.
Once you have that, you should be able to run this from the CLI.
sanic path.to.server:main --factory --debug --port=5277
If you want to run it as a script, and do the attaching of the blueprint in a function, then you need to use an AppLoader.
from sanic.worker.loader import AppLoader
if __name__ == "__main__":
loader = AppLoader(factory=main)
app = loader.load()
app.prepare(port=5277, debug=True)
Sanic.serve(app, app_loader=loader)
You have a couple options. I'd suggest you make
main
a proper factory. With minimal changes to your code:from sanic import Blueprint, Sanic, text app = Sanic(name="test") test_bp = Blueprint("test", url_prefix="/test") @app.get("/") def index(r): return text("server") @test_bp.get("/hello") def hello(r): return text("xxx") def main(): api_blueprint = Blueprint.group(url_prefix="/api") api_blueprint.append(test_bp) app.blueprint(api_blueprint) return appOf course, to make it a TRUE factory, then
main
would also create the app instance too.Once you have that, you should be able to run this from the CLI.
sanic path.to.server:main --factory --debug --port=5277
If you want to run it as a script, and do the attaching of the blueprint in a function, then you need to use an AppLoader.
from sanic.worker.loader import AppLoader if __name__ == "__main__": loader = AppLoader(factory=main) app = loader.load() app.prepare(port=5277, debug=True) Sanic.serve(app, app_loader=loader)
Thank you very much for your help, it solved my problem perfectly