Multiple accidental POST requests in Python

2019-09-08 00:50发布

I have this program that sends a GET request using requests library and then sends a POST request to another server.

import requests 

# inside the loop : 
headers = {'charset':'utf-8','Content-Type':'application/json'}
url = "http://someurl/_get_v2.php"
data = jenal

try :
    resp = requests.post(url,json=data,headers=headers, timeout=(connect_timeout,read_timeout))

    print "Post request sent" 
# If a connection error occurs, start from the beginning of the loop
except requests.exceptions.ConnectionError as e: 
    continue 
# If a read_timeout error occurs, start from the beginning of the loop
except requests.exceptions.ReadTimeout as e:  
    continue
time.sleep(10)

This is the POST part from the main loop. I used try and except in case if the program runs into a delay, I don't want it to stop for any error, but refreshes and continues from the beginning of the loop and so on for ever. Logically, the program should be fine, but when there is a multiple number of delays suddenly the program sends multiple POST requests at the same time.

E.g: the log should be like this: 10 sent. 20 sent. 30 sent. 45 sent (5 seconds delay). 55 sent

but what happens is this : 10 sent 20 sent 30 sent delay..
45 sent 45 sent 45 sent (a few copies of the data are sent at the same time which corrupts my database) 55 sent

How am I supposed to prevent the extra copies?

This is the first part of the program. In case there's anything in the post part, this part repeats and I can see the print each time:

connect_timeout = 3.05
read_timeout = 2

while True:
loop_time_start = time.time()
# GET

url_source = 'http://something/api_json.asp?cmd=list_metering&auth=YWRtaW46YWRtaW4='
try: 
    url = requests.get(url_source)
    print "GET request sent" 
except requests.exceptions.ConnectionError as e: continue

2条回答
老娘就宠你
2楼-- · 2019-09-08 01:16

What if you add a timer to the code.

import requests 
from datetime import datetime, time

posting = False

# inside the loop :

if not posting:
    posting = True

    headers = {'charset':'utf-8','Content-Type':'application/json'}
    url = "http://someurl/_get_v2.php"
    data = jenal

    start = datetime.now()
    try :
        resp = requests.post(url,json=data,headers=headers,timeout=(connect_timeout,read_timeout))

        print "Post request sent" 

        posting = False

    except requests.exceptions.ConnectionError as e:
        # If you continue here, then there will be no sleep.
        # If your POST fails straight away, it tries again straight away. 

        # You should print/log here so you know which exception is being caught.

        # Add Timer
        end = datetime.combine(start.date(), time(0))

        ShouldISleep(start, end)

        posting = False

        continue

    except requests.exceptions.ReadTimeout as e:
        # If you continue here, then there will be no sleep.
        # If your POST fails straight away, it tries again straight away.

        # You should print/log here so you know which exception is being caught.

        # Add Timer
        end = datetime.combine(start.date(), time(0))

        ShouldISleep(start, end)

        posting = False

        continue

    time.sleep(10)

Create a function

def ShouldISleep(t1, t2):
    passed = (t1 - t2).seconds
    if passed < 10:
        time.sleep(10 - passed)
查看更多
登录 后发表回答