Skip to main content

markus-autotesting-core

markus-autotesting-core defines the data types for MarkUs autotester test settings. The types are msgspec structs, so one definition gives you both:

  • validation: decoding settings JSON into typed objects, rejecting invalid settings
  • a JSON schema: used by MarkUs to render the test settings form

Each tester (Python, Java, Haskell, …) defines its own settings by subclassing the base types here.

Installation

pip install markus-autotesting-core

Requires Python 3.11 or later.

Usage

Defining a tester's settings

Subclass BaseTestData for the settings of one test group, and BaseTesterSettings for the tester as a whole:

from typing import Annotated, Literal

from msgspec import Meta
from markus_autotesting_core.types import BaseTestData, BaseTesterSettings


class PyTestData(BaseTestData, kw_only=True):
    """The settings for one Python test group."""

    tester: Literal["pytest", "unittest"] = "pytest"


class PyTesterSettings(BaseTesterSettings):
    """The settings for the Python tester."""

    test_data: Annotated[list[PyTestData], Meta(title="Test Groups", min_length=1)]

BaseTestData provides the fields every test group has:

Field Type Default
category list[str], no duplicates required
script_files list[str], at least one, no duplicates required
timeout int, in seconds 30
feedback_file_names list[str] []
extra_info any {}

BaseTesterSettings is a tagged union on the tester_type field. A subclass's tag is its class name without the TesterSettings suffix, lowercased, so PyTesterSettings is "py". To use a different tag, pass tag=:

class CustomTesterSettings(BaseTesterSettings, tag="custom"): ...

Decoding settings

create_autotest_settings_class builds the type for a complete settings document from the tester classes you have:

import msgspec
from markus_autotesting_core.types import create_autotest_settings_class

AutotestSettings = create_autotest_settings_class([PyTesterSettings])

settings = msgspec.json.decode(
    b'{"testers": [{"tester_type": "py", "test_data": [{"category": ["instructor"], "script_files": ["test.py"]}]}]}',
    type=AutotestSettings,
)
settings.testers[0].tester_type  # "py"
settings.testers[0].test_data[0].timeout  # 30

Invalid settings raise msgspec.ValidationError, with the location of the problem:

msgspec.json.decode(
    b'{"testers": [{"tester_type": "py", "test_data": [{"category": [], "script_files": ["a.py", "a.py"]}]}]}',
    type=AutotestSettings,
)
# msgspec.ValidationError: `script_files` contains duplicate items: ['a.py'] - at `$.testers[0].test_data[0]`

msgspec.to_builtins(settings) converts decoded settings back to plain dicts and lists, with defaults filled in.

Generating the JSON schema

schema, components = msgspec.json.schema_components([PyTesterSettings])

Some values depend on the assignment, so the schema refers to definitions that the consumer (MarkUs) fills in before rendering the form:

Definition Used for Filled in with
#/definitions/files_list each entry of script_files the assignment's test files
#/definitions/test_data_categories each entry of category the test categories
#/definitions/extra_group_data extra_info MarkUs's test group settings

msgspec's decoder doesn't check these definitions, or other keywords added with Meta(extra_json_schema=...). The one exception is uniqueItems, which BaseTestData checks when decoding.

Development

The project uses uv.

uv sync
uv run pytest

Linting and formatting use ruff, and run as pre-commit hooks:

uv run ruff check .
uv run ruff format .

Contributions are welcome: please open an issue or a pull request.

License

MIT. See LICENSE.

Metadata

Release files for markus-autotesting-core 0.2.0

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

Source distribution (sdist)

Source distribution for markus-autotesting-core 0.2.0
File Size Uploaded Provenance Actions
markus_autotesting_core-0.2.0.tar.gz 4.6 kB Without provenance Details for markus_autotesting_core-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for markus-autotesting-core 0.2.0
File Interpreter ABI Platform Actions
markus_autotesting_core-0.2.0-py3-none-any.whl Python 3 none any Details for markus_autotesting_core-0.2.0-py3-none-any.whl

Total release size: 10.1 kB

Release files / markus_autotesting_core-0.2.0.tar.gz

Download URL markus_autotesting_core-0.2.0.tar.gz
Size 4.6 kB
Tags Source
SHA-256 checksum
How to use checksums
44ffe5b6ae4fa01945db15a75fc35967ccf478ec8d2ed80f58e6480018829de2
BLAKE2b-256 checksum
How to use checksums
d43005e208aac14fbacf8f328be01eaae8fdc51d7d664bca8d7931c320bbf011
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / markus_autotesting_core-0.2.0-py3-none-any.whl

Download URL markus_autotesting_core-0.2.0-py3-none-any.whl
Size 5.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bbf6c939bb365eeb8d1bdb0de687aaeda1b8b3ae65e1c65461cdc2d541043805
BLAKE2b-256 checksum
How to use checksums
3577d64afa2f60a264ab73cb9265e9cf4367ce2a26bc954b1941f87bc47fe88b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for markus-autotesting-core 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

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