2

I have a python program, which will make some api calls and print some output depending upon the api's response. I am using flush = true argument in the print function call. Sometimes the python program looks hung (It won't print anything to the terminal). But when i press CTRL-C, some output is printed to the output and python (looks to)resumes again. I have not written any signal handler for SIGINT. Why is this behavior?

UPDATE (Added python code)

import requests
import config
import json
from ipaddress import IPv4Address, IPv4Network

ip_list = []

filepath = "ip_address_test.txt"
with open(filepath) as fp:
    line = fp.readline()
    ip_list.append(line.rstrip())
    while line:
        line = fp.readline()
        ip_list.append(line.rstrip())

print(ip_list)
del ip_list[-1]
sysparm_offset = 0
sysparm_limit = 2
flag = 1
for ip in ip_list:
    hosts = []
    while flag == 1:
        print("ip is "+str(ip), flush=True)
        # Set the request parameters
        url = 'https://xxx.service-now.com/api/now/table/u_cmdb_ci_subnet?sysparm_query=u_lifecycle_status!=end of life^GOTOname>='+ip+'&sysparm_limit='+str(sysparm_limit)+'&sysparm_offset='+str(sysparm_offset)

        # Eg. User name="username", Password="password" for this code sample.
        user = config.asknow_username
        pwd = config.asknow_password

        headers = {"Accept":"application/json"}

        # Do the HTTP request
        response = requests.get(url, auth=(user, pwd), headers=headers,verify=False)

        # Check for HTTP codes other than 200
        if response.status_code != 200: 
            print('Status:', response.status_code, 'Headers:', response.headers, 'Error Response:', response.content)
            exit()

        # Decode the json response into a dictionary and use the data
        result = json.loads(response.content)['result']
        iter = 0
        while iter < sysparm_limit:
            print("iter = "+str(iter),flush=True)
            print("checking "+result[iter]["name"], flush=True)
            id = result[iter]["u_guid"]
            url = "https://xxx.service-now.com/api/now/cmdb/instance/u_cmdb_ci_subnet/" + str(id)
            response = requests.get(url, auth=(user, pwd), headers=headers,verify=False)

            # Check for HTTP codes other than 200
            if response.status_code != 200: 
                print('Status:', response.status_code, 'Headers:', response.headers, 'Error Response:', response.content)
                exit()
            result1 = json.loads(response.content)['result']
            for relation in result1["outbound_relations"]:
                if relation["type"]["display_value"] == "IP Connection::IP Connection":
                    if IPv4Address(relation["target"]["display_value"]) in IPv4Network(ip):
                        print("appending host", flush=True)
                        hosts.append(relation["target"]["display_value"])
                    else:
                        print("ip not in subnet", flush=True)
                        flag = 0
                        break
            if flag == 0:
                break
            iter = iter+1
        sysparm_offset = sysparm_offset + 2
    with open('output.txt',"a+") as output_file:
        for value in hosts:
            output_file.write(str(value)+"\n")   
    print("completed "+ip,flush=True)
    flag = 1
  • Are you using windows? – Ishan Joshi Oct 17 '19 at 06:40
  • Yes and "Command Prompt" as the terminal. – ravenclaw_guy Oct 17 '19 at 06:42
  • Are you using any sub-processes, e.g. are you calling another program in your Python code? – Elijan9 Oct 17 '19 at 06:42
  • Welcome to [SO]! Provide a [mcve] so we have more context of what's going on. – Sнаđошƒаӽ Oct 17 '19 at 06:43
  • 1
    I'm not creating any child processes and i'm not using multi threading too. FYI: I'm using requests library for making api calls. – ravenclaw_guy Oct 17 '19 at 06:46
  • In Linux you coul try to use stdbuf: stdbuf -oL python script.py. Could you try something like this for Windows? https://stackoverflow.com/questions/13317375/is-there-an-stdbuf-equivalent-for-windows-7-command-prompt – Michal Špondr Oct 17 '19 at 06:49
  • 1
    @MichalŠpondr I don't there's a problem with the buffer. Since i'm explicitly using flush=true argument, it should flush the output as soon as the print function is called. Right? – ravenclaw_guy Oct 17 '19 at 06:54
  • @ravenclaw_guy That's true, I just wanted to make sure it's not the flushing issue. In this case a minimal reproducible example is really necessary. – Michal Špondr Oct 17 '19 at 06:58
  • @Sнаđошƒаӽ I have attached my code. The url i'm using is an internal url. But I think the code i'm using is not radically different from the general flow for calling apis. – ravenclaw_guy Oct 17 '19 at 07:03

1 Answers1

1

I am not sure if my issue is the same since you didn't mention clicking inside the command prompt and you didn't mention if it also resumes when pressing something besides ctrl-c, but it sounds a lot like what I had.

A little more googling led me to an insight I wish I had found as an answer to your question a while ago:

https://www.davici.nl/blog/the-mystery-of-hanging-batch-script-until-keypress

I had no idea a QuickEdit mode existed but besides following the steps in the article, you can also simply open the commandprompt, right-click the title bar, choose "defaults", and then under "Edit Options" disable "QuickEdit Mode".

I hope this helps you (or someone else) as much as it just helped me

Stryder
  • 848
  • 6
  • 9