Package: z2
Table of ContentsBackgroundLog variables / output messagesRun a command with realtime stdoutRun a command with blocked stdoutPrint with ColorGet a single character from user inputHandle network interface addressesBackgroundQ: What exactly is this module calledz2?A: Various code bites to keep my python code DRY.Log variables / output messages## LogIt() is implemented by loguru.##  loguru is a complete python logging rewrite.####  See https://github.com/Delgan/logurufromz2.utilsimportLogItLogIt().info("You forgot to eat your corn flakes")Run a command with streaming realtime stdoutThere are a couple ofzrunrecipies to consider...Run three pings and see output in realtime.realtime=Trueallows you to watch individual pings as they happen...add all stdout to a listfromz2.processimportzrun## Call z2.process.zrun()...## - Watch individual pings as they happen... like you ran it in bash / zsh / ??## - add all output to a listoutput=list(zrun("ping -c3 172.16.1.1",print_stdout=True,realtime=True))print(output)Run non-stop pings and act on individual pings.realtime=Trueallows you to watch individual pings as they happen...add all stdout to a listfromdatetimeimportdatetimeimporterrnofromz2.processimportzrundefact_on_ping(condition=None,now=datetime.now()):assertisinstance(condition,str)ifcondition=="foo":# Do something...pass# Much more here...## Call z2.process.zrun()...## - Watch individual pings as they happen... like you ran it in bash / zsh / ??## - add all output to a listforiiinzrun("ping -c5 -O 172.16.1.1",print_stdout=True,realtime=True):ifisinstance(ii,str):output.append(ii)ifisinstance(ii,str)and"no answer"inii.lower():# Lost a ping -> "no answer yet for icmp_seq=1"#     do something hereact_on_ping(condition="ping_timeout")elifisinstance(ii,int)andii==errno.EWOULDBLOCK:# This is normal while waiting on ping stdout...print("    errno.EWOULDBLOCK")passprint(output)Run a command with blocked stdoutRun three pings with blocked stdoutrealtime=Falseblocks stdoutresults are returned in alist()fromz2.processimportzrun## Call z2.process.zrun()...## - stdout is blocked during cmd execution## - return all output as a list of stringsoutput=list(zrun("ping -c3 172.16.1.1",print_stdout=True,realtime=False))print(output)getchar()- Get a single character from user inputgetchar()is a function to read a single letter from stdin and return it.fromz2.stringsimportgetcharinput_character=getchar(prompt_text="What letter are you thinking of? ")print(f"The character input was '{input_character}'")input_character=getchar(prompt_text="What letter are you thinking of? ",allowed_chars=set({"a","b","c"}),)print(f"The input restricted character was '{input_character}'")Print with Colorfromz2.stringsimportC# Print with green, orangeprint(C.GREEN+"Hello"+C.YELLOW+" World"+C.ENDC)Handle network interface addressesMost network interfaces take an IPv4 or IPv6 address format with a network
mask or a mask-length.  However, when you try to store both address and
mask in Python stdlib, you hit a problem.IPv4Address()does not process a
mask, andIPv4Network()does not store "host-bits".  Consider the following:>>># IPv4Address() and IPv4Network() are from python stdlib.>>>fromipaddressimportIPv4Address,IPv4Network>>>intfAddr=IPv4Address("1.1.1.200/24")Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>File"/opt/python37/lib/python3.7/ipaddress.py",line1300,in__init__raiseAddressValueError("Unexpected '/' in%r"%address)ipaddress.AddressValueError:Unexpected'/'in'1.1.1.200/24'>>>>>>>>>### IPv4Network() does not store "host bits", only "network bits".>>>### As such, IPv4Network() is **useless** to hold network devices'>>>### real-life needs (to store the interface address and mask).>>>>>>intfAddr=IPv4Network("1.1.1.200/24")Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>File"/opt/python37/lib/python3.7/ipaddress.py",line1536,in__init__raiseValueError('%shas host bits set'%self)ValueError:1.1.1.200/24hashostbitsset>>>intfAddr=IPv4Network("1.1.1.200/24",strict=False)>>>intfAddrIPv4Network('1.1.1.0/24')>>>### Above ^^^^^^ we see that IPv4Network() strips .200 from the>>>### address.Keepingtheinterfaceaddressandmaskissupportedoutoftheboxwithz2.IPv4Obj().Seebelow...>>>fromz2importIPv4Obj>>>intfAddr=IPv4Obj("1.1.1.200/24")>>>>>>intfAddr<IPv4Obj1.1.1.200/24>>>>