【问题标题】:Pyodide filesystem for NLTK resources : missing filesNLTK 资源的 Pyodide 文件系统:缺少文件
【发布时间】:2021-10-20 10:12:24
【问题描述】:

感谢pyodide,我正在尝试在浏览器中使用NLTK。 Pyodide 启动良好,设法加载 NLTK,打印其版本。

尽管如此,虽然包下载看起来不错,但在调用 nltk.sent_tokenize(str) 时,NLTK 会引发找不到包“punkt”的错误。

我会说下载的资源在某个地方丢失了,但我不太了解 Pyodide / WebAssembly 如何管理文件。有什么见解吗?

简单版:

import nltk
nltk.download(pkg)
for sent in nltk.sent_tokenize("Test string"):
    print(sent)

具有更多详细信息的版本,指定下载目录和服务器 url。

import nltk
pkg = "punkt"
downloader = nltk.downloader.Downloader(server_index_url="https://raw.githubusercontent.com/nltk/nltk_data/gh-pages/index.xml") 
downloader.download(pkg, download_dir='/nltk_data')
downloader.status(pkg)
for sent in nltk.sent_tokenize("Test string"):
    print(sent)

完整示例代码:

<!DOCTYPE html>
<html>
  <body>
    <script type="text/javascript" src="https://cdn.jsdelivr.net/pyodide/v0.18.0/full/pyodide.js"></script>
    <script type="text/javascript">
      // init Pyodide
      async function pyodide_loader() {
        let pyodide_premise = loadPyodide({
          indexURL: "https://cdn.jsdelivr.net/pyodide/v0.18.0/full/",
        });
        let pyodide = await pyodide_premise;
        await pyodide.loadPackage("micropip");
        await pyodide.loadPackage("nltk");
        return pyodide_premise;
      }
      let pyodideReadyPromise = pyodide_loader();

      
      // run Python code and load NLTK
      async function load_packages() {
        let pyodide = await pyodideReadyPromise;
        let output = pyodide.runPython(`
print(f"*** import nltk")
import nltk
print(f"*** NLTK version {nltk.__version__=} imported, downloading resources now")

pkg = "punkt"
nltk.download(pkg)

str = "Just for testing"
for sent in nltk.sent_tokenize(str):
    print(sent)
      `);
      }
      load_packages()
    </script>
  </body>
</html>

【问题讨论】:

    标签: filesystems nltk webassembly pyodide


    【解决方案1】:

    简短的回答是,目前在 Pyodide 中无法使用 Python 下载文件,因为 http.clientrequests 等需要浏览器 VM 不支持的 POSIX 套接字。

    奇怪的是nltk.download 并没有出错——它应该有。

    解决方法是手动下载所需资源,例如使用 JavaScript fetch API,如 this comment 所示;

    from js import fetch
    
    response = await fetch("<url>")
    js_buffer = await response.arrayBuffer()
    py_buffer = js_buffer.to_py()  # this is a memoryview
    stream = py_buffer.tobytes()  # now we have a bytes object
    
    # that we can finally write under the appropriate path
    with open("<file_path>", "wb") as fh:
        fh.write(stream)
    

    我不太了解 Pyodide / WebAssembly 是如何管理文件的。

    默认情况下,它是在每次页面加载时重置的虚拟文件系统 (MEMFS)。您可以使用标准 python 工具(open、'os' 等)访问它。如有需要也可以mount a persistent filesystem

    【讨论】:

    • 当我尝试复制时,nltk.download 出现错误。
    • 我设法通过使用 js.window.fetch 下载文件来解决它。谢谢!
    • 如何等待 Pyodide 中的函数?我总是遇到像RuntimeWarning: coroutine '&lt;async_function&gt;' was never awaited 这样的问题。
    • 我使用的是 pyodide.runPython() 而不是 async 版本 pyodide.runPythonAsync()
    【解决方案2】:

    这是一个使用pyodide v0.18.1 加载punkt 的工作示例。我试图将此作为评论发布到@rth 接受的答案,但字符数超过了 240 个字符的限制。

    from js import fetch
    import nltk
    from pathlib import Path
    import os, sys, io, zipfile
    
    response = await fetch('https://raw.githubusercontent.com/nltk/nltk_data/gh-pages/packages/tokenizers/punkt.zip')
    js_buffer = await response.arrayBuffer()
    py_buffer = js_buffer.to_py()  # this is a memoryview
    stream = py_buffer.tobytes()  # now we have a bytes object
    
    d = Path("/nltk_data/tokenizers")
    d.mkdir(parents=True, exist_ok=True)
    
    Path('/nltk_data/tokenizers/punkt.zip').write_bytes(stream)
    
    # extract punkt.zip
    zipfile.ZipFile('/nltk_data/tokenizers/punkt.zip').extractall(
        path='/nltk_data/tokenizers/'
    )
    
    # check file contents in /nltk_data/tokenizers/
    # print(os.listdir("/nltk_data/tokenizers/punkt"))
    
    nltk.word_tokenize("some text here")
    

    我从pyodide 维护者和https://github.com/pyodide/pyodide/issues/1798 的其他优秀人士那里得到了很多帮助来解决这个问题。谢谢!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-04
      • 1970-01-01
      • 2014-03-28
      • 2011-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多