Generate class diagrams or code in another programming language from you Python classes.
- .dot: DOT files
- .png: Images, generated from .dot-files with graphviz
- .ts: TypeScript
Let's assume your file models.py
contains following code:
class Person:
def __init__(self, name:str, age:int):
self.name: str
self.age: int
class Developer(Person):
def __init__(self, name:str, age:int, languages: list[str]):
super().__init__(name=name, age=age)
self.languages: list[str] = languages
def brag(self) -> str:
return "Look at me, I know all these languages: " + ",".join(self.languages) + "."
Create the file you want with specifying the file extension (see above for supported extensions). Let's assume we want to create a TypeScript file, we then use .ts:
py-model --files models.py --output models.ts
which creates following models.ts
file:
interface Person {
name: string;
age: number;
}
interface Developer extends Person {
languages: Array<string>;
brag(): string;
}
Let's also generate a class diagram for our coworkers:
py-model --files models.py --output models.png
#TODO
Install py-model with your common package manager. For pip
this would look like
pip install py-model
To get aqcuainted witht the command line interfacc run py-model --help
.
When parsing the structure of your python models regular classes and dataclasses are supported. However, if you also want to export your datatypes, then only annotated assignments will have a datatype, as an example
ann_assign: int = 5
assign = 5
will be parsed as something similar to {ann_assign: int, assign: undefined}
:
from dataclasses import dataclass
@dataclass
class Person:
self.name: int # datatype will be picked up
class Company:
def __init__(self, num_employees: int):
self.num_employees = num_employees # datatype will NOT be picked up (not annotated)
It is important that only the specified datatypes in the assignments are used, not the ones specified in the constructor`s signature. This has the simple reason, that the variables in the constructor don't need to be the resulting attributes and it would be too complicated to check any conversions etc. Also, only attributes that are set within the constructor are considered to be instance attributes:
class Tree:
def __init__(self, height: int)
self.heigt = float(number) # datatype will NOT be picked up (not annotated)
def cut_branches(cut_branches: int) -> None:
self.cut_branches: int = cut_branches # attribute will NOT be picked up (not in constructor)
Following data types are supported, with their equivalent in the other languages implemented:
- None
- bool
- int
- float
- str
- dict
- list
- tuple
- set
- class
Also the union is supported (please rewrite Optional[int]
to int | None
). Any combination of supported datatypes works, e.g.,
some_attribute: list[tuple[str, bool | int]]
Not implemented yet, but planned and listed in their order of planned implementation:
- Enum
- complex
- frozenset
- range
- bytes
- bytearray
"Never. Ever. Buy a tech prouct based on the promise of future software updates." - Marques Brownlee, around 2021
Lucky you, it's open source... 👀 These are the planned features for future versions:
- Support for Django projects such that one could export the models and use them for their frotend as types
Additional cardsupport for class diagrams, where
from dataclasses import dataclass
from py_model.decorators import cardinality
class Wagon:
pass
@dataclass
@cardinality(wagons=('1', '1..*'))
class Train:
wagons: list[Wagon]
which would result in something like: #TODO ****
- Nested Classes: parsing them correctly etc.
This is a fairly young project and any type of contribution is welcome. Just open a pull request and I am happy to check it. Please make sure to write some tests for it. The contribution for the following languages is highly appreciated (and wanted)...
- .puml (Plant UML)
This is a list that came to my mind where I think implementation is useful, I am open to any other suggestions though and happy to merge a pull request for them.
- .java (Java)
- .kt (Kotlin)
- .dart (Dart)
- .swift (Swift)
To be filled in