Set timer for a Django view execution - python

I'm struggling trying to prevent a Django view from being executed more than once within an hour period. In other words, if the function runs at 15:00, all future requests for all users should be ignored until 17:00 when it's allowed to run once more again.
Tried with a timer, but it does get reset every time the view is called. Maybe someone can point me in the right direction? Thanks!!!
import threading as th
def hello():
print("hello, world")
def webhook(request):
tm = th.Timer(3600, hello)
if request.method == 'POST' and not tm.is_alive():
tm.start()
code_to.ecexute()
return HttpResponse("Webhook received!")

Ultimately, this is what I did and it seems to work fine. I actually need it to run no more than once a day, hence the conditional below.
Thanks for all the suggestions!!!
def webhook2 (request):
today = datetime.now().date()
with open('timestamp.txt') as f:
tstamp = f.read()
last_run = datetime.strptime(tstamp, '%Y-%m-%d')
last_run_date = datetime.date(last_run)
print ("last run: " + str(last_run_date))
if last_run_date < today:
file = open("timestamp.txt" ,"w")
file.write(str(today))
file.close()
if request.method == 'POST':
msg = str(request.body)
final_msg=msg[2:-1]
print("Data received from Webhook is: ", request.body)
# creates a google calendar event
function_logic()
return HttpResponse("Webhook received! Event added to calendar")
else:
print ("we already have a record for today")
return HttpResponse("Not adding a record. We already have one for today.")

Your timer is being reset everytime because it is inside a function that is execute everytime when request is being made.
You should try to set the timer globally, such as outside your function. ( be aware when your script will re-run, timer will be reset again ).
import threading as th
def hello():
print("hello, world")
tm = None
def webhook(request):
# check here if timer is dead then process the request.
if timer_is_dead || tm is None:
# accessing global value and setting it for first time
if tm is None:
global tm
tm = th.Timer(3600, hello)
tm.start()
if request.method == 'POST' and not tm.is_alive():
code_to.ecexute()
# start timer again for next hour
return HttpResponse("Webhook received!")
else:
return HttResponse("Not Allowed")
Edit: Handling first request and then starting timer

Related

How to change code to avoid unreacheable error in python

Wrote this telegram bot. Pycharm gives me error 'The last two lines are unreacheable'. What is the solution? Without 'while true' part code isn't working
import telebot
import gspread
import datetime
import schedule
import time
bot_token = '____'
googlesheet_id = '___'
bot = telebot.TeleBot(bot_token)
gc = gspread.service_account(filename='.json')
sh = gc.open('___')
wks = sh.worksheet('sheet1')
CHAT_ID = "___"
def check_date():
current_date = datetime.datetime.now()
current_date_string = current_date.strftime('%d.%m.%Y')
sh = gc.open('___')
search_data = wks.find(current_date_string)
list = wks.row_values(search_data.row)
bot.send_message(CHAT_ID, '%s expires today' % (list[0]))
schedule.every().day.at("12:00:00").do(check_date)
while True:
schedule.run_pending()
time.sleep(1)
if __name__ == '__main__':
bot.polling(none_stop=True)
You (roughly) wrote
def check_date():
...
while True:
do_thing_one()
if __name__ == '__main__':
do_thing_two()
The last two lines, testing __name__ and doing thing two, are useless, they will never execute.
Why are they unreachable?
Because of the thing one while loop,
which never lets us get down to attempt thing two.
Notice that the while loop is not part of
the check_date function.
If you were to indent that section four spaces,
then the check_date function would never exit
but we would be able to do thing two.
It does not appear that thing two,
the .polling() call, relates to check_date.
Perhaps there is some unseen linkage behind
the scenes.

Example of how to avoid duplicate order ids and corrupt prints in a multithreaded app thanks to queues with IB TWS Python API

My trading app written with Python and using the IB TWS API is multithreaded and I'm looking to solve once and for all the issues of corrupt prints and duplicate order ids, both of which can happen once multiple threads are running at the same time.
For the purpose of this question I've put together a simple script that has for goal nothing other than providing a support for solving it. What I'm hoping for is to see how someone more experienced would implement queues in order to make the script do 2 things:
print 'safely' in a non corrupt way
each order should execute without the 'duplicate order id' error code popping up
I know that I need to use queues but I'm just starting to read up on the topic and since the IB TWS API is fairly specific, I'm not sure how to implement. Thank you.
from ibapi.wrapper import EWrapper
from ibapi.client import EClient
from ibapi.order import Order
from ibapi.contract import Contract
import threading
import time
buyOrder1Id = 0
buyOrder2Id = 0
buyOrder3Id = 0
buyOrder4Id = 0
buyOrder5Id = 0
buyOrder6Id = 0
buyOrder7Id = 0
buyOrder8Id = 0
buyOrder9Id = 0
buyOrder10Id = 0
class TradingApp(EWrapper, EClient):
def __init__(self):
self.BidPrice = 0
self.AskPrice = 0
self.LastPrice = 0
EClient.__init__(self,self)
def error(self, reqId, errorCode, errorString):
print("Error. Id: ", reqId, " Code: ", errorCode, " Msg: ", errorString)
def nextValidId(self, orderId):
super().nextValidId(orderId)
self.nextValidOrderId = orderId
def websocket_con():
app.run()
Underlying = Contract()
Underlying.localSymbol = "ESU2"
Underlying.secType = "FUT"
Underlying.currency = "USD"
Underlying.exchange = "GLOBEX"
BuyOrder1 = Order()
BuyOrder1.action = "BUY"
BuyOrder1.totalQuantity = 1
BuyOrder1.orderType = "MKT"
BuyOrder1.account = "DU2312534"
BuyOrder1.tif = "GTC"
app = TradingApp()
app.connect("127.0.0.1", 7497, 2000)
time.sleep(1)
# starting a separate daemon thread to execute the websocket connection
con_thread = threading.Thread(target=websocket_con, daemon=True)
con_thread.start()
time.sleep(1)# some latency added to ensure that the connection is established
def Level1():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder1Id = app.nextValidOrderId
print("buyOrder1Id: ",buyOrder1Id)
app.placeOrder(buyOrder1Id,Underlying,BuyOrder1)
time.sleep(3)
def Level2():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder2Id = app.nextValidOrderId
print("buyOrder2Id: ",buyOrder2Id)
app.placeOrder(buyOrder2Id,Underlying,BuyOrder1)
time.sleep(3)
def Level3():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder3Id = app.nextValidOrderId
print("buyOrder3Id: ",buyOrder3Id)
app.placeOrder(buyOrder3Id,Underlying,BuyOrder1)
time.sleep(3)
def Level4():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder4Id = app.nextValidOrderId
print("buyOrder4Id: ",buyOrder4Id)
app.placeOrder(buyOrder4Id,Underlying,BuyOrder1)
time.sleep(3)
def Level5():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder5Id = app.nextValidOrderId
print("buyOrder5Id: ",buyOrder5Id)
app.placeOrder(buyOrder5Id,Underlying,BuyOrder1)
time.sleep(3)
def Level6():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder6Id = app.nextValidOrderId
print("buyOrder6Id: ",buyOrder6Id)
app.placeOrder(buyOrder6Id,Underlying,BuyOrder1)
time.sleep(3)
def Level7():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder7Id = app.nextValidOrderId
print("buyOrder7Id: ",buyOrder7Id)
app.placeOrder(buyOrder7Id,Underlying,BuyOrder1)
time.sleep(3)
def Level8():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder8Id = app.nextValidOrderId
print("buyOrder8Id: ",buyOrder8Id)
app.placeOrder(buyOrder8Id,Underlying,BuyOrder1)
time.sleep(3)
def Level9():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder9Id = app.nextValidOrderId
print("buyOrder9Id: ",buyOrder9Id)
app.placeOrder(buyOrder9Id,Underlying,BuyOrder1)
time.sleep(3)
def Level10():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder10Id = app.nextValidOrderId
print("buyOrder10Id: ",buyOrder10Id)
app.placeOrder(buyOrder10Id,Underlying,BuyOrder1)
time.sleep(3)
level1_thread = threading.Thread(target=Level1)
level1_thread.start()
level2_thread = threading.Thread(target=Level2)
level2_thread.start()
time.sleep(1)
level3_thread = threading.Thread(target=Level3)
level3_thread.start()
time.sleep(1)
level4_thread = threading.Thread(target=Level4)
level4_thread.start()
time.sleep(1)
level5_thread = threading.Thread(target=Level5)
level5_thread.start()
time.sleep(1)
level6_thread = threading.Thread(target=Level6)
level6_thread.start()
time.sleep(1)
level7_thread = threading.Thread(target=Level7)
level7_thread.start()
time.sleep(1)
level8_thread = threading.Thread(target=Level8)
level8_thread.start()
time.sleep(1)
level9_thread = threading.Thread(target=Level9)
level9_thread.start()
time.sleep(1)
level10_thread = threading.Thread(target=Level10)
level10_thread.start()
time.sleep(1)
I'm not familiar with Python, but I see the logical error - you're using "nextValiOrderId" in your app.1st thing you do - you start a bunch of threads.2nd thing that happens - each thread would send a request app.reqIds(1)
Now you need to understand what's reqIds() function logic (from this discussion):
The nextValidId method is a wrapper method. From the client, you need
to call reqIds to get an Order ID.
ib_api.reqIds(-1) The parameter of reqIds doesn't matter. Also, it doesn't have a return value. Instead, reqIds sends a message to IB,
and when the response is received, the wrapper's nextValidId method
will be called.
So you called reqIds(1) many times (almost at the same time), eventually the response will come in form of nextValidId() callback f-n, which sets app.nextValidOrderId to ever growing number, but the same time you reading that number from all your threads, which is complete mess.
Instead you could reorganize the code logic the following way:  - ask for reqIds(1) only once:
then do nothing (no code executed after that request is sent) 
the continuation logic will reside inside the body of the nextValidId() callback f-n: upon getting back a valid integer number from IB you would set it to some of you application variable and do not call reqIds(1) anymore.
call your "main_continuation()" function will will use that number as an argument to pass to i-th thread, then in a loop you'd increment this number and pass it to the next thread, and so on.In this case none of the threads will be trying to use the same order ID.
But even this approach is not ideal.. in case you need to start 100s of threads they will exceed 50 requests / second rate (one of many other rate limits by IB API), thus may be add 30 milliseconds sleep between starting new threads (in the loop where you create them one-by-one).
But now if you think over the design of your application a bit more - you'll see that you do NOT need many threads at all.
ps: I would strongly recommend for any Pythonista to carefully look at the ib_insync project, created by Ewald de Wit and it has growing community behind it and everybody is so happy with ease of use of ib_insync (written in python). This is their discussion forum.
and this is the ib_insync on the github
Cheers,Dmitry

How can I run a function forever?

Im trying to run the listener function forever, for example I want any time there is new information available in the stream it updates on the list automatically. Any idea in how to do it would be appreciated.
class Notifications(Screen):
notificationslist = ObjectProperty(None)
def listener(self, event = None):
notifications_screen = self.manager.get_screen('notif')
print(event.event_type) # can be 'put' or 'patch'
print(event.path) # relative to the reference, it seems
print(event.data) # new data at /reference/event.path. None if deleted
notifications = event.data
if notifications.items() == None:
return
else:
for key, value in notifications.items():
thevalue = value
notifications_screen.notificationslist.adapter.data.extend([value[0:17] + '\n' + value[18:]])
print(thevalue)
id = (thevalue[thevalue.index("(") + 1:thevalue.rindex(")")])
print(id)
If you want a function to run forever but that does not block you from doing other functions, then you can use threads.
Here is an example with example_of_process that runs forever, and then the main program with time.sleep(3)
import threading
import time
def example_of_process():
count = 0
while True:
print("count", count)
count += 1
time.sleep(1)
thread_1 = threading.Thread(target=example_of_process)
thread_1.daemon = True # without the daemon parameter, the function in parallel will continue even if your main program ends
thread_1.start()
# Now you can do anything else. I made a time sleep of 3s, otherwise the program ends instantly
time.sleep(3)

(python) execute function every x seconds

this is my source code that executes function every 1 seconds
buy, it only executes one times.
In short, I want to get the # of line from the named pipe output every seconds
Is there any suggestion for this problem?
thank you for your help in advance
class Monitor:
def __init__(self, namedpipe, name):
self.namedpipe = namedpipe
self.name = name
self.count = 0
def run(self):
print self.name+" start run"
while True:
line = self.namedpipe.readline()
self.count = self.count+1
def getCost(self):
print "Hi"
while True:
line = monitor.readline()
line = line.strip()
if not line:
ans =raw_input('stop?')
if ans=='y': break
monitorList = open(line, 'r')
m = Monitor(monitorList, line)
thread.start_new_thread(m.run, ())
time.sleep(1)
threading.Timer(0.1, m.getCost).start()
With Threading.Timer, you have to restart the timer each time it has expired - so during the execution of the function called when the timer expires - m.getCost in your code - the timer has to be started again. You might want to define a wrapper function to do this work, to avoid polluting m.getCost() with timer stuff.

Implementing Timeout. Whats wrong with the following code?

The program prints Expired the first time. I am expecting the code to print "not expired" for atleast 4 times before printing expired. Can someone please explain the reason and help me correct the code. Thank you
import time
TIMEOUT = 5
class Timer ():
def __init__(self):
self.timeout = time.time()+TIMEOUT
def isExpired ():
return time.time() > self.timeout
timing = Timer()
def main():
while 1:
if timing.isExpired:
print "Expired"
return
else:
print "Not expired"
print "sleeping for 1 second"
time.sleep(1)
if __name__== "__main__":
main()
You have several problems:
You did not give your isExpired method a self argument. Define it as def isExpired(self):.
You are creating a new Timer instance on each loop iteration. Move the timing = Timer() outside the while loop.
timing.isExpired is a reference to the method object iself (which is always true in a boolean context). You need to do timing.isExpired() to actually call it.
These are all basic Python issues that have nothing to do with Timer. Read the Python tutorial to learn how to use classes and so on.
You are creating a Timer instance everytime. Take it away from loop, or your while loop is never going to terminate. Also, you need to call timing.isExpired as it is a method. So your code should be:
import time
TIMEOUT = 60 * 5
class Timer ():
def __init__(self):
self.timeout = time.time()+TIMEOUT
def isExpired (self):
return time.time() > self.timeout
def main():
timing = Timer()
while 1:
if timing.isExpired():
print "Expired"
return
else:
print "Not expired"
print "sleeping for 1 second"
time.sleep(1)

Categories

Resources