BackgroundScheduler stucks after supposed end of the program - python

Following this article I have managed to do the following example code:
import subprocess
import time
from apscheduler.schedulers.background import BackgroundScheduler
class Test:
#classmethod
def test_method(cls):
subprocess.call(['notepad.exe'])
#classmethod
def test_stop(cls, scheduler):
print(scheduler.state)
scheduler.shutdown()
scheduler.remove_all_jobs()
print(scheduler.state)
scheduler = BackgroundScheduler()
scheduler.add_job(Test.test_method, 'interval', seconds=1, id='My Job')
scheduler.start()
time.sleep(10)
print("After Sleep")
Test.test_stop(scheduler)
The problem is that after the tenth try to open "Notepad" the program just stucks and does not end.
Can someone explain what is happening and why the script does not end?
P.S. If it helps, I am runnig it on Windows.

I found the problem:
The problem is that subprocess.call() "calls" the notepad and waits for its completion.
What it menas in simple words is that the program will end when the Notepad opened from this script is closed.

Related

How to Schedule Python Code To Run Daily Using Apschedulers?

I am trying to use Apschedulers to Run a code Daily But i am facing some issue
Here is Code :
async def job():
print("Boss Wake Up")
scheduler = AsyncIOScheduler()
scheduler.add_job(job, "cron", day_of_week="mon-sun", hour=21, minute=10)
scheduler.start()
But its not working starting from today. why? i wanna make it start from day one and run daily. Can anyone help me ? Thanks !
Can you try the following
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.triggers.interval import IntervalTrigger
sched = BlockingScheduler()
#sched.scheduled_job(IntervalTrigger(seconds=10)) #set the interval you need
def timed_job():
print('This job is run every 10 seconds.')
sched.start()
You can use BackgroundScheduler() if you want to run this in background
You still need to run the asyncio event loop. Add the following block:
try:
asyncio.get_event_loop().run_forever()
except (KeyboardInterrupt, SystemExit):
pass

Can we add jobs to running schedular in ApSchedular

I started Background scheduler in one file and ran it. Then from other file I accessed scheduler instance and added job. What my thought was the instance will add the job and it will run. I am new to this scheduling mechanisms. What I did is
On one file Main.py
import time
from apscheduler.schedulers.background import BackgroundScheduler
class Main:
a = 2
sched = BackgroundScheduler()
sched.start()
while True:
time.sleep(5)
From other file Bm.py
from Main import Main
class Bm(Main) :
def timed_job():
print 'aa'
Main.sched.add_job(timed_job,'interval',seconds=1)
I thought this would do, but it didnot.I need to this way from seperate file because I need to make a task manager which would run jobs and I need to be able to add or remove jobs anytime needed.SO how can we add and remove jobs to/from running apscheduler?
UPDATE :
This is confusing. I added a function printme on Main.py and did sched.add_job(printme,'interval',seconds=5), it prints me as expected but when I run Bm.py it also prints me, when it was supposed to print aa
def printme():
print 'me'
while True:
# time.sleep(5)
sched.add_job(printme,'interval',seconds=5)
if (input() is 'q'):
sched.shutdown()

how to make timer for quiting from python3

I have a script and it doesn't work proper, so in bash I let script in while loop and I wanna my script can close itself after a while, I tried to use threading.timer but my code wont run quit() or exit() command, could anyone please help me?
#!/usr/bin/env python3
import threading
from time import sleep
def qu():
print("bye")
exit()
t=threading.Timer(5.0,qu)
t.start()
while(True):
sleep(1)
print("hi")
You could use the os._exit function instead of exit()
Getting the code as follows:
#!/usr/bin/env python3
import threading
import os
from time import sleep
def qu():
print("bye")
os._exit(0)
t=threading.Timer(5.0,qu)
t.start()
while(True):
sleep(1)
print("hi")
Anyways I would suggest you to checkout this question as it is similar to yours.

Python - Apscheduler not stopping a job even after using 'remove_job'

This is my code
I'm using the remove_job and the shutdown functions of the scheduler to stop a job, but it keeps on executing.
What is the correct way to stop a job from executing any further?
from apscheduler.schedulers.background import BlockingScheduler
def job_function():
print "job executing"
scheduler = BlockingScheduler(standalone=True)
scheduler.add_job(job_function, 'interval', seconds=1, id='my_job_id')
scheduler.start()
scheduler.remove_job('my_job_id')
scheduler.shutdown()
Simply ask the scheduler to remove the job inside the job_function using the remove_function as #Akshay Pratap Singh Pointed out correctly, that the control never returns back to start()
from apscheduler.schedulers.background import BlockingScheduler
count = 0
def job_function():
print "job executing"
global count, scheduler
# Execute the job till the count of 5
count = count + 1
if count == 5:
scheduler.remove_job('my_job_id')
scheduler = BlockingScheduler()
scheduler.add_job(job_function, 'interval', seconds=1, id='my_job_id')
scheduler.start()
As you are using BlockingScheduler , so first you know it's nature.
So, basically BlockingScheduler is a scheduler which runs in foreground(i.e start() will block the program).In laymen terms, It runs in the foreground, so when you call start(), the call never returns. That's why all lines which are followed by start() are never called, due to which your scheduler never stopped.
BlockingScheduler can be useful if you want to use APScheduler as a standalone scheduler (e.g. to build a daemon).
Solution
If you want to stop your scheduler after running some code, then you should opt for other types of scheduler listed in ApScheduler docs.
I recommend BackgroundScheduler, if you want the scheduler to run in the background inside your application/program which you can pause, resume and remove at anytime, when you need it.
The scheduler needs to be stopped from another thread. The thread in which scheduler.start() is called gets blocked by the scheduler. The lines that you've written after scheduler.start() is unreachable code.
This is how I solved the problem. Pay attention to the position where the code schedule.shutdown() is located!
def do_something():
global schedule
print("schedule execute")
# schedule.remove_job(id='rebate')
schedule.shutdown(wait=False)
if __name__ == '__main__':
global schedule
schedule = BlockingScheduler()
schedule.add_job(do_something, 'cron', id='rebate', month=12, day=5, hour=17, minute=47, second=35)
schedule.start()
print('over')

APscheduler will not stop

I have python code that I am developing for a website that, among other things, creates an excel sheet and then converts it into a json file. I need for this code to run continuously unless it is killed by the website administrator.
To this end, I am using APscheduler.
The code runs perfectly without APscheduler but when I attempt to add the rest of the code one of two things happens; 1) It runs forever and will not stop despite using "ctrl+C" and I need to stop it using task manager or 2) It only runs once, and then it stops
Code That doesn't Stop:
from apscheduler.scheduler import Scheduler
import logging
import time
logging.basicConfig()
sched = Scheduler()
sched.start()
(...)
code to make excel sheet and json file
(...)
#sched.interval_schedule(seconds = 15)
def job():
excelapi_final()
while True:
time.sleep(10)
sched.shutdown(wait=False)
Code that stops running after one time:
from apscheduler.scheduler import Scheduler
import logging
import time
logging.basicConfig()
sched = Scheduler()
(...)
#create excel sheet and json file
(...)
#sched.interval_schedule(seconds = 15)
def job():
excelapi_final()
sched.start()
while True:
time.sleep(10)
sched.shutdown(wait=False)
I understand from other questions, a few tutorials and the documentation that sched.shutdown should allow for the code to be killed by ctrl+C - however that is not working. Any ideas? Thanks in advance!
You could use the standalone mode:
sched = Scheduler(standalone=True)
and then start the scheduler like this:
try:
sched.start()
except (KeyboardInterrupt):
logger.debug('Got SIGTERM! Terminating...')
Your corrected code should look like this:
from apscheduler.scheduler import Scheduler
import logging
import time
logging.basicConfig()
sched = Scheduler(standalone=True)
(...)
code to make excel sheet and json file
(...)
#sched.interval_schedule(seconds = 15)
def job():
excelapi_final()
try:
sched.start()
except (KeyboardInterrupt):
logger.debug('Got SIGTERM! Terminating...')
This way the program will stop when Ctrl-C is pressed
You can gracefully shut it down:
import signal
from apscheduler.scheduler import Scheduler
import logging
import time
logging.basicConfig()
sched = Scheduler()
(...)
#create excel sheet and json file
(...)
#sched.interval_schedule(seconds = 15)
def job():
excelapi_final()
sched.start()
def gracefully_exit(signum, frame):
print('Stopping...')
sched.shutdown()
signal.signal(signal.SIGINT, gracefully_exit)
signal.signal(signal.SIGTERM, gracefully_exit)

Categories