hio.core.memo.memoing

hio.core.memoing Module

Mixin Base Classes that add support for memograms over datagram based transports. In this context, a memo made is a larger message that is partitioned into smaller memograms parts that fit into transport specific datagrams. This allows larger messages (memos) to be transported over datagram transports which messages are larger than a single datagram in the underlying transport.

Module Contents

class hio.core.memo.memoing.MemoGramCodex

MemoGramCodex is codex of all varieties of MemoGram Hard Codes. Only provide defined codes. Undefined are left out so that inclusion(exclusion) via ‘in’ operator works.

class hio.core.memo.memoing.ZeroGramCodex

GramCodex is codex of all Zero Gram Hard Codes. Only provide defined codes. Undefined are left out so that inclusion(exclusion) via ‘in’ operator works.

class hio.core.memo.memoing.GramCodex

GramCodex is codex of all Non-Zero Gram Hard Codes. Only provide defined codes. Undefined are left out so that inclusion(exclusion) via ‘in’ operator works.

class hio.core.memo.memoing.AuthGramCodex

AuthGramCodex is codex of all AuthGram (authenticated signed) Hard Codes. Only provide defined codes. Undefined are left out so that inclusion(exclusion) via ‘in’ operator works.

class hio.core.memo.memoing.AckCodex

AckCodex is codex of all Ack Hard Codes. Only provide defined codes. Undefined are left out so that inclusion(exclusion) via ‘in’ operator works.

class hio.core.memo.memoing.Memoer(*, tymeout=None, name=None, bc=None, bs=None, version=None, rxgs=None, sources=None, counts=None, vids=None, rxms=None, txms=None, txgs=None, txbs=None, code=MemoDex.GramZero, curt=False, size=None, authic=False, echoic=False, keep=None, vid=None, **kwa)

Bases: hio.base.tyming.Tymee

Memoer base class subclass of Tymee that adds memogram support to a transport class.

Memoer supports memos composed of asynchronous memograms. Provides common methods for subclasses.

A memogram is a higher level construct that sits on top of a datagram transport. A memogram supports the segmentation and desegmentation of memos to respect the underlying datagram size, buffer, and fragmentation behavior.

When indicated a memoer provides reliable delivery over unreliable datagram transports using retry tymers and acknowldged services.

Layering a reliable transaction protocol for memos on top of a memogram transport enables reliable asynchronous messaging over unreliable datagram transport protocols.

When the datagram protocol is already reliable, then a memogram transport enables larger memos (messages) than that natively supported by the datagram.

Usage:

Do not instantiate directly but use as a mixin with a transport class
in order to create a new subclass that adds memogram support to the
datagram transport class. For example MemoerUdp or MemoerUxd

When using non-blocking IO, asynchronous datagram transport protocols may have hidden buffering constraints that result in fragmentation of the sent datagram which means the whole datagram is not sent at once via a non-blocking send call. This means that the remainder of the datagram must be sent later and may take multiple send calls to complete. The datagram protocol is responsible for managing the buffering and fragmentation but depends on the sender repeated attempts to send the remainder of the full datagram. This is ensured with the final tier with a raw transmit buffer that waits until it is empty before attempting to send another gram. Because sending to different destinations may fail for different reasons such as bad addresses or bad routing each destination gets its own buffer so that a bad destination does not block other destinations.

Memo partition/departition information is embedded in the grams.

When grams are signed, the signature is computed on the over the wire serialization of the header (qb2 or qb64). This is more efficient and since gram headers will be stripped and discarded there is no need to archive them. The encapsulated unpartitioned memogram with its signature it what is meant for archival not the partitioned gram and per gram signature.

Each direction of dataflow uses a tiered set of buffers that respect the constraints of non-blocking asynchronous IO with datagram transports.

Transmit Flow::

memo to .txms deque -> .rend -> grams to .txgs deque -> .send to .txbs

On the transmit side memos are placed in a memo deque (double ended queue). Each memo is then segmented into grams (memograms) that respect the size constraints of the underlying datagram transport. These grams are placed in the outgoing gram deque. Each entry in this deque is a duple of form: (gram: bytes, dst: str). Each duple is pulled off the self._serviceOneRxMemo()deque and its gram is put in bytearray for transport.

Receive Flow::

.receive -> (gram, src) -> grams parsed to .rxgs .counts .vids .sources -> signing key pair sigkey and verifier key ->

.fuse -> memo .rxms deque

On the receive side each complete memogram (gram) is put in a gram receive deque as a memogram (datagram sized) segment of a memo. These deques are indexed by the sender’s source addr. The grams in the gram receive deque are then desegmented into a memo and placed in the memo deque for consumption by the application or some other higher level protocol.

Inherited Class Attributes:

MaxGramSize (int): absolute max gram size on tx with overhead, override
                   in subclass

Class Attributes:

Version (Versionage): default version consisting of namedtuple of form
    (major: int, minor: int)
Codex (GramDex): dataclass ref to gram codex
Codes (dict): maps codex names to codex values
Names (dict): maps codex values to codex names
Sodex (SGDex): dataclass ref to signed gram codex
Sizes (dict): gram head part sizes Sizage instances keyed by gram codes
MaxMemoSize (int): absolute max memo size
MaxGramCount (int): absolute max gram count
BufSize (int): used to set default buffer size for transport datagram buffers
Tymeout (float): default timeout for retry tymer(s) if any

Stubbed Attributes:

name (str):  unique name for Memoer transport.
             Used to manage multiple instances.
opened (bool):  True means transport open for use
                False otherwise
bc (int or None): count of transport buffers of MaxGramSize
bs (int or None): buffer size of transport buffers. When .bc is provided
        then .bs is calculated by multiplying, .bs = .bc * .MaxGramSize.
        When .bc is not provided, then if .bs is provided use provided
        value else use default .BufSize

Stubbed Methods:

send(gram, dst, *, echoic=False) -> int  # send gram over transport to dst
receive(self, *, echoic=False) -> (bytes, str or tuple or None)  # receive gram

Attributes:

version (Versionage): version for this memoir instance consisting of
        namedtuple of form (major: int, minor: int)
rxgs (dict): keyed by mid (memoID) with value of dict where each
        value dict holds grams from memo keyed by gram number.
        Grams have been stripped of their headers.
        The mid appears in every gram from the same memo.
sources (dict): keyed by mid (memoID) that holds the src for the memo.
    This enables reattaching src to fused memo in rxms deque tuple.
counts (dict): keyed by mid (memoID) that holds the gram count from
    the first gram for the memo. This enables lookup of the gram count when
    fusing its grams.
vids (dict[mid: (vid or None)]): keyed by mid that holds the vid verifier
        ID str for the memo indexed by its mid (memoID). This enables
        reattaching the vid to memo when placing fused memo in rxms deque.
        vid is only present when signed header otherwise vid is None
rxms (deque): holding rx (receive) memo tuples desegmented from rxgs grams
        each entry in deque is tuple of form:
        (memo: str, src: str, vid: str) where:
        memo is fused memo, src is source addr, vid is verifier ID
txms (deque): holding tx (transmit) memo tuples to be segmented into
        txgs grams where each entry in deque is tuple of form
        (memo: str, dst: str, vid: str or None)
        memo is memo to be partitioned into gram
        dst is dst addr for grams
        vid is verifier id when gram is to be signed
            (authenticated) or None otherwise
txgs (deque): grams to transmit, each entry is duple of form:
        (gram: bytes, dst: str).
txbs (tuple): current transmisstion duple of form:
    (gram: bytearray, dst: str). gram bytearray may hold untransmitted
    portion when Encodesdatagram is not able to be sent all at once so can
    keep trying. Nothing to send indicated by (bytearray(), None)
    for (gram, dst)
echos (deque): holds echo receive duples for testing. Each duple of
               form: (gram: bytes, dst: str).
inbox (deque): holds final received complete memos for testing when not
               overridden in subclass to further process otherwise
tymeout (float): default timeout for retry tymer(s) if any
tymers (dict): keys are tid and values are Tymers for retry tymers for
               each inflight tx
Inherited Properties (Tymee)::
tyme (float or None): relative cycle time of associated Tymist which is

provided by calling .tymth function wrapper closure which is obtained from Tymist.tymen(). None means not assigned yet.

tymth (Callable or None): function wrapper closure returned by

Tymist.tymen() method. When .tymth is called it returns associated Tymist.tyme. Provides injected dependency on Tymist cycle tyme base. None means not assigned yet.

Properties::

code (bytes or None): gram code for gram header when rending for tx curt (bool): True means when rending for tx encode header in base2

False means when rending for tx encode header in base64

size (int): gram size when rending for tx.

first gram size = over head size + neck size + body size. other gram size = over head size + body size. Min gram body size is one. Gram size also limited by MaxGramSize and MaxGramCount relative to MaxMemoSize.

authic (bool): True means any rx grams must be signed.

False otherwise

echoic (bool): True means use .echos in .send and .receive to mock the

transport layer for testing and debugging. False means do not use .echos. Each entry in .echos is a duple of form:

(gram: bytes, src: str)

Default echo is duple that indicates nothing to receive of form (b’’, None). When False may be overridden by a method parameter.

keep (dict): labels are vids, values are Keyage instances

named tuple of signature key pair: sigkey = private signing key verkey = public verifying key Keyage = namedtuple(“Keyage”, “sigkey verkey”)

vid (str or None): own vid defaults used to lookup keys to sign on tx

Hidden:

_code (bytes or None): see size property
_curt (bool): see curt property
_size (int): see size property
_authic (bool): see authic property
_echoic (bool): see echoic property
_keep (dict): see keep property
_oid (str or None): see vid property
classmethod makeMID(code='0A')

Make new random memo ID (MID) as 24 char CESR encoded qb64 UUID

Returns::
mid (str): 24 char qb64 CESR encoded qualified base64 from 128 bit UUID

default CESR code ‘0A’ labeled Salt_128

Parameters::

code (str): CESR code for MID

property code

Property getter for ._code

Returns::

code (str): two char base64 gram code

property curt

Property getter for ._curt

Returns::
curt (bool): True means when rending for tx encode header in base2

False means when rending for tx encode header in base64

property size

Property getter for ._size, maximum gram size when rending for tx

Returns:

gram size when rending for tx.

Zeroth gram size = zeroth overhead + body. Non-Zeroth gram size = non-zeroth overhead + body. Min gram body size is one. Gram size also limited by MaxGramSize and MaxGramCount relative to MaxMemoSize.

Return type:

size (int)

property vid

Property getter for ._vid

Returns:

vid used to sign on tx if any

Return type:

vid (str or None)

property authic

Property getter for ._authic

Returns:

True means any rx grams must be signed; False otherwise.

Return type:

bool

property echoic

Property getter for ._echoic

Returns:

True means use .echos in .send and .receive to mock the

transport layer for testing and debugging; False means do not use .echos. Each entry in .echos is a duple of form (gram: bytes, src: str). Default echo is a duple that indicates nothing to receive of form (b’’, None).

Return type:

bool

property keep

Property getter for ._keep

Returns:

Mapping of vids to Keyage instances (sigkey, verkey).

Return type:

dict

open()

Opens transport in nonblocking mode

This is a stub. Override in transport specific subclass

reopen(**kwa)

Idempotently open transport

This is a stub. Override in transport specific subclass

close()

Closes transport

This is a stub. Override in transport subclass

wind(tymth)

Inject new tymist.tymth as new ._tymth. Changes tymist.tyme base. Updates winds .tymer .tymth

serviceTymers()

Service all retry tymers

Must be overriden in subclass. This is a stub.

wiffOld(gram)

Determines encoding of gram bytes header when parsing grams. The encoding maybe either base2 or base64.

Returns::
curt (bool): True means base2 encoding

False means base64 encoding Otherwise raises hioing.MemoerError

All gram head codes start with ‘_’ in base64 text or in base2 binary. Given only allowed chars are from the set of base64 then can determine if header is in base64 or base2.

First sextet: (0b is binary, 0o is octal, 0x is hexadecimal)

0o27 = 0b010111 means first sextet of ‘_’ in base64 0o77 = 0b111111 means first sextet of ‘_’ in base2

Assuming that only ‘_’ is allowed as the first char of a valid gram head, in either Base64 or Base2 encoding, a parser can unambiguously determine if the gram header encoding is binary Base2 or text Base64 because 0o27 != 0o77.

Furthermore, it just so happens that 0o27 is a unique first sextet among Base64 ascii chars. So an invalid gram header when in Base64 encoding is detectable. However, there is one collision (see below) with invalid gram headers in Base2 encoding. So an erroneously constructed gram might not be detected merely by looking at the first sextet. Therefore unreliable transports must provide some additional mechanism such as a hash or signature on the gram.

All Base2 codes for Base64 chars are unique since the B2 codes are just the count from 0 to 63. There is one collision, however, between Base2 and Base 64 for invalid gram headers. This is because 0o27 is the base2 code for ascii ‘X’. This means that Base2 encodings that begin with 0o27 which is the Base2 encoding of the ascii ‘X’, would be incorrectly detected as text not binary.

wiff(gram)

Determines encoding of gram bytes header when parsing grams. The encoding maybe either base2 or base64.

Returns::
curt (bool): True means base2 encoding

False means base64 encoding Otherwise raises hioing.MemoerError

All gram head codes start with ‘1’ in base64 text or in base2 binary. Given only allowed chars are from the set of base64 then can determine if header is in base64 or base2.

1AAQ, 1AAR, 1AAS, 1AAT, 1AAU, 1AAV, 1AAW, 1AAX, 1AAY, 1AAZ

First sextet: 0b is binary, 0o is octal 2 octal digits or 6 bits

0x is hexadecimal 1 sextet is 1.5 hex digits or octets

0o14 = 0b001100 means first sextet of ‘1’ in base64 (0b00110001) 0o65 = 0b110101 means first sextet of ‘1’ in base2 (0b110101)

Assuming that only ‘1’ is allowed as the first char of a valid gram head, in either Base64 or Base2 encoding, a parser can unambiguously determine if the gram header encoding is binary Base2 or text Base64 because 0o14 != 0o65.

The sextet 0o14 is not a unique first sextet among Base64 ascii chars. It is shared with the ascii chars ‘0’, ‘1’, ‘2’, ‘3’. So an invalidly encoded gram header when in Base64 encoding is not fully detectable unless the full first octet (8bits) is examined. But an invalid gram header could have any of the following sextets also encoded invalidly. Thise means that in general some other mechanism is required to detect and invalidly encoded gram header. Therefore some additional tamper evident mechanism such as a digest or signature is required to detect and invalidly encoded gram header. But all we really need wiff to do is to detect if a validly encoded gram header is encoded in Base64 or Base2 and merely examining the first sextet is enough to unambiguously make that determination.

In addition there is one collision (see below) with invalid gram headers in Base2 encoding. So an erroneously constructed gram might not be detected merely by looking at the first sextet.

All Base2 codes for Base64 chars are unique since the B2 codes are just the count from 0 to 63. There is one collision, however, between Base2 and Base 64 for the first sextet of an invalid gram header. This is because 0o14 is the base2 code for ascii ‘M’. This means that invalid Base2 encoded gram headers that begin with 0o14 (the Base2 encoding of the ascii ‘M’) would be incorrectly detected by wiff as text not binary.

verify(vid, sig, ser)

Verify signature sig on signed part of gram, ser, using current verkey for vid.

Verify the signature on the header as per the serialized header format given by the header code as either qb2 or qb64. Do not convert qb2 to qb64 or vice versa.

Allowed Codes: (CESR compatible)

Ed25519_Sig: str = ‘0B’ # Ed25519 signature. not indexed

Returns:

True if signature verifies

Raises MemoerVerifyError otherwise

Return type:

result (bool)

Parameters:
  • vid (bytes or str) – qualified base64 qb64b of verifier ID

  • sig (bytes or str) – qualified base64 qb64b signature

  • ser (bytes or str) – serialization to be signed

pick(gram)

Strips header from gram bytearray leaving only gram body in gram and returns (mid, gn, gc). Raises MemoerError if unrecognized or invalid header this includes signature verification failure when signed.

When signed the signature is computed on the body of the gram as is when gramified for transmission whether the body be in domain qb64b or qb2. The body is assumed to always be in the raw domain ser when signed. The header and signature parts are converted to raw from base2 or base64

Note the full packet itself is not concatenation composable (does not align on 24 bit boundary) as per CESR. Only the header elements and sig are CESR 24 bit aligned so there is no enmass conversion possible of concatenated memograms. This is ok for a datagram segmentation that is decidedly not a stream.

Returns:

tuple of form:

(mid: str, vid: str, gn: int, gc: int or None) where: mid is fully qualified memoID, vid is verifier ID used to look up signature verification key, gn is gram number, gc is gram count. When first gram (zeroth) returns (mid, vid, 0, gc). When other gram returns (mid, vid, gn, None) When code has empty vid then vid is None Otherwise raises MemoerError error.

Return type:

result (tuple)

When valid recognized header, strips header bytes from front of gram leaving the gram body part bytearray.

Parameters:

gram (bytearray) – memo gram from which to parse and strip its header.

pickOld(gram)

Strips header from gram bytearray leaving only gram body in gram and returns (mid, gn, gc). Raises MemoerError if unrecognized or invalid header this includes signature verification failure when signed.

When signed the signature is computed on the domain qb64b or qb2 that the packet is transmitted in. Note the packet itself is not concatenation composable as per CESR only the header elements and sig are CESR 24 bit aligned so there is no enmass conversion of concatenated memograms. This is ok for a datagram segmentation that is decidedly not a stream.

Returns:

tuple of form:

(mid: str, vid: str, gn: int, gc: int or None) where: mid is fully qualified memoID, vid is verifier ID used to look up signature verification key, gn is gram number, gc is gram count. When first gram (zeroth) returns (mid, vid, 0, gc). When other gram returns (mid, vid, gn, None) When code has empty vid then vid is None Otherwise raises MemoerError error.

Return type:

result (tuple)

When valid recognized header, strips header bytes from front of gram leaving the gram body part bytearray.

Parameters:

gram (bytearray) – memo gram from which to parse and strip its header.

receive(*, echoic=False)

Attempts to receive bytes from remote source.

May use echoic=True and .echos to mock a transport layer for testing Puts sent gram into .echos so that .receive can extract it when using same Memoer to send and receive to itself via its own .echos When using different Memoers each for send and receive then must manually copy from sender Memoer .echos to Receiver Memoer .echos

Must be overridden in subclass. This is a stub to define mixin interface.

Parameters:

echoic (bool) – True means use .echos in .send and .receive to mock the transport layer for testing and debugging; False means do not use .echos. Each entry in .echos is a duple of form (gram: bytes, src: str). Default echo is a duple that indicates nothing to receive of form (b’’, None).

Returns:

(data: bytes, src: str or tuple or None) where data is the bytes

of received data and src is the source address. When no data the duple is (b’’, None) unless echoic is True, then pop off echo from .echos.

Return type:

tuple

serviceReceivesOnce(*, echoic=False)

Service receives once (non-greedy) and queue up

Parameters:

echoic (bool) –

True means use .echos in .receive debugging purposes

where echo is duple of form: (gram: bytes, src: str)

False means do not use .echos default is duple that

indicates nothing to receive of form (b’’, None)

serviceReceives(*, echoic=False)

Service all receives (greedy) and queue up

Parameters:

echoic (bool) –

True means use .echos in .receive debugging purposes

where echo is duple of form: (gram: bytes, src: str)

False means do not use .echos default is duple that

indicates nothing to receive of form (b’’, None)

fuse(grams, cnt)

Fuse cnt gram body parts from grams dict into whole memo . If any grams are missing then returns None.

Returns:

fused memo or None if incomplete.

Return type:

memo (str or None)

Override in subclass

Parameters:
  • grams (dict) – memo gram body parts each keyed by gram number from which to fuse memo. Headers have been stripped.

  • cnt (int) – gram count for mid

serviceRxGramsOnce()

Service one pass (non-greedy) over all unique sources in .rxgs dict if any for received incoming grams.

serviceRxGrams()

Service one pass (non-greedy) over all unique sources in .rxgs dict if any for received incoming grams. No different from serviceRxGramsOnce because service all mids each pass.

serviceRxMemosOnce()

Service memos in .rxms deque once (non-greedy one memo) if any

Override in subclass to handle result and put it somewhere

serviceRxMemos()

Service all memos in .rxms (greedy) if any

Override in subclass to handle result(s) and put them somewhere

serviceAllRxOnce()

Service receive side of stack once (non-greedy)

serviceAllRx()

Service receive side of stack (greedy) until empty or waiting for more

memoit(memo, dst, vid=None)

Append (memo, dst, vid) tuple to .txms deque

Parameters:
  • memo (str) – to be segmented and packed into gram(s)

  • dst (str) – address of remote destination of memo

  • vid (str or None) – verifier ID for verifying signature on grams

sign(vid, ser)

Sign serialization ser using private sigkey for verifier ID vid and return signature in serialized format defined by .curt

Sign the serialized signed part of gram given by ser. Assumes that the header in ser is in qb2 or qb64 as defined by .curt

Allowed Codes for sigseed:

Ed25519_Seed:str = ‘A’ # Ed25519 256 bit random seed for private key

Returns:

qb64b or qb2 when .curt

if not .curt then qualified base64 of signature else if .curt then qualified base2 of signature raises MemoerError if problem signing

Return type:

sig (bytes)

Parameters:
  • vid (bytes or str) – qb64 or qb2 if .curt of vid of signer assumes vid of correct length

  • ser (bytes or str) – serialization to be signed (usually qb64 or qb64b)

rend(memo, vid=None)

Partition memo into packed grams with headers.

Returns:

list of grams with headers.

Return type:

grams (list[bytes])

Parameters:
  • memo (str) – to be partitioned into grams with headers

  • vid (str or None) – verifier ID when gram is to be signed, used to lookup sigkey to sign. None means not signable

Note zeroth gram has head + neck overhead, zhz = oz + nz

so bz that fits is smaller by nz relative to non-zeroth non-zeroth grams just head overhead oz so bz that fits is bigger by nz relative to zeroth

send(gram, dst, *, echoic=False) int

Attempts to send bytes in txbs to remote destination dst.

May use echoic=True and .echos to mock a transport layer for testing Puts sent gram into .echos so that .receive can extract it when using same Memoer to send and receive to itself via its own .echos When using different Memoers each for send and receive then must manually copy from sender Memoer .echos to Receiver Memoer .echos

Must be overridden in subclass. This is a stub to define mixin interface.

Returns:

bytes actually sent

Return type:

count (int)

Parameters:
  • gram (bytearray) – of bytes to send

  • dst (str) – remote destination address

  • echoic (bool) – True means use .echos in .send and .receive to mock the transport layer for testing and debugging; False means do not use .echos. Each entry in .echos is a duple of form (gram: bytes, src: str). Default echo is a duple that indicates nothing to receive of form (b’’, None).

serviceTxMemosOnce()

Service one outgoing memo from .txms deque if any (non-greedy)

serviceTxMemos()

Service all outgoing memos in .txms deque if any (greedy)

gramit(gram, dst)

Append (gram, dst) duple to .txgs deque. Utility method for testing.

Parameters:
  • gram (bytes) – gram to be sent

  • dst (str) – address of remote destination of gram

serviceTxGramsOnce(*, echoic=False)

Service one pass (non-greedy) over all unique destinations in .txgs dict if any for blocked destination or unblocked with pending outgoing grams.

Parameters:

echoic (bool) – True means echo sends into receives via. echos False measn do not echo

serviceTxGrams(*, echoic=False)

Service multiple passes (greedy) over all unqique destinations in .txgs dict if any for blocked destinations or unblocked with pending outgoing grams until there is no unblocked destination with a pending gram.

Parameters:

echoic (bool) – True means echo sends into receives via. echos False measn do not echo

serviceAllTxOnce()

Service the transmit side once (non-greedy) one transmission.

serviceAllTx()

Service the transmit side until empty (greedy) multiple transmissions until blocked by pending transmission on transport.

serviceLocal()

Service the local Peer’s receive and transmit queues

serviceAllOnce()

Service all Rx and Tx Once (non-greedy)

serviceAll()

Service all Rx and Tx (greedy)

hio.core.memo.memoing.openMemoer(cls=None, name='test', **kwa)

Wrapper to create and open Memoer instances When used in with statement block, calls .close() on exit of with block

Parameters:
  • cls (Class) – instance of subclass instance

  • name (str) – unique identifier of Memoer peer. Enables management of transport by name.

Usage:

with openMemoer() as peer:
    peer.receive()

with openMemoer(cls=MemoerSub) as peer:
    peer.receive()
class hio.core.memo.memoing.MemoerDoer(peer, **kwa)

Bases: hio.base.doing.Doer

Memoer Doer for both reliable and unreliable transports. Doer is a subclass of Tymee and is wound.

Reliable do not require retry tymers Unreliable require retry tymers for acknowldged services.

See Doer for inherited attributes, properties, and methods.

Attributes:

.peer (Memoer): underlying transport instance subclass of Memoer
wind(tymth)

Inject new tymist.tymth as new ._tymth. Changes tymist.tyme base. Updates winds .tymer .tymth

enter(*, temp=None)

Do ‘enter’ context actions. Override in subclass. Not a generator method. Set up resources. Comparable to context manager enter.

Parameters:

temp (bool or None) – True means use temporary file resources if any None means ignore parameter value. Use self.temp

Inject temp or self.temp into file resources here if any

Doist or DoDoer winds its doers on enter

recur(tyme)

Run one service cycle for the peer.

exit()

Do ‘exit’ context actions. Override in subclass. Not a generator method. Clean up resources. Comparable to context manager exit. Called by finally after normal return, close, or abort. After .exit() do returns resulting in StopIteration.

class hio.core.memo.memoing.AuthMemoer(*, code=MemoDex.GramAuthZero, authic=True, **kwa)

Bases: Memoer

AuthMemoer mixin base class that enforces authenticated memo delivery.

Subclass of Tymee and Memoer

Inherited Class Attributes (Memoer):

Version (Versionage): default version consisting of namedtuple of form
    (major: int, minor: int)
Codex (GramDex): dataclass ref to gram codex
Codes (dict): maps codex names to codex values
Names (dict): maps codex values to codex names
Sodex (SGDex): dataclass ref to signed gram codex
Sizes (dict): gram head part sizes Sizage instances keyed by gram codes
MaxMemoSize (int): absolute max memo size
MaxGramCount (int): absolute max gram count
BufSize (int): used to set default buffer size for transport datagram buffers
Tymeout (float): default timeout for retry tymer(s) if any

Inherited Stubbed Attributes (Memoer):

name (str):  unique name for Memoer transport.
             Used to manage multiple instances.
opened (bool):  True means transport open for use
                False otherwise
bc (int or None): count of transport buffers of MaxGramSize
bs (int or None): buffer size of transport buffers. When .bc is provided
        then .bs is calculated by multiplying, .bs = .bc * .MaxGramSize.
        When .bc is not provided, then if .bs is provided use provided
        value else use default .BufSize

Inherited Stubbed Methods (Memoer):

send(gram, dst, *, echoic=False) -> int  # send gram over transport to dst
receive(self, *, echoic=False) -> (bytes, str or tuple or None)  # receive gram

Inherited Attributes (Memoer):

version (Versionage): version for this memoir instance consisting of
        namedtuple of form (major: int, minor: int)
rxgs (dict): keyed by mid (memoID) with value of dict where each
        value dict holds grams from memo keyed by gram number.
        Grams have been stripped of their headers.
        The mid appears in every gram from the same memo.
sources (dict): keyed by mid (memoID) that holds the src for the memo.
    This enables reattaching src to fused memo in rxms deque tuple.
counts (dict): keyed by mid (memoID) that holds the gram count from
    the first gram for the memo. This enables lookup of the gram count when
    fusing its grams.
vids (dict[mid: (vid or None)]): keyed by mid that holds the verifier ID str for
        the memo indexed by its mid (memoID). This enables reattaching
        the vid to memo when placing fused memo in rxms deque.
        Vid is only present when signed header otherwise vid is None
rxms (deque): holding rx (receive) memo tuples desegmented from rxgs grams
        each entry in deque is tuple of form:
        (memo: str, src: str, vid: str) where:
        memo is fused memo, src is source addr, vid is verifier ID
txms (deque): holding tx (transmit) memo tuples to be segmented into
        txgs grams where each entry in deque is tuple of form
        (memo: str, dst: str, vid: str or None)
        memo is memo to be partitioned into gram
        dst is dst addr for grams
        vid is verifier id when gram is to be signed or None otherwise
txgs (deque): grams to transmit, each entry is duple of form:
        (gram: bytes, dst: str).
txbs (tuple): current transmisstion duple of form:
    (gram: bytearray, dst: str). gram bytearray may hold untransmitted
    portion when Encodesdatagram is not able to be sent all at once so can
    keep trying. Nothing to send indicated by (bytearray(), None)
    for (gram, dst)
echos (deque): holding echo receive duples for testing. Each duple of
               form: (gram: bytes, dst: str).
tymeout (float): default timeout for retry tymer(s) if any
tymers (dict): keys are tid and values are Tymers for retry tymers for
               each inflight tx

Inherited Properties (Tymee):

tyme (float or None):  relative cycle time of associated Tymist which is
    provided by calling .tymth function wrapper closure which is obtained
    from Tymist.tymen().
    None means not assigned yet.
tymth (Callable or None): function wrapper closure returned by
    Tymist.tymen() method. When .tymth is called it returns associated
    Tymist.tyme. Provides injected dependency on Tymist cycle tyme base.
    None means not assigned yet.

Inherited Properties (Memoer):

code (bytes or None): gram code for gram header when rending for tx
curt (bool): True means when rending for tx encode header in base2
             False means when rending for tx encode header in base64
size (int): gram size when rending for tx.
    first gram size = over head size + neck size + body size.
    other gram size = over head size + body size.
    Min gram body size is one.
    Gram size also limited by MaxGramSize and MaxGramCount relative to
    MaxMemoSize.
authic (bool): True means any rx grams must be signed.
                False otherwise
echoic (bool): True means use .echos in .send and .receive to mock the
                    transport layer for testing and debugging.
               False means do not use .echos
               Each entry in .echos is a duple of form:
                   (gram: bytes, src: str)
               Default echo is duple that
                   indicates nothing to receive of form (b'', None)
               When False may be overridden by a method parameter
keep (dict): labels are vids, values are Keyage instances
                 named tuple of signature key pair:
                 sigkey = private signing key
                 verkey = public verifying key
                Keyage = namedtuple("Keyage", "sigkey verkey")
vid (str or None): own vid defaults used to lookup keys to sign on tx
hio.core.memo.memoing.openAM(cls=None, name='test', **kwa)

Wrapper to create and open SureMemoer instances When used in with statement block, calls .close() on exit of with block

Parameters:
  • cls (Class) – instance of subclass instance

  • name (str) – unique identifier of Memoer peer. Enables management of transport by name.

Usage:

with openAM() as peer:
    peer.receive()

with openAM(cls=SureMemoerSub) as peer:
    peer.receive()
class hio.core.memo.memoing.AuthMemoerDoer(peer, **kwa)

Bases: hio.base.doing.Doer

AuthMemoerDoer Doer to ensure authenticated/signed memograms. For both reliable and unreliable transports. Reliable do not require retry tymers Unreliable require retry tymers for acknowldged services.

See Doer for inherited attributes, properties, and methods. Doer is a subclass of Tymee and is wound.

Attributes:

.peer (AuthMemoer) is underlying transport instance subclass of AuthMemoer
wind(tymth)

Inject new tymist.tymth as new ._tymth. Changes tymist.tyme base. Updates winds .tymer .tymth

enter(*, temp=None)

Do ‘enter’ context actions. Override in subclass. Not a generator method. Set up resources. Comparable to context manager enter.

Parameters:

temp (bool or None) – True means use temporary file resources if any None means ignore parameter value. Use self.temp

Inject temp or self.temp into file resources here if any

Doist or DoDoer winds its doers on enter

recur(tyme)

Run one service cycle for the peer.

exit()

Do ‘exit’ context actions. Override in subclass. Not a generator method. Clean up resources. Comparable to context manager exit. Called by finally after normal return, close, or abort. After .exit() do returns resulting in StopIteration.