Home > Software engineering >  Change parts of code automatically on deployment
Change parts of code automatically on deployment

Time:10-12

I have a small Python flask project that uses SSH tunneling to access a remote database hosted in Pythonanywhere. However, on deployment (to a server that also serves the database), the database has to be accessed without SSH. Does anyone have any tricks on how to make the code "detect" if the code is run on the server vs. on a client? The code is shown below. Currently I have to remember to change the onServer variable before deploying to make the database still accessible.

from flask import request, Flask, render_template, send_from_directory, url_for
from flask_sqlalchemy import SQLAlchemy
import sshtunnel

sshtunnel.SSH_TIMEOUT = 5.0
sshtunnel.TUNNEL_TIMEOUT = 5.0

app = Flask(__name__)
app.jinja_env.filters['zip'] = zip
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 1

onServer = 1
if onServer:
    app.config['SQLALCHEMY_DATABASE_URI']='mysql://username:[email protected]/username$default'
    
else:
    # SSH to pythonanywhere to get access to database
    tunnel = sshtunnel.SSHTunnelForwarder(
        ('ssh.pythonanywhere.com'),
        ssh_username='username',
        ssh_password='password',
        local_bind_address=("127.0.0.1",1000),
        remote_bind_address=('username.mysql.pythonanywhere-services.com', 3306)
    )

    # Start SSH tunneling
    tunnel.start()
    app.config['SQLALCHEMY_DATABASE_URI']='mysql://username:[email protected]:{}/username$default'.format(tunnel.local_bind_port)

db = SQLAlchemy(app)

CodePudding user response:

Detecting whether you're on the server is an example of environment detection: determining what environment your script is running in.

An easy way to provide this information to your script is by using environment variables. These can be set on your server, and picked up in your Python code using os.environ.

You can get a given environment variable using os.environ.get() -- this will return None if the variable is not set in the current environment.

import os

>>> ON_SERVER = os.environ.get('ON_SERVER')
>>> ON_SERVER
>>> type(ON_SERVER)
<class 'NoneType'>

Your can compare the result against None to get a True or False value if you prefer (although None is already falsey).

>>> ON_SERVER = os.environ.get('ON_SERVER') is not None
>>> ON_SERVER
False

Below I set the ON_SERVER environment variable in the shell -- here using export (Linux/Unix/Mac) you can see the result

martin@MacBook ~ % export ON_SERVER=yes
martin@MacBook ~ % python3
Python 3.9.6 (default, Jun 29 2021, 06:20:32)
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> ON_SERVER = os.environ.get('ON_SERVER') is not None
>>> ON_SERVER
True

Inside Python, I am now detected as being "on the server" since the environment variable is set.

Note that all environment variables are strings, and all non-empty strings in Python are truthy. So it doesn't matter what you set the environment variable to.

  • Related