Skip to main content

PODM: (P)ython (O)bject - (D)ictionary (M)apper

This library is intended to create objects that easily serialize to dictionaries that can be later stored as JSON or YAML. It is intended as a replacement of jsonpickle for cases where jsonpickle output format is not good at all.

Features:

  • Support for ordered dictionaries or custom mapping classes
  • Custom field serialization/deserialization
  • Validators
  • Json Schema generation

Installation

	pip3 install podm

Some use case samples

Very simple case:

from podm import JsonObject, Property

class Person(JsonObject):

   first_name = Property()
   last_name = Property()

person = Person(first_name='John',last_name='Doe')
person_dict = person.to_dict()
print(json.dumps(person_dict,indent=4))

# will output
{
    "py/object": "__main__.Person",
    "first_name": "John",
    "last_name": "Doe"
}

Notice the field "py/object", if you don't need it, you can specify on the class declaration:

class Person(JsonObject):

    __add_type_identifier__ = False

    first_name = Property()
    last_name = Property()

If you need to specify a different name when the field is converted to dictionary:

class Person(JsonObject):

    __add_type_identifier__ = False

    first_name = Property('first-name')
    last_name = Property('last-name')


person = Person(first_name='John',last_name='Doe')
person_dict = person.to_dict()
print(json.dumps(person_dict,indent=4))

# will output
{
    "first-name": "John",
    "last-name": "Doe"
}

Now, when you need to convert the dictionary back to object:

person = Person.from_dict({'first-name':'John', 'last-name':'Doe'})

In case you don't want to explicitly use the class, or you are working with a hierarchy of classes, you will need the type identifier field in order to let the library recognize the object type:

some_dictionary = {
    "py/object": "__main__.Person",
    "first-name": "John",
    "last-name": "Doe"
}
some_obj = JsonObject.parse(some_dictionary)

Handling complex data types:

from podm import JsonObject, Property, Handler

class DateTimeHandler(Handler):
	"""
	Define a custom handler for datetime objects
	"""
	def encode(self, obj):
		return {
			'year' : obj.year,
			'month' : obj.month,
			'day' : obj.day,
			'hour' : obj.hour,
			'minute' : obj.minute,
			'second' : obj.second,
			'microsecond' : obj.microsecond
		}

	def decode(self, obj_data):
		return datetime(**obj_data)

class Entity(JsonObject):
	"""
	A base class for the object model
	"""
	oid = Property()
	created = Property('created', handler=DateTimeHandler(), default=datetime.now) # Default value when object is instantiated

class Company(Entity):
	company_name = Property('company-name') # Specify a different field name in json.
	description = Property()        

class Sector(Entity):
	employees = Property('employees', default=[])

class Employee(Entity):
	name = Property()

company = Company(
  name='My great company',
  description='....'
)

json_data = company.to_dict()

company_2 = Company.from_dict(json_data)

Jsonpickle format support

data = {
	'py/object' : 'Company',
	'py/state': {
		'company-name' : 'master',
		'description'  : 'some description'
	}
}
company = JsonObject.parse(data) 

Automatically generated getters/setters.

If they are declared property accessors will use them instead.

class Company(JsonObject):
	company_name = Property('company-name') # Specify a different field name in json.

# Automatically generated getter
company_name = company.get_company_name()

# Also property accessors
company_name = company.company_name

# And private attributes
company_name = company._company_name

Write custom getters and setters

class Company(JsonObject):
	company_name = Property('company-name') # Specify a different field name in json.

	def get_company_name(self):
		print('Getter called!!!')
		# generated attribute
		return self._company_name

# So, when calling the property getter ...
company_name = company.company_name

# will print 'Getter called!!!'

Enum support

It is possible to decide how to serialize/deserialize enums.

class InvoiceType(Enum):
	TYPE_A = 1
	TYPE_B = 2


class Invoice(JsonObject):
	invoice_type = Property(type=InvoiceType, enum_as_str=True)


invoice = Invoice(invoice_type=InvoiceType.TYPE_A)

serialized = invoice.to_dict()

print(serialized['invice_type'])
# Will print 'TYPE_A'

class Invoice(JsonObject):
	invoice_type = Property(type=InvoiceType)


invoice = Invoice(invoice_type=InvoiceType.TYPE_A)

serializd = invoice.to_dict()
print(serialized['invoice_type'])
# Will print 1

Json Schema generation.

Check test cases for examples.

Validators.

Check test cases for examples.

Metadata

Release files for podm 0.0.19

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for podm 0.0.19
File Size Uploaded
podm-0.0.19.tar.gz 21.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for podm 0.0.19
File Interpreter ABI Platform
podm-0.0.19-py3-none-any.whl Python 3 none any Details

Total release size: 51.1 kB

Release files / podm-0.0.19.tar.gz

Download URL podm-0.0.19.tar.gz
Size 21.9 kB
Tags Source
SHA-256 checksum
How to use checksums
73ea8403552edece1691a45aeea271d7551ac265692adc07f03bc2c93d6e6ac9
BLAKE2b-256 checksum
How to use checksums
902098e16f269bf5fbf9b4840d497d3cc075822aa9b566a94d3c9f7e4c365c71
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.2 importlib_metadata/4.0.1 pkginfo/1.7.1 requests/2.22.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.7

Release files / podm-0.0.19-py3-none-any.whl

Download URL podm-0.0.19-py3-none-any.whl
Size 29.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7654f7b093b9ebe1ca1e466864f828b47a51082f27132dc6c5ec00cb054a876e
BLAKE2b-256 checksum
How to use checksums
fc1d6ca68bfae1cb3ec35e61e5db073477ffc00f6dbcced2f4445385f2c6f4c1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.2 importlib_metadata/4.0.1 pkginfo/1.7.1 requests/2.22.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.7

Release history Release notifications | RSS feed

This release

0.0.19 This release

2 release files

0.0.18

2 release files

0.0.17

2 release files

0.0.15

2 release files

0.0.14

2 release files

0.0.13

2 release files

0.0.10

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page