For API Python requests file Post how can I make my code wait until the file is uploaded

I have an API test where I'm sending files to an endpoint through a multipart/form-data request using Python's (3.6) requests and the requests_toolbelt MultipartEncoder. In my tests I dynamically create a text file and use a timestamp for the name, then I upload the file through the API request and once it's done I remove the file from my local test data directory.

My issue is that when I try to remove the file often this part of the code fails because the request is still uploading even though the API response has returned a 200 response. My question is how do I make it wait till the upload is complete? The question is more about making it wait after the file post rather than deleting. I may choose to do other functions that also rely on the post-upload being finished.

I'm told that requests are synchronous unless you set up an asynchronous request (which I don't). But in my code when I try to remove the file it says that it's being used by another process, which I gather is the upload still running.

I've provided the following code, which does work although it's a distilled version of what I use (distilled down from lot's of classes and modules throughout a much larger project), but it essentially does the same thing with some hard-coded values, and there is a bit of repetition of paths here.

The very last line of the main method is where I receive an error: os.remove(os.path.join(uploadpath, file))

and returns the following error:

os.remove(os.path.join(uploadpath, file))
PermissionError: [WinError 32] The process cannot access the file because it 
is being used by another process:   

the code I have is as follows (sorry it's a bit messy, begin at the main section):

import rootdir_ref
import os
import datetime
import requests
from requests_toolbelt import MultipartEncoder
import jwt
import simplejson

class AppCredentials():
    # Use this class to set up your app credentials
    # To run a different API Version submit the api_version agrument
    def __init__(self, cred_file_name=None, api_version=None):
        if cred_file_name == None:
            cred_file_name = 'API_Credentials.txt'

        if api_version == None:
            api_version = 'v2.1'

        self.cred_file_name = cred_file_name
        self.api_version = api_version

        theRootDir = os.path.dirname(rootdir_ref.__file__)
        cred_file = os.path.join(theRootDir, 'TestDataFiles', self.cred_file_name)
        with open(cred_file) as json_data:
            cred_dict = simplejson.load(json_data)
        assert isinstance(cred_dict, object)

        self.consumer_id = cred_dict.get('app_consumer_id')
        self.secret = cred_dict.get('app_consumer_secret')
        self.access_token = cred_dict.get('app_access_token')
        self.base_url = cred_dict.get('base_url')

def create_timestamped_file(file_name, file_path):
    f = open(file_path, 'w')
    f.write('This is sample text file uploaded using Automation Testing')
    print('-----Created Sample file ' + file_name)
    return True

def post_new_client_file(client_id, testdata_file_name, parent_folder_id):
    # Locate file
    therootdir = os.path.dirname(rootdir_ref.__file__)
    uploadfilepath = os.path.join(therootdir, 'TestDataFiles', testdata_file_name)
    filesize = os.stat(uploadfilepath).st_size

    # Prepare data payload and claim payload

    datapayload = {
        'parentFolderId': parent_folder_id,
        'name': testdata_file_name,
        'size': str(filesize),
        'isFolder': False,
        'entity': 'Client',
        'primaryDomainKey': client_id
    end_point_url_sfx_str = '/API/Core/v2.1/File/'
    app_creds = AppCredentials()
    claim_payload = {'iss': '',
              'aud': '',
              'nbf': datetime.datetime.utcnow(),
              'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=60),
              'consumerId': app_creds.consumer_id,
              'accessToken': app_creds.access_token,
              'url': app_creds.base_url + end_point_url_sfx_str,
              'httpMethod': 'POST'}

    #create JwToken
    encoded_jwt_byte = jwt.encode(claim_payload, app_creds.secret, algorithm='HS256')
    jwt_str = str(encoded_jwt_byte, 'utf-8')
    uri = app_creds.base_url + end_point_url_sfx_str

    # create mutlipart/form-data
    m = MultipartEncoder([
        ('json', (None, simplejson.dumps(datapayload), 'text/plain')),
        ('file', (os.path.basename(uploadfilepath), open(uploadfilepath, 'rb'), 'text/plain'))],
        None, encoding='utf-8')

    headers = {'Authorization': 'JwToken' + ' ' + jwt_str, 'content-type': m.content_type}

    #send request
    response =, headers=headers, data=m, timeout=45, verify=True )

    if response.status_code != 200:
        print('File post failed: ' + str(response.status_code))
        print("successful api file post!")
    return response

if __name__ == '__main__':

    num_of_files_int = 10
    client_id = '57479659-b77e-4399-b53a-300ba865a17d'

    therootdir = os.path.dirname(rootdir_ref.__file__)
    uploadpath = os.path.join(therootdir, 'TestDataFiles')

    file_name_list = []

    for i in range(num_of_files_int):
        file_name = ("%H_%M_%S_%f")) + ".txt"
        uploadfilepath = os.path.join(therootdir, 'TestDataFiles', file_name)
        create_timestamped_file(file_name, uploadfilepath)

    for file in file_name_list:
        response = post_new_client_file(client_id, file, parent_folder_id)
        if response.status_code != 200:
            os.remove(os.path.join(uploadpath, file))

            file_response_id = response.json().get('id')
                '\nFile: ' + file + ' uploaded for client ' + str(client_id) + ' with file id ' + file_response_id)
            os.remove(os.path.join(uploadpath, file))