Skip to main content

ActionCore

English | 繁體中文 | 简体中文

je_action_core is the keyword-driven action executor shared by APITestka, LoadDensity, MailThunder and FileAutomation. Each of them carried its own copy of the same executor, package manager, callback executor, action-file reader and socket server. This package replaces those copies: a project configures it with its own command prefix, document key, exceptions and messages.

It has no dependencies and supports Python 3.10 to 3.14.

Contents

Installation

pip install je_action_core

A framework that is built on it installs it as a dependency.

Actions

An action list is a JSON list of actions, or a document that keeps the list under one key ({"api_testka": [...]}). Each action takes one of three forms:

Action Call
["name"] command()
["name", {"a": 1}] command(a=1)
["name", [1, 2]] command(1, 2)

Running a list returns one record per action: the command's return value, or repr(error) when it raised. One failing action does not stop the rest.

Quick start

from je_action_core import (
    ActionExecutor, ActionListRules, CommandPolicy, CommandRegistry, ExecutorSettings, LoggingReporter,
)
import logging

registry = CommandRegistry({"MY_add": lambda a, b: a + b}, policy=CommandPolicy.FUNCTIONS_ONLY)
executor = ActionExecutor(
    ExecutorSettings(rules=ActionListRules("my_tool"), reporter=LoggingReporter(logging.getLogger("my_tool"))),
    registry,
)

executor.execute_action({"my_tool": [["MY_add", [1, 2]], ["MY_add", {"a": 3, "b": 4}]]})
# {"execute: ['MY_add', [1, 2]]": 3, "execute: ['MY_add', {'a': 3, 'b': 4}]": 7}

The pieces

Module What it gives you Settings
registry CommandRegistry: commands by name, event_dict as the live mapping CommandPolicy.FUNCTIONS_ONLY or ANY_CALLABLE for caller-added commands; the exception for a refused one
action_list ActionListRules (where the list is), LegacyActionParser and StrictActionParser document key and legacy keys (with a DeprecationWarning); empty list raises or returns {}; error messages
executor ActionExecutor: execute_action, collect_action_results (records and the failed keys, unreported), execute_files, add_command_to_executor; override attempt to wrap every action (retries, a span) ExecutorSettings: rules, parser, reporter, file reader, record key (execute: … or execute[i]: …), repeated keys replaced or numbered (#2), what a failure records (repr(error) by default), action rewrite
reporting LoggingReporter, PrintReporter, or your own ExecutionReporter where events, failures and records go
package_manager PackageManager: load an installed package's members as commands, behind the package gate member naming (<package>_<member> or bare), predicates, name check, errors to log
callback CallbackFunctionExecutor: run a trigger, then a callback legacy or strict checking; raise or log and return None
json_io ActionJsonFile, read_action_json, write_action_json: UTF-8, locked, non-ASCII kept exception class and message templates
file_listing get_dir_files_as_list: action files under a directory —
socket_server, socket_auth start_action_socket_server and the request handlers (plain, secret header, JSON-envelope token) executor, payload check, errors answered, framing, TLS, reply templates, secret
builtins_policy SAFE_BUILTINS: the builtins an action list may call —
request_record, request_context Versioned request-result validation, JSON serialization/schema and isolated RunContext storage source, phase, engine, worker and run identities

__all__ in je_action_core/__init__.py is the supported import surface.

Request results

HTTP request_method: uppercase ASCII token; schema and Python validation enforce the same rule.

Run identities are validated when the context is constructed. Retries compare JSON content with object keys sorted, distinguishing booleans from numbers. Assertion messages must be strings when present, and failed assertions require a message. Integer values beyond the portable JSON conversion limit and unrepresentable measurement values raise field-located contract errors.

Request results are separate from executor action records. RequestRecord v1 gives functional, load and synthetic runs the same method/URL, numeric status, nullable measurements, structured error, assertions and run/worker/step identities. validate_request_record returns a detached JSON-safe result; serialize_request_record exports it and request_record_schema describes the contract. Bytes become base64 objects, datetimes become epoch seconds and timedeltas become milliseconds. Unknown versions, invalid fields, non-finite measurements and opaque objects raise RequestRecordError.

RunContext(source="loaddensity", phase="load", engine="asyncio") owns one run's records. Use capture(fields) for a new result, append(record) for a validated retry, snapshot() for a detached copy and to_json() for an array export. Identical record IDs deduplicate; conflicting retries and foreign run identities raise an error. use_run_context(context) activates it for a thread/task scope and restores the previous context on exit; get_run_context() returns the active context or None. Storage retains the complete run; long-lived monitors should create a new context per iteration and persist results. The contract records the runner's judgement and does not decide whether a status code is successful.

Package gate

PackageManager.add_package_to_executor imports a package and registers its members as commands. An action list that can name os or subprocess could therefore run anything. The host program decides what may load:

package_manager.allow_packages("my_helpers")          # these, and their submodules
package_manager.set_allow_arbitrary_packages(False)   # refuse everything else before importing it

Neither switch should ever be exposed as an action command, so an action list cannot open its own gate. A refused package raises the project's refused exception, which the executor records as that action's result. Until the host calls either switch, any package still loads but raises a DeprecationWarning. A project can turn the gate off (PackageGate.OFF) while it moves to it.

Socket server protocol

start_action_socket_server(host, port, settings, handler_class=ActionRequestHandler) serves on a daemon thread. A client sends one JSON action document per connection. The server replies with one line per record, then Return_Data_Over_JE. A failure replies with the error text and the same marker. quit_server stops the server and sets close_flag and close_event. What can be configured:

  • Framing: Framing.RAW reads one 8 KiB recv, and OversizePolicy says what happens to a full buffer. Framing.LENGTH_PREFIX reads a 4-byte big-endian length, then the body (at most 1 MiB), and sends every reply line as its own frame.
  • TLS: tls_context=server_tls_context(certfile, keyfile) wraps each connection (TLS 1.2 or later).
  • Replies: ReplyMessages holds the templates for a record line, each failure stage (JSON, refused by validate, execution), an undecodable request, the quit reply, the authentication refusals and the log line.
  • Authentication: the base handler has none. SecretHeaderRequestHandler requires a first line <auth_prefix><secret>. EnvelopeTokenRequestHandler accepts {"token": ..., "command": ...} and {"token": ..., "op": "quit"}. Both compare secrets in constant time.

Without authentication, bind the server only to a trusted interface.

Who uses it

APITestka (AT_, port 9939), LoadDensity (LD_), MailThunder (MT_, port 9942) and FileAutomation (FA_) are the projects this package is for. architecture.md §6 lists which of them have moved to it and which pieces and settings each one uses. All four run their TCP servers on socket_server: LoadDensity with the JSON-envelope token, framing and TLS, FileAutomation with the AUTH header and its ACL.

WebRunner (WR_) runs its action executor on it as well. Its own action format ([name, [args], {kwargs}]) is a parser, and its retries and action span wrap attempt. Failure screenshots go into failure_record, and repeated actions are numbered (DuplicateKeys.NUMBER).

n and an ACL.

Development

pip install -e .
pip install pytest
python -m pytest test/

architecture.md describes the layers and the contracts with the four projects. Outstanding work is in progress.md, and finished work is recorded in docs/updates/.

License

MIT, see LICENSE.

Metadata

Release files for je-action-core 0.0.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for je-action-core 0.0.4
File Size Uploaded
je_action_core-0.0.4.tar.gz 32.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for je-action-core 0.0.4
File Interpreter ABI Platform
je_action_core-0.0.4-py3-none-any.whl Python 3 none any Details

Total release size: 66.6 kB

Release files / je_action_core-0.0.4.tar.gz

Download URL je_action_core-0.0.4.tar.gz
Size 32.0 kB
Tags Source
SHA-256 checksum
How to use checksums
bd371fa6a8c88db94a25a05d2129b9b7ce88d621f2b361407ca2f58e8d52d9f7
BLAKE2b-256 checksum
How to use checksums
9668bf6aaa0b24c3aee8649466474b15bbe954485a7e3c6203410a9230874bca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.15

Release files / je_action_core-0.0.4-py3-none-any.whl

Download URL je_action_core-0.0.4-py3-none-any.whl
Size 34.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a996e667057b8935969ad5fe92364c7bc76134ac7e22f468cc4536cc602fa8f6
BLAKE2b-256 checksum
How to use checksums
9f1569485d614edba19a944b3504fea40f12f07d2d718978dbbbe6186d297272
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.15

Release history Release notifications | RSS feed

This release

0.0.4 This release

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page