2

Some time ago I created a script using Python, the script will execute some actions in an instance based on a configuration file.

This is the issue, I created 2 configuration files.

Config.py

instance= <Production url>
Value1= A
Value2= B
...

TestConfig.py

instance= <Development url>
Value1= C
Value2= D
...

So when I want the script to execute the tasks in a development instance to do tests, I just import the TestConfig.py instead of the Config.py.

Main.py

# from Config import *
from TestConfig import *

The problem comes when I update the script using git. If I want to run the script in development I have to modify the file manually, this means that I will have uncommited changes in the server.

Doing this change takes about 1 min of my time but I feel like I'm doing something wrong.

Do you know if there's a standard or right way to accomplish this kind of tasks?

Geoffrey-ap
  • 380
  • 3
  • 12

4 Answers4

2

Use that:

try:
    from TestConfig import *
except ImportError:
    from Config import *

On production, remove TestConfig.py

Daniel
  • 573
  • 6
  • 14
1

Export environment variables on your machines, and chose the settings based on that environment variable.

DhruvPathak
  • 42,059
  • 16
  • 116
  • 175
  • Thanks for your answer. I'm currently running the script in the same machine. Should I deploy the script in 2 different servers(the one from production and the one from development) and then modify the script to run according to the environment variables? – Geoffrey-ap Apr 19 '16 at 18:32
0

I think Django addresses this issue best with local_settings.py. Based on this approach. at the end of all your imports (after from config import *), just add:

# Add this at the end of all imports
# This is safe to commit and even push to production so long as you don't have local_config in your production server
try:
    from local_config import *
except ImportError:
    pass

And create a local_config.py per machine. What this will do is import everything from config, and then again from local_config, overriding global configuration settings, should they have the same name as the settings inside config.

Community
  • 1
  • 1
Bahrom
  • 4,752
  • 32
  • 41
0

The other answers here offer perfectly fine solutions if you really want to differentiate between production and test environments in your script. I would advocate for a different approach, however: to properly test your code, you should create an entirely separate test environment and run your code there, without any changes (or changes to the config files).

I can't make any specific suggestions for how to go about this since I don't know what the script does. In general though, you should try to create a sandbox that spoofs your production environment and is completely isolated. You can create a wrapper script that will run your code in the sandbox and modify the inputs and outputs as necessary to make your code interact with the test environment instead of the production environment. This wrapper is where you should be choosing which environment the code runs in and which config files it uses.

This approach abstracts the testing away from the code itself, making both easier to maintain. Designing for test is a reasonable approach for hardware, where you are stuck with the hardware you have after fabrication, but it makes less sense for software, where wrappers and spoofed data are easier to manage. You shouldn't have to modify your production code base just to handle testing.

It also entirely elimiates the chance that you'll forget to change something when you want to switch between testing and deployment to production.

skrrgwasme
  • 9,358
  • 11
  • 54
  • 84