3

I am somewhat new to Python. I have looked around but cannot find an answer that fits exactly what I am looking for.

I have a function that makes an HTTP call using the requests package. I'd like to print a '.' to the screen (or any char) say every 10 seconds while the HTTP requests executes, and stop printing when it finishes. So something like:

def make_call:  
  rsp = requests.Post(url, data=file)  
  while requests.Post is executing print('.')  
   

Of course the above code is just pseudo code but hopefully illustrates what I am hoping to accomplish.

user3472
  • 173
  • 9

4 Answers4

3

Every function call from the requests module is blocking, so your program waits until the function returns a value. The simplest solution is to use the built-in threading library which was already suggested. Using this module allows you to use code "parallelism"*. In your example you need one thread for the request which will be blocked until the request finished and the other for printing.

If you want to learn more about more advanced solutions see this answer https://stackoverflow.com/a/14246030/17726897

Here's how you can achieve your desired functionality using the threading module

def print_function(stop_event):
    while not stop_event.is_set():
        print(".")
        sleep(10)


should_stop = threading.Event()
thread = threading.Thread(target=print_function, args=[should_stop])
thread.start() # start the printing before the request
rsp = requests.Post(url, data=file) # start the requests which blocks the main thread but not the printing thread
should_stop.set() # request finished, signal the printing thread to stop
thread.join() # wait for the thread to stop

# handle response

* parallelism is in quotes because of something like the Global Interpreter Lock (GIL). Code statements from different threads aren't executed at the same time.

1

i don't really getting what you looking for but if you want two things processed at the same time you can use multithreading module Example:

import threading
import requests
from time import sleep

def make_Request():
    while True:
        req = requests.post(url, data=file)
        sleep(10)


makeRequestThread = threading.Thread(target=make_Request)
makeRequestThread.start()

while True:
    print("I used multi threading to do two tasks at a same time")
    sleep(10)

or you can use very simple schedule module to schedule your tasks in a easy way

docs: https://schedule.readthedocs.io/en/stable/#when-not-to-use-schedule

Ahmad
  • 119
  • 4
  • You missed main point of question - the opp would like to stop printing when response comes – kosciej16 Dec 22 '21 at 23:07
  • Thank you. I should have mentioned I'd prefer not to use an external package. If I am more clear, I just want to print to the console some status while a requests.Post() call executes, and stop printing when it finishes execution. A way to let the user know that the HTTP request is still in process. For status, I just chose printing a '.' character. – user3472 Dec 22 '21 at 23:13
  • If I understood correctly You can not do 2 processes at the same time without using some packages like threading, multiprocessing... – Ahmad Dec 23 '21 at 15:03
1
import threading
import requests
from time import sleep

#### Function print and stop when answer comes ###    
def Print_Every_10_seconds(stop_event):
    while not stop_event.is_set():
        print(".")
        sleep(10)

### Separate flow of execution ###
Stop = threading.Event()
thread = threading.Thread(target=Print_Every_10_seconds, args=[Stop])

### Before the request, the thread starts printing ### 
thread.start()

### Blocking of the main thread (the print thread continues) ###
Block_thread_1 = requests.Post(url, data=file) 

### Thread stops ###
Stop.set() 
thread.join()
Erling Olsen
  • 1
  • 4
  • 15
0

The below code also solves the problem asked. It will print "POST Data.." and additional trailing '.' every second until the HTTP POST returns.

import concurrent.futures as fp
import logging

with fp.ThreadPoolExecutor(max_workers=1) as executor: 
  post = executor.submit(requests.post, url, data=fileobj, timeout=20)     
  logging.StreamHandler.terminator = ''
  logging.info("POST Data..")
  while (post.running()):
    print('.', end='', flush=True)
    sleep(1)
  print('')
  logging.StreamHandler.terminator = '\n'
  http_response = post.result()
user3472
  • 173
  • 9
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 28 '21 at 03:28