在 Google Colab 上有 运行 Web 应用程序的通用方法吗?

Is there a general way to run Web Applications on Google Colab?

我想在 Google colab 中开发网络应用程序。唯一的问题是您需要一个连接到本地主机的浏览器才能查看网络应用程序,但 Google colab 在笔记本中没有浏览器。

但似乎有办法解决这个问题。例如 run_with_ngrok 是 运行ning flaks apps in colab/jupyter notebooks

的库

https://github.com/gstaff/flask-ngrok#inside-jupyter--colab-notebooks

当你使用它时,它会给出一个随机地址,"Running on http://.ngrok.io"

并且 运行 在 Google colab 上 运行 的 Web 应用程序也在该地址 运行 上。

这是 Flask 应用程序的一个很好的解决方案,但我希望在 Google Colab 上寻找 运行 一般的网络应用程序,而不仅仅是 Flask 应用程序。在 colab/jupyter 笔记本中 运行 网络应用程序有通用方法吗?

下面是一个示例,说明如何启动网络服务器并将资源提供给 Colab 输出框架。

https://colab.research.google.com/notebooks/snippets/advanced_outputs.ipynb#scrollTo=R8ZvCXC5A0wT

Colab 缓存提供的输出,以便笔记本无需重新执行即可呈现。对于实时服务器,用户需要重新执行代码才能启动服务器。但是,之后,Colab 会将引用 localhost 的输出帧中的请求代理到 Colab 后端。

答案在这里

### Install ngrok
!wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip
!unzip ngrok-stable-linux-amd64.zip

### Run ngrok to tunnel Dash app port 8050 to the outside world. 
### This command runs in the background.
get_ipython().system_raw('./ngrok http 8050 &')

### Get the public URL where you can access the Dash app. Copy this URL.
! curl -s http://localhost:4040/api/tunnels | python3 -c \
    "import sys, json; print(json.load(sys.stdin)['tunnels'][0]['public_url'])"

然后在端口 8050 上启动您的 webapp

您可以计划在端口上启动服务器,例如端口=8000。找到URL使用这种方式。

from google.colab.output import eval_js
print(eval_js("google.colab.kernel.proxyPort(8000)"))
# https://z4spb7cvssd-496ff2e9c6d22116-8000-colab.googleusercontent.com/

然后,启动服务器,例如

!python -m http.server 8000

然后点击上面的第一个 link(而不是 localhost 或 127.0.0.1),它将在新选项卡中打开。

在单元格中显示

您可以在输出部分的 iframe 中显示结果。我把它变成了一个易于调用的函数。

from IPython.display import Javascript

def show_port(port, height=400):
  display(Javascript("""
  (async ()=>{
    fm = document.createElement('iframe')
    fm.src = await google.colab.kernel.proxyPort(%s)
    fm.width = '95%%'
    fm.height = '%d'
    fm.frameBorder = 0
    document.body.append(fm)
  })();
  """ % (port, height) ))

现在您可以在后台启动 web 应用程序(这里是 http.server)。并将结果显示为下方的 iframe。

get_ipython().system_raw('python3 -m http.server 8888 &') 
show_port(8888)

要停止服务器,您可以调用 ps 并终止进程。

下面的解决方案,解释

  1. 运行在后台python script/API
  2. 获取网络 link 以访问浏览器选项卡中的脚本输出
  3. 使用 cherrypy
  4. 在 ip:port 上将脚本配置为网络服务器
  5. 在脚本中创建定义(端点,例如:/index)。

运行后台的脚本,使用下面的代码,会输出一个link,看起来像https://wrea1crizb-496ff2e9c6d22116-8888-colab.googleusercontent.com/,通过它可以在网络浏览器上看到输出

!pip install CherryPy #webserver package

#bind the port 8888 and get a weblink to access
from google.colab.output import eval_js
print(eval_js("google.colab.kernel.proxyPort(8888)"))

#run the script/API in the background
import subprocess
subprocess.Popen(["python", "/content/test.py", "8888"]) 

创建test.py文件并添加以下代码,

import cherrypy
import sys

class HelloWorld:
    def index(self):
        return "Hello World!"
    index.exposed = True
if __name__ == '__main__':
   config = {'server.socket_host': '0.0.0.0','server.socket_port' : int(sys.argv[1])}
   cherrypy.config.update(config)
   cherrypy.quickstart(HelloWorld())

你可以查看我的示例笔记本

https://colab.research.google.com/github/popcornylu/web-server-in-colab/blob/main/web_server_in_colab.ipynb

  1. 定义魔法线
from IPython.core.magic import register_line_magic
import subprocess

@register_line_magic
def run_local_server(line):
    handle = IPython.display.display(
            IPython.display.Pretty("Launching my server..."),
            display_id=True,
    )
    subprocess.Popen(['python', '-m', 'http.server'])
    shell = """
        (async () => {
            const url = new URL(await google.colab.kernel.proxyPort(8000, {'cache': true}));
            const iframe = document.createElement('iframe');
            iframe.src = url;
            iframe.setAttribute('width', '100%');
            iframe.setAttribute('height', '400');
            iframe.setAttribute('frameborder', 0);
            document.body.appendChild(iframe);
        })();
    """
    script = IPython.display.Javascript(shell)
    handle.update(script)
  1. 在另一个单元格中使用线条魔法
%run_local_server

它允许您在您的应用程序包中实现您的线条魔法。