Skip to main content

A refined, full scale solution to CLIs .

Project description

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

endpoint_cli-2.1.1.4.tar.gz (84.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

endpoint_cli-2.1.1.4-py3-none-any.whl (89.5 kB view details)

Uploaded Python 3

File details

Details for the file endpoint_cli-2.1.1.4.tar.gz.

File metadata

  • Download URL: endpoint_cli-2.1.1.4.tar.gz
  • Upload date:
  • Size: 84.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for endpoint_cli-2.1.1.4.tar.gz
Algorithm Hash digest
SHA256 f3f04ebec2e2673f077dfb734ddf87dcb877fad555263755e7392a8d08da055f
MD5 a0344cbde2b7135e36a1cba7cd23ae26
BLAKE2b-256 4f90392f2fb99ed056d4f665a61b69296990e55240bb3af8a5b7470835cd7c0f

See more details on using hashes here.

File details

Details for the file endpoint_cli-2.1.1.4-py3-none-any.whl.

File metadata

  • Download URL: endpoint_cli-2.1.1.4-py3-none-any.whl
  • Upload date:
  • Size: 89.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for endpoint_cli-2.1.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 fd4d1e2cee49771cc5aeecf317a570f1fd22ad8defd5c14fee26fd214f1a7abb
MD5 21c2ab9102be8f1605e811ea77100184
BLAKE2b-256 70c5454c2145887b90de275908280d7bff902293e10607bb5251c40ab438c64b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page