【问题标题】:How to send spacy doc object as payload in a REST api request and reconstruct the spacy doc object back inside the api?如何在 REST api 请求中将 spacy doc 对象作为有效负载发送并在 api 中重建 spacy doc 对象?
【发布时间】:2020-11-03 15:29:36
【问题描述】:

我有

类型的 spacy 对象
import spacy
import requests
nlp = spacy.load("en_core_web_sm")
spacy_doc = nlp("hello")

如何在 api 请求中将此对象作为有效负载发送?目前,当我尝试使用以下代码发布它时

requests.post(API_URL, json={'doc': spacy_doc}, timeout=3)

我收到以下错误

ERROR:Object of type 'Doc' is not JSON serializable

https://spacy.io/usage/saving-loading中提到了Doc.to_bytes()

但是当我使用它时

requests.post(API_URL, json={'doc': spacy_doc.to_bytes()}, timeout=3)

我明白了

ERROR:Object of type 'bytes' is not JSON serializable

发送 spacy doc 并在 api 中重建它的正确方法是什么(我正在开发这个目标 api 服务并使用 fastapi 制作)?

【问题讨论】:

  • 能否添加导致错误的代码sn-p?
  • 刚刚添加了代码。 Shaji pappan enthu parayunnu?

标签: python flask serialization spacy fastapi


【解决方案1】:

使用.to_json()--(doc) 会将文档转换为 JSON,并且可以通过网络发送。

requests.post(API_URL, json={'doc': <b>spacy_doc.to_json()</b>}, timeout=3)

【讨论】:

  • 一旦我们在 api 中收到它,我们如何将它重建回 spacy doc 对象?我没有看到相应的 from_json() spacy 方法。
  • 我不太擅长 spaCy,但是,您可能需要使用 form-data 来发送原始字节,afaik,JSON 与字节不兼容。
  • 好主意。是否可以将字节作为表单数据发送并在单个发布请求中发送常规 json。
  • 我认为您不能同时发送表单数据和 json。但是,I found this,可能对你有用。
【解决方案2】:

所以你想序列化文档对象:

通常使用 Doc.to_array 功能来序列化文档并仅序列化 numpy 数组就足够了 - 但有时您需要一种更通用的方法来保存和恢复 Doc 对象。

DocBin 类使serialize 和一起反序列化 Doc 对象集合变得容易,并且比在每个单独的 Doc 对象上调用 Doc.to_bytes 效率更高。您还可以控制要保存哪些数据(请参阅attrs=["LEMMA", "ENT_IOB", "ENT_TYPE"]),并且可以将托盘合并在一起以轻松进行 map/reduce 样式的处理。

    import spacy
    from spacy.tokens import DocBin
    
    doc_bin = DocBin(attrs=["LEMMA", "ENT_IOB", "ENT_TYPE"], store_user_data=True) 
    texts = ["Some text", "Lots of texts...", "..."]
    nlp = spacy.load("en_core_web_sm")
    for doc in nlp.pipe(texts):
        doc_bin.add(doc)
    bytes_data = doc_bin.to_bytes()

    # Deserialize later, e.g. in a new process
    nlp = spacy.blank("en")
    doc_bin = DocBin().from_bytes(bytes_data)
    docs = list(doc_bin.get_docs(nlp.vocab))

source

【讨论】:

  • 收到此错误错误:“字节”类型的对象不是 JSON 可序列化的
【解决方案3】:

这个解决方案有效

即将 python 对象转换为 str 并将其放入 json 有效负载中。 稍后从 str 重建 python 对象

import pickle
import codecs
# encode returns bytes so it needs to be decoded to string
pickled = pickle.loads(codecs.decode(pickled.encode(), 'base64')).decode()

type(pickled)  # <class 'str'>

unpickled = pickle.loads(codecs.decode(pickled.encode(), 'base64'))

【讨论】:

    猜你喜欢
    • 2015-05-07
    • 2022-08-15
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 2019-05-14
    • 2023-02-04
    • 2021-01-04
    相关资源
    最近更新 更多