I am working on a series of command line tools which connect to the same server and do related but different things. I'd like users to be able to have a single configuration file where they can place common arguments such as connection information that can be shared across all the tools. Ideally, I'd like something that does the following for me:
If the server address is specified at the command line use this and ignore any other values
If the server address is not specified at the command line but is in a config file that is specified at the command line use this address. Ignore any other values.
If the server address is not specified at the command line or a config file specified at the command, but is available in a in a config file in the user's home directory (say .myapprc), use this value.
If the server address is not specified in any of the above mechinisms exit with an error message.
The closest I've seen to this is the configparse module, which from what I can tell offers an option parser that will also look at config files, but does not seem to have the notion of "Must be specified somewhere" which I need.
Does anyone know of an existing module that can cover my use case above? If not, a simple extension to optparse, configparse, or some other module I have not reviewed would also be greatly appreciated.
This-party module configparse is written to extend optparse from the standard Python library. As the optparse docs I pointed to mention, "optparse doesn’t prevent you from implementing required options, but doesn’t give you much help at it either" (though it follows with a couple of URLs that show you ways to do it). Simplest is to use the default value functionality: specify a default value that's not actually a legal value (for something like a server's address, that's pretty easy) -- then, once options are processed, verify that the specified value is legal (which is a good idea anyway!-) and raise the appropriate exception otherwise.
I've used opster's middleware feature together with SafeConfigParser to achieve a similar (but slightly simpler) effect as you ask. You have to implement the specific logic you described yourself, but it assists you enough to make it relatively painless. An example of opster's middleware use is in its test/test.py example.
use a dict to store options to your program.
first parse the option file in the user's directory and store every options in a dict (configparse or any other module is welcome). then parse the command line (using any module you want, optparse might fit well), if an arguments specifies a config file, parse the specified file in a dict and update your options from what you read (dict.update is really handy to merge 2 dict). then store all other arguments into another dict, and merge them again (dict.update again...).
this way, you are sure that the dict in which you stored the options contains the value you want, which was either read from the user's file, from the specified config file or directly from the command line. if it does not contain a required value, exit with an error.
Related
What I'm trying to do is load a list of custom variables depending upon whether I want to run against my production server or my development server. The program that I'm writing uses argparser to parse the arguments username, server_ip, server_version, and optionally, a password. I would like to modify the launch.json file to specify whether I'm running this configuration against prod or dev, and depending upon which, loads the variables from its respective file.
Any recommendations? Thanks in advance!
I've tried using the envFile functionality and then just setting argparse to call os.environ.get() for each respective argument's default, but I had to specify nargs='?' which with multiple positional arguments, I feel like would cause issues if one happened to be omitted.
With the extension Command Variable and the command extension.commandvariable.pickStringRemember you can pick an item in the pick list prod or dev that set a number of things to remember. And then use extension.commandvariable.remember and use the values stored in strings of the args argument of the launch config
See the example: task that picks multiple values
I'm stuck in a rock and a hard place.
I have been given a very restricted Python 2/3 environment where both os and subprocess library are banned. I am testing file upload functionality using Python selenium; creating the file is straight forward, however, when I use the method driver.send_keys(xyz), the send_keys is expecting a full path rather than just a file name. Any suggestions on how to work around this?
I do not know if it would work in very restricted Python 2/3, but you might try following:
create empty file, let say empty.py like so:
with open('empty.py','w') as f:
pass
then do:
import empty
and:
pathtofile = empty.__file__
print(pathtofile)
This exploits fact empty text file is legal python module (remember to set name which is not use) and that generally import machinery set __file__ dunder, though this is not required, so you might end with None. Keep in mind that if it is not None then it is path to said file (empty.py) so you would need to further process it to get catalog itself.
with no way of using the os module it would seem you're SOL unless the placement of your script is static (i.e. you define the current working dirrectory as a constant) and you then handle all the path/string operations within that directory yourself.
you won't be able to explore what's in the directory but you can keep tabs on any files you create and just store the paths yourself, it will be tedious but there's no reason why it shouldn't work.
you won't be able to delete files i don't think but you should be able to clear their contents
I would like to pass command line arguments to pycharm script from file.
I am aware command line arguments can be passed via run->edit configurations -> parameters.
This method is not good enough for me because
In some cases the parameters line gets deleted. not sure why, maybe git-pull? maybe other reason.
I want several configurations, and I want to save them in source control
I want to set those parameters programaticaly.
I think taking command-line arguments from some config file would solve all my problems.
How can I do that?
EDIT1:
Use case example, as it seems my point isn't perfectly clear:
I want to debug my code in pycharm with some configuration. add some breakpoints, go line by line.
Next I want to change configuration and debug again, with pycharm.
Doing this with some script that hacks the pycharm file where the run configurations are stored seems to me like going too far.
Does pycharm offer no way to give it command line parameters from file?
PyCharm lets you have unlimited named runtime configurations, as you appear to know, so I am a little puzzled that you ask. Click on the current configuraton name to the left of the green Run arrow, top right, then Edit Configurations.
These configurations live in workspace.xml. Nothing stopping you from checking it in.
For programs that take complex command line parameters it is traditional to provide a way to read the values from a named file, typically introduced by #. In argparse you specify this as follows:
parser = argparse.ArgumentParser(fromfile_prefix_chars='#')
Arguments read from a file must by default be one per line.
Create shell scripts calling the Python script the way you need.
I need some Python module to support forwarding command line arguments to other commands.
argparse allows to parse arguments easily, but doesn't deliver any "deparsing" tool.
I could just forward os.sys.argv if I hadn't need to delete or change values of any of them, but I have.
I can imagine myself a class that just operates on array of strings all the time, without losing any information, but I failed finding any.
Does somebody know such tool or maybe met similar problem and found out another nice way to handle?
(Sorry for English :()
If you use the subprocess module to run the commands with delegated arguments you can specify your command as a list of strings that won't be subject to shell parsing (as long as you don't use shell=True). You therefore don't need to bother about quoting concerns the same way you would if you were reconstructing a command line. See https://docs.python.org/2/library/subprocess.html#frequently-used-arguments for further details.
I am writing a command-line plugin-based program where the plugins will provide additional functionality on top of whatever I provide.
So for example suppose I wrote a simple script that parsed images and stored them, and that's all I do. Then someone else can write a set of scripts to manipulate the image, putting his scripts in a plugin.
The plugin would be loaded and users can access the plugin by specifying its name in the command line.
It is not uncommon for scripts to want to provide additional options for the user.
So suppose in some years, 20 different plugins have been written.
Now, all of the authors want to allow users to provide options, so the main engine should take the user's options and pass them to the plugin so that it can handle them however it wants.
To keep it uniform, they might agree that certain options should perform a similar operation. Like "-o name" should set the output name to "name". They would then go about implementing their own options and stuff, which the main engine does not know about (of course, it shouldn't know what the plugins do)
I am using the deprecated getopt module, and it will throw exceptions whenever I specify an undefined option. I have heard of optparse and argparse, but I am not sure if these will allow the user to specify any options he wants without the code throwing an exception.
How can I make it so I can specify any command-line option?
argparse lets you partially parse an argument list with the parse_known_args method, returning what was parsed correctly, together with a list of the remaining arguments.
The solution you want is probably to treat the command line arguments as a sort of in process pipeline. Which options are also a part of where the options may go.
command <global options> sub_command <sub_options> new_sub_command <new_sub_options>
each command will shift options off of sys.argv until it finds one it doesn't understand, or one that cannot be a valid option, and then it stops parsing arguments, does its job, and returns control to the plugin-dispatcher.