Code Monkey home page Code Monkey logo

django-click's People

Contributors

allen-munsch avatar dchiquito avatar flipperpa avatar garetjax avatar joshuadavidthomas avatar lukaszb avatar philipstarkey avatar requires avatar simonpercivall avatar ulope avatar ykshatroff avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-click's Issues

Click 8 is a rejected dependency

A couple of days ago, Click 8 was released. I've since tried using this with a project that has a dependency on Click 8, which led to some invalid dependency resolution due to the fact that django-click specifies a strict upper bound smaller than 7.2. Is there any reason why that limit is enforced, or can it be removed? Alternatively, is there more work that's needed to check that it runs with Click 8 and enable that?

click.exceptions.MissingParameter: None

click==6.6, django-click==1.2.0, django==1.5.12

If the one required parameter is omitted from the following management command, the user sees the error message in the subject of this issue

import djclick as click

@click.command()
@click.argument('name')
def command(name):
   click.secho('Hello, {}'.format(name), fg='red')

If the one required parameter is omitted from the following command, the user sees a better error message.

import click

@click.command()
@click.argument('name')
def hello(name):
    click.secho('Hello, {}'.format(name), fg='red')

if __name__ == '__main__':
    hello()
$ python foo.py 
Usage: foo.py [OPTIONS] NAME

Error: Missing argument "name".

Any ideas? This would seem to be a django-click issue?

call_command replacement

I'm trying to call a djclick based management command using the traditional Django API, django.core.management.call_command and I'm getting this traceback:

Traceback (most recent call last):
  File "_log.py", line 34, in <module>
    call_command('sync_models')
  File "/home/user/.cache/pypoetry/virtualenvs/ht-ZBbfQ9hA-py3.8/lib/python3.8/site-packages/django/core/management/__init__.py", line 135, in call_command
    for group in parser._mutually_exclusive_groups
AttributeError: 'ArgumentParserAdapter' object has no attribute '_mutually_exclusive_groups'

I could do from myproject.myapp.management.commands.my_command import command although the command I'm using is the grouping feature.

What would be the advised methodology to run the command in a programmatic fashion?

Django-click doesn't work with click >= 7.1

When installing a version of click later than 7.0, the djclick import fails with an error:

    import djclick
/usr/local/lib/python3.6/site-packages/djclick/__init__.py:16: in <module>
    __all__ = click.__all__ + ['pass_verbosity']
E   AttributeError: module 'click' has no attribute '__all__'

The click module does not define __all__ as of 7.1 and later.

quotes arguments do not work with django 2.2

I migrated a project using django-click from Django 1.9 to Django 2.2

In Django 1.9 the following command worked:

@click.command(help='Mailer send mail')
@click.argument('schema_url')
@click.argument('token')
@click.argument('subject')
@click.argument('body')
@click.argument('to', nargs=-1)
def command(schema_url, token, subject, body, to):
    click.echo(f'send "{subject}" to "{to}')

when called like this

./manage.py mailer_send http://mailer:8000/mailer/api/schema $token "hello subject" "hello body" [email protected]
With Django 2.2 the same command results in

subject = 'hello'
body = 'subject'
to = ['hello', 'body', '[email protected]']

django-click does not respect the quotes

Use commands.py instead of management/commands/each_one.py

This will allow getting rid of this rediculous deep directory structure and lots of files. It should be still possible to split commands into several files, but python way:

commands/
    __init__.py
    command1.py
    command2.py
    filecommands.py
    utils.py

with commands/__init__.py:

from .command1 import Command1
from .command2 import Command2
from .filecommands import *

Different splitting srategies are possible this way: single file for command or file for some logical command group or just no splitting. Also this resembles how models.py was split.

--help incorrectly repeats command name

Caling a django-click management command with --help incorrectly prints the command name twice. For example, using the official django-click example:

import djclick as click

@click.command()
@click.argument('name')
def command(name):
    click.secho('Hello, {}'.format(name), fg='red')

and calling it

./manage.py testdjclick --help

results in

Usage: manage.py testdjclick testdjclick [OPTIONS] NAME
...

note that testdjclick is repeated?! It should presumably be

Usage: manage.py testdjclick [OPTIONS] NAME

Am using:

Click                    7.0  
Django                   2.1.3     
django-click             2.1.0     

on a Mac under pipenv, Python 3.6.6

Move from Travis CI to Github Actions for CI

Since June earlier this year, Travis CI no longer supports free open source CI. If you look at the Travis builds, you can see they haven't been running since then.

Github Actions has become the defacto standard for CI for open source projects. This repository offers a good template for using a testing matrix against all the different versions of Python & Django this package needs to support.

Raising Abort Causes Stacktrace Instead of Clean Shutdown.

When either sending a SIGINT or using raise click.Abort, I would expect the application to shut down cleanly with the appropriate error code. Instead, I get the following stack trace:

Traceback (most recent call last):
  File "./manage.py", line 24, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.8/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.8/site-packages/django/core/management/__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.8/site-packages/djclick/adapter.py", line 68, in run_from_argv
    exit_code = self.main(
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.8/site-packages/djclick/adapter.py", line 50, in invoke
    return super(DjangoCommandMixin, self).invoke(ctx)
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/srv/service/vite_frontend/management/commands/frontend.py", line 157, in dev
    f.write(f"{app.name}\n{process.pid}\n")
  File "/usr/local/lib/python3.8/contextlib.py", line 120, in __exit__
    next(self.gen)
  File "/srv/service/vite_frontend/management/commands/frontend.py", line 70, in run_vite
    yield process
  File "/usr/local/lib/python3.8/contextlib.py", line 120, in __exit__
    next(self.gen)
  File "/srv/service/vite_frontend/management/commands/frontend.py", line 47, in run_in_app
    raise click.Abort()

We have worked around this by instead throwing a SystemExit exception, but it would be nice to be able to use Abort

Typer Integration

I am usually using Typer on top of Click for command line. This gives a nice way to use Type hints to define variables.
https://typer.tiangolo.com

How complex do you think it would be to have a Typer adopter for django-click?

stdout does not work on `call_command`

Assuming we have a command named foo...

import io

buffer = io.StringIO()
from django.core.management import call_command
call_command("foo", stdout=buffer)
out = buffer.getvalue()
assert "whatever" in out

This is not possible with django-click, instead saying:

TypeError: Unknown option(s) for dumb command: stdout. Valid options are: color, h, help, pythonpath, settings, traceback, v, verbosity, version.

Environment

  • Django 3.2.5
  • Python 3.8
  • Poetry 1.1.7
  • Pytest 6.2.4
  • Pytest Django 4.4.0
  • (if relevant) Ubuntu 20.04

Can't pass "help" parameter to click argument

The following script works with the base click library but raises an exception with the django-click library.

import djclick as click

@click.command()
@click.argument("name", help="Some name")
def command(name):
    click.echo(f"Hi {name}!")

Exception:

Traceback (most recent call last):
  File "/app/./manage.py", line 22, in <module>
    main()
  File "/app/./manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py", line 395, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py", line 244, in fetch_command
    klass = load_command_class(app_name, subcommand)
  File "/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py", line 37, in load_command_class
    module = import_module('%s.management.commands.%s' % (app_name, name))
  File "/usr/local/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 790, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/app/core/management/commands/click1.py", line 6, in <module>
    def command(name):
  File "/usr/local/lib/python3.9/site-packages/click/decorators.py", line 168, in decorator
    _param_memo(f, ArgumentClass(param_decls, **attrs))
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1984, in __init__
    Parameter.__init__(self, param_decls, required=required, **attrs)
TypeError: __init__() got an unexpected keyword argument 'help'

ClickExceptions with no ctx cause an error

Doing something as simple as raise ClickException('my error message') results in an error being thrown during the handling of the ClickException:

Traceback (most recent call last):
  File "/home/daniel.chiquito/envs/dandi-api/lib/python3.8/site-packages/djclick/adapter.py", line 69, in run_from_argv
    exit_code = self.main(
  File "/home/daniel.chiquito/envs/dandi-api/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/daniel.chiquito/envs/dandi-api/lib/python3.8/site-packages/djclick/adapter.py", line 51, in invoke
    return super(DjangoCommandMixin, self).invoke(ctx)
  File "/home/daniel.chiquito/envs/dandi-api/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/daniel.chiquito/envs/dandi-api/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/daniel.chiquito/git/dandi-api/dandiapi/api/management/commands/collect_garbage.py", line 26, in collect_garbage
    raise click.ClickException('my error message')
click.exceptions.ClickException: my error message

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "./manage.py", line 20, in <module>
    main()
  File "./manage.py", line 16, in main
    execute_from_command_line(sys.argv)
  File "/home/daniel.chiquito/envs/dandi-api/lib/python3.8/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
    utility.execute()
  File "/home/daniel.chiquito/envs/dandi-api/lib/python3.8/site-packages/django/core/management/__init__.py", line 413, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/daniel.chiquito/envs/dandi-api/lib/python3.8/site-packages/djclick/adapter.py", line 76, in run_from_argv
    if getattr(e.ctx, "traceback", False):  # NOCOV
AttributeError: 'ClickException' object has no attribute 'ctx'

The error is occurring here:

except click.ClickException as e:
if getattr(e.ctx, "traceback", False): # NOCOV
raise
e.show()
sys.exit(e.exit_code)

The problem is that many subclasses of ClickException include a ctx, but not all: https://github.com/pallets/click/blob/9da166957f5848b641231d485467f6140bca2bc0/src/click/exceptions.py

Feature Request: Make click management commands discoverable and runnable via django admin

It would be cool if these commands could be available via Django admin with auto generated form fields to provide inputs based on the click command definition. This likely falls out of the scope of this project but would come in handy for discoverability and ease of use. Output from the command could be downloaded after run or dumped in the browser window potentially.

Add typing annotations

Hi and thanks for maintaining this convenient library. It really makes our management commands look a lot cleaner.
What's missing for us at the moment, though, is typing annotations, since we're running mypy on all of our code.

Right now we're working around this by creating a stub for mypy to use, but it would obviously be much better to have first party type annotations. Is this something that's planned/you're interested in adding?

Thanks for considering :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.