Code Architecture - C-Accel-Project-Old-Version/old-sdk GitHub Wiki
How Is the Code Structured?
This is a great place to learn more about the code, how it is structured, in what order, and how to read it.
It is often difficult to get 100s of files of code with many directories and be able to know how it all works easily. This documentation attempts to make that process immensely easier.
Data Integrity and Giant JSON
In the previous SDK, nodes had to be saved one at a time, this created issues because if half way through the script the user got an error, then within the database half of the project would have been uploaded and half would not have been. This becomes a bigger issue for update when if the script has a bug half way through upload, then half of the nodes are updated and half are outdated creating bad data in total.
API
The API client class is meant to be used to interact with the API. An instance of the object is available globally for the whole SDK to use when needing to interact with the db schema, know the host the user defined, upload files, or more.
HTTP Headers
_http_headers variable is created in the cript.API() object to be able to interact with the API through http requests
AWS S3
S3 variable/property is created from the api storage_token and this object is only initialized and cached if the user needs to start upload files to cloud storage, otherwise, it is never initialized as it is not needed.
cript.API.save()
Please refer to save & update wiki documentation
Nodes
Node Attributes
All node attributes are encapsulated in Python dataclass to easily serialize and deserialize
@dataclass(frozen=True)
class JsonAttributes(PrimaryBaseNode.JsonAttributes):
"""
all Material attributes
"""
# identifier sub-object for the material
identifiers: List[Dict[str, str]] = field(default_factory=dict) # type: ignore
component: List["Material"] = field(default_factory=list)
process: Optional[Process] = None
property: List[Any] = field(default_factory=list)
parent_material: Optional["Material"] = None
computational_forcefield: Optional[Any] = None
keyword: List[str] = field(default_factory=list)
_json_attrs: JsonAttributes = JsonAttributes()
all node attributes for the class are manipulated with getters and setters
@property
@beartype
def keyword(self) -> List[str]:
return self._json_attrs.keyword
@keyword.setter
@beartype
def keyword(self, new_keyword_list: List[str]) -> None:
new_attrs = replace(self._json_attrs, keyword=new_keyword_list)
self._update_json_attrs_if_valid(new_attrs)
Property special case
There are some places that the node attribute is named property and python has a reserved keyword called property, for those scenarios we have put the property of the node at the bottom of the file, so that it doesn't create and issues with name clashes
Upgrade: in the future we are planning to use Pydantic and maybe we can use the python convention of calling it
property_to not clash with the name. That way when we turn the node to JSON we call itpropertybut when we are using it within Python we call itproperty_
Serialization and Deserialization
Please refer to serialization & deserialization wiki
Exceptions
Please refer to Exceptions wiki
Documentation
Please refer to documentation wiki
Tests
please refer to Tests Wiki