Este pacote simples pode ser usado para corrigir uma string json inválida. Para saber todos os casos em que este pacote funcionará, consulte o teste de unidade.
Se você achar útil esta biblioteca, pode me ajudar doando para o meu orçamento mensal de cerveja aqui: https://github.com/sponsors/mangiucugna
Se você não tiver certeza se esta biblioteca corrigirá seu problema específico ou simplesmente deseja que seu JSON valesse -se on -line, você pode visitar o site de demonstração nas páginas do Github: https://mangiucugna.github.io/json_repair/
Ou ouça um áudio DeepDive gerar pelo Notebooklm do Google para uma introdução ao módulo
Alguns LLMs são um pouco duvidosos quando se trata de retornar dados JSON bem formados, às vezes eles pulam um parênteses e, às vezes, adicionam algumas palavras, porque é isso que um LLM faz. Felizmente, os erros que os LLMs cometem são simples o suficiente para serem consertados sem destruir o conteúdo.
Eu procurei por um pacote Python leve capaz de corrigir com segurança esse problema, mas não consegui encontrar nenhum.
Então eu escrevi um
Como parte do meu trabalho, usamos APIs OpenAI e notamos que, mesmo com a saída estruturada, às vezes o resultado não é um JSON totalmente válido. Portanto, ainda usamos esta biblioteca para cobrir esses outliers.
Instale a biblioteca com PIP
pip install json-repair
Então você pode usar usá -lo em seu código como este
from json_repair import repair_json
good_json_string = repair_json(bad_json_string)
# If the string was super broken this will return an empty string
Você pode usar esta biblioteca para substituir completamente json.loads()
:
import json_repair
decoded_object = json_repair.loads(json_string)
ou apenas
import json_repair
decoded_object = json_repair.repair_json(json_string, return_objects=True)
Alguns usuários desta biblioteca adotam o seguinte padrão:
obj = {}
try:
obj = json.loads(string)
except json.JSONDecodeError as e:
obj = json_repair.loads(string)
...
Isso é um desperdício porque json_repair
já verificará para você se o JSON for válido, se você ainda quiser fazer isso, adicione skip_json_loads=True
à chamada, conforme explicado a seção abaixo.
O reparo JSON fornece também um substituto de drop-in para json.load()
:
import json_repair
try:
file_descriptor = open(fname, 'rb')
except OSError:
...
with file_descriptor:
decoded_object = json_repair.load(file_descriptor)
e outro método para ler de um arquivo:
import json_repair
try:
decoded_object = json_repair.from_file(json_file)
except OSError:
...
except IOError:
...
Lembre-se de que a biblioteca não pegará nenhuma exceção relacionada a IO e esses precisarão ser gerenciados por você
Ao trabalhar com caracteres que não são latinos (como chinês, japonês ou coreano), você precisa passar por ensure_ascii=False
para repair_json()
para preservar os caracteres não latinos na saída.
Aqui está um exemplo usando caracteres chineses:
repair_json("{'test_chinese_ascii':'统一码'}")
voltará
{"test_chinese_ascii": "u7edfu4e00u7801"}
Em vez disso, passa ensure_ascii=False
:
repair_json("{'test_chinese_ascii':'统一码'}", ensure_ascii=False)
voltará
{"test_chinese_ascii": "统一码"}
Se você achar esta biblioteca muito lenta porque estiver usando json.loads()
poderá pular isso passando por skip_json_loads=True
para repair_json
. Como:
from json_repair import repair_json
good_json_string = repair_json(bad_json_string, skip_json_loads=True)
Eu escolhi não usar nenhuma biblioteca JSON rápida para evitar ter qualquer dependência externa, para que qualquer pessoa possa usá -la, independentemente da pilha.
Algumas regras práticas para usar:
return_objects=True
sempre será mais rápido porque o analisador retorna um objeto já e não tem serializando esse objeto para JSONskip_json_loads
é mais rápido apenas se você souber 100% que a string não é um json válidor"string with escaping""
Instale a biblioteca para linha de comando com:
pipx install json-repair
Para saber todas as opções disponíveis:
$ json_repair -h
usage: json_repair [-h] [-i] [-o TARGET] [--ensure_ascii] [--indent INDENT] filename
Repair and parse JSON files.
positional arguments:
filename The JSON file to repair
options:
-h, --help show this help message and exit
-i, --inline Replace the file inline instead of returning the output to stdout
-o TARGET, --output TARGET
If specified, the output will be written to TARGET filename instead of stdout
--ensure_ascii Pass ensure_ascii=True to json.dumps()
--indent INDENT Number of spaces for indentation (Default 2)
Por favor, prenda esta biblioteca apenas na versão principal!
Usamos TDD e versão semântica estrita, haverá atualizações frequentes e nenhuma mudança nas versões menores e patches. Para garantir que você fixe apenas a versão principal desta biblioteca em seus requirements.txt
, especifique o nome do pacote seguido pela versão principal e um curinga para versões menores e patches. Por exemplo:
json_repair==0.*
Neste exemplo, qualquer versão que inicie com 0.
Será aceitável, permitindo atualizações nas versões menores e patches.
Se você estiver usando esta biblioteca em seu trabalho acadêmico (como eu sei que muitas pessoas são), encontre o Bibtex aqui:
@software{Baccianella_JSON_Repair_-_2024,
author = {Baccianella, Stefano},
month = aug,
title = {{JSON Repair - A python module to repair invalid JSON, commonly used to parse the output of LLMs}},
url = {https://github.com/mangiucugna/json_repair},
version = {0.28.3},
year = {2024}
}
Obrigado por citar meu trabalho e envie -me um link para o papel, se puder!
Este módulo analisará o arquivo JSON após a definição do BNF:
<json> ::= <primitive> | <container>
<primitive> ::= <number> | <string> | <boolean>
; Where:
; <number> is a valid real number expressed in one of a number of given formats
; <string> is a string of valid characters enclosed in quotes
; <boolean> is one of the literal strings 'true', 'false', or 'null' (unquoted)
<container> ::= <object> | <array>
<array> ::= '[' [ <json> *(', ' <json>) ] ']' ; A sequence of JSON values separated by commas
<object> ::= '{' [ <member> *(', ' <member>) ] '}' ; A sequence of 'members'
<member> ::= <string> ': ' <json> ; A pair consisting of a name, and a JSON value
Se algo estiver errado (um parênteses ou citações ausentes, por exemplo), ele usará algumas heurísticas simples para consertar a string json:
Tenho certeza de que alguns casos de canto estarão faltando, se você tiver exemplos, por favor, abra um problema ou melhor ainda, empurre um PR
Basta criar um ambiente virtual com requirements.txt
, a configuração usa pré-compromisso para garantir que todos os testes sejam executados.
Certifique -se de que as ações do Github em execução depois de pressionar um novo compromisso não falhem também.
Você precisará do acesso do proprietário a este repositório
pyproject.toml
e atualize o número da versão adequadamente usando a Notação semver
python -m build