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
Related
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.
In Python I can access an environment variable as:
os.environ['FOO']
I would like to know if the variable was set previously via export or if it was set only for the current python script like so:
FOO=BAR python some-script.py
Basically I want to only use FOO if it was set like in the line above and not permanently defined per export.
Arguments to the python script itself unfortunately are no option here. This is a plugin and the parent application does not allow passing custom arguments it does not understand itself.
I was hoping I somehow could access the exact and full command (FOO=BAR python some-script.py) that started python but it appears like there is nothing like that. I guess if there was a feature like this it would be somewhere in the os or sys packages.
The environment is simply an array of C strings, there is no metainformation there which helps you find out whether or not the invoking shell had the variable marked for export or not.
On Linux, you could examine /proc/(pid)/environ of the parent PID (if you have suitable permissions) to see what's in the parent's permanent environment, but this is decidedly nonportable and brittle.
Spending time on this seems misdirected anyway; let the user pass the environment variable in any way they see fit.
Usually, it is a good idea to load a configuration from a configurable file. This is what from_envvar() can do, replacing the from_object() line above:
app.config.from_envvar('FLASKR_SETTINGS', silent=True)
That way someone can set an environment variable called FLASKR_SETTINGS to specify a config file to be loaded which will then override the default values. The silent switch just tells Flask to not complain if no such environment key is set.
I am not too familiar with environment variables. I would like an explanation of the above paragraph in simple terms. My best guess is that when the program reads FLASKR_SETTING does that mean that on my own computer I have set up a mapping to this file with that name with something called an environment variable? Ive messed with my environment path before and to be honest I still don't understand it, so I came here looking for a clear answer
Environment variables are a name,value pair that are defined for a particular process running on a computer (windows or UNIX/LINUX etc.). They are not files. You can create your own environment variables and give it any name/value. For example, FLASKR_SETTING is the name of the environment variable who value could be set to a config file. On a UNIX terminal for example, you can do:
export FLASKR_SETTING = /somepath/config.txt
By doing the above, you have just created an environment variable named FLASKR_SETTING whose value is set to /somepath/config.txt. The reason you use environment variables is because you can tie them to a certain process and use on demand when your process starts. You don't have to worry about saving them in a file. In fact, you can create a launch script for your process/application that can set a variety of environment variables before you starting using the application.
In case of flask, app.config.from_envvar('FLASKR_SETTINGS', silent=True) sets the value of FLASKR_SETTINGS to the value from the env. variable. So it basically translates to:
- Find the config file (/somepath/config.txt etc.)
- lets say the contents of config file is:
SECRET_KEY="whatever"
DEBUG = True
- Then using the 2 above, it will be translated to:
app.config['SECRET_KEY'] = "whatever"
app.config['DEBUG'] = True
So this way, you can just update the config file as needed and you will not need to change your code.
Environment variables are a simple, ad-hoc way of passing information to programs. On unixy machines, from a command shell, it's as simple as
export FLASKR_SETTINGS=/path/to/settings.conf
/path/to/program
This is especially useful when installing programs to start up at reboot; the configuration can be easily included in the same setup script that launches the system program.
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.
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.