I recently came across Fabric, a library that can be used for deployment or system administration tasks. To check out the most basic usage refer this tutorial. I’m going to assume that now you have a basic understanding of Fabric.
You run fabric using the fab
command on the terminal. This is efficient if you are using the terminal but what about a web app? In my case, I had to run a script in a remote machine, fetch it’s results and enable/disable certain fields in a form.
Easy right? Just add a few environment variables in the python file and you are done! Not really.
Fun Fact
Fabric environment settings cannot be accessed over your web app using the typical syntax mentioned in the docs.
Examples that will NOT work:
- @hosts
- env.hosts = [‘myserver1’]
When the app started running, it would prompt me for username and password on the console which is not what I could do on Production.
Enter “settings” context manager
Fabric provides a settings context manager, which takes any number of key/value pairs and will use them to modify env within its wrapped block. Read more…
Talk is cheap, show me the code
Here’s a sample of the code I implemented –
fabric_tasks.py
from fabric.api import settings, run
from app import app
HOST_STRING = app.config.get('FABRIC_ENV_HOST')
USER = app.config.get('FABRIC_ENV_USER')
PASSWORD = app.config.get('FABRIC_ENV_PASSWORD')
def list_users():
# `warn_only` if set to true will make sure your whole module does not error
# out inside the with block
# in `host_string` you can pass user@hostname as well instead of including
# the `user` argument
with settings(warn_only='true', host_string=HOST_STRING, user=USER,
password=PASSWORD, connection_attempts=5, keepalive=10,
timeout=15):
output = run("cat /etc/passwd")
return output
init.py
from fabric_tasks import list_users
from Flask import jsonify
@app.route('/listusers/')
def server_list_users():
response = list_users()
if response:
jsonify(users=response, success=true)
else:
jsonify(users=None, success=false)
That’s all folks!