How to run arbitrary code when django shell starts?
Question:
This question: Automatically import models on Django shell launch has answers explaining how to import models upon start by using shell_plus, but no answer about how to run code in general.
But is there an easy way to just run a python script?
python manage.py shell [or shell_plus] --run=script.py
Would just run the script as if you’d typed the whole thing in as the shell started.
I realize that you can import things in the shell, but then they’re stuck within a namespace.
I would think ipython should have a way to run a script, and then import its locals()
into the toplevel namespace. In that case you could just do %magic script.py
and we’d be down to just one step, which would be good.
Changing the way you start the shell should be fine – the main goal is to just be able to create a file that’s run on startup of the shell.
Answers:
Not sure if there’s a flag you can use, but if you have ipython installed it should be as simple as:
ipython
Then when you’re in the prompt:
run script.py
Then:
run manage.py shell
You can create your own custom command just like shell_plus
has done: see the source of the shell_plus
command to see how. In that code you can specify and run the file that needs to be executed before starting the shell. Also useful is Django’s documentation on creating custom commands.
You can try to use environment variable PYTHONSTARTUP.
Also try django-extensions: django-extensions
See django-extensions/management/commands/shell_plus.py command.
From source code of this command I see that it respects PYTHONSTARTUP env variable.
shell_plus uses a limited form of IPython which doesn’t process its startup & configuration, which defeats most normal attempts to run things at django+ipython shell startup. You can switch it to use the full version which will solve most problems.
Modify django_extensions/management/commands/shell_plus.py
remove:
embed(user_ns=imported_objects)
and replace it with:
from IPython import start_ipython
start_ipython(argv=[], user_ns=imported_objects)
Then your python code in the startup directories will be loaded.
It seems that the easiest way is to run
cat myscript.py | awx-manage shell
For reference, see https://github.com/ansible/awx-operator/blob/7d2d1b3c5e3766966bfec0f9f58037f654b93b59/roles/installer/tasks/initialize_django.yml#L21-L24
This question: Automatically import models on Django shell launch has answers explaining how to import models upon start by using shell_plus, but no answer about how to run code in general.
But is there an easy way to just run a python script?
python manage.py shell [or shell_plus] --run=script.py
Would just run the script as if you’d typed the whole thing in as the shell started.
I realize that you can import things in the shell, but then they’re stuck within a namespace.
I would think ipython should have a way to run a script, and then import its locals()
into the toplevel namespace. In that case you could just do %magic script.py
and we’d be down to just one step, which would be good.
Changing the way you start the shell should be fine – the main goal is to just be able to create a file that’s run on startup of the shell.
Not sure if there’s a flag you can use, but if you have ipython installed it should be as simple as:
ipython
Then when you’re in the prompt:
run script.py
Then:
run manage.py shell
You can create your own custom command just like shell_plus
has done: see the source of the shell_plus
command to see how. In that code you can specify and run the file that needs to be executed before starting the shell. Also useful is Django’s documentation on creating custom commands.
You can try to use environment variable PYTHONSTARTUP.
Also try django-extensions: django-extensions
See django-extensions/management/commands/shell_plus.py command.
From source code of this command I see that it respects PYTHONSTARTUP env variable.
shell_plus uses a limited form of IPython which doesn’t process its startup & configuration, which defeats most normal attempts to run things at django+ipython shell startup. You can switch it to use the full version which will solve most problems.
Modify django_extensions/management/commands/shell_plus.py
remove:
embed(user_ns=imported_objects)
and replace it with:
from IPython import start_ipython
start_ipython(argv=[], user_ns=imported_objects)
Then your python code in the startup directories will be loaded.
It seems that the easiest way is to run
cat myscript.py | awx-manage shell
For reference, see https://github.com/ansible/awx-operator/blob/7d2d1b3c5e3766966bfec0f9f58037f654b93b59/roles/installer/tasks/initialize_django.yml#L21-L24