Classes And Functions

Reference information for the significant classes, methods and functions in the library, appears here.

Application Startup

layer_cake.object_startup.create(object_type, object_table=None, environment_variables=None, sticky: bool = False, strict: bool = True)

Creates an async process shim around a “main” async object. Returns nothing.

Parameters:
  • object_type (object type) – type of object to be instantiated

  • object_table (a list of registered functions) – sub-commmands accepted by this object type

  • environment_variables (message) – container of values to be extracted from environment

  • sticky – object requires persistent storage

  • strict – object requires all args to match

Portable Type System

class layer_cake.message_memory.Portable

Base for all portables.

This is the type that is combined with Word to implement the Any concept.

class layer_cake.message_memory.Boolean

True or false.

class layer_cake.message_memory.Integer8

An 8-byte, signed integer.

class layer_cake.message_memory.Float8

An 8-byte, floating point number.

class layer_cake.message_memory.Byte

The smallest unit of data - 8 bit, unsigned integer.

class layer_cake.message_memory.Character

A byte that more often than not, contains a printable ASCII character.

class layer_cake.message_memory.Rune

A Unicode codepoint.

class layer_cake.message_memory.String

A sequence of Character.

class layer_cake.message_memory.Unicode

A sequence of Rune.

class layer_cake.message_memory.Block

A sequence of Byte.

class layer_cake.message_memory.Enumeration(element)

Names for integers.

class layer_cake.message_memory.ClockTime

The time on the wall clock as an epoch value; a float.

class layer_cake.message_memory.TimeSpan

Difference between two ClockTime values; a float.

class layer_cake.message_memory.WorldTime

The time at the Greenwich meridian; a datetime object.

class layer_cake.message_memory.TimeDelta

Difference between two WorldTime values; a timedelta object.

class layer_cake.message_memory.UUID

An RFC 4122 UUID (random); a uuid.UUID object.

class layer_cake.message_memory.UserDefined(element)

A function, message class or enum class.

Parameters:

element (object type) – Python reference

class layer_cake.message_memory.ArrayOf(element: Portable, size: int)

A fixed-length sequence of elements.

Parameters:
  • element – type of the content.

  • size – fixed size.

class layer_cake.message_memory.VectorOf(element: Portable)

A variable-length sequence of elements.

Parameters:

element – type of the content.

class layer_cake.message_memory.DequeOf(element: Portable)

A double-ended sequence of elements.

Parameters:

element – type of the content.

class layer_cake.message_memory.SetOf(element: Portable)

A collection of unique elements.

Parameters:

element – type of the content, a hash-able value.

class layer_cake.message_memory.MapOf(key: Portable, value: Portable)

A map of unique, key-value pairs.

Parameters:
  • key – type of the key, a hash-able value.

  • value – type of the content.

class layer_cake.message_memory.Type

The unique, portable identity of a registered class or function.

Transfer a function or class across a network connection. The matching name must exist in the receiver or a TypeNotBound is created.

class layer_cake.message_memory.Word

An intermediate form of application data.

This is a transformation of application into a generic form before it is presented for encoding and it is the generic form that results from a decoding, e.g. a dict has no representation in JSON and is converted into a list of pairs.

class layer_cake.message_memory.Any

The combination of a Portable and a Word.

A portable representation of any registered type (see bind() and def_type()). Suitable for passing across a network connection or storing in a file.

Further information can be found here.

class layer_cake.message_memory.Address

A runtime-generated, layer-cake address.

The unique identity of an asynchronous object, usually obtained from a call to create(). These are the values that can be passed as a destination to functions such as send().

Further information can be found here.

class layer_cake.message_memory.PointerTo(element: Portable)

An instance of an object that may be appear in multiple places.

These are instances of data that are tracked by their Python id. When they are encoded for the purposes of networking or saving as a file, multiple appearances of the same id are collapsed into one actual data item and multiple references. This process is reversed during decoding, allowing the passing of graphs (linked lists, trees and networks) across network connections. Circular references are properly handled, pointer-to-pointer is not.

class layer_cake.message_memory.Incognito(type_name: str = None, decoded_word: Word = None, saved_pointers=None, address_book=None)

A class that holds the recovered materials of an unregistered message.

Parameters:
  • type_name – portable identity of the associated word

  • decoded_word – parsed but unmarshaled object

  • saved_pointers (internal) – table of Pointer values

  • address_book (internal) – table of Address values

Message And Registration

layer_cake.bind_type.bind(object_type, *args, **kw_args)

Forwards all arguments on to a custom bind function according to the type of the first argument.

Parameters:
  • object_type (object type) – type of async entity

  • args (tuple) – arguments passed to special bind function

  • kw_args (dict) – named arguments passed to special bind function

layer_cake.bind_type.bind_point(point: Point, return_type=None, entry_point: list = None, thread: str = None, lifecycle: bool = True, message_trail: bool = True, execution_trace: bool = True, user_logs: USER_LOG = USER_LOG.DEBUG, **explicit_schema)

Set the type information and runtime controls for the asynchronous object.

Values assigned in this function affect the behaviour for all instances of the given type.

Parameters:
  • point – instance of an asynchronous object

  • return_type (tip) – type expression for the return value

  • lifecycle – enable log when object is created or destroyed

  • message_trail – enable log when message is sent

  • execution_trace – enable log when message is received

  • user_logs – the logging level for this object type

layer_cake.bind_type.bind_routine(routine, return_type=None, entry_point: list = None, lifecycle: bool = True, message_trail: bool = True, execution_trace: bool = True, user_logs: USER_LOG = USER_LOG.DEBUG, **explicit_schema)

Set the type information and runtime controls for the function.

Values assigned in this function affect the behaviour for all instances of the given type.

Parameters:
  • routine (object type) – function to be registered as a routine

  • return_type (tip) – type expression for the return value

  • entry_point – enable library loading with list of expected messages

  • lifecycle – enable log at creation, ending…

  • message_trail – enable log when message is sent

  • execution_trace – enable log when message is received

  • user_logs – the logging level for this message type

layer_cake.bind_type.bind_stateless(machine: Stateless, dispatch: tuple, return_type=None, entry_point: list = None, **explicit_schema)

Set the type information and runtime controls for the non-FSM machine.

Values assigned in this function affect the behaviour for all instances of the given type.

Parameters:
  • machine – class to be registered as a machine

  • dispatch – list of expected messages

  • return_type (tip) – type expression for the return value

  • entry_point – enable library loading with list of expected messages

layer_cake.bind_type.bind_statemachine(machine: StateMachine, dispatch: dict, return_type=None, entry_point: list = None, **explicit_schema)

Set the type information and runtime controls for the FSM machine.

Values assigned in this function affect the behaviour for all instances of the given type.

The dispatch is a description of states, expected messages and messages that deserve saving:

dispatch = {
    STATE_1: (Start, ()),
    STATE_2: ((Job, Pause, UnPause, Stop), (Check,)),
    STATE_3: ((Stop, ()),
}

Consider STATE_2; The machine will accept 4 messages and will save an additional message, Check.

Parameters:
  • machine – class to be registered as a machine

  • dispatch – table of current state and expected messages

  • return_type (tip) – type expression for the return value

  • entry_point – enable library loading with list of expected messages

layer_cake.message_memory.bind_message(message, message_trail: bool = True, execution_trace: bool = True, copy_before_sending: bool = True, not_portable: bool = False, **object_schema)

Set the type information and runtime controls for the given message type.

Values assigned in this function affect the behaviour for all instances of the given type.

Parameters:
  • message (message) – class to be registered as a message

  • message_trail – enable log when message is sent

  • execution_trace – enable log when message is received

  • copy_before_sending – enable copying of message before each send

  • not_portable – disable serialization/transfer, e.g. of a file handle

  • object_schema – explicit type declarations by name

Return type:

None

class layer_cake.command_line.ScopeOfDirectory(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

Enumeration of the scopes within the layer-cake directory.

  • LAN - local area network

  • HOST - networking limited to 127.0.0.0

  • GROUP - a composite process

  • PROCESS - a single process

  • LIBRARY - dynamically loaded process

class layer_cake.command_line.ProcessOrigin(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

Enumeration of context in the chain of processes.

  • SHELL - running from the command-line

  • RUN - run an entry in a composite process

  • RUN_CHILD - run as a subprocess of a composite entry

  • START - background run, entry in a composite process

  • START_CHILD - background run, subprocess of a composite entry

class layer_cake.virtual_runtime.USER_LOG(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

Enumeration of the levels within the layer-cake logging.

  • NONE - no logs at all

  • FAULT - a definite problem that will compromise the service.

  • WARNING - something unexpected that may compromise the service.

  • CONSOLE - an operational milestone worthy of note.

  • OBJECT - asynchronous operation

  • TRACE - progress of the service, suitable for public viewing.

  • DEBUG - not suitable for customer or support.

class layer_cake.virtual_runtime.USER_TAG(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

Enumeration of the tags used to stamp each log entry.

  • CREATED + new object

  • DESTROYED X object gone

  • SENT > object sent a message

  • RECEIVED < object received a message

  • STARTED ( object started a subprocess

  • ENDED ) subprocess ended

  • FAULT ! compromised operation

  • WARNING ? may be compromised

  • CONSOLE ^ application milestone

  • TRACE ~ technical notes

  • DEBUG _ developer notes

  • SAMPLE & formal sample of local data

  • CHECK = assert a condition

class layer_cake.point_runtime.Start

Notification sent to new object, from parent.

class layer_cake.point_runtime.Returned(message: Any = None)

Notification sent to parent, from terminating object.

class layer_cake.point_runtime.Stop

Initiate termination in the receiving object.

class layer_cake.point_runtime.Pause

Suspend operation in the receiving object.

class layer_cake.point_runtime.Resume

Resume operation in the receiving object.

class layer_cake.point_runtime.Ready

Report a state of readiness.

class layer_cake.point_runtime.NotReady

Report that currently not ready.

class layer_cake.point_runtime.Ping

Test for reachability and presence.

class layer_cake.point_runtime.Enquiry

Prompt an action from receiver.

class layer_cake.point_runtime.Discover

Request for capabilities.

class layer_cake.point_runtime.Inspect

Request for operational status.

class layer_cake.point_runtime.Ack

Report in the positive.

class layer_cake.point_runtime.Nak

Report in the negative.

class layer_cake.point_runtime.Anything(thing=None)
class layer_cake.point_runtime.Faulted(condition: str = None, explanation: str = None, error_code: int = None, exit_status: int = None)

Generic error signal to interested party.

Parameters:
  • condition – description of fault

  • explanation – description of cause

  • error_code – internal error code

  • exit_status – recommended exit status

class layer_cake.point_runtime.Aborted

Asynchronous object received a Stop. Terminating.

Derived from Faulted.

class layer_cake.point_runtime.TimedOut(timer=None)

Asynchronous object received a timer message.

Derived from Faulted.

Parameters:

timer (object type) – timer that was exceeded

class layer_cake.point_runtime.TemporarilyUnavailable(text: str = None, unavailable: list[str] = None)

Temporarily unable to deliver normal service.

Derived from Faulted.

Parameters:
  • text – description of reason

  • unavailable – names of unavailable services

class layer_cake.point_runtime.Busy(condition: str = None, explanation: str = None)

Experiencing heavy load, recovery expected. Request is rejected.

Derived from Faulted.

Parameters:
  • condition – description of load

  • explanation – description of cause

class layer_cake.point_runtime.Overloaded(text: str = None)

Experiencing heavy load, recovery unknown. Request is rejected.

Derived from Faulted.

Parameters:

text – description of condition

class layer_cake.point_runtime.OutOfService(text: str = None)

Service not available until further notice. Request is rejected.

Derived from Faulted.

Parameters:

text – description of load

class layer_cake.point_runtime.ReForm(form: str = None, **entry)

Text forms based on re’s embedded in character decoration.

Form is expected as plain text with “{name}” fields. The fields are replaced with matching values from entry. The compile_form() method does all the prep. Returns a 2-tuple of compiled pattern and a list of the field names that can be extracted from a match.

e.g. ‘/{resource}(/{identity})?’, resource=’w+’…

Parameters:
  • form – the text form

  • entry – dict of named re’s

layer_cake.convert_type.def_type(hint_or_portable)

Register an application type. Return Portable.

Register a type for use within an application. Where necessary, convert Python hints into Portable equivalents.

Parameters:

hint_or_portable (tip) – a type description

layer_cake.convert_type.cast_to(value, p: Portable)

Accept Python value and type. Return a message.

For registered messages, this is a no-op. For constructed types it’s required for encoding/decoding to function properly.

Parameters:
  • value – the application value

  • p – portable representation of type

layer_cake.convert_type.cast_back(message: Any)

Accept the results of a cast_to() or network receive. Returns a 2-tuple.

Splits the message into an application value and a portable type.

Parameters:

message – class instance or constructed

Object Methods

class layer_cake.virtual_point.Point

The base class to all class-based asynchronous objects.

Methods of this class are the user entry-point for SDL primitives such as;

Point.create(object_type, *args, object_ending=<function returned_object>, **kw)

Create a new asynchronous object. Return the address.

Parameters:
  • object_type (object type) – type of object to instantiate

  • args – positional arguments passed to the new object

  • object_ending (function) – override standard termination

  • kw – named arguments passed to the new object

Return type:

Address

Point.send(message: Any, to: Address)

Transfer a message to the specified address.

Parameters:
  • message – message to be sent

  • to – intended receiver of the message

Point.reply(message: Any)

Send a response to the sender of the current message.

This is a shorthand for self.send(m, self.return_address). Reduces keystrokes and risk of typos.

Parameters:

message – the message to be sent

Point.forward(message: Any, to: Address, return_address: Address)

Send a message to an address, as if it came from a 3rd party.

Send a message but override the return address with the address of another arbitrary object. To the receiver the message appears to have come from the arbitrary object.

Useful when building relationships between objects. This allows objects to “drop out” of 3-way conversations, leaving simpler and faster 2-way conversations behind.

Parameters:
  • message – the message to be sent

  • to – intended receiver of the message

  • return_address – the other object

Point.start(timer, seconds: float, repeating: bool = False)

Start the specified timer for this object.

An instance of the timer class will be sent to this address after the given number of seconds. Any registered message can be used as a timer. Layer cake provides the standard timers T1, T2, T3, and T4 for convenience and to reduce duplication.

Timers are private to each async object and there is no limit to the number of pending timers an object may have. Starting a timer with the same class is not an error, the timeout for that timer is reset to the new number of seconds. It is also not an error to terminate an object with outstanding timers - expiry messages fall on the floor.

It is difficult to make guarantees about the order that messages will arrive at an object. In the case of timers, its possible to receive the timeout after the sending of a cancellation. Async objects are best written to cope with every possible receive ordering.

Parameters:
  • timer (class) – type of the object that will be sent back on timeout

  • seconds – time span before expiry

  • repeating – enable endless repeat

Point.cancel(timer)

Abort the specified timer for this object.

Discard the pending timer. It is not an error to find that there is no such pending timer. The timeout can still be received after a cancellation.

Parameters:

timer (class) – the pending timer

Point.complete(message: Any = None)

Cause an immediate termination. The method never returns.

Parameters:

message – message to be returned to parent.

Point.assign(address: Address, context=True)

The specified child object is associated with the specified context, e.g. callback.

Parameters:
  • address – address of the child object

  • context (any) – what the child object is doing on behalf of this object

Point.progress(address: Address = None)

Find the context associated with the specified child object. Return the context or None.

If no address is provided the current return address is used.

Parameters:

address – address of the child object

Return type:

any

Point.debrief(address: Address = None)

Find the context associated with the child object. Return the context.

If no address is provided the current return address is used. If a match is found the record is removed, decrementing the number of active contexts.

Parameters:

address – address of the child object

Return type:

any

Point.working()

Check if there are child objects still active. Returns the count.

Return type:

int

Point.on_return(address: Address, f, **kw)

Register a callback, to be executed on termination of the specified object.

Parameters:
  • address – address of the child object

  • f (function) – the function to be called

  • kw (dict) – named arguments to be saved and presented on the callback

Point.continuation(address: Address, f, args: Gas)

Register a chained callback, to be executed on termination of the specified object.

Parameters:
  • address – address of the child object

  • f (function) – the function to be called

  • args – named arguments saved by a prior on_return()

Point.fault(*a, **kv)

Generate a log at level FAULT.

Parameters:
  • a (tuple) – positional args catenated into a single string

  • kv (dict) – key-value pairs listed with a separating = character

Point.warning(*a, **kv)

Generate a log at level WARNING.

Parameters:
  • a (tuple) – positional args catenated into a single string

  • kv (dict) – key-value pairs listed with a separating = character

Point.sample(name, **kv)

Generate a row in a sample stream.

Logging is limited to a single positional name and a set of key-value pairs. This appears in the log with the same layout as console et al, but with the ‘&’ object tag. The layer-cake log command can be used to extract the series of samples and print them as a row of timestamped values separated by a tab. Logging sample values that may include ‘,’ (comma) or ‘=’ (equals) will eventually lead to unexpected output from the log command.

Parameters:
  • name (str) – name of this dataset

  • kv (dict) – key-value pairs listed with a separating = character

Point.console(*a, **kv)

Generate a log at level CONSOLE.

Parameters:
  • a (tuple) – positional args catenated into a single string

  • kv (dict) – key-value pairs listed with a separating = character

Point.trace(*a, **kv)

Generate a log at level TRACE.

Parameters:
  • a (tuple) – positional args catenated into a single string

  • kv (dict) – key-value pairs listed with a separating = character

Point.debug(*a, **kv)

Generate a log at level DEBUG.

Parameters:
  • a (tuple) – positional args catenated into a single string

  • kv (dict) – key-value pairs listed with a separating = character

class layer_cake.virtual_point.Threaded(blocking=False, maximum_size=16384)

Base class for asynchronous machines that require dedicated threads.

Parameters:
  • blocking (bool) – block on queue full

  • maximum_size (int) – number of pending messages

class layer_cake.virtual_point.T1

Predeclared timer class.

A class suitable for passing to start(). The library provides the T1, T2, T3 and T4 timer classes for general use.

class layer_cake.virtual_point.Buffering

Base for any object intending to perform sophisticated I/O, i.e. channels and routines.

Buffering.input()

Block until the next message arrives. Return the value.

Part of the “save” machinery that can buffer and replay messages. Sets addresses and type information (i.e. Point.received_type) associated with the received message.

Return type:

application value

Buffering.select(*matching, saving: tuple = None, seconds: float = None)

Expect one of the listed messages, with optional saving and timeout. Return a 2-tuple.

Reads the input queue looking for a message matching one of the types listed in matching. The method returns the application-ready data and the ordinal position of the match. Before dropping an unmatched message there is a check against the types listed in saving. A match here results a “push back” of the message onto the input queue.

For optimum performance the method also accepts the results of select_list() as replacements for matching and saving tuples.

Parameters:
  • matching (the positional arguments tuple) – message types to be accepted

  • saving (tuple) – message types to be deferred

  • seconds (float) – waiting period

Return type:

message object

Buffering.save(message)

Pushback the most recent input message.

Pass the application data that was returned by input() or select().

Parameters:

message – message to be saved

layer_cake.point_runtime.select_list(*selection)

Compile the list of types into an object suitable for select().

Prepare a lookup table for efficient matching of received messages. This is used to create global materials during loading.

Parameters:

selection – message types to be included

Stateless and FSM

class layer_cake.point_machine.Stateless

Base for simple machines that maintain no formal state.

Messages are received by an assigned thread and dispatched to handlers according to the type of the received message.

class layer_cake.point_machine.StateMachine(initial)

Base for machines that maintain a formal state.

Messages are received by an assigned thread and dispatched to handlers according to the current state and the type of the received message.

Every handler must return the next state. In those cases where the state remains unchanged, return self.current_state. Termination of a machine is by a call to complete().

Parameters:

initial (class) – Start state for all instances of derived class

Concurrency

class layer_cake.get_response.CreateFrame(object_type, *args, **kw)

Capture values needed for async object creation.

Parameters:
  • object_type (object type) – type to be created

  • args – positional args to be passed on creation

  • kw – named values to be passed on creation

class layer_cake.get_response.Delay(seconds=None)

Object that does nothing for the specified number of seconds.

class layer_cake.get_response.GetResponse(request, server_address: Address, seconds: float = None)

Delegated request-response.

Send the request to the given address and expect a response. Pass the response back as the return value for this object.

Parameters:
  • request (message) – message to be sent

  • server_address – where to send the message

  • seconds – acceptable delay

class layer_cake.get_response.Concurrently(*get, seconds: float = None)

Delegated, multi-way request-response.

Manage one or more concurrent requests. Terminate on completion of full set, or a timer. Accepts a mixed tuple, i.e. either request-address pairs or CreateFrame objects.

Parameters:
  • get (tuple) – a list of request-address pairs or frames

  • seconds – acceptable delay

class layer_cake.object_spool.ObjectSpool(object_type, *args, role_name: str = None, object_count: int = 8, size_of_queue: int = None, responsiveness: float = 5.0, busy_pass_rate: int = 10, stand_down: float = 30.0, **settings)

Distribute messages across a pool of computing resources.

Parameters:
  • object_type (object type) – type of asynchronous object

  • args – positional arguments to pass on object creation

  • role_name – name of process objects, e.g. spool-{i} or None

  • object_count – number of objects to create

  • size_of_queue – maximum number of pending messages

  • responsiveness – expected performance before imposing busy state

  • busy_pass_rate – rate of messages processed in busy state, as a denominator

  • stand_down – delay in seconds before restart of terminated object

  • settings – named arguments to pass on object creation

class layer_cake.process_object.ProcessObject(object_or_name, *args, origin: ProcessOrigin = None, home_path: str = None, role_name: str = None, top_role: bool = False, object_api: list = None, extra_types: list = None, remainder_args: list = None, **settings)

An async proxy object that starts and manages a platform sub-process.

Parameters:
  • object_or_name (object type or str) – object to run as a process or the executable file name

  • args – positional arguments to be passed to the process

  • origin – processing context

  • home_path – location of a composite process

  • role_name – name within the composite process

  • top_role – enable top-level behaviour

  • object_api – enable private library behaviour for named process (str)

  • extra_types – force loading of library types

  • remainder_args – forward unknown command-line args to process

  • settings – named arguments to be encoded for the process

class layer_cake.retry_intervals.RetryIntervals(first_steps: list[float] = None, regular_steps: float = None, step_limit: int = None, randomized: float = None, truncated: float = None)

Capture the values needed to manage exponential backoff.

Parameters:
  • first_steps – initial series of explicit float values

  • regular_steps – float value repeated after first_steps

  • step_limit – maximum number of steps

  • randomized – micro-steps used when randomizing

  • truncated – add step * truncated when randomizing

class layer_cake.general_purpose.Gas(**kv)

Build an object from the specified key-value args.

Create an attribute for each of the named arguments. The values are subsequently available using standard object member access.

Parameters:

kv – map of names and value

Folders And Files

class layer_cake.folder_object.Folder(path: str = None, tip=None, re: str = None, encoding=None, pretty_format: bool = True, decorate_names: bool = True, create_default: bool = False, keys_names=None, make_absolute: bool = False, auto_create: bool = True)

Create and manage a folder of application encodings.

Parameters:
  • path – the location in the filesystem

  • tip (tip) – type expression for the content

  • re – formal, regular expression description of expected file names

  • encoding (class) – selection of representation, defaults to CodecJson

  • pretty_format – generate human-readable file contents, defaults to True

  • decorate_names – auto-append an encoding-dependent extension to the file name, defaults to True

  • keys_names (2-tuple of functions) – a key-composer function and a name-composer function

  • make_absolute – expand a relative path to be an absolute location, defaults to True

  • auto_create – create folders as necessary, defaults to True

Folder.file(name: str, tip=None, encoding=None, pretty_format: bool = None, decorate_names: bool = None, create_default: bool = None)

Create a new File object representing a file at the current location.

Parameters:
  • name – the name to be added to the saved path

  • tip (tip) – type expression for the content

  • encoding (class) – selection of representation, defaults to CodecJson

  • pretty_format – generate human-readable file contents, defaults to True

  • decorate_names – auto-append an encoding-dependent extension to the file name, defaults to True

  • create_default – return default instance on file not found, defaults to False

Returns:

a new file in the filesystem

Return type:

File

Folder.folder(name: str, tip=None, re: str = None, encoding=None, pretty_format: bool = None, decorate_names: bool = None, create_default: bool = None, auto_create: bool = None, keys_names=None)

Create a new Folder object representing a sub-folder at the current location.

Parameters:
  • path – the name to be added to the saved path

  • tip (tip) – type expression for the content

  • re – formal, regular expression description of expected file names

  • encoding (class) – selection of representation, defaults to CodecJson

  • pretty_format – generate human-readable file contents, defaults to True

  • decorate_names – auto-append an encoding-dependent extension to the file name, defaults to True

  • keys_names (2-tuple of functions) – a key-composer function and a name-composer function

  • make_absolute – expand a relative path to be an absolute location, defaults to True

  • auto_create – create folders as necessary, defaults to None

Returns:

a new location in the filesystem

Return type:

Folder

Folder.matching()

Scan for files in the folder.

Returns:

a sequence of filenames matching the Folder criteria.

Return type:

str

Folder.each()

Process the files in the folder.

Returns:

a sequence of File objects matching the Folder criteria.

Return type:

File

Folder.store(values: dict)

Store a dict of values as files in the folder.

Parameters:

values – a collection of application values

Folder.recover()

Recover application values from the files in the folder.

A generator function that yields a sequence of tuples that allow the caller to process an entire folder with a clean loop.

All arguments are forwarded to recover().

The return value includes the version of the main decoded object, or None if the encoding and decoding applications are at the same version. This value is the mechanism by which applications can select different code-paths in support of older versions of encoded materials.

Returns:

a sequence of 2-tuples, 0) key and 1) the value

Return type:

tuple

Folder.add(values: dict, item)

Add a value, both to a dict of values and as a file in the folder.

Parameters:
  • values – a collection of application values

  • item (tip) – the value to be added

Folder.update(values: dict, item)

Update a value, both in a dict of values and as a file in the folder.

Parameters:
  • values – a collection of application values

  • item (tip) – the value to be updated

Folder.remove(values: dict, item)

Remove a value, both from a dict of values and as a file in the folder.

Parameters:
  • values – a collection of application values

  • item (tip) – the value to be removed

Folder.clear(values: dict)

Remove all values, both from a dict of values and as files in the folder.

Parameters:

values – a collection of application values

Folder.erase(name: str)

Delete the named file from the folder.

Parameters:

name – a name of a file

Folder.exists(name: str = None)

Detect the named file, within the folder.

Parameters:

name – a name of a file

Returns:

does the file exist

Return type:

bool

class layer_cake.file_object.File(name: str, tip, encoding=None, create_default: bool = False, pretty_format: bool = True, decorate_names: bool = True)

Store and recover application values using files.

Parameters:
  • name – name of the file

  • tip (tip) – type expression for the content

  • encoding (class) – selection of representation, defaults to CodecJson

  • create_default – return default instance if file not found on read, defaults to False

  • pretty_format – generate human-readable file contents, defaults to True

  • decorate_names – auto-append an encoding-dependent extension to the file name, defaults to True

File.store(value, as_name=None, as_path=None)

Generate a representation of value and write to the saved name.

Parameters:

value (matching the tip saved on construction) – any application value

File.recover()

Read from the saved name, parse and marshal into an application value.

Returns:

any application value

Return type:

matching the saved tip

Listening And Connecting

class layer_cake.listen_connect.EndOfTransport

Enumeration of the reasons that a connect/listen transport might close.

  • ON_REQUEST - local process sent a Close.

  • ABANDONED_BY_REMOTE - transport abandoned by network or remote.

  • WENT_STALE - transport closed by keep-alive machinery.

  • OUTBOUND_STREAMING - fault during outboud serialization.

  • INBOUND_STREAMING - fault during inboud serialization.

class layer_cake.listen_connect.ListenForStream(lid: UUID = None, requested_ipp: HostPort = None, encrypted: bool = False, http_server: list[Type] = None, uri_form: ReForm = None, default_to_request: bool = True)

Session request, open a server presence.

Parameters:
  • lid – unique id for this listen request

  • requested_ipp – IP and port requested by the application

  • encrypted – enable encryption

  • http_server – list of classes

  • default_to_request – default to HttpRequest

class layer_cake.listen_connect.ConnectStream(requested_ipp: HostPort = None, encrypted: bool = False, keep_alive: bool = False, http_client: str = None, layer_cake_json: bool = False)

Session request, open a transport to an address.

Parameters:
  • requested_ipp – IP and port requested by the application

  • encrypted – enable encryption

  • keep_alive – monitor the connection

  • http_client – inserted as the path in the request URI

  • layer_cake_json – enable layer-cake JSON body

class layer_cake.listen_connect.Listening(request: ListenForStream = None, listening_ipp: HostPort = None, controller_address: Address = None)

Session notification, server presence established.

Parameters:
  • request – original listen request

  • listening_ipp – network address in use

  • controller_address – object that requested the listen

class layer_cake.listen_connect.Connected(request: ConnectStream = None, opened_ipp: HostPort = None, proxy_address: Address = None, opened_at: datetime = None)

Session notification, transport to server established.

Parameters:
  • request – original connect request

  • opened_ipp – network address of connected transport

  • proxy_address – address of remote party

  • opened_at – moment of connection

class layer_cake.listen_connect.Accepted(listening: Listening = None, opened_ipp: HostPort = None, proxy_address: Address = None, opened_at: datetime = None)

Session notification, transport to client established.

Parameters:
  • listening – listening server

  • opened_ipp – network address of accepted transport

  • proxy_address – address of remote party

  • opened_at – moment of acceptance

class layer_cake.listen_connect.Close(message: Any = None, reason: EndOfTransport = None, note: str = None, error_code: int = None)

Session control, terminate the messaging transport.

Parameters:
  • message (message) – completion message for the session

  • reason – what prompted the termination

  • note – short diagnostic

  • error_code – platform error code

class layer_cake.listen_connect.Closed(message: Any = None, reason: EndOfTransport = None, note: str = None, error_code: int = None, opened_ipp: HostPort = None, opened_at: datetime = None)

Session notification, local termination of the messaging transport.

Parameters:
  • message (message) – completion message for the session

  • reason – what prompted the termination

  • note – short diagnostic

  • error_code – platform error code

  • opened_ipp – network address of terminated transport

  • opened_at – moment of termination

class layer_cake.listen_connect.NotListening(request: ListenForStream = None, error_code: int = 0, error_text: str = None)

Session notification, server not established.

Parameters:
  • request – original listen request

  • error_code – platform error number

  • error_text – platform error message

class layer_cake.listen_connect.NotConnected(request: ConnectStream = None, error_code: int = 0, error_text: str = None)

Session notification, transport to server not established.

Parameters:
  • request – original connect request

  • error_code – platform error number

  • error_text – platform error message

layer_cake.listen_connect.connect(self: Point, requested_ipp: HostPort, encrypted: bool = False, keep_alive: bool = False, http_client: str = None, layer_cake_json: bool = False)

Initiates a network connection to the specified IP address and port number.

Parameters:
  • self – asynchronous identity

  • requested_ipp – host and port to connect to

  • encrypted – enable encryption

  • keep_alive – enable keep-alives

  • http_client – leading part of the outgoing request URI

  • layer_cake_json – is the remote server a layer-cake server

layer_cake.listen_connect.listen(self: Point, requested_ipp: HostPort, encrypted: bool = False, http_server: list[Type] = None, uri_form: ReForm = None, default_to_request: bool = True)

Establishes a network presence at the specified IP address and port number. Returns UUID.

Parameters:
  • self – asynchronous identity

  • requested_ipp – network address to listen at

  • encrypted – enable encryption

  • http_server – enable HTTP with list of expected requests

  • default_to_request – enable default conversion into HttpRequests

Return type:

UUID

layer_cake.listen_connect.stop_listening(self: Point, lid: UUID)

Shutdown the listen port with the specified identity.

Parameters:
  • self – asynchronous identity

  • lid – UUID assigned at time of listen()

class layer_cake.ip_networking.HostPort(host: str = None, port: int = None)

Combination of an IP address or name, and a port number.

Parameters:
  • host – IP address or name

  • port – network port

Publish And Subscribe

layer_cake.process_directory.publish(self: Point, name: str, scope: ScopeOfDirectory = ScopeOfDirectory.HOST, encrypted: bool = False)

Establish a service presence under the specified name.

Parameters:
  • self – asynchronous identity

  • name – name to be used as alias for the given object

  • scope – scope in which the name is available

  • encrypted – enable encryption of subscriber sessions

layer_cake.process_directory.subscribe(self: Point, search: str, scope: ScopeOfDirectory = ScopeOfDirectory.HOST)

Establish a lookup for services matching the specified pattern.

Parameters:
  • self – asynchronous identity

  • search – pattern to be used for matching with services

  • scope – scope in which to search

layer_cake.process_directory.clear_published(self: Point, published: Published, note: str = None)

Remove all trace of the previously published service.

Parameters:
  • self – asynchronous identity

  • published – message confirming a publish()

  • note – short description added to logs

layer_cake.process_directory.clear_subscribed(self: Point, subscribed: Subscribed, note: str = None)

Remove all trace of the previously registered search.

Parameters:
  • self – asynchronous identity

  • published – message confirming a subscribe()

  • note – short description added to logs

class layer_cake.object_directory.Published(name: str = None, scope: ScopeOfDirectory = None, encrypted: bool = False, published_id: UUID = None, listening_ipp: HostPort = None, home_address: Address = None)

Successful completion of publish().

Parameters:
  • name – name the service is known by

  • scope – scope in which to search

  • published_id – unique identity assigned to registration

  • listening_ipp – IP and port assigned to this service

  • home_address – address of the publishing process

class layer_cake.object_directory.Subscribed(search: str = None, scope: ScopeOfDirectory = None, subscribed_id: UUID = None, home_address: Address = None)

Successful completion of subscribe().

Parameters:
  • search – pattern to match with services

  • scope – scope in which to search

  • subscribed_id – unique identity assigned to registration

  • home_address – address of the subscribing process

class layer_cake.object_directory.Available(name: str = None, scope: ScopeOfDirectory = None, route_id: UUID = None, subscribed_id: UUID = None, published_id: UUID = None, publisher_address: Address = None, opened_at: datetime = None)

Session notification, peer transport to service established.

Parameters:
  • name – name of the matched service

  • scope – scope at which name was matched

  • route_id – unique identity assigned to match

  • subscribed_id – unique identity assigned to subscription

  • published_id – unique identity assigned to publication

  • publisher_address – address of the publishing process

  • opened_at – moment the match occurred

class layer_cake.object_directory.Delivered(name: str = None, scope: ScopeOfDirectory = None, route_id: UUID = None, subscribed_id: UUID = None, published_id: UUID = None, subscriber_address: Address = None, opened_at: datetime = None)

Session notification, peer transport to subscriber established.

Parameters:
  • name – name of the matched service

  • scope – scope at which name was matched

  • route_id – unique identity assigned to match

  • subscribed_id – unique identity assigned to subscription

  • published_id – unique identity assigned to publication

  • subscriber_address – address of the subscribing process

  • opened_at – moment the match occurred

class layer_cake.object_directory.Dropped(name: str = None, scope: ScopeOfDirectory = None, route_id: UUID = None, subscribed_id: UUID = None, published_id: UUID = None, remote_address: Address = None, opened_at: datetime = None)

Session notification, peer transport to published/subscriber lost.

Parameters:
  • name – name of the matched service

  • scope – scope at which name was matched

  • route_id – unique identity assigned to match

  • subscribed_id – unique identity assigned to subscription

  • published_id – unique identity assigned to publication

  • remote_address – address of the subscriber/publisher

  • opened_at – moment the match occurred

class layer_cake.object_directory.NotPublished(name: str = None, scope: ScopeOfDirectory = None, note: str = None)

Unsuccessful completion of publish().

Derived from Faulted

Parameters:
  • name – name the service would be known by

  • scope – scope in which service would be available

  • note – short description added to logs

class layer_cake.object_directory.NotSubscribed(search: str = None, scope: ScopeOfDirectory = None, note: str = None)

Unsuccessful completion of subscribe().

Derived from Faulted

Parameters:
  • name – pattern for matching services

  • scope – scope in which to search

  • note – short description added to logs

class layer_cake.object_directory.PublishedCleared(name: str = None, scope: ScopeOfDirectory = None, published_id: UUID = None, note: str = None)

Successful completion of clear_published().

Parameters:
  • name – name the service is known by

  • scope – scope in which to search

  • published_id – unique identity assigned to registration

  • note – short description appearing in logs

class layer_cake.object_directory.SubscribedCleared(search: str = None, scope: ScopeOfDirectory = None, subscribed_id: UUID = None, note: str = None)

Successful completion of clear_subscribed().

Parameters:
  • name – name the service is known by

  • scope – scope in which to search

  • subscribed_id – unique identity assigned to registration

  • note – short description appearing in logs

HTTP Integration

class layer_cake.http.HttpRequest(method: str = None, request_uri: str = None, http: str = None, header: dict[str, str] = None, body: bytearray = None)

The message generated by an HTTP client and received by an HTTP server.

Parameters:
  • method – one of GET, POST, PUT, …

  • request_uri – the path section of a URI

  • http – version of HTTP

  • header – name-value pairs

  • body – payload, value

class layer_cake.http.HttpResponse(http: str = None, status_code: int = 200, reason_phrase: str = None, header: dict[str, str] = None, body: bytearray = None, plain_text=None, application_json=None)

The message generated by an HTTP server and received by an HTTP client.

Parameters:
  • http – version of HTTP

  • status_code – 100, 200, 300, …

  • reason_phrase – short description

  • header – name-value pairs

  • body – payload, value

class layer_cake.http.FormRequest(method: str = None, request: str = None, form_entry: dict[str, str] = None, http: str = None, header: dict[str, str] = None, body: bytearray = None)

The message generated by an HTTP client and received by an HTTP server.

Passing an ReForm to listen() causes special processing of the request URI. The URI is deconstructed into a FormRequest and presented to the calling object, e.g. a server. This should be combined with use of the ResourceDispatch, to route inbound FormRequests to a resource- based function.

Parameters:
  • method – one of GET, POST, PUT, …

  • form_entry – the path section of a URI

  • http – version of HTTP

  • header – name-value pairs

  • body – payload, value

class layer_cake.http.ResourceDispatch(form: ReForm, resource: list[Type])

Build up the info needed to dispatch from FormRequest to function.

Define a global instance passing the ReForm and list of resource types. Accept mappings of request-to-function, using the add() method. Then expect calls to lookup() that matches the runtime FormRequest to a saved function.

ResourceDispatch.add(resource: Type, method: HttpMethod, f, **kv)

Add a mapping for a resource+method to a function.

Compose a key based on resource, method and the set of expected args (kv). Then table[key] = f. Each kv entry is a name and a conversion function.

ResourceDispatch.lookup(request: FormRequest)

Resolve the function to call based on info in FormRequest.

Compose a key based on resource, method and the set of detected args (request.form_entry), convert the args from matched text to application values, Return function and args.

ResourceDispatch.__call__(layer, request: FormRequest)

Resolve the request to a function and call it.

Make the call to lookup() and execute the resulting call materials. If the result of that call is not a None - send it on to the original client.

Composite Processes

layer_cake.home_role.resource_path()

Application access to the shared, per-executable file space. Return the path or None.

Return type:

str

layer_cake.home_role.model_path()

Application access to the operational, per-role file space. Return the path.

Return type:

str

layer_cake.home_role.tmp_path()

Application access to the transient, per-role file space. Return the path.

Return type:

str