How would I do the following in my wsgi file, which is imported by apache on production?
$ source env_template.sh
$ python manage.py runserver
>>> Stage: debugging
Validating models...
In my settings file I have stuff like the following, which source sets:
AWS_ACCESS_KEY = os.environ['AWS_ACCESS_KEY']
I would like apache to load all the variables in env_template.sh on starting it. Am I able to do that in the wsgi.py file?
Not in any sane manner. I recommend that you either restrict the file to simple "key=value" lines and then parse it out, or move the specific values to separate files and then read them out in both scripts.
Related
My project structure looks like this: backend/src/apps/app_name/tests/foo.py and when I'm trying to run the tests by entering a command python manage.py test it runs 0 tests. The only correct way to test is python manage.py test src.apps.app_name but I'm to lazy to do it with every app. 😄
Change
backend/src/apps/app_name/tests/foo.py
to
backend/src/apps/app_name/tests/test_foo.py
Make sure all your test files and functions start with test
I have custom locale path in my settings
PROJECT_ROOT = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
LOCALE_PATHS = (
os.path.join(PROJECT_ROOT,'templates','v1','locale'),
)
but when i'm trying to create .po files, i've get error:
$ python manage.py makemessages --locale=ru
CommandError: This script should be run from the Django Git tree or your project or app tree. If you did indeed run it from the Git checkout or your project or application, maybe you are just missing the conf/locale (in the django tree) or locale (for project and application) directory? It is not created automatically, you have to create it by hand if you want to enable i18n for your project or application.
Why django doesn't want to use LOCALE_PATHS?
Absolute paths are:
PROJECT_ROOT = '/home/creotiv/ENVS/project_env/project/project'
LOCALE_PATHS = ('/home/creotiv/ENVS/project_env/project/project/templates/v1/locale')
PS: Also i added translation to main app and django doesnt see it either.
First things first; You need to give correct path of the manage.py to the python.
$ python /path/to/the/manage.py makemessages --locale=ru
Or go to directory which is included manage.py. After that run that command you've wrote in your question.
$ python manage.py makemessages --locale=ru
Next; Did you create ./templates/v1/locale directories under the project home?
According to error you may check existence of the ./templates/v1/locale' folder.
Also; You may need to append LANGUAGES setting in to project settings.py file:
LANGUAGES = (
('ru', _('Russian')),
('en', _('English')), # (Optional)
)
Appendix:
If you are developing under virtual environment, do not forget to enable virtual environment first.
Maybe you have to go inside the app or project directory. Try this:
$ ls # should return also the manage.py
$ cd myproject
$ ls # should return also the settings.py
$ python ../manage.py makemessages --locale=ru
Just updated to django 1.7 and problem gone.
Synopsis of problem:
I want to use django-pytest to test my django scripts yet py.test complains that it cannot find DJANGO_MODULE_SETTINGS. I have followed the documentation of django-pytest for setting DJANGO_MODULE_SETTINGS. I am not getting the expected behavior from py.test.
I would like help troubleshooting this problem. Thank you in advance.
References—django-pytest documentation
Setting the DJANGO_SETTINGS_MODULE in virtualevn postactivate script:
In a new shell, the $DJANGO_SETTINGS_MODULE is not set.
I expect that the $DJANGO_SETTINGS_MODULE would be None. It
is.
In: echo $DJANGO_SETTINGS_MODULE
Out:
Contents of .virtualenv/browsing/bin/postactivate
As documented in the django-pytest documents, one may set
$DJANGO_SETTINGS_MODULE by exporting it in the postactivate
script for virutalenv.
export DJANGO_SETTINGS_MODULE=automated_browsing.settings
At terminal cli:
As expected, $DJANGO_SETTING_MODULE is defined.
# activate the virtualenv
In: workon browsing
In: echo $DJANGO_SETTINGS_MODULE
Out: automated_browsing.settings
As expected, the settings module is set as shown when the server runs:
# cd into django project
In: cd ../my_django/automated_browsing
# see if server runs
In: python manage.py runserver
Out: # output
Validating models...
0 errors found
September 02, 2014 - 10:45:35
Django version 1.6.6, using settings 'automated_browsing.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
In: ^C
As NOT expected, py.test cannot find it.
In: echo $DJANGO_SETTINGS_MODULE
Out: automated_browsing.settings
In: py.test tests/test_browser.py
Out: …
_pytest.config.UsageError: Could not import settings
'automated_browsing.settings'
(Is it on sys.path? Is there an import error in the settings file?)
No module named automated_browsing.settings
installed packages
Django==1.6.6
EasyProcess==0.1.6
PyVirtualDisplay==0.1.5
South==1.0
argparse==1.2.1
ipython==2.2.0
lxml==3.3.6
psycopg2==2.5.4
py==1.4.23
pytest-django==2.6.2
pytest==2.6.1
selenium==2.42.1
test-pkg==0.0
wsgiref==0.1.2
Had the same problem today. In the project/settings/ you have to create init.py . Like this django recognize the folder.
In my case I just typed __inti__.py which was wrong. I corrected inti.py --> init.py and it works fine.
Hope it helps.
V.
Inspired by this answer, I have solved my problem.
According to the django-pytest documentation for managing the python path:
By default, pytest-django tries to find Django projects by
automatically looking for the project’s manage.py file and adding its
directory to the Python path.
I assumed that executing py.test tests/test_browser.py inside of the django project containing manage.py would handle the PYTHONPATH. This was an incorrect assumption in my situation.
I added the following to .virtualenv/$PROJECT/bin/postactivate:
export PYTHONPATH=$PYTHONPATH:$HOME/development/my_python/my_django/automated_browsing
And now py.test works as expected.
I have a very simple Python question, with examples using Django. When running a Python script, do I always have to precede the script filename with the python command?
In the Django tutorial I am following, some commands are as follows:
django-admin.py startproject mysite
However, other are like this:
python manage.py runserver
Why does the top one not need the python command?
Alternatively, if my system knows that all Python scripts are to be executed by my python interpreter, why does the bottom one need the python command at all?
The answer lies in a combination of two things:
The shebang, the first line of a file.
The permissions on the file, namely whether the executable flag is set or not.
Consider the first line of django-manage.py. On my system it is at /usr/local/bin/django-admin.py and the first line is:
#!/usr/bin/python2.7
And the permissions on the file:
-rwxr-xr-x 1 root root 127 Jan 9 13:38 /usr/local/bin/django-admin.py
The shebang tells my OS that I want to execute the file with the interpreter at /usr/bin/python2.7. The x characters in the permissions say that it is an executable file. I don't need to specify python beforehand, because the OS can figure out that stuff automatically from the above pieces of information.
Now for a freshly created manage.py, which I made by running django-admin.py startproject mysite, it looks like this:
#!/usr/bin/env python
And the permissions:
-rw-r--r-- 1 wim wim 249 Feb 17 17:33 manage.py
The shebang indicates to use whatever python interpreter my env is pointing at, so that part is in place already. But the file lacks executable permissions, so just running ./manage.py won't work (yet).
I can make it behave the same as django-manage.py by explicitly setting the executable flag using chmod +x manage.py. After that, you should see the x flags set when you do ls -l in the directory, and you should be able to run the file without specifying python beforehand.
Note: you do still have to use ./manage.py not just manage.py, this discrepancy is because django-admin.py lives in /usr/local/bin/ which is contained in PATH whereas the manage.py file likely doesn't. So we explicitly specify the path at the shell, where . refers to the current directory.
You can make the script executable by using chmod +x script.py, but you need the shebang line, usually #!/usr/bin/python
If you are using a script heavily on a unix-based maching (mac,linux) making an alias can be useful:
alias command="python path/to/script.py"
I'm developing an application using Flask.
I want a quick, automated way to add and remove debug=True to the main function call:
Development:
app.run(debug=True)
Production:
app.run()
For security reasons, as I might expose private/sensitive information about the app if I leave debug mode on "in the wild".
I was thinking of using sed or awk to automate this in a git hook (production version is kept in a bare remote repo that I push to), or including it in a shell script I am going to write to fire up uwsgi and some other "maintenance"-ey tasks that allow the app to be served up properly.
What do you think?
That is not the way to go! My recommendation is to create some configuration Python module (let us say, config.py) with some content such as:
DEBUG = True
Now, in our current code, write this:
import config
app.run(debug=config.DEBUG)
Now, when you run in production, just change DEBUG from True to False. Or you can leave this file unversioned, so the copy of development is different of the copy of production. This is not uncommon since, for example, one does not use the same database connection params both in development and production.
Even if you want to update it automatically, just call sed on the config file with the -i flag. It is way more secure to update just this one file:
$ sed -i.bkp 's/^ *DEBUG *=.*$/DEBUG = False/' config.py
You should set up some environment variable on server. Your script can detect presense of this variable and disable debugging.
You probably should not be using app.run in production (and you definitely don't need it if you are using uwsgi). Instead, use one of the several deployment options discussed in the deployment section of Flask's excellent documentation. (app.run simply calls werkzeug.serving.run_simple which executes Python's included wsgiref server.)
That being said, the correct way to do this is not with a post-deploy edit to your source code but with a server-specific config file that changes your settings as #brandizzi pointed out in his answer.
You can do this in several different ways (Flask has documentation on this too - see Armin's suggestions on configuring from files and handling the development-production switch):
Include both your development and your server's configs in your repository. Use an environmental variable to switch between them:
# your_app.config.develop
DEBUG = True
# your_app.config.production
DEBUG = False
# your_app.app
from flask import Flask
from os import environ
mode = environ.get("YOURAPP_MODE")
mode = "production" if mode is None else "develop"
config = __import__("your_app.config." + mode)
app = Flask("your_app")
app.config.from_object(config)
Store your production configuration in a separate repository along with any other server-specific configurations you may need. Load the config if an environmental variable is set.
I'd use sed:
sed 's/debug=True//'
portable, scriptable, ubiquitous.
You can also use a NOCOMMIT hook (from gitty):
Set this as a pre-commit hook
if git diff --cached | grep NOCOMMIT > /dev/null; then
echo "You tried to commit a line containing NOCOMMIT"
exit 1
fi
exit 0
This will prevent the commit if it contains NOCOMMIT.
You can of course directly replace NOCOMMIT by Debug=True in the hook.