I have a python script with indefinite loop it keeps in checking for the data, now I am confused how do I execute it so that it keeps running if the server is running.
I think the script should run just after I run server in django but how do I run this script?
Any suggestions?
django-admin runserver is only for development use. Assuming this is a development environment, probably simplest to just run your script in a separate console, or make a simple shell script that starts the django server, backgrounds that process, then runs your script.
#!/bin/sh
django-admin runserver &
/path/to/my/script.py &
You'll need to kill those processes manually before re-running that script.
In a production environment, use WSGI to run Django and something like supervisord to run the other script. You could configure the OS init system (probably systemd) to ensure both of these tasks start on reboot and remain running.
The first big part is to pack your indefinite loop into a function, and use huey/celery/etc to make it a 'task' that runs asynchronously.Then, call this task to run in your views.py/models.py/manage.py.
HOW TO LET THE TASK RUN ASYNCLY:
HUEY:[https://huey.readthedocs.io/en/latest/]
HOW TO RUN THE TASK WHEN YOU START THE SERVER (2 ways):
Edit your manage.py ,add your function call at the line right behind the import of manage.py.
#!/usr/bin/env python
import os
import sys
print('Interesting things happens.') # THIS IS WHERE YOU RUN YOUR tasks.checkdata.
if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'OTAKU.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
However , maybe you want to leave the manage.py alone. Create a new app in your project, with views.py and models.py.(Remember to add this app to your INSTALLED_APPS in settings.py)
In views.py :
print("The view is loading.")# THIS IS WHERE YOU CAN RUN YOUR tasks.checkdata.
In models.py:
print("The models is loading.")# THIS IS WHERE YOU CAN RUN YOUR tasks.checkdata.
And when you run your server now, this is what you might see:
Interesting things happens.
The models is loading.
Interesting things happens.
The models is loading.
Performing system checks...
The view is preparing itself.
System check identified no issues (0 silenced).
July 15, 2019 - 11:52:03
Django version 2.1.3, using settings 'rayos.settings'
Starting development server at http://0.0.0.0:9988/
Quit the server with CONTROL-C.
Replace the print part of the script with your data checking functions and it will work.
Related
My django app starts very slowly. I ran python -v manage.py check and it stucks at line
import 'netrc' # <_frozen_importlib_external.SourceFileLoader object at 0x7efff40f3d30>
I found this related question : Django "Performing System Checks" is running very slow
Here it says he removed the elastic beanstalk urls from ALLOWED_HOSTS and it fixed. I did that too but my app still stucks at that import statement. What else can cause that?
Now, to run the bot through Django, I first use the python manage.py runserver command and then follow the link to launch a view with my bot. Can you tell me if there is an easier way to start my bot automatically when starting a Django project?
Actually, you can use a management command to run your bot with something like
python manage.py runbot
All Django context, including DB and settings, will be available
Reference to management command page:
https://simpleisbetterthancomplex.com/tutorial/2018/08/27/how-to-create-custom-django-management-commands.html
Maybe is a little late but you can do the following:
create the bot.py file in the same folder where manage.py is.
inside the bot.py make sure you import the following:
import django
import os
os.environ['DJANGO_SETTINGS_MODULE'] = '{Folder where your settings are}.settings'
django.setup()
and in order to run you just type python bot.py
Several configuration files exist.
If these files have different names
How do I change the settings file every time I run this command?
"python manage.py runserver"
Its so simple
read Main Django Tutorial, its all about setting django configuration
a shortcut for using in runserver command is --settings= and this also works with uwsgi
but if you intend to change setting without re-running the server django-constance is the answer
you can add to manage.py file
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project_name.settings_name')
After that run
py manage.py ----
I am developing a web application with React for frontend and Django for backend. I use Webpack to watch for changes and bundle code for React apps.
The problem is that I have to run two commands concurrently, one for React and the other one for Django:
webpack --config webpack.config.js --watch
./manage.py runserver
Is there any way to customize runserver command to execute the npm script, like npm run start:dev? When you use Node.js as a backend platform, you can do the similar job like npm run build:client && npm run start:server.
If you are already using webpack and django, probably you can be interested in using webpack-bundle-tracker and django-webpack-loader.
Basically webpack-bundle-tracker will create an stats.json file each time the bundle is build, and django-webpack-loader will watch for those stats.json file to relaunch the dev server. This stack allows to separate the concerns between the server and the client.
There are a couple of posts out there explaining this pipeline.
I'm two and a half years late, but here's a management command that implements the solution that OP wanted, rather than a redirection to another solution. It inherits from the staticfiles runserver and runs webpack concurrently in a thread.
Create this management command at <some_app>/management/commands/my_runserver.py:
import os
import subprocess
import threading
from django.contrib.staticfiles.management.commands.runserver import (
Command as StaticFilesRunserverCommand,
)
from django.utils.autoreload import DJANGO_AUTORELOAD_ENV
class Command(StaticFilesRunserverCommand):
"""This command removes the need for two terminal windows when running runserver."""
help = (
"Starts a lightweight Web server for development and also serves static files. "
"Also runs a webpack build worker in another thread."
)
def add_arguments(self, parser):
super().add_arguments(parser)
parser.add_argument(
"--webpack-command",
dest="wp_command",
default="webpack --config webpack.config.js --watch",
help="This webpack build command will be run in another thread (should probably have --watch).",
)
parser.add_argument(
"--webpack-quiet",
action="store_true",
dest="wp_quiet",
default=False,
help="Suppress the output of the webpack build command.",
)
def run(self, **options):
"""Run the server with webpack in the background."""
if os.environ.get(DJANGO_AUTORELOAD_ENV) != "true":
self.stdout.write("Starting webpack build thread.")
quiet = options["wp_quiet"]
command = options["wp_command"]
kwargs = {"shell": True}
if quiet:
# if --quiet, suppress webpack command's output:
kwargs.update({"stdin": subprocess.PIPE, "stdout": subprocess.PIPE})
wp_thread = threading.Thread(
target=subprocess.run, args=(command,), kwargs=kwargs
)
wp_thread.start()
super(Command, self).run(**options)
For anyone else trying to write a command that inherits from runserver, note that you need to check for the DJANGO_AUTORELOAD_ENV variable to make sure you don't create a new thread every time django notices a .py file change. Webpack should be doing it's own auto-reloading anyway.
Use the --webpack-command argument to change the webpack command that runs (for example, I use --webpack-command 'vue-cli-service build --watch'
Use --webpack-quiet to disable the command's output, as it can get messy.
If you really want to override the default runserver, rename the file to runserver.py and make sure the app it lives in comes before django.contrib.static in your settings module's INSTALLED_APPS.
You shouldn't mess with the built-in management commands but you can make your own: https://docs.djangoproject.com/en/1.10/howto/custom-management-commands/.
On your place I'd leave runserver in place and create one to run your custom (npm in this case) script, i.e. with os.execvp.
In theory you could run two parallel subprocesses one that would execute for example django.core.management.execute_from_command_line and second to run your script. But it would make using tools like pbd impossible (which makes work very hard).
The way I do it is that I leverage Docker and Docker compose. Then when I use docker-compose up -d my database service, npm scripts, redis, etc run in the background (running runserver separately but that's another topic).
I have a Django project. Everytime I deploy, I need to run a series of manage.py command (such as syncdb, south migiration, fixture update).
I am getting tired of type the command line by line and therefore I wrote a python script to do these:
import subprocess
subprocess.call(['python', 'manage.py', 'syncdb'])
#Skip the detail
subprocess.call(['python', 'manage.py', 'loaddata', 'setup/fixture.xml'])
I am wondering if there is a better way to do this?
Thanks.
You can use fabric, a Python library that allows you to script remote actions. This question has some links in the accepted answer for more information on fabric and django.
You can also call management commands directly:
from django.core.management import call_command
call_command('syncdb')
call_command('loaddata', 'setup/fixture.xml')
Save that as a normal python file and execute it from your shell or as part of your deployment scripts.