Search code examples
pythonpython-requestsdiscord

Python Request Module 'function' object is not iterable - Discord


Having a hard time figuring out why this error is being caused on my IdleRPG bot, each function works perfectly fine in its own file but gives the errors detailed below when together, anyone have a fix for this?

import time
import datetime
import threading
import requests
import json
import getpass
import os

print()
print('-----------------------------------------------------------------------------------------------------')
print()



user = getpass.getuser()
path = (f'C:/Users/{user}/autoadventure')
if os.path.exists(path) == True:
    pass
else:
    os.mkdir(path)
boosters = input('Do you have boosters enabled? Y/N ').upper()
adv = int(input('Which adventure did you want to idle? '))
leng = adv * 3600
chng = input('Are you using a different channel than last use? Y/N: ').upper()
if chng == 'Y':
    channelid = input('Input Channel ID for discord: ')
    f = open(f'C:/Users/{user}/autoadventure/channelid.txt', 'w+')
    f.write(f'{channelid}')
    f.close()
else:
    f = open(f'C:/Users/{user}/autoadventure/channelid.txt', 'r+')
    channelid = f.read()
    f.close()
auth = input('Has your authorization key changed? Y/N: ').upper()
if auth == 'Y':
    f = open(f'C:/Users/{user}/autoadventure/authkey.txt', 'w+')
    authcode = input('Please enter your authorization key: ')
    f.write(f'{authcode}')
    f.close()
else:
    f = open(f'C:/Users/{user}/autoadventure/authkey.txt', 'r+')
    authcode = f.read()
    f.close()
if boosters == 'Y':
    leng = leng/2
convert = datetime.timedelta(seconds=leng)

# payloads

url = f'https://discord.com/api/v9/channels/{channelid}/messages'

adventure = {
    'content': f"<@424606447867789312> adventure {adv}"
}
steal = {
    'content': f"<@424606447867789312> steal"
}
pray = {
    'content': f"<@424606447867789312> pray"
}
status = {
    'content': f"<@424606447867789312> status"
}
headers = {
        'authorization': f'{authcode}'
    }

def adventure():
    global adv
    msg= []
    counter = 0
    while True:
        time.sleep(5)
        r = requests.post(url, headers=headers, data=adventure,)
        print(f'Adventure Started | Level {adv} | Length {convert}')
        time.sleep(leng)
        r = requests.post(url, headers=headers, data=status,)
        counter = counter+1
        time.sleep(2)
        r2 = requests.get(url, headers=headers,)
        info = json.loads(r2.text)
        for value in info:
            msg.append(value['content'])
        check = msg[0]
        if check == (f'You reached a new level:'):
            adv = adv+1
            print(f'You leveled up! advancing to adventure {adv}!')
        print(f'Adventure {adv} Complete!')
        print(f'You have completed {counter} adventure(s) this session!')
def pray():
    while True:
        time.sleep(10)
        r = requests.post(url, headers=headers, data=pray,)
        print(f'Pray attempted, will try again in 5 hours')
        time.sleep(18000)

def steal():
    while True:
        time.sleep(15)
        r = requests.post(url, headers=headers, data=steal,)
        print(f'Steal attempted, will try again in 1 hour')
        time.sleep(3600)

if __name__ == "__main__":
    p1 = threading.Thread(target=adventure)
    p2 = threading.Thread(target=pray)
    p3 = threading.Thread(target=steal)

    p1.start()
    p2.start()
    p3.start()

When the program runs its presents me with this:

Exception in thread Thread-1 (adventure):
Traceback (most recent call last):
  File "C:\Users\ethan\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1016, in _bootstrap_inner
    self.run()
  File "C:\Users\ethan\AppData\Local\Programs\Python\Python310\lib\threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
  File "c:\Users\ethan\Desktop\autoadventurenew.py", line 74, in adventure
    r = requests.post(url, headers=headers, data=adventure,)
  File "C:\Users\ethan\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\api.py", line 115, in post
    return request("post", url, data=data, json=json, **kwargs)
  File "C:\Users\ethan\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\api.py", line 59, in request
    return session.request(method=method, url=url, **kwargs)
  File "C:\Users\ethan\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Users\ethan\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
  File "C:\Users\ethan\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\adapters.py", line 486, in send
    resp = conn.urlopen(
  File "C:\Users\ethan\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 703, in urlopen
    httplib_response = self._make_request(
  File "C:\Users\ethan\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 396, in _make_request
    conn.request_chunked(method, url, **httplib_request_kw)
  File "C:\Users\ethan\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connection.py", line 265, in request_chunked
    for chunk in body:
TypeError: 'function' object is not iterable

It does this for each of the three threads. am i missing something?


Solution

  • In your code you've defined a function called adventure. You've also used the alias adventure for the name of a dictionary. You are attempting to use the dictionary version in the line r = requests.post(url, headers=headers, data=adventure,). The error you receive is because Python can't tell the difference between the two objects with the same name. In fact, you've overwritten the reference to the dictionary by defining a function with the same name in a following line. Additionally, both references are in global scope.

    # Dictionary variable declared here
    adventure = {
        'content': f"<@424606447867789312> adventure {adv}"
    }
    
    # Function declared here
    def adventure():
       ...
    
    # Now `adventure` references the function due to global scope
    

    The quickest way to fix this is to rename the variable you are calling adventure so it doesn't conflict with any function names (or vice versa).