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.