Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inspect sys.argv for --projects with argparse before click #283

Merged
merged 10 commits into from
Jun 26, 2019

Conversation

juhoinkinen
Copy link
Member

This is just first trial, here's some thoughts:

At first the best way to set the path to projects.cfg seemed to use some click decorator, but the first problem with this approach is that the cli methods are defined only after the app is already created in https://github.com/NatLibFi/Annif/blob/master/annif/cli.py#L22:
cli = FlaskGroup(create_app=annif.create_app)

Also I could not yet find a way to add an option to be used directly after annif, i.e. which would apper along --version and --help in help:

$ annif
Usage: annif [OPTIONS] COMMAND [ARGS]...

Options:
  --version  Show the flask version
  --help     Show this message and exit.

But this is possible, https://kite.com/blog/python/python-command-line-click-tutorial, I just can't get it work in this case when FlaskGroup is involved.

So for now, this first attempt inspects sys.argv with argparse for --projects and uses its value to set the env ANNIF_PROJECTS which in turn sets the path to projects.cfg. This works, but

  • uses argparse just for the --projects flag, when click is used for other cli cases
  • the option is not shown in help (along --version and --help)
  • is not very testable

Maybe the FlaskGroup should be wrapped in custom class as in https://stackoverflow.com/questions/44056153/optional-argument-in-command-with-click

@codecov
Copy link

codecov bot commented Jun 18, 2019

Codecov Report

Merging #283 into master will increase coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #283      +/-   ##
==========================================
+ Coverage   99.31%   99.32%   +<.01%     
==========================================
  Files          52       52              
  Lines        2624     2651      +27     
==========================================
+ Hits         2606     2633      +27     
  Misses         18       18
Impacted Files Coverage Δ
annif/project.py 100% <100%> (ø) ⬆️
annif/cli.py 99.46% <100%> (+0.03%) ⬆️
annif/__init__.py 88.46% <100%> (+0.46%) ⬆️
tests/test_cli.py 100% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a2d3be4...882eec4. Read the comment docs.

@osma
Copy link
Member

osma commented Jun 19, 2019

This was for #210

Some thoughts:

It'd be better to be able to use Click. I'm a bit nervous about combining two different ways of processing command line arguments. For one thing, Click generates nice help texts. Argparse does that too, but both cannot work at the same time. After this change, annif --help has lost all information about Click-based commands:

$ annif --help
usage: annif [-h] [--projects [PROJECTS]]

Optional app description

optional arguments:
  -h, --help            show this help message and exit
  --projects [PROJECTS]
                        An optional path to projects.cfg.

The order of parameters is not crucial. The --projects argument could come after the subcommand instead of before:

annif suggest --projects /etc/annif/projects.cfg tfidf-en <file.txt

But the initialization order is difficult. Right now the value is passed via os.environ, which seems a bit wrong - an explicit parameter for create_app would be better.

It seems to me that the first time the projects file is actually needed is when create_app calls annif.project.initialize_projects. Perhaps that initialization could be delayed, so that there is still a possibility to change the projects file path from within CLI functions and the projects would be initialized lazily only when they are actually needed for the first time?

@juhoinkinen juhoinkinen marked this pull request as ready for review June 26, 2019 12:37
@juhoinkinen
Copy link
Member Author

Code-wise ready for review. I'm not really sure what to do with the failing quality checks, I'll look at the failed Drone build (it should not even be building for this).

Copy link
Member

@osma osma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks very good.

The Code Climate complaints can be ignored. I think that in general this PR improves the overall code quality, thanks to the @common_options decorator, despite the small additional complexity it introduces.

The test should be split into two separate functions, but other than that, this is OK for merging.

assert 'Project configuration file "{}" is missing.'.format(
nonexistent_file) in result.output

result = runner.invoke(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is testing a different situation (existing config file), so it should be separated into its own test.

@juhoinkinen juhoinkinen merged commit f9b1294 into master Jun 26, 2019
@osma osma added this to the v0.41 milestone Jun 28, 2019
@juhoinkinen juhoinkinen deleted the issue210-cli-option-path-to-projects-file branch August 15, 2019 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants