Skip to main content

A set of tools

Project description

Table of Contents

  1. Background
  2. Log variables / output messages
  3. Run a command with realtime stdout
  4. Run a command with blocked stdout
  5. Print with Color
  6. Get a single character from user input
  7. Handle network interface addresses

Background

Q: What exactly is this module called z2?

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/loguru

from z2.utils import LogIt

LogIt().info("You forgot to eat your corn flakes")

Run a command with streaming realtime stdout

There are a couple of zrun recipies to consider...

  1. Run three pings and see output in realtime.
  • realtime=True allows you to watch individual pings as they happen...
  • add all stdout to a list
from z2.process import zrun

## Call z2.process.zrun()...
## - Watch individual pings as they happen... like you ran it in bash / zsh / ??
## - add all output to a list
output = list(zrun("ping -c3 172.16.1.1", print_stdout=True, realtime=True))

print(output)
  1. Run non-stop pings and act on individual pings.
  • realtime=True allows you to watch individual pings as they happen...
  • add all stdout to a list
from datetime import datetime
import errno

from z2.process import zrun

def act_on_ping(condition=None, now=datetime.now()):
    assert isinstance(condition, str)

    if condition=="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 list

for ii in zrun("ping -c5 -O 172.16.1.1", print_stdout=True, realtime=True):

    if isinstance(ii, str):
        output.append(ii)

    if isinstance(ii, str) and "no answer" in ii.lower():
        # Lost a ping -> "no answer yet for icmp_seq=1"
        #     do something here
        act_on_ping(condition="ping_timeout")

    elif isinstance(ii, int) and ii==errno.EWOULDBLOCK:
        # This is normal while waiting on ping stdout...
        print("    errno.EWOULDBLOCK")
        pass

print(output)

Run a command with blocked stdout

  1. Run three pings with blocked stdout
  • realtime=False blocks stdout
  • results are returned in a list()
from z2.process import zrun

## Call z2.process.zrun()...
## - stdout is blocked during cmd execution
## - return all output as a list of strings
output = list(zrun("ping -c3 172.16.1.1", print_stdout=True, realtime=False))

print(output)

getchar() - Get a single character from user input

getchar() is a function to read a single letter from stdin and return it.

from z2.strings import getchar

input_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 Color

from z2.strings import C

# Print with green, orange
print(C.GREEN + "Hello" + C.YELLOW + " World" + C.ENDC)

Handle network interface addresses

Most 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, and IPv4Network() does not store "host-bits". Consider the following:

>>> # IPv4Address() and IPv4Network() are from python stdlib.
>>> from ipaddress import IPv4Address, IPv4Network
>>> intfAddr = IPv4Address("1.1.1.200/24")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/python37/lib/python3.7/ipaddress.py", line 1300, in __init__
    raise AddressValueError("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 (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/python37/lib/python3.7/ipaddress.py", line 1536, in __init__
    raise ValueError('%s has host bits set' % self)
ValueError: 1.1.1.200/24 has host bits set
>>> intfAddr = IPv4Network("1.1.1.200/24", strict=False)
>>> intfAddr
IPv4Network('1.1.1.0/24')
>>> ### Above ^^^^^^ we see that IPv4Network() strips .200 from the
>>> ### address.

Keeping the interface address and mask is supported out of the box with
z2.IPv4Obj(). See below...

>>> from z2 import IPv4Obj
>>> intfAddr = IPv4Obj("1.1.1.200/24")
>>>
>>> intfAddr
<IPv4Obj 1.1.1.200/24>
>>>

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

z2-0.0.30.tar.gz (13.6 kB view hashes)

Uploaded Source

Built Distribution

z2-0.0.30-py3-none-any.whl (13.0 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page