Skip to content

Commit

Permalink
add datetime example (#13)
Browse files Browse the repository at this point in the history
* Update setup.py

* Update __init__.py

* add `datetime` example

* add keywords

* test not serializable
  • Loading branch information
PythonFZ authored Mar 11, 2022
1 parent b2a6ad3 commit 60032c0
Show file tree
Hide file tree
Showing 5 changed files with 259 additions and 6 deletions.
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,56 @@ The resulting ``*.json`` file is partially readable and looks like this:
4
]
}
````

# Custom Converter

ZnJSON allows you to easily add custom converters.
Let's write a serializer for ``datetime.datetime``.

````python
from znjson import ConverterBase
from datetime import datetime

class DatetimeConverter(ConverterBase):
"""Encode/Decode datetime objects
Attributes
----------
level: int
Priority of this converter over others.
A higher level will be used first, if there
are multiple converters available
representation: str
An unique identifier for this converter.
instance:
Used to select the correct converter.
This should fulfill isinstance(other, self.instance)
or __eq__ should be overwritten.
"""
level = 100
representation = "datetime"
instance = datetime

def _encode(self, obj: datetime) -> str:
"""Convert the datetime object to str / isoformat"""
return obj.isoformat()
def _decode(self, value: str) -> datetime:
"""Create datetime object from str / isoformat"""
return datetime.fromisoformat(value)
````

This allows us to use this new serializer:
````python
znjson.register(DatetimeConverter) # we need to register the new converter first
json_string = json.dumps(dt, cls=znjson.ZnEncoder, indent=4)
json.loads(json_string, cls=znjson.ZnDecoder)
````

and will result in
````json
{
"_type": "datetime",
"value": "2022-03-11T09:47:35.280331"
}
````
194 changes: 194 additions & 0 deletions example/datetime_converter.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
{
"cells": [
{
"cell_type": "markdown",
"source": [
"# Write a custom Converter\n",
"\n",
"In this Example we will write a custom converter for `datetime` objects."
],
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%% md\n"
}
}
},
{
"cell_type": "code",
"execution_count": 1,
"outputs": [],
"source": [
"import json\n",
"\n",
"from znjson import ConverterBase\n",
"from datetime import datetime\n",
"import znjson"
],
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%%\n"
}
}
},
{
"cell_type": "code",
"execution_count": 2,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2022-03-11 10:02:18.048121\n"
]
}
],
"source": [
"dt = datetime.now()\n",
"print(dt)"
],
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%%\n"
}
}
},
{
"cell_type": "code",
"execution_count": 3,
"outputs": [],
"source": [
"class DatetimeConverter(ConverterBase):\n",
" \"\"\"Encode/Decode datetime objects\n",
"\n",
" Attributes\n",
" ----------\n",
" level: int\n",
" Priority of this converter over others.\n",
" A higher level will be used first, if there\n",
" are multiple converters available\n",
" representation: str\n",
" An unique identifier for this converter.\n",
" instance:\n",
" Used to select the correct converter.\n",
" This should fulfill isinstance(other, self.instance)\n",
" or __eq__ should be overwritten.\n",
" \"\"\"\n",
" level = 100\n",
" representation = \"datetime\"\n",
" instance = datetime\n",
"\n",
" def _encode(self, obj: datetime) -> str:\n",
" \"\"\"Convert the datetime object to str / isoformat\"\"\"\n",
" return obj.isoformat()\n",
" def _decode(self, value: str) -> datetime:\n",
" \"\"\"Create datetime object from str / isoformat\"\"\"\n",
" return datetime.fromisoformat(value)"
],
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%%\n"
}
}
},
{
"cell_type": "markdown",
"source": [
"To use the new converter we have to add it to `znjson.config.ACTIVE_CONVERTERS` via `znjson.register()`"
],
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%% md\n"
}
}
},
{
"cell_type": "code",
"execution_count": 4,
"outputs": [],
"source": [
"znjson.register(DatetimeConverter)"
],
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%%\n"
}
}
},
{
"cell_type": "code",
"execution_count": 5,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"_type\": \"datetime\",\n",
" \"value\": \"2022-03-11T10:02:18.048121\"\n",
"}\n"
]
}
],
"source": [
"json_string = json.dumps(dt, cls=znjson.ZnEncoder, indent=4)\n",
"print(json_string)"
],
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%%\n"
}
}
},
{
"cell_type": "code",
"execution_count": 6,
"outputs": [
{
"data": {
"text/plain": "datetime.datetime(2022, 3, 11, 10, 2, 18, 48121)"
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"json.loads(json_string, cls=znjson.ZnDecoder)"
],
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%%\n"
}
}
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@

setuptools.setup(
name="znjson",
version="0.1.0",
version="0.1.2",
author="zincwarecode",
author_email="zincwarecode@gmail.com",
description="A Python Package to Encode/Decode some common file formats to json",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/zincware/ZnJSON",
download_url="https://github.com/zincware/ZnJSON/archive/beta.tar.gz",
keywords=["json", "zntrack"],
keywords=["json", "zntrack", "jsonpickle", "serialization", "deserialization"],
packages=setuptools.find_packages(),
classifiers=[
"Development Status :: 3 - Alpha",
Expand Down
13 changes: 10 additions & 3 deletions tests/converter/test_class_converter.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import json

import numpy as np
import pytest

import znjson

znjson.register(znjson.converter.ClassConverter)


class HelloWorld:
def __init__(self):
Expand All @@ -25,3 +22,13 @@ def test_encode(example_class):
def test_decode(example_class):
encoded_str = json.dumps(example_class, cls=znjson.ZnEncoder)
assert isinstance(json.loads(encoded_str, cls=znjson.ZnDecoder), type(example_class))


def test_unable_to_encode():
class OutOfScope:
"""Can not be imported, so it can not be encoded"""

pass

with pytest.raises(TypeError):
json.dumps(OutOfScope(), cls=znjson.ZnEncoder)
2 changes: 1 addition & 1 deletion znjson/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@

__all__ = ["ConverterBase", "ZnDecoder", "ZnEncoder", "register", "deregister", "config"]

__version__ = "0.1.0"
__version__ = "0.1.2"

register()

0 comments on commit 60032c0

Please sign in to comment.