Skip to main content

Active Development CI Test Status License: GPL v3 PyPI Downloads coverage

end.

endpoint is a refined, full scale solution to CLIs .

Compatibility

🟩 (Works perfectly); 🟨 (Untested); 🟧 (Some Issues); 🟥 (Unusable)

OS
Windows 🟩
MacOS 🟩
Linux (Ubuntu 22.04 LTS) 🟩

Features

  • Easy to use for beginners, but not lacking for experts
  • Efficient
  • Fully cross-platform
  • Regular updates and support
  • Comprehensive documentation

Installation

You can install endpoint via pip:

pip install endpoint.cli --pre --upgrade

Or clone the repository and install manually:

git clone https://github.com/Adalfarus/endpoint-py.git
cd endpoint-py
python -m pip install .

If you have problems with the package please use py -m pip install endpoint.cli[dev] --pre --upgrade --user

📦 Usage

The examples below are grouped by capability so you can copy only what you need.

1. Route commands with Interface

from endpoint.interface import Interface


def hello(name: str = "world") -> None:
    print(f"hello {name}")


app = Interface("my-cli", default_endpoint_or_message="Unknown command")
app.path("greet", hello, "Print a greeting")
app.path("math::sum", lambda a: print(sum(map(int, a))), "Sum integers")

# Simulate: my-cli greet --name Ada
app.parse_cli(["my-cli", "greet", "--name", "Ada"], skip_first_arg=True)

2. Build endpoints from function signatures

from endpoint.endpoints import NativeEndpoint
from endpoint.native_parser import NativeParser


def deploy(env: str, *, dry_run: bool = False, retries: int = 1) -> None:
    """Deploy app.
    env: Deployment target.
    dry_run: Validate only.
    retries: Retry count.
    """
    print(env, dry_run, retries)


endpoint = NativeEndpoint.from_function(
    deploy,
    name="deploy",
    parser=NativeParser({}),
)

# Simulate: deploy production --dry-run --retries 3
endpoint.parse(["deploy", "production", "--dry-run", "--retries", "3"], skip_first_arg=True)

3. Define arguments manually (all core knobs)

from endpoint.endpoints import NativeEndpoint
from endpoint.native_parser import NativeParser, NArgsMode, NArgsSpec, ArgumentParsingError


def run(input_file: str, **kwargs) -> None:
    print(input_file, kwargs)


ep = NativeEndpoint("run", "Manual argument model", function=run, parser=NativeParser({}))

ep.add_argument("input_file", types=[str], positional_only=True, required=True, help_="Input path")
ep.add_argument("count", types=[int], default=1, choices=[1, 2, 3], help_="How many times")
ep.add_argument("verbose", types=[bool], default=False, help_="Enable verbose output")
ep.add_argument("tags", types=[list[str]], default=[], nargs=NArgsMode.ZERO_OR_MORE(NArgsSpec.MANY))
ep.add_argument("mode", types=[str], default="safe", kwarg_only=True, help_="Execution mode")

def validate_count(arg, value):
    if value < 1:
        return ArgumentParsingError("count must be >= 1")
    return value

ep.change_argument("count", checking_func=validate_count)
ep.guess_letters_and_shortforms()

# Simulate: run file.txt --count 2 --verbose --mode fast --tags a,b
ep.parse(["run", "file.txt", "--count", "2", "--verbose", "--mode", "fast", "--tags", "a,b"], skip_first_arg=True)

4. Wrap endpoint invocation (logging, timing, tracing, auth)

from endpoint.endpoints import NativeEndpoint


def add(a: int, b: int) -> int:
    return a + b


def wrapper(endpoint, fn, *args, **kwargs):
    print(f"calling {endpoint!r} with {args=} {kwargs=}")
    return fn(*args, **kwargs)


ep = NativeEndpoint.from_function(add, "add")
ep.set_calling_func(wrapper)
ep.parse(["add", "2", "3"], skip_first_arg=True)

5. Use parser backends

NativeEndpoint accepts any parser implementing Parser.

from endpoint.endpoints import NativeEndpoint
from endpoint.native_parser import NativeParser
from endpoint.parser_collection import LightParser, TokenStreamParser, StrictDFAParser, FastParser, TinyParser


def task(value: int, flag: bool = False) -> None:
    print(value, flag)


NativeEndpoint.from_function(task, "native", parser=NativeParser({}))
NativeEndpoint.from_function(task, "light", parser=LightParser({}))
NativeEndpoint.from_function(task, "stream", parser=TokenStreamParser({"repeatable_collections": True}))
NativeEndpoint.from_function(task, "dfa", parser=StrictDFAParser({}))
NativeEndpoint.from_function(task, "fast", parser=FastParser({"FAST_ALLOW_POSITIONALS": True}))
NativeEndpoint.from_function(task, "tiny", parser=TinyParser({}))

6. Use ArgparseEndpoint when you want argparse behavior

from endpoint.endpoints import ArgparseEndpoint


ep = ArgparseEndpoint(prog="my-cli", description="Argparse-backed endpoint")
ep.add_argument("--value", type=int, required=True)
ep.set_calling_func(lambda *, value: print(value))

ep.parse(["my-cli", "--value", "5"], skip_first_arg=True, automatic_help_args=())

7. Convert native endpoint definitions to argparse

from endpoint.endpoints import NativeEndpoint


ep = NativeEndpoint.from_function(lambda count=1: print(count), "tool")
argparse_parser = ep.to_argparse()
argparse_ep = ep.to_argparse_endpoint()

ns = argparse_parser.parse_args(["--count", "3"])
print(ns.count)

_, parsed = argparse_ep.parse(["tool", "--count", "3"], skip_first_arg=True, automatic_help_args=())
print(parsed["count"])

8. Inspect callables and types

from endpoint.functional import analyze_function, get_analysis, break_type, pretty_type


def sample(a: int, b: str = "x") -> bool:
    """sample function"""
    return True


print(analyze_function(sample))
print(get_analysis(sample).to_dict())
print(break_type(list[int]))
print(pretty_type(dict[str, int]))

9. Build command trees manually

from endpoint.structure import Structure, add_command_to_structure, structure_help
from endpoint.endpoints import NativeEndpoint


tree = Structure("demo")
add_command_to_structure("ops::health", "Check health", NativeEndpoint("health"), tree)
add_command_to_structure("ops::version", "Show version", NativeEndpoint("version"), tree)
print(structure_help(tree["demo"]))

10. Project CLI entrypoint

The package installs endpoint-cli for project workflows:

endpoint-cli help
endpoint-cli tests run tests/ --minimal

Naming convention, dependencies and library information

PEP 8 -- Style Guide for Python Code

For modules I use 'lowercase', classes are 'CapitalizedWords' and functions and methods are 'lower_case_with_underscores'.

Contributing

We welcome contributions! Please see our contributing guidelines for more details on how you can contribute to endpoint.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a pull request

Aps Build master

You can use the aps_build_master script for your os to make your like a lot easier. It supports running tests, installing, building and much more as well as chaining together as many commands as you like.

This example runs test, build the project and then installs it

Windows:

call .\aps_build_master.bat 234

Unix:

sudo apt install python3-pip
sudo apt install python3-venv
chmod +x ./aps_build_master.sh
./aps_build_master.sh 234

License

endpoint is licensed under the GPL-3.0 License - see the LICENSE file for details.

Metadata

Release files for endpoint.cli 2.1.1.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 endpoint.cli 2.1.1.4
File Size Uploaded
endpoint_cli-2.1.1.4.tar.gz 84.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for endpoint.cli 2.1.1.4
File Interpreter ABI Platform
endpoint_cli-2.1.1.4-py3-none-any.whl Python 3 none any Details

Total release size: 174.0 kB

Release files / endpoint_cli-2.1.1.4.tar.gz

Download URL endpoint_cli-2.1.1.4.tar.gz
Size 84.6 kB
Tags Source
SHA-256 checksum
How to use checksums
f3f04ebec2e2673f077dfb734ddf87dcb877fad555263755e7392a8d08da055f
BLAKE2b-256 checksum
How to use checksums
4f90392f2fb99ed056d4f665a61b69296990e55240bb3af8a5b7470835cd7c0f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.25

Release files / endpoint_cli-2.1.1.4-py3-none-any.whl

Download URL endpoint_cli-2.1.1.4-py3-none-any.whl
Size 89.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fd4d1e2cee49771cc5aeecf317a570f1fd22ad8defd5c14fee26fd214f1a7abb
BLAKE2b-256 checksum
How to use checksums
70c5454c2145887b90de275908280d7bff902293e10607bb5251c40ab438c64b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.25

Release history Release notifications | RSS feed

This release

2.1.1.4 This release

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