Introducción a orjson

  • Serializar dataclass.
  • Serializar objetos datetime, numpy.ndarray y UUID nativamente.
  • Serializar a byte en vez de string.
  • Serializar string sin escapado de unicode a ASCII.
  • Más rápido para serializar y desserializar.
  • No tiene load() y dump() para leer o escribir de o a un archivo.

Instalación

pip install orjson

Implementación

  1. Se importa el módulo:
import orjson
from datetime import datetime
import uuid
dato = {
"emoji_lagrimas": "😂",
"emoji_reloj": "⏰",
"entero": 123,
"flotante": 10.4,
"boleano": False,
"lista": ["element1", "element2"],
"diccionario": {"key1": "value1", "key2": "value2"},
"ruso": "Привет",
"chino": "您好",
"japones": "こんにちは",
"datetime": datetime.now(),
"uuid": uuid.uuid1()
}

print(data)

{'emoji_tears': '😂', 'emoji_clock': '⏰', 'integer': 123, 'float': 10.4, 'boolean': False, 'list': ['element1', 'element2'], 'dict': {'key1': 'value1', 'key2': 'value2'}, 'russian': 'Привет', 'chinese': '您好', 'japanese': 'こんにちは', 'datetime': datetime.datetime(2022, 1, 20, 19, 25, 28, 555227), 'uuid': UUID('40d49edc-7a48-11ec-865d-9078414427c1')}
json_byte = orjson.dumps(data)

print(json_byte)

b'{"emoji_tears":"\xf0\x9f\x98\x82","emoji_clock":"\xe2\x8f\xb0","integer":123,"float":10.4,"boolean":false,"list":["element1","element2"],"dict":{"key1":"value1","key2":"value2"},"russian":"\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82","chinese":"\xe6\x82\xa8\xe5\xa5\xbd","japanese":"\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf","datetime":"2022-01-20T19:20:56.518677","uuid":"9f8d3b92-7a47-11ec-865d-9078414427c1"}'
TypeError: Type is not JSON serializable. decimal.Decimal
json_data = orjson.loads(json_byte)

print(json_data)

{'emoji_tears': '😂',
'emoji_clock': '⏰',
'integer': 123,
'float': 10.4,
'boolean': False,
'list': ['element1', 'element2'],
'dict': {'key1': 'value1', 'key2': 'value2'},
'russian': 'Привет',
'chinese': '您好',
'japanese': 'こんにちは',
'datetime': '2022-01-20T19:25:28.555227',
'uuid': '40d49edc-7a48-11ec-865d-9078414427c1'}

Argumentos adicionales para serialización

  • default: Un invocable que devuelve un tipo compatible.
  • option: Para modificar cómo se serializan los datos a través de una constante entera en orjson.
import decimal
orjson.dumps(decimal.Decimal("3.141592653"))
TypeError: Type is not JSON serializable. decimal.Decimal
import decimal
import math
def default(obj):
if isinstance(obj, decimal.Decimal):
return str(obj)
raise TypeError
orjson.dumps(decimal.Decimal(f"{math.pi}"), default=default)

b'"3.141592653589793"'

Option

import orjson
import datetime
import numpy as np
data = {
"datetime": datetime.datetime.now(),
"numpy": np.array([[1, 2], [3, 4]])
}
json_byte = orjson.dumps(data, option=orjson.OPT_NAIVE_UTC | orjson.OPT_SERIALIZE_NUMPY)
print(json_byte)

print(orjson.loads(json_byte))

b'{"datetime":"2022-01-20T19:48:45.924867+00:00","numpy":[[1,2],[3,4]]}'

{'datetime': '2022-01-20T19:48:45.924867+00:00', 'numpy': [[1, 2], [3, 4]]}
  • OPT_APPEND_NEWLINE — Agrega \n .
  • OPT_INDENT_2 — Identa a 2 espacios la salida .
  • OPT_NAIVE_UTC — Serializa objetos datetime.datetime objects sin tzinfo como UTC.
  • OPT_SERIALIZE_NUMPY — Serializa instancias de numpy.ndarray.

Dataclass

import dataclasses, orjson, typing
@dataclasses.dataclass
class Person:
id: int
name: str
status: bool = dataclasses.field(default=True)
@dataclasses.dataclass
class Class:
id: int
name: str
students: typing.List[Person]
data = Class(1, "Class A", [Person(1, "John Doe", False), Person(2, "Mary Sue")])
json_byte = orjson.dumps(data)
print(json_byte)
print(orjson.loads(json_byte))


b'{"id":1,"name":"Class A","students":[{"id":1,"name":"John Doe","status":false},{"id":2,"name":"Mary Sue","status":true}]}'
{'id': 1,
'name': 'Class A',
'students': [{'id': 1, 'name': 'John Doe', 'status': False},
{'id': 2, 'name': 'Mary Sue', 'status': True}]}

Escritura/Lectura de archivos

with open("example.json", "wb") as f:
f.write(orjson.dumps(data))
with open("example.json", "rb") as f:
json_data = orjson.loads(f.read())

print(json_data)

{'id': '1',
'name': 'Class A',
'students': [{'id': 1, 'name': 'John Doe', 'status': False},
{'id': 2, 'name': 'Mary Sue', 'status': True}]}
  1. Choosing a faster JSON library for Python
  2. orjson — A fast json parser for python (artículo en inglés en el que se basa este artículo)
  3. Rendimiento de orjson
  4. Repositorio github

--

--

Senior Python Developer, Software Architect, Big Data, Data Science, Machine Learning and Deep Learning, Debian SysAdmin, DevOps, Blogger and Freelancer.

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Ernesto Crespo

Ernesto Crespo

Senior Python Developer, Software Architect, Big Data, Data Science, Machine Learning and Deep Learning, Debian SysAdmin, DevOps, Blogger and Freelancer.