Basic Tutorial (Python)
This tutorial introduces how CBOT can be used in Python for both untyped and Typed Model which is the intended use case for the protocol.
Installation
pip install sisujs-cbot
Untyped Example: Library
CBOT can be used as a simple replacement for json.dumps() and
json.loads() and this example will demonstrate typical JSON-like behavior
that you may be accustomed to. The example consists of a library with three
concepts: Author, Book and Catalog.
Let's define some values:
isaac = {
"name": "Isaac Asimov",
"birthdate": date(1902, 1, 2)
}
foundation = {
"title": "Foundation",
"isbn": "978-0-394-51330-7",
"publication_year": 1951,
"author": isaac
}
i_robot = {
"title": "I, Robot",
"isbn": "978-0-394-51331-4",
"publication_year": 1950,
"author": isaac
}
catalog = [
{
"genre": "Science Fiction",
"books": [
foundation,
i_robot
],
"authors": [isaac]
}
]
In order to serialize something, one needs an instance of CBOT in some static variable. You should always create just one instance for each model and use it globally.
from sisujs_cbot import Cbot, CbotOptions
cbot = Cbot(CbotOptions())
Now we can actually serialize an object to a message and vice versa:
msg = cbot.serialize(foundation)
deserialized = cbot.deserialize(msg)
This example demonstrated how serialization and deserialization are used in a JSON-like way.
Typed Example: Library
This example employs the same concepts as the untyped one but with actual types. Cbot-implementation relies on Pydantic-models to create proper class-model
Namespace
The first step is to create a namespace which is an important tool for categorizing Pydantic models into usable groups.
Namespace is created as follows:
from sisujs_cbot import Cbot, CbotNamespace, CbotOptions
ns = CbotNamespace("library")
Typed Model
Then model is created as follows:
@ns.model()
class Author(BaseModel):
name: str = string_type()
birthdate: date = local_date_type()
@ns.model()
class Book(BaseModel):
title: str = string_type()
isbn: str = string_type()
author: Author = model_object_type()
publication_year: int = int32_type("publicationYear")
rating: float = float64_type()
@ns.model()
class Catalog(BaseModel):
genre: str = string_type()
books: list[Book] = model_object_type()
authors: list[Author] = model_object_type()
ns.seal()
What can be observed here is that classes and all their properties require a
corresponding type-information for the model to be constructed correctly.
For instance Python has a int-type which is in practice arbitrary long integer.
In this case it must indentified as int32(), int64() or big_integer().
It is also possible to have (transient) properties without adding the indentifier at all, and these will not be included in the model.
Also, note that publication_year property has additional name in the indentifier.
The publicationYear is a public name so that property names do not have be in camelcase.
The last thing is to call seal() function for all declared types, which
prevents adding further declarations.
Creating Objects
After this object creation happens as expected:
isaac = Author(name="Isaac Asimov", birthdate=date(1902, 1, 2))
foundation = Book(
title="Foundation",
isbn="978-0-394-51330-7",
publication_year=1951,
author=isaac,
rating=7.0)
i_robot = Book(
title="I, Robot",
isbn="978-0-394-51331-4",
publication_year=1950,
author=isaac,
rating=10.0)
catalog = Catalog(
genre="Science Fiction",
books=[foundation, i_robot],
authors= [isaac])
Cbot instance
Next a proper Cbot-instance is created as follows:
cbot = Cbot(CbotOptions(namespaces=[ns]))
Usage
Next we can serialize and deserialize a catalog as expected:
msg = cbot.serialize(catalog);
deserialized:Catalog = cbot.deserialize(msg);