Python method missing an argument but all seems to be there [duplicate] - python

This question already has answers here:
TypeError: Missing 1 required positional argument: 'self'
(8 answers)
Closed 3 years ago.
What i'm trying to do is run a piece of code that did work at one time, but when i loaded up the project the captcha solving function is saying i'm missing an argument in a function but i don't see where.
Code:
This piece of code:
elif action_to_take == "RECAPTCHA_V2":
selenium_field = self.execute_recaptcha_v2_solver(captcha_key, url_or_field_identifier)
self.write_to_debug_file("--> SOLVING RECAPTCHA V2 ...", _filename)
Then executes:
# this function executes the ReCaptcha solver ...
def execute_recaptcha_v2_solver(self, api_key, url_or_field_identifier):
solve_recaptcha_v2 = CaptchaReCaptchaSolver.solve_recaptcha(api_key,
self.extract_data_site_key(self.driver.page_source),
url_or_field_identifier)
javascript_code = 'document.getElementById("g-recaptcha-response").innerHTML = "{}"'.format(solve_recaptcha_v2)
return self.driver.execute_script(javascript_code)
Which runs the Class:
class CaptchaReCaptchaSolver(object):
# noinspection PyMethodMayBeStatic
def solve_recaptcha(self, _captcha_api_key, _site_key, _url):
print(_captcha_api_key, _site_key, _url)
""" this function solves recaptcha using 2captcha.com """
try:
# p = '127.0.0.1:6969'
# p = {'http': 'http://' + p, 'https': 'https://' + p}
# send off requests ...
s = requests.Session()
cap_id = s.post('http://2captcha.com/in.php?key={}&method=userrecaptcha&googlekey={}&pageurl={}'.format(
_captcha_api_key, _site_key, _url)).text.split('|')[1]
rec_an = s.get("http://2captcha.com/res.php?key={}&action=get&id={}".format(_captcha_api_key, cap_id)).text
# tell us what is going on ...
print("--> ReCAPTCHA V2 SOLVING")
print("--> SOLVING ...")
while "CAPTCHA_NOT_READY" in rec_an:
sleep(5)
rec_an = s.get("http://2captcha.com/res.php?key={}&action=get&id={}".format(_captcha_api_key, cap_id)).text
rec_an = rec_an.split('|')[1]
# solved ...
print("--> " + rec_an)
print("--> SOLVED ...")
print("--> ReCAPTCHA V2 RESPONSE")
# payload ...
payload = {'key': 'value', 'gresponse': rec_an}
s.post(_url, payload)
# return ReCaptcha answer ...
return rec_an
except Exception as e:
print("2CAPTCHA.COM [ReCAPTCHA] ERROR: ", e)
The error is:
LINE 222 "selenium_field = self.execute_recaptcha_v2_solver(captcha_key, url_or_field_identifier)"): solve_recaptcha() missing 1 required positional argument: '_url'
The class method solve_recaptcha() is missing an argument it is saying, but i have printed them out and they are all there, am i missing something obvious? i cannot see what the issue could be, any help would be appreciated.

Notice here... CaptchaReCaptchaSolver.solve_recaptcha this is how you would call a static class member not an instance. Since the method's first param is self then it requires the function be called on an instance of the object.
This should fix.
CaptchaReCaptchaSolver().solve_recaptch(...
Now your final code is
# this function executes the ReCaptcha solver ...
def execute_recaptcha_v2_solver(self, api_key, url_or_field_identifier):
solve_recaptcha_v2 = CaptchaReCaptchaSolver().solve_recaptcha(api_key,
self.extract_data_site_key(self.driver.page_source),
url_or_field_identifier)
javascript_code = 'document.getElementById("g-recaptcha-response").innerHTML = "{}"'.format(solve_recaptcha_v2)
return self.driver.execute_script(javascript_code)

Related

python __init__() takes 1 positional argument but 2 were given newbie

I have an attribute error in a little spotify-api program i am trying to run
my run file contains the following
import os
from spotify_client import AddSongs
def run():
spotify_client = AddSongs('spotify_token')
random_tracks = spotify_client.get_random_tracks()
track_ids = [track['id'] for track in random_tracks]
was_added_to_queue = spotify_client.add_tracks_to_queue()
if was_added_to_queue:
for track in random_tracks:
print(f"Added {track['name']} to your library")
if __name__ == '__main__':
run()
then in spotify_client is the following class
class AddSongs(object):
def __init__(self,):
self.spotify_token = ""
self.uri = ""
def get_random_tracks(self):
wildcard = f'%{random.choice(string.ascii_lowercase)}%'
query = urllib.parse.quote(wildcard)
offset = random.randint(0, 2000)
url = f"https://api.spotify.com/v1/search?q={query}&offset={offset}&type=track&limit=1"
response = requests.get(
url,
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {self.spotify_token}"
}
)
response_json = response.json()
print(response)
tracks = [
track for track in response_json['tracks']['items']
]
self.uri = response_json["tracks"]["items"][0]["uri"]
print(f'Found {len(tracks)} tracks to add to your queue')
return tracks
return self.uri
def add_tracks_to_queue(self,):
print('adding to queue...')
url =f"https://api.spotify.com/v1/me/player/queue?uri={self.uri}"
response = requests.post(
url,
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {self.spotify_token}"
}
)
print(f"Added {track['name']} to your queue")
return response.ok
def callrefresh(self):
print("Refreshing token")
refreshCaller = Refresh()
self.spotify_token = refreshCaller.refresh()
self.get_random_tracks()
a = AddSongs()
a. callrefresh()
As you can see it runs the code fine up untill add_tracks_to_queue
this is giving me the following traceback
Refreshing token
<Response [200]>
Found 1 tracks to add to your queue
Traceback (most recent call last):
File "/Users/shakabediako/Documents/free_streams/run.py", line 18, in <module>
run()
File "/Users/shakabediako/Documents/free_streams/run.py", line 7, in run
spotify_client = AddSongs('spotify_token')
TypeError: __init__() takes 1 positional argument but 2 were given
>>>
I know there are multiple threads about this error but after reading most of them i haven't been able to understand the concept or find the answer.
I think it has something to do with me calling the function from another file but i do not understand why this creates another "positional argument"
I know this because if i just run the spotify_client file i get the following response
Refreshing token
<Response [200]>
Found 1 tracks to add to your queue
>>>
which are just my print values up until def add_tracks_to_queue (which i also don't understand why it is not running)
I really hope someone can help me with this
Thanks in advance
Your AddSongs class doesn't accept any variables as input (also there's a stray comma in the __init__ which doesn't seem to serve any purpose):
class AddSongs(object):
def __init__(self,):
Yet you're calling it as if it does accept a variable:
spotify_client = AddSongs('spotify_token')
The self parameter has to be in there, but if you want to accept any other variables, you need to actually define them. The solution could therefore be to add a token parameter:
class AddSongs(object):
def __init__(self, token=""): # defaults to an empty string if token is not passed in
self.spotify_token = token
That way, if you call AddSongs('spotify_token'), the class's self.spotify_token will get set to 'spotify_token'.

Mocking requests.post [duplicate]

This question already has answers here:
How can I mock requests and the response?
(20 answers)
Closed 2 years ago.
This is my first time writing unit tests, apologies for the annoyances inevitably present, despite my best efforts. I am trying to mock requests.post but my test function is not having the desired effect, to induce a 404 status code so that I can test error handling.
mymodule.py
def scrape(data):
logger.debug(f'\nBeginning scrape function')
result = {}
exceptions = {}
for id, receipts in data.items():
logger.debug(f'Looking up Id # {id} and receipts: \n{receipts}')
dispositions = []
for receipt in receipts:
logger.debug(f'The length of receipts is:' + str(len(receipts)))
attempts = 1
while attempts < 6:
logger.debug(
f'This is attempt number {attempts} to search for {receipt}')
payload = {'receipt': 'receipt',
'button': 'CHECK+STATUS', }
try:
NOW = datetime.today().strftime('%c')
logger.debug(NOW)
logger.debug(f'Making post request for: {receipt}')
response = requests.post(URL, data=payload, headers=HEADERS, timeout=10)
except Exception as e:
logger.debug(f'There was an exception: {e}')
exceptions[id] = receipt + f': {e}'
time.sleep(3)
attempts += 1
else:
logger.debug(f'It worked {response.status_code}')
attempts = 6
disp = parse(response)
dispositions.append(f'{receipt}: {disp}')
result[id] = dispositions
logger.debug(f'Here is the result: {result}')
return result
test_mymodule.py
def test_scrape(self):
print(f'\ntest_scrape running')
# mock a 404 in scrape() here
with patch("mymodule.requests") as patched_post:
# mock a request response
patched_post.return_value.status_code = 404
print('404 mocked')
# verify the function returns nothing due to 404
result = scrape(test_data)
print(f'\n{result}')
mock_requests.post.assert_called_once()
self.assertEqual(result, {})
def test_scrape(self):
print(f'\ntest_scrape running')
# mock a 404 in scrape() here
with patch("mymodule.requests") as patched_post:
# mock a request response
patched_post.return_value.status_code = 404
print('404 mocked')
# verify the function returns nothing due to 404
result = scrape(test_data)
print(f'\n{result}')
mock_requests.post.assert_called_once()
self.assertEqual(result, {})

Flask SQLAlchemy: filter_by() takes 1 positional argument but 2 were given

I have the following lines in my python api which deletes a function created by user from postgres db upon request.
#func_app.route("/delete", methods=["POST"])
def delete_func():
try:
JSON = request.get_json()
user_func = function_table.query.filter_by(
created_by=token_payload["email"], functionid=JSON["funcId"]
).all()
functionid=JSON["funcId"]
func_detail = function_table.query.filter_by(functionid).first()
user = users_table.query.filter_by(email=token_payload["username"]).first()
if len(user_func) == 0:
log_metric(g.request_id + " " + "No functions found")
return make_response(
jsonify("User does not have any functions. Please try again later."),
204,
)
else:
function_table.query.filter_by(functionid).delete()
db.session.commit()
except Exception as err:
db.session.rollback()
log_metric(g.request_id + " " + str(err))
return make_response(
jsonify(
"Unable to process your request at the moment. Please try again later."
),
400,
)
finally:
db.session.close()
I have used filter_by similarly before but there I didn't find any issue. Can anyone help me figure out what went wrong?
Thanks!
You need to define the column name with the value in filter_by, it take **kwargs arguments not *args type of input.
you need to change
func_detail = function_table.query.filter_by(functionid).first()
to
func_detail = function_table.query.filter_by(id = functionid).first()
considering id is column name.
For more information, see the sqlalchemy documentation.

Weird Python error

This error: cancel_agreement() missing 1 required positional argument: 'agreement_id'
appeared while executing this method:
def force_cancel(self):
api = model_from_ref(self.processor.api)
api.cancel_agreement(self.subscription_reference)
# transaction.cancel_subscription() # runs in the callback
Here is cancel_agreement() method:
def cancel_agreement(self, agreement_id, is_upgrade=False):
note = _("Upgrading billing plan") if is_upgrade else _("Canceling a service")
r = self.session.post(self.server + '/v1/payments/billing-agreements/%s/cancel' % agreement_id,
data='{"note": "%s"}' % note,
headers={'content-type': 'application/json'})
if r.status_code != requests.codes.ok:
raise RuntimeError(_("Cannot cancel a billing agreement at PayPal. Please contact support."))
I don't understand why the error happens: It is calling a two-argument function (api and self.subscription_reference) and its definition is also two required arguments (self and agreement_id).
Sadly I can't show the entire code, because my business partner is against releasing it open source.
It should be:
def force_cancel(self):
klass = model_from_ref(self.processor.api)
api = klass()
api.cancel_agreement(self.subscription_reference)

Instancemethod object is not iterable (AirPi) (Python)

I got ERROR:Exception during output: 'instancemethod' object is not iterable when debugging this AirPi code from https://github.com/haydnw/AirPi/blob/master/outputs/ubidots.py
This suppose to upload my sensor data to the Ubidots server.
*I'd put my correct token and variable ID inside the configuration file for this AirPi.
requiredSpecificParams = ["token"]
optionalSpecificParams = ["showcost",
"ID-BMP085-temp",
"ID-BMP085-pres",
"ID-DHT22-hum",
"ID-DHT22-temp",
"ID-LDR",
"ID-TGS2600",
"ID-MiCS-2710",
"ID-MiCS-5525",
"ID-Microphone",
"ID-Raingauge"
]
def __init__(self, config):
super(Ubidots, self).__init__(config)
self.token = self.params["token"]
if "showcost" in self.params:
self.showcost = self.params["showcost"]
else:
self.showcost = False
self.ubivariables = {}
for key, value in self.params.iteritems():
if key[:3] == "ID-":
if value:
self.ubivariables[key[3:]] = value
def output_data(self, datapoints, dummy):
"""Output data.
Output data in the format stipulated by the plugin. Calibration
is carried out first if required.
Because this particular plugin (ubidots) does not show time, the
third argument (normally called 'sampletime') is called 'dummy'
to facilitate compliance with pylint.
Args:
self: self.
datapoints: A dict containing the data to be output.
dummy: datetime representing the time the sample was taken.
Returns:
boolean True if data successfully output to Ubidots; False if
not
"""
if self.params["calibration"]:
datapoints = self.cal.calibrate(datapoints)
payload = []
for point in datapoints:
for ubivariablename, ubivariableid in self.ubivariables.iteritems():
if point["sensor"] == ubivariablename:
if point["value"] is not None:
thisvalue = {}
thisvalue["variable"] = ubivariableid
thisvalue["value"] = point["value"]
payload.append(thisvalue)
break
headers = {'Accept': 'application/json; indent=4', 'Content-Type': 'application/json', 'X-Auth-Token': self.token}
url = "http://things.ubidots.com/api/v1.6/collections/values"
req = None
cost = 0
try:
req = requests.post(url, data=json.dumps(payload), headers=headers)
except Exception, e:
print("ERROR: Failed to contact the Ubidots service.")
print("ERROR: " + str(e))
return False
for response in req.json:
if response["status_code"] is not 201:
print("ERROR: Ubidots responded with an error for one of the values.")
return False
else:
cost += 1
if self.showcost:
print("Ubidots upload cost " + str(cost) + " dots.")
return True
for response in req.json:
According to the documentation, json is a method and must be called, so this should be:
for response in req.json():
In the future it is helpful to include just as much of your code as is necessary to reproduce the problem, and to include the complete error message with traceback.

Categories