python 在Jupyter Notebook中调试Flask服务器

ktca8awb  于 2023-01-29  发布在  Python
关注(0)|答案(3)|浏览(363)

我想调试小 flask 服务器内jupyter笔记本的演示。
我在最新的Ubuntu和Python2上创建了virtualenv(在Mac上使用Python3也会发生这个错误),pip安装flask jupyter。
然而,当我用helloworld脚本创建一个单元格时,它不能在notebook中运行。

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run(debug=True,port=1234)

文件"/home/***/test/local/lib/python2.7/site-packages/ipykernel/www.example.com ",第177行,位于绑定套接字s. bind(" tcp://% s:% i " %(self. ip,port))文件" zmq/backend/cython/socket. pyx ",第495行,位于zmq. backend. cython. socket. bind(zmq/backend/cython/socket. c:5653)文件" zmq/backend/cython/checkrc. pxd ",第25行,位于zmq. backend. cython. checkrc(zmq/backend/cython/socket. c:10014),引发ZMQ错误(错误号)ZMQ错误:kernelapp.py", line 177, in _bind_socket s.bind("tcp://%s:%i" % (self.ip, port)) File "zmq/backend/cython/socket.pyx", line 495, in zmq.backend.cython.socket.Socket.bind (zmq/backend/cython/socket.c:5653) File "zmq/backend/cython/checkrc.pxd", line 25, in zmq.backend.cython.checkrc._check_rc (zmq/backend/cython/socket.c:10014) raise ZMQError(errno) ZMQError: Address already in use
NB-每次失败后我都会更改端口号。
当然,它作为独立脚本运行。
更新而不使用(debug = True)它是正常的。

oxiaedzo

oxiaedzo1#

我安装了Jupyter和 flask 和您的原始代码的作品。
flask.Flask对象是一个WSGI应用程序,而不是服务器。当您在shell中调用python -m flask run时,Flask使用Werkzeug的开发服务器作为WSGI服务器。它创建一个新的WSGI服务器,然后将您的应用程序作为参数传递给werkzeug.serving.run_simple。也许您可以尝试手动执行此操作:

from werkzeug.wrappers import Request, Response
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == '__main__':
    from werkzeug.serving import run_simple
    run_simple('localhost', 9000, app)

Flask.run()在内部调用run_simple(),因此这里应该没有区别。

q5lcpyga

q5lcpyga2#

诀窍是在一个单独的线程中运行Flask服务器。这段代码允许注册数据提供程序。

  • 为服务器查找一个空闲端口。如果在不同的笔记本电脑上运行多个服务器示例,它们将争用同一端口。
  • register_data函数返回服务器的URL,以便您可以根据需要使用它。
  • 服务器按需启动(注册第一个数据提供程序时)
    • 注意:* 我从flask-cors包中添加了@cross_origin()装饰器。否则你不能在笔记本中调用API表单。
    • 注意:* 在此代码中无法停止服务器...
    • 注意:* 代码使用了类型和python 3
    • 注意:* 目前没有很好的错误处理
import socket
import threading
import uuid
from typing import Any, Callable, cast, Optional

from flask import Flask, abort, jsonify
from flask_cors import cross_origin
from werkzeug.serving import run_simple

app = Flask('DataServer')

@app.route('/data/<id>')
@cross_origin()
def data(id: str) -> Any:
    func = _data.get(id)
    if not func:
        abort(400)
    return jsonify(func())

_data = {}

_port: int = 0

def register_data(f: Callable[[], Any], id: Optional[str] = None) -> str:
    """Sets a callback for data and returns a URL"""
    _start_sever()
    id = id or str(uuid.uuid4())
    _data[id] = f
    return f'http://localhost:{_port}/data/{id}'

def _init_port() -> int:
    """Creates a random free port."""
    # see https://stackoverflow.com/a/5089963/2297345
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('localhost', 0))

    port = sock.getsockname()[1]
    sock.close()
    return cast(int, port)

def _start_sever() -> None:
    """Starts a flask server in the background."""
    global _port
    if _port:
        return
    _port = _init_port()
    thread = threading.Thread(target=lambda: run_simple('localhost', _port, app))
    thread.start()
kmbjn2e3

kmbjn2e33#

虽然这个问题很早以前就提出了,但我提出了另一个建议:
下面的代码改编自PyCharm启动Flask控制台的方式。

import sys
from flask.cli import ScriptInfo
app = None
locals().update(ScriptInfo(create_app=None).load_app().make_shell_context())
print("Python %s on %s\nApp: %s [%s]\nInstance: %s" % (sys.version, sys.platform, app.import_name, app.env, app.instance_path))

现在,您可以访问app并使用working with the shell上的Flask文档中描述的所有内容

相关问题