ramonhagenaars / jsons

🐍 A Python lib for (de)serializing Python objects to/from JSON
https://jsons.readthedocs.io
MIT License
289 stars 41 forks source link

How to load json from a file? #122

Closed hf-krechan closed 4 years ago

hf-krechan commented 4 years ago

Hello together,

I am looking for a easy and pythonic way to load a json file with jsons. I expected that jsons works the same way like the json package:

import jsons

with open("foo.json", encoding="utf-8") as json_file:
    adress_data = jsons.load(json_file)

But then I get the following error:

Fail: jsons.exceptions.DeserializationError: Invalid type: "_io.TextIOWrapper", only arguments of the following types are allowed: str, int, float, bool, list, tuple, set, dict, NoneType

The content of the json file looks like this:

{
    "city": "Köln",
    "street": "Goethestraße",
    "house number": "11A"
}

Of course I could read the whole file as a string. But then I must also remove the newline signs. And importing two packages (json and jsons) does not feel right.

Do I miss here something?

RHagenaars commented 4 years ago

Hi @hf-krechan,

Currently jsons does not support loading a file directly. You can think of jsons to be a libary that takes off were json stops; that is to load into objects (rather than just dicts).

That being said, using jsons to load into a dict can be done as well:

import jsons

with open("foo.json", encoding="utf-8") as json_file:
    address_data = jsons.loads(json_file.read())

The above example should work perfectly fine with the content you drew. However, using jsons in this example is kind of an overkill. The standard lib json could the same thing without forcing you to an additional dependency.

As I said before, jsons could take you one step further. Like in the following example:

from dataclasses import dataclass

import jsons

@dataclass
class Address:
    city: str
    street: str
    house_number: str

with open("foo.json", encoding="utf-8") as json_file:
    address = jsons.loads(json_file.read(), cls=Address,
                          key_transformer=lambda key: key.replace(" ", "_"))

(the "key_transformer" is necessary here to translate "house number" into "house_number")

hf-krechan commented 4 years ago

Hi @RHagenaars,

thanks for your detailed answer =) The second part is exactly what I do. I have to create new classes which have to be serialized and deserialized later. That was also the reason why I came across jsons.

By the way the combination of attr and jsons works really great so far. Thanks a lot for this nice package and its documentation.