Skip to main content
# clilabs: the python CLI framework for getting things done

```
$ pip install clilabs
```

Try with your own command first, put this in example.py:

```
def main(*args, **kwargs):
print(f'Args: {args}')
print(f'Kwargs: {kwargs}')
```

Note that you can also use the example.py at the root of the repo for testing
purposes.

You invoke your own functions by defining the main function in a python module
that takes args and kwargs:

```
$ clilabs example.main somearg somekwarg=1
```

Note that you can either omit `:main` that is the default,
either target a callable:

```
$ clilabs example:SomeClass.some_attr.somestaticmethod
```

If an argument starts with `-`, it will be available with in the context object
you can import from clilabs. Change example.py to the following:

```
def main(*args, **kwargs):
print(f'Args: {args}')
print(f'Kwargs: {kwargs}')

from clilabs import context
print(f'Context args: {context.args}')
print(f'Context kwagrs: {context.kwargs}')
```

Now try:

```
$ clilabs your.module --noinput -c=2
```

The tradeoff is that you cannot use space to delimit key from value because
that would confuse the lexer which wouldn't be able to distinguish value from
un-named argument:

```
# results in context.args == ['c'] and args == ['somearg']
# NOT in context['c'] == 'somearg'
$ clilabs your.module -c somearg
```

When it finds only a `-` alone then it will read stdin for a value:

```
$ echo bar | clilabs example -
```

If you want to get the help of a command, sorry but this framework is too
stupid. However, you can try to read its docstring with the builtin
introspection command:

```
# docstring of function
$ clilabs clilabs.inspect:doc your.mod:main

# docstring of module
$ clilabs clilabs.inspect:doc clilabs.django
```

Pycli also bundles a nice bunch of functions for Django, for now it has a
django submodule that defines a bunch of CLI functions:

```
# find the content for this variable in your project manage.py
# because automated software should be available automatically
# changing INSTALLED_APPS is considered a manual operation
$ export DJANGO_SETTINGS_MODULE=your.settings

# you will probably run this from your directory parent to manage.py:
$ clilabs clilabs.django:create auth.user username=pony is_superuser=1

# i just checked and chpasswd command in django supports only interactive
$ clilabs clilabs.django:chpasswd /path/to/password username=pony

# supports stdin too with -
$ echo yourpassword | clilabs.django:chpasswd - username=pony

# find stuff:
$ clilabs clilabs.django:list auth.user username is_superuser
| pk | username | is_superuser |
| 1 | pony | True |
| 2 | ninja | False |

# and filter
$ clilabs clilabs.django:list auth.user username is_superuser=true
| pk | username | is_superuser |
| 1 | ninja | True |

# count supports filters too
$ clilabs clilabs.django:count is_superuser=true
1

# delete stuff, would be nicer with --noinput
$ clilabs clilabs.django:delete auth.user username=pony --noinput
1

# you can use other models
$ clilabs clilabs.django:create sites.site name='awesome site' domain=awesome.com
$ clilabs clilabs.django:list admin.logentry
$ clilabs clilabs.django:detail auth.groups pk=1

# and of course your own apps:
$ clilabs yourapp.cli:dosomething with_that_arg with_that_kwarg=1 --noinput --othercontextarg=1
```

## Why not use a management command ?

**Because automation software should be automatically made available in an
automated way.**

That means, having to add it to INSTALLED_APPS is: no because it's a manual
operation.

## Why is it not available as management command ?

Because we need to break out of the framework's inversion of control to make
such a rich user experience from the command line: with dynamic options.

## Why not use click ?

I really wonder how to use click to work out with this weird cli.

## Do you have crazy ideas for new django functions ?

Always, why not being able to run a forms on the command line given a dotted
import path, both in interactive, and non interactive mode ?

Or, why not provision a model from a file tree of YAML files to replace
loaddata ?

Last time I needed those features, I passed, but it's over now.

Release files for clilabs 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 clilabs 0
File Size Uploaded
clilabs-0.tar.gz 4.4 kB Details

Release files / clilabs-0.tar.gz

Download URL clilabs-0.tar.gz
Size 4.4 kB
Tags Source
SHA-256 checksum
How to use checksums
8d222fe2ed7d1b2f8434a6de3b1ea225ea7d18e0f30f42a2461bfd5861449c16
BLAKE2b-256 checksum
How to use checksums
f3b6867e691443d48849e1b3cd00fda3b9b472040ca980abaef2dc844af12eb4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Python-urllib/3.7

Release history Release notifications | RSS feed

1.3.1

1 release file

1.3.0

1 release file

1.2.3

1 release file

1.2.2

1 release file

1.2.0

1 release file

1.1.10

1 release file

1.1.1

1 release file

1.1.0

1 release file

1.0.1

1 release file

1.0.0

1 release file

0.3.2

1 release file

0.3.1

1 release file

0.3.0

1 release file

0.2.0

1 release file

0.1.0

1 release file

This release

0 This release

1 release file

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