Learning Center

Learning Center

Learn Menu

Python Engine

Supported Versions

We currently support Python 3.7 and newer. It's the lowest version that contains both typing and datetime functions.

We are open to support lower python versions based on user feedback.

Data Types

Standard

Design Python Default Value
bool boole False
int int 0
int8 int 0
int16 int 0
int32 int 0
int64 int 0
uint int 0
uint8 int 0
uint16 int 0
uint32 int 0
uint64 int 0
float float 0.0
double float 0.0
string str ''
char str ''
byte int 0
bytea bytes None
date datetime None
datetime datetime None

Complex

Name Default Value
Array []
Object (Map) {}

Config

There's currently no python config options available for this engine. It's likely to change in the future based on user feedback.

Typing

OneGen takes advantage of the typing library to make your models more predictable and easier to work with.

Optionals

Optional[X] is a type that's part the typing library. It contains either the underlying value, or None.

Let's say you decide one of your model properties should be an optional string (string?). Such property in Python engine would be generated as Optional[str].

Enum

We use Python's Enum class as shown in an example below.

  from enum import Enum

class Color(Enum):
    GREEN = "GREEN"
    BLUE = "BLUE"
    BROWN = "BROWN"

eye_color = Color.BROWN
print(eye_color)  # prints out 'Color.BROWN'

# To create Color enum from raw value:
car_color = Color("BLUE")
print(car_color)  # prints out 'Color.BLUE'

Class

Every class is generated with all of its properties set to a default value and a constructor that accepts **kwargs. See an example User class below.

  class User:
    email: str = ''
    password: str = ''
    age: int = 0

    def __init__(self, **kwargs) -> None:
        if 'email' in kwargs:
            self.email = kwargs['email']
        if 'password' in kwargs:
            self.password = kwargs['password']
        if 'age' in kwargs:
            self.age = kwargs['age']


# Usage
if __name__ == "__main__":
    u = User(email="john@doe.com")
    print(u.email)  # prints john@doe.com

Serialization

OneGen generates serialization (to_dict) and deserialization (from_dict) methods for every class. These methods make serialization a breeze.

Let's consider the following example. We have two models, User and Company (which is referenced from the User model). Take a look at the generated serialization methods and how they work.

  # File: models/company.py
class Company:
    name: str = ''

    def __init__(self, **kwargs) -> None:
        if 'name' in kwargs:
            self.name = kwargs['name']

    def to_dict(self) -> dict:
        result: dict = {}
        result['name'] = self.name
        return result

    @staticmethod
    def from_dict(obj: dict) -> 'Company':
        model = Company()
        model.name = obj['name']
        return model


# File: models/user.py
import datetime
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from .company import Company


class User:
    email: str = ''
    password: str = ''
    is_subscribed: bool = False
    created: datetime = None
    company: 'Company' = None

    def __init__(self, **kwargs) -> None:
        if 'email' in kwargs:
            self.email = kwargs['email']
        if 'password' in kwargs:
            self.password = kwargs['password']
        if 'is_subscribed' in kwargs:
            self.is_subscribed = kwargs['is_subscribed']
        if 'created' in kwargs:
            self.created = kwargs['created']
        if 'company' in kwargs:
            self.company = kwargs['company']

    def to_dict(self) -> dict:
        result: dict = {}
        result['email'] = self.email
        result['password'] = self.password
        result['isSubscribed'] = self.is_subscribed
        result['created'] = self.created.isoformat() if self.created else None
        result['company'] = self.company.to_dict() if self.company else None
        return result

    @staticmethod
    def from_dict(obj: dict) -> 'User':
        from .company import Company

        model = User()
        model.email = obj['email']
        model.password = obj['password']
        model.is_subscribed = obj['isSubscribed']
        model.created = datetime.datetime.fromisoformat(obj['created']) if obj['created'] else None
        model.company = Company.from_dict(obj['company']) if obj['company'] else None
        return model



from_dict (deserialize)

This static method takes a Python dictionary and returns a new instance of the associated model. It's very easy to use, let's say we want to create a User object from a mocked API response.

  # File main.py
from models.user import User

if __name__ == "__main__":
    # Imagine the following object is returned from your API
    userAPIResponse = {
        "email": "joe@doe.com",
        "password": "",
        "isSubscribed": True,
        "created": "2022-05-30T21:26:49+00:00",
        "company": {"name": "Friendly Corp"}  # Notice the plain Company object here
    }

    user = User.from_dict(userAPIResponse)
    print(user.email)       # prints out 'joe@doe.com'
    print(user.company)     # it's an instance of Company now
    print(user.created)     # it's an instance of Date now

to_dict (serialize)

This instance method doesn't accept any parameters and returns a new Python dictionary. Let's use the previous example to serialize the User instance.

  newPlainUser = user.to_dict()
print(newPlainUser['company'])  # it's a dict now
print(newPlainUser['created'])  # it's an ISO 8601 string now.

Copy/Clone

If you've already noticed, congratulations! Because our serialization methods safely copy data from/to dictionary, we can actually use them to create a deep clone/copy of any model. Check out the example below.

  from models.user import User
from models.company import Company

if __name__ == "__main__":
    user = User()
    user.email = 'john@doe.com'
    user.company = Company.from_dict({"name": "Cat Cafe, LLC."})

    clone = User.from_dict(user.to_dict())
    clone.company.name = 'Dog Cafe, LLC.'   # we can just rename the company and leave the rest
    print(user.company.name)                # prints out 'Cat Cafe, LLC.'
    print(clone.company.name)               # prints out 'Dog Cafe, LLC.'

Date format

We use Python's standard datetime object for model generation. As for serialization, ISO 8601 format is expected. In other words, from_dict method expects all date/datetime fields to be in the ISO 8601 format and to_dict converts all datetime objects into the ISO 8601 format. For instance, January 5th, 2022 at 11:45 am would be represented as 2022-01-05T11:45:00.000Z

We use cookies to track activity using Google Analytics & reCAPTCHA. It helps us understand what our visitors like about our product and how they interact with our website. For more information, check out our Privacy Policy.