Execute script after `python manage.py shell` is up - python

There is a command that calls Django's shell:
python manage.py shell
I would like to create a BASH-alias, that will:
Start python manage.py shell
Execute print 'foo'
Something similar to -i option: python -i /usr/bin/print_foo.py but with manage.py shell
The reason for doing it is too speed up the debug process. So instead of importing all relevant models and assigning variables, I want to do it in the separate PY file. So each time I start the manage.py shell, I will just have all the tools in hand.
EDIT: using python manage.py shell < /usr/bin/print_foo.py almost does the trick. However the terminal gets closed.. if there is a way to make it stay opened.

You can use the following simple shell script:
#!/bin/bash
export PYTHONSTARTUP="$1" # Set the startup script python will run when it start.
shift # Remove the first argument, don't want to pass that.
python manage.py shell "$#" # Run manage.py with the startup script.
Just supply the python script you want to run first as the first argument to the script. All other arguments are directly passed to manage.py. The change to $PYTHONSTARTUP won't affect the environment in your shell.

I also battled with this, the < test.py closes the shell, and shell_plus doesn't add much here beside auto loading of the models, doesn't load the code you want to debug
However I can do this: I make a test.py that is initializes Django if it's not ran from a Django environment, and run it with python -i test.py
The basic idea is to not use manage.py shell
if __name__ == '__main__':
# This will run e.g. from python -i test.py, but will be skipped if from Django
import django # 1.7
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
django.setup()
# Your regular Django stuff here
# Init your vars etc and prepare values to debug
# The Python prompt will remain active here so you can work on it
Another less automated solution is to call execfile('test.py') or %run test.py if you're in IPython,
pro is you can reload the test.py module without leaving the shell (faster and preserves the context), con is you have to load it manually when the shell opens up

Not a direct answer, but Django Extensions (Github, Docs) shell_plus might be interesting for that. (the package has many useful tools, so it is a valuable dependency in many cases.)
The app's models are automatically imported. To configure further imports, see the additional imports section.
If you want to automatically execute code from arbitrary python modules with shell_plus, you can use the SHELL_PLUS_PRE_IMPORTS and SHELL_PLUS_POST_IMPORTS setting. Any python modules that are configured there run a) before or b) after Django's app models are auto-imported.

Related

Make each run of python interpreter automatically call `coverage`?

I have test.sh that runs python command on many different scripts. Is there a way to emit coverage -a for each python call without prepending each command with coverage -a?
See the coverage.py docs about subprocess measurement for a way to invoke coverage automatically when starting Python: http://coverage.readthedocs.io/en/latest/subprocess.html . It will require some fiddling.
It might be easier to alias in the shell script. For things like "nosetests", change it to "python -m nose".

Setting startup script in PyCharm debugger console

In PyCharm, it is possible to set a script that runs upon opening a new console (through Settings -> 'Build, Execution, Deployment' -> Console -> Python Console -> Starting script).
Is there a way to similarly apply a startup script to the debugger console? I find myself importing the same packages over and over again, each time I run the code.
When you run Python Console inside PyCharm, it executes custom PyCharm script at <PYCHARM_PATH>/plugins/python/helpers/pydev/pydevconsole.py.
On the other hand, when you run PyCharm Debug Console while debugging, it executes custom PyCharm script at <PYCHARM_PATH>/Plugins/python/helpers/pydev/pydevd.py with command line parameter --file set to script you are debugging.
You can modify pydevd.py file if you want (Apache 2 license), but the easier approach would be to create startup script in which you import modules you need, functions and such and import ALL while inside PyCharm Debug Console. This would reduce all your imports to one.
Walkthrough:
Let's create 2 files:
main.py - Our main script which we will debug
startup.py - Modules, functions or something else that we would like to import.
main.py content:
sentence = 'Hello Debugger'
def replace_spaces_with_hyphens(s):
return s.replace(' ', '-')
replace_spaces_with_hyphens(sentence) # <- PLACE BREAKPOINT!
When breakpoint is hit, this is what we have inside scope:
If you always find yourself importing some modules and creating some functions, you can define all that inside startup.py script and import everything as from startup import *.
startup.py:
# Example modules you always find yourself importing.
import random
import time
# Some function you always create because you need it.
def my_imported_function():
print("Imported !")
Inside Python Debugger Console, use from startup import * as mentioned above and you would see all modules and function inside scope, ready for use.
you could just create a new debug configuration (run > edit configurations) and point it to a script in your project (e.g. called debug.py that you gitignore). Then when you hit debug it will run that script and drop you into a console.
Personally, I prefer to just launch ipython in the embedded terminal than using the debug console. On linux, you can create a bash alias in your .bashrc such as alias debug_myproject=PYTHONSTARTUP=$HOME/myproject/debug.py ipython. Then calling debug_myproject will run that script and drop you into an ipython console.

When to use python interpreter vs shell

I have a very basic question: If we want to run a script called script.py, we go to shell and type "python script.py". However, if we want to check, for example, if Django is installed or not, we first go into Python interpreter by typing "python" in the shell, and while we get the >>> then we type import Django. What is the conceptual difference? For example, in the second case, why directly running "python import Django" in the shell does not work?
python import Django tries to run a Python script named import with an argument Django.
python -c 'import Django' would attempt to execute the Python statement import Django as if you had typed it from the Python interpreter directly.
python launch interpreter. You can easly test script on it, and after create a file *.py that you can use on CRON (for ex)
When you type python and import Django it do
Open Python interpreter
Import Django library on it (to use it)
If an error raise, it seems than Django wasn't installed on computer

How to setup DreamPie to mimic Django's "manage.py shell" functionality

I would like to use DreamPie, a python shell, as a CLI that functions the same way that manage.py shell works.
Additionally, it would be very nice to have some way to automatically run some code when the shell starts, like a set of import statements.
If you are unfamiliar with the specifics of getting this to work with DreamPie, I could also appreciate knowing what it is that manage.py shell does so I could apply it to another shell environment/interpreter.
Go to Django project directory
Execute DreamPie there
Then copy and paste manage.py on DreamPie console replacing sys.argv by ['manage.py', 'shell']

Workaround Way To Install Numpy?

Right now I have a script which uses numpy that I want to run automatically on a server. When I ssh in and run it manually, it works fine. However, when I set it to run as a cron job, it can't find numpy. Apparently due to the shared server environment, the cron demon for whatever reason can't find numpy. I contacted the server host's tech support and they told me to set up a vps or get my own damn server. Is there any way to hack a workaround for this? Perhaps, by moving certain numpy files into the same directory as the script?
If you have numpy installed somewhere on the server, you can add it into the import path for python; at the beginning of your script, do something like this:
import sys
sys.path.append("/path/to/numpy")
import numpy
The cronjob runs with an empty environment. As such, it's either not using the same python binary as you are at the shell, or you have PYTHONPATH set, which it won't have under crontab.
You should run env -i HOME=$HOME sh to get a fascimile of the cronjob's environment. Set environment variables until your command works, and record them.
You can then set these in your crontab file, again using the env command, like:
* * * * * env PYTHONPATH=/my/pythonpath OTHERVAR=correct-value /path/to/mycommand
Processes invoked by the cron daemon have a minimal environment, generally consisting of $HOME, $LOGNAME and $SHELL.
It sounds like numpy is perhaps somewhere on your $PYTHONPATH? If so, you will need to specify that within the crontab line. Such as
/usr/bin/env PYTHONPATH=... <then the command to run>
If you are on a Linux system using vixie cron, then you can also specify global variables in your crontab by using lines such as
# my environment settings
PYTHONPATH = <path>
SOMETHING_ELSE = blah
<then my normal cron line>
See man -s 5 crontab
Your cron job is probably executing with a different python interpreter.
Log in as you (via ssh), and say which python. That will tell you where your python is. Then have your cron job execute that python interpreter to run your script, or chmod +x your script and put the path in a #! line at the top of the script.

Categories

Resources