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.3.tar.gz (84.1 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.3-py3-none-any.whl (89.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: endpoint_cli-2.1.1.3.tar.gz
  • Upload date:
  • Size: 84.1 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.3.tar.gz
Algorithm Hash digest
SHA256 8344cd83133a4c735af641bd37976ff1a13389f181aa5b1bea4ad4a0283dc055
MD5 9c42f170e21b8010aa5a944001da3c9e
BLAKE2b-256 892a5acad7b7f6f3e40cb726f65a310f733578cfd990384ed1fd52aad93075ae

See more details on using hashes here.

File details

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

File metadata

  • Download URL: endpoint_cli-2.1.1.3-py3-none-any.whl
  • Upload date:
  • Size: 89.1 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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 966c6f37d84ed1d79c58c86f1e304c3cce7139495ea608fff619b4f9f9b06820
MD5 490aa79ba5b0ac63ead16841b6147bac
BLAKE2b-256 25ae5976cdfc1e76f2f8e68687c506833c2dac5eecd562ddf2159ae7158c984d

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