I have about 700 lines of code. I have to write a little doc about this code. In this doc, I plan to have a sequence diagram to explain a bit more. something like this: Since Iam a bit lazy, I would like to know if there is a tool to generate this diagram from code. I don't want to lose my entire weekend doing this.
Do some have an idea that could help me?
Thanks.
The Plantuml in python could be helpful. For how to install use link PlantUML with python
Text file should be like so:
Python -> HL : create
activate HL
HL -> LL : run
activate LL
LL -> SLI : exec
activate SLI
SLI --> LL
deactivate SLI
LL --> HL
deactivate LL
HL -> LL : push
activate LL
LL -> SLI : push
activate SLI
SLI --> LL
deactivate SLI
LL --> HL
deactivate LL
HL -> LL : run
activate LL
LL -> SLI : exec
activate SLI
SLI --> LL
deactivate SLI
LL --> HL
deactivate LL
HL -> LL : pop
activate LL
LL -> SLI : pop
activate SLI
SLI --> LL
deactivate SLI
LL --> HL
deactivate LL
HL --> Python
deactivate HL
It is possible to generate the text by python for this purpose, for example, you can add after the method declaration.
print>>sd.txt, "->"+str(self.name)+":className"
This will append to sd.txt and finally create png file in the project directory by running:
python -m plantuml sd.txt
python-UML-sequence-diagram
I was searching for this topic too and found the following usefull: https://github.com/bereal/pyspy
It patches the bytecode using byteplay and you can add your own callback-functions to do something before each call and after each. Similar to writting a profiler using sys.settrace
but easier.
Well, I added some fixes as issue-comments because I was not able to use git properly from here. Your functions may write DLS as text, like is needed by PlantUML or ZenUML... and use it to generate your diagram.
Here is a simple tracing class and an example of what can be done with it. instantiate the class at the beginning of each function you want to trace. A decorator could also be done on the same principle but you would have to adapt the python frame parsing accordingly
class SequenceOn:
autonumber = True
init_done = False
def __init__(self,participant=""):
if not SequenceOn.init_done :
#activate if requested only once
if SequenceOn.autonumber:
print ("autonumber")
SequenceOn.init_done = True
#retrieve callee frame
callee_frame = sys._getframe(1)
#method/function name
self.__funcName = callee_frame.f_code.co_name
# look for a class name
if 'self' in callee_frame.f_locals:
self.__className = callee_frame.f_locals['self'].__class__.__name__
else:
self.__className = participant
#retrieve the caller frame and class name of the caller
caller_frame = sys._getframe(2)
if 'self' in caller_frame.f_locals:
self.__caller = caller_frame.f_locals['self'].__class__.__name__
else:
self.__caller = ""
#print the plantuml message
activate = "++" if self.__caller != self.__className else ""
print (f'{self.__caller} -> {self.__className} {activate} :{self.__funcName}')
def __del__(self):
''' print the return message upon destruction '''
if self.__caller != self.__className:
print (f'{self.__caller} <-- {self.__className} -- ')
def note(self,msg):
print (f'note over {self.__className}:{msg}')
class SequenceOff:
''' empty class allowing to disable the trace by eg doing in the begining of a file:
Seq = SequenceOn # enable sequence generation
Seq = SequenceOff # disable sequence generation
and using seq for tracing instead of SequenceOn
'''
def __init__(self,participant=""):
pass
def __call__(self,msg):
pass
def note(self,msg):
pass
On the below sample code:
if __name__ == "__main__":
class B:
def __init__(self):
pass
def funcB1(self):
s = SequenceOn()
def funcB2(self):
s = SequenceOn()
s.note("calling private method")
self.__funcB22()
def __funcB22(self):
s = SequenceOn()
class A:
def __init__(self):
pass
def funcA(self):
s = SequenceOn()
b = B()
b.funcB1()
b.funcB2()
# simple sequence
a = A()
a.funcA()
You get:
autonumber
-> A ++ :funcA
A -> B ++ :funcB1
A <-- B --
A -> B ++ :funcB2
note over B:calling private method
B -> B :__funcB22
A <-- B --
<-- A --
Which generates:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With