Why can't I get Environ variables within a Flask script? - python

I have this script:
import os
secret = os.environ.get('MFS')
print(secret)
For some reason, it returns None. I set that environment variable to a secret key that I want to use to set app.config['SECRET_KEY']. But, if I run this command: python3 -c 'import os;print(os.environ.get("MFS"))', it returns the correct environment variable. It doesn't matter if I cd to the project folder and run that or not, it just works. Even though I am using a venv to run the Flask app, that command still works when I run the venv Python. Why is this happening?

Related

How to run bash commands from Python preferably with the os library?

I am trying to run the following python script named test.py. It contains multiple bash commands which I would like to execute in a Linux terminal (unix). This is the content of the file:
import os
os.system('echo install virtualenv')
os.system('sudo pip install virtualenv')
os.system('echo create virtual environment')
os.system('virtualenv my_virtualenvironment')
os.system('echo activate virtual environment')
os.system('source my_virtualenvironment/bin/activate')
I am running the Python script using the following in the terminal:
python3 test.py
The problem that I have is that the commands do not run the same way as they would on a Linux terminal. The output is the following error when trying to execute the last line of the Python script:
sh: 1: source: not found
The last command source my_virtualenvironment/bin/activate normally runs fine if I execute it directly in the terminal (without my Python script). Now, what does sh: 1: mean and why does it not work with my code? I would expect to get something starting with bash: .
Also I have found this solution, but I would like not to use lists for executing commands and maybe even to stick with the os library (if there is a simpler solution without os, I am also open for that):
https://stackoverflow.com/a/62355400/11535508
source is a bash built-in command, not an executable.
Use the full path to the python interpreter in your commands instead of venv activation, e.g. os.system('<venv>/bin/python ...').
The second option is to write your commands into a separate bash script and call it from python:
os.system('bash script.sh')

ModuleNotFoundError: No module named 'hello'

I did something really bad. I don't know what I did. I created a test project with hello.py where I did some mistake when running with some command. Now, I have deleted that and back to the real project, and I got the following error:
File "/home/bhojendra/anaconda3/envs/myenv/lib/python3.9/site-packages/flask/cli.py", line 240, in locate_app
import(module_name)
ModuleNotFoundError: No module named 'hello'
I don't have even the word hello anywhere in the project.
I have removed all pycaches from the project, cleaned the conda conda clean -a, removed myenv environment and removed pip cache directory. Then, I re-created the environment and and re-installed the requirements and when launching the project with flask run, it throws that error again. Not sure what's happening.
It might be the issue with flask cache, I don't know how to overcome this issue.
In your environment, you likely left your FLASK_APP set to the file hello, so it was trying to run that, although it doesn't exist. You just have to export or set your flask app based on what machine you are using.
Unix Bash (Linux, Mac, etc.):
$ export FLASK_APP=hello
$ flask run
Windows CMD:
> set FLASK_APP=hello
> flask run
Windows PowerShell:
> $env:FLASK_APP = "hello"
> flask run
You could also unset the export:
unset FLASK_APP
And then set the flask app

How to set password for snowchange

Trying to run snowchange as explained in the README.
python snowchange/cli.py -a SNOWFLAKE_ACCOUNT -u SNOWFLAKE_USER -r SNOWFLAKE_ROLE -w SNOWFLAKE_WAREHOUSE -d SNOWFLAKE_DATABASE --create-change-history-table
However I do not understand how to set the environment variable for the password.
Tried: Setting the password in an interactive python. It doesn't work as the variable is set only for the current process and when going out of the python command line to execute the command, I don't have access anymore.
You can pass by Powershell command as below
setx SNOWFLAKE_PASSWORD passwordvalue
But make sure when you have a $ sign in password, it can't work from client, you have to add it from GUI User-specific windows envs.
Ref: https://rajivgupta780184.medium.com/database-change-management-tool-schemachange-with-snowflake-overview-b62dec744e0a

Setting up crontab for my Django Application

I had an issue with setting up crontab for my Django application for a week and I have almost figured out the same. (Issue linked with Unable to make a function call using Django-cron)
My crontab -e syntax is
* * * * * /Users/ashwin/dashboard/proj_application/exec.sh >> /Users/ashwin/dashboard/proj_application/data.log 2>&1
And in my exec.sh, I have
#!/bin/bash
cd "$(dirname "$0")";
CWD="$(pwd)"
echo $CWD
python -c 'import proj_application.cron as cron; cron.test()'
And in cron.py,
from django.core.mail import send_mail
from smtplib import SMTP
from email.mime.text import MIMEText
import datetime
def test():
message = "<p>This is test mail scheduled to send every minute</p>"
my_email = MIMEText(message, "html")
my_email["From"] = "xxx#domain.com"
my_email["To"] = "yyy#domain.com"
my_email["Subject"] = "Title"
sender = "person1#domain.com"
receivers = ["person2#domain.com"]
with SMTP("localhost") as smtp:
smtp.login(sender, "yyy#1234")
smtp.sendmail(sender, receivers, my_email.as_string())
Actual Problem:
The crontab is now able to call the exec.sh file and I am able to print $CWD in echo, when the call comes to cron.py, It is unable to recognize django.core.mail and throws the following error.
from django.core.mail import send_mail
ImportError: No module named django.core.mail
I think, I need to set up virtual environment or python variable path somewhere, but since I am new to crontab, I am not sure how to do that.
Any assistance is appreciated. Thanks in advance.
The way I interpret this is that you are normally running your script in a virutal environment, and it is failing now that you added it to a cron job. If this is incorrect, just skip to the last paragraph.
To run a cron job through a virutal environment, you need to use the virtual environment's python as the python you want. E.g to run the cron.py file:
* * * * * /path/to/venv/bin/python3 /path/to/cron.py >> /Users/ashwin/dashboard/proj_application/data.log 2>&1
This is the way I would recommend doing it, as it doesn't seem like that shell script is entirely necessary (anything in there can easily be done at the top of the python script), but if it is you can do something similar where you call the virtual environment's python instead of the default python. like this:
/path/to/venv/bin/python3 -c 'import proj_application.cron as cron; cron.test()'
However, if this doesn't work, this may not be an issue with the cron job, and instead with the django setup of the mail client (e.g. making sure it is included in the installed apps, etc.)
Since it is a little unclear where your issue is (mail client setup, cron setup, venv configuration, etc), if you are sure it is an issue with running your scripts you usually run in a virtual environment, than these steps should help, otherwise I would make sure your mail client is configured correctly. Make sure your scripts are correct by running them in the console (not through a cron job), and then you can come back and update the post with more detailed info about where the problem you have lies.
yes you are correct you may need to use virtual environment(although its optional but best practice).
To create virtual environment(expects python to be installed prior)
python -m venv venv
To activate (path may differ based on OS(mine is windows))
source venv/Scripts/activate
To install dependency in virtual environment
pip install Django
Now you all set to use virtual env's Django.
which python should map to venv path.
Now you have two ways to run python script
#1 use direct python path
absolute/path/of/venv/bin/python3 -c 'import proj_application.cron as cron; cron.test()'
#2 activate virtual environment and use the bash script as same.
#!/bin/bash
cd "$(dirname "$0")";
CWD="$(pwd)"
echo $CWD
source venv/Scripts/python # this will be in windows
python -c 'import proj_application.cron as cron; cron.test()'

Get the a variable defined in the command running python

I have this script named test.py:
import os
print(os.environ['LOL'])
That I run as follow :
(LOL=HAHAHA; python3 test.py)
But it raises a KeyError because it can't find the variable LOL.
I also tried with :
os.getenv('LOL')
But it just returns None.
How can I access to the variable LOL in this context.
You need to supplement the environment variables for the command during which you invoke python3 test.py as follows
$ LOL=HAHAHA python3 test.py
HAHAHA
$ env LOL=HAHAHA python3 test.py
HAHAHA
$ echo $LOL
<empty string>
or you can export the variable for the current session as:
$ export LOL=HAHAHA
$ python3 test.py
HAHAHA
$ echo $LOL
HAHAHA
Simply doing LOL=HAHAHA; python3 test.py doesn't work because that just sets the LOL=HAHAHA variable for the shell process.
Another thing to note, the first approach shown only sets the environment variable for that specific command. It does not set it in the environment. Doing it with the export instead, sets it for the environment. You can see the difference in the values of $LOL above
You are trying to access an environmental variable, so if you are on windows to set it you need to do something like:
set LOL=HAHAHAHA
Then you should be able to access it. To make sure it was set correctly you can also just run:
set
To get a full list of environmental variables.
Just export the variable, i.e. run the command with:
export LOL=HAHA; python3 test.py
or set LOL in the same command, i.e. without the semicolon:
LOL=HAHA python3 test.py
Content of test.py:
import os
print(os.environ['LOL'])

Categories

Resources