A simple task runner that generates command line interfaces
Project description
A simple task runner that generates command line interfaces
from cleek import task
@task
def binary_op(x: int, y: int, op: Literal['add', 'sub'] = 'add') -> None:
print(x, op, y)
⬇️ Becomes ⬇️
$ clk binary-op -h
usage: clk binary-op [-h] [-o {add,sub}] x y
positional arguments:
x
y
options:
-h, --help show this help message and exit
-o, --op {add,sub} default: add
Install
PyPI
$ pip install cleek
GitHub
$ git clone https://github.com/petersuttondev/cleek.git
$ pip install ./cleek
Get Started
- Create a
cleeks.pyfile in the root of your project and add tasks
from cleek import task
@task
def greet(name: str) -> None:
print(f'Hello, {name}!')
- Run
clkfrom anywhere inside your project to see your tasks.
$ clk
┏━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┓
┃ Task ┃ Usage ┃
┡━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━┩
│ greet │ clk greet [-h] name │
└───────┴─────────────────────┘
- Run
clk <task> -hto print a task's help.
$ clk greet
usage: clk greet [-h] name
positional arguments:
name
options:
-h, --help show this help message and exit
Finally, run a task:
$ clk greet Peter
Hello, Peter!
Customizing Tasks
- Set a task's name:
from cleek import task
@task('bar')
def foo() -> None:
print('foo function, bar task')
$ clk bar
foo function, bar task
- Set a task's group:
from cleek import task
@task(group='foo')
def bar() -> None:
print('bar task in the foo group')
$ clk foo.bar
bar task in the foo group
- Set a task's style. Used when listing tasks. See Rich's Style documentation for supported styles.
from cleek import task
@task(style='red')
def foo() -> None:
print("I'll be red if you run clk")
- To apply the same customization to many tasks, use
customize()to create a pre-configured version of thetaskdecorator.
from cleek import customize
foo_task = customize('foo', style='red')
@foo_task
def a() -> None: ...
@foo_task
def b() -> None: ...
bar_task = customize('bar', style='blue')
@bar_task
def c() -> None: ...
@bar_task
def d() -> None: ...
$ clk
┏━━━━━━━┳━━━━━━━━━━━━━━━━┓
┃ Task ┃ Usage ┃
┡━━━━━━━╇━━━━━━━━━━━━━━━━┩
│ foo.a │ clk foo.a [-h] │
│ foo.b │ clk foo.b [-h] │
│ bar.c │ clk bar.c [-h] │
│ bar.d │ clk bar.d [-h] │
└───────┴────────────────┘
Async Support
Your tasks can be async functions:
from cleek import task
import trio
@task
async def sleep(duration: float = 1.0) -> None:
print(f'Sleeping for {duration} seconds')
await trio.sleep(duration)
At the moment, trio is the only supported event loop. If want to use another
event loop (I'm guessing asyncio), open an issue and I'll add it.
Finding Tasks
-
If the environmental variable
CLEEKS_PATHis set,clktreats the value as a path and attempts to load it. If the load fails,clkfails. -
clksearches upwards from the current working directory towards the root directory/, looking for acleeks.pyscript or acleekspackage. A script takes precedence over a package if both are found in the same directory.
Supported Parameters
If you get an error saying your task's parameters are not supported, open an issue containing the function signature and I'll add support.
bool
- Keyword
boolwithFalseorTruedefault
def foo(a: bool = False): ...
def foo(a: bool = True): ...
- Keyword optional
boolwithFalse,True, orNonedefault
def foo(a: bool | None = False): ...
def foo(a: bool | None = True): ...
def foo(a: bool | None = None): ...
str
- Positional
str
def foo(a: str): ...
- Positional optional
str
def foo(a: str | None): ...
- Keyword
strwithstrdefault
def foo(a: str = 'a'): ...
- Keyword optional
strwithstrorNonedefault
def foo(a: str | None = 'a'): ...
def foo(a: str | None = None): ...
- Variadic positional
str
def foo(*a: str): ...
int
- Positional
int
def foo(a: int): ...
- Keyword
intwithintdefault
def foo(a: int = 1): ...
- Keyword optional
intwithintorNonedefault
def foo(a: int | None = 1): ...
def foo(a: int | None = None): ...
float
- Positional
float
def foo(a: float): ...
- Keyword
floatwithfloatdefault
def foo(a: float = 1.0): ...
- Keyword optional
floatwithfloatorNonedefault
def foo(a: float | None = 1.0): ...
def foo(a: float | None = None): ...
Literal[T]
- Positional
intliteral
@task
def foo(a: Literal[1, 2, 3]): ...
- Positional
strliteral
@task
def foo(a: Literal['a', 'b', 'c']): ...
- Keyword
intliteral withintdefault
@task
def foo(a: Literal[1, 2, 3] = 1): ...
- Keyword
strliteral withstrdefault
@task
def foo(a: Literal['a', 'b', 'c'] = 'a'): ...
Misc
- Variadic positional
pathlib.Path
from pathlib import Path
@task
def foo(*a: Path): ...
- Variadic positional
trio.Path
from trio import Path
@task
def foo(*a: Path): ...
Shell Completion
clk --completion prints all task names to stdout.
zsh
_complete_clk() {
reply=($(clk --completion))
}
compctl -K _complete_clk + -f clk
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cleek-0.1.0.tar.gz.
File metadata
- Download URL: cleek-0.1.0.tar.gz
- Upload date:
- Size: 96.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7480611e86b91e89046137c0909d56860fe06e8dbfb2ef28dcd0b7a59f69b394
|
|
| MD5 |
db54513cb7ef1b8548c86a34f850caab
|
|
| BLAKE2b-256 |
2020047f03c3a17f1bcf168ad46ba6dfc56021fce7e1138eb15d5e69271e8666
|
File details
Details for the file cleek-0.1.0-py3-none-any.whl.
File metadata
- Download URL: cleek-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
84e388e2d055fc6a76b9fc76836806bebb93deecf69050dfdfab9522c7c9fa31
|
|
| MD5 |
a50184a5017777eff9fae7138cf9fe8f
|
|
| BLAKE2b-256 |
0023ceaac2ad5f14820526d18d0c99ef492db65e928e78107b24747be6388642
|