I need to get twitter friends from an user. With twitter "friends" I mean user A follows user B, and also user B follows A.
Ok, so my idea was getting a list of people who are followed by user A, and if they are followed by user B, it increases numFriends.
First part works fine, but when I do that second request it falls apart and throws me an ugly 'error 400' :(
I read about the restrictions of twitter and all that, but it seems weird that second request so I don't know if it's doing ok.
Thank you in advance, I'm a noob at python and twitter api, and my mother tongue is not english, so I really hope it is everything clear. I will thank any help about this.
Here is the code :)
def getNumFriends(user):
dataUser=0
numFriends=0
url ="https://api.twitter.com/1.1/friends/ids.json?cursor=-1&screen_name=%s&count=5000"%(user.screen_name)
auth = OAuth1(getConsumerKey(), getConsumerSecret(), getAccessToken(), getAccessTokenSecret())
response = requests.get(url, auth=auth)
if response.status_code == 200:
dataUser = response.json()
userIDs = dataUser['ids']
else:
print "Error code %s" %response.status_code
#Here comes the problem :S
for friend in userIDs:
url = "https://api.twitter.com/1.1/friendships/show.json?source_id=%s&target_screen_name=%s"%(friend, user)
response = requests.get(url, auth)
if response.status_code == 200:
dataCompare = response.json()
mutualfriends = dataCompare['relationship']['target']['followed_by']
if mutualfriends =='true':
numFriends=numFriends+1
else:
print "First request OK. Second request error code %s" %response.status_code
break
return numFriends
Your code is fine, there are only a couple of minor mistakes. The error code 400, "bad request", does not give you very concrete info, but it tells you that something in the way you've written the url is wrong.
It should be:
url = "https://api.twitter.com/1.1/friendships/show.json?source_id=%s&target_screen_name=%s"%(friend, user.screen_name)
i.e it should be user.screen_name instead of user.
Besides, the second argument of requests.get() is not auth, thus you should specify always the name of the argument,
response = requests.get(url, auth=auth)
which wasn't the case in your second call.
BTW, just curious, any reason why you are not using a library like twython?
Hope it helps.
** EDIT after comments: **
There was another minor mistake in the code. Note that your variable mutualfriends is already boolean, in order to check its value you can do it like this,
if mutualfriends:
...
BTW, to check the type of a variable,
print(type(mutualfriends))
Related
So I am working on Python FastAPI project.
My current objective is to correctly authenticate password so correct password should trigger HTTP 204 response code, in every other case (also empty params) HTTP 401 should be triggered.
The examples look like that:
Here the response should be: 204
/auth?password=haslo&password_hash=013c6889f799cd986a735118e1888727d1435f7f623d05d58c61bf2cd8b49ac90105e5786ceaabd62bbc27336153d0d316b2d13b36804080c44aa6198c533215
And here: 401
/auth?password=haslo&password_hash=f34ad4b3ae1e2cf33092e2abb60dc0444781c15d0e2e9ecdb37e4b14176a0164027b05900e09fa0f61a1882e0b89fbfa5dcfcc9765dd2ca4377e2c794837e091
I am correctly handling RequestValidationError, and my hashed password validation looks like this:
class AuthResponse(BaseModel):
status_code: int
#app.get("/auth", response_model=AuthResponse)
async def auth(password: str, password_hash: str, response: Response):
try:
m = hashlib.sha512(bytes(password, encoding="ASCII"))
if str(m.hexdigest()) == password_hash:
response.status_code = 204
else:
response.status_code = 401
except Exception:
response.status_code = 401
return AuthResponse(status_code=response.status_code)
Now I cannot think of any passed parameter that would trigger incorrect validation (passing 204 code instead of 401), but it seems that it is possible, as external assertion shows. I know it must be something about empty values other than None, but I can't figure it out by myself.
I have already tried patterns like:
/auth?password=&password_hash=
/auth?password=%00&password_hash=%00
http://127.0.0.1:8000/auth?password=%0&password_hash=%0
I would really appreciate some kind of help, hint or suggestion.
Thank you all, it is only a coding exercise project, so many things could be a little bit off. But as it happens I didn't check the empty password parameter which creates valid hash, but is not correct according to task.
I've been looking around and trying to get a post request to work, but I haven't found any luck. I keep getting a MISSING_REQUIRED_PARAM each time the request is being made. My following code is shown below.
def create_sign_group(group_name, header, url):
temp_header = header
temp_header['Content-Type'] = 'application/json'
temp_header['Accept'] = 'application/json'
data = {
"GroupCreationInfo": {
"groupName": group_name
}
}
res = requests.post(url + 'groups', headers=temp_header, data=json.dumps(data))
if res.status_code == 200:
print('{} Group Created...'.format(group_name))
else:
print(res.status_code)
print(res.headers)
print(res.text)
exit(res.status_code)
I've tried using json instead of data, but still getting the same error. Using a the REST API client I was able to successfully make the call. The rest client is shown below:
If anyone can point shine some knowledge and point me in the right direction I would greatly appreciate it. Take care.
You should assign headers=temp_header not headers=header. MISSING_REQUIRED_PARAM is often griping about the content type header, which, as you can see IS being included in your screenshot test.
So I figured it out, I guess I was passing the wrong payload into the data param. I changed the code to:
data = {
"groupName": group_name
}
It looks like I didn't need the "GroupCreationInfo" parameter.
Okay to save on space I will post pieces of the code. Secondly I am not a Python coder. I am usually C#. So I did my best especially when finding out there was no SWITCH STATEMENT.
So I have one method in my class to talk to Lifx Cloud API and it works fine.
def GetAllLifxs(self):
selector = 'all';
uri = '%s%s' % (self._baseUri, selector)
response = requests.get(uri, headers = self._headers)
result = LifxProxyResult(999, {})
if response:
result = LifxProxyResult(response.status_code, json.loads(response.text))
return result
The above code ends up hitting the API URL: https://api.lifx.com/v1/lights/all
I am attempting to call (this is not the only method that has this same issue) the toggle api call. I have tried a few different selectors still nothing.
The toggle code is as such:
def ToggleLight(self, value, selectorType = 'all'):
if not selectorType == 'all':
if value == None:
raise TypeError('[value] cannot be None.')
typeSwitch = {
'id': 'id:%s' % value,
'label': 'label:%s' % value,
'group_id': 'group_id:%s' % value,
'group': 'group:%s' % value,
'location_id': 'location_id:%s' % value,
'location': 'location:%s' % value,
'scene_id': 'scene_id:%s' % value
}
#If nothing just for fun Toggle ALL lights
selector = '%s/toggle' % typeSwitch.get(selectorType, 'all')
uri = '%s%s' % (self._baseUri, selector)
response = requests.get(uri, headers = self._headers)
return response
Three attempts have a Response Code of 404. The ToggleLight method in each case produces these URLs.
https://api.lifx.com/v1/lights/label:DreLight/toggle
https://api.lifx.com/v1/lights/id:d073d5127a6e/toggle
https://api.lifx.com/v1/lights/all/toggle
None of them work when I call the ToggleLight method. But here is the kicker. When I copy the URLs generated urls into this plain Python file and run it functions and manipulates the light properly.
import requests
token = "MyMagicKeyHere"
headers = {
"Authorization": "Bearer %s" % token,
}
response = requests.post('https://api.lifx.com/v1/lights/label:DreLight/toggle', headers=headers)
Python is so new to me I don't understand what my issue is. As the function that works and sets the header information with the token is the same for every method so I don't think it could be that.
Thanks in advance for the second pair of eyes. Business.
EDIT:---------------------
To go along with the answer I was given I could pay closer attention to my method chart and what I type. I messed up pretty stupidly (new word). Lesson here kids is walk away when you get stuck then come back. more staring doesn't help.
The issue appears to be calling a request.get in ToggleLight, instead of requests.post, like in the stand alone program.
I'm trying to create a python function that will connect to a URL and check if a list of directory's exists on that website. So the input consists of a target and the directory's. My ultimate goal is to write some sort of DirBuster like program.
This is my function untill now:
def checkDir(checkDir_target):
breakurl = urlparse(target)
conn = httplib.HTTPConnection(breakurl.netloc)
conn.request('HEAD', checkDir_target)
response = conn.getresponse()
print response.status
complete = target + x
if (response.status < 400):
print(" [X] " + complete)
global total_resp
total_resp += 1
found.append(complete)
else:
print(" [ ] " + complete)
The only problem I'm having right now is that dynamic created pages like wordpress pages also return HTTP Status 200 codes. So even when I'm testing on a non-existing url the website will still return a HTTP 200 OK.
Example: testing on www.wordpressexamplesite.com/DIRECTORYTHATDOESNTEXISTS/ gives a HTTP 200 code as well as website URL's that DOES exist.
This means that the whole check in the checkDir function is not doing it's work like I want it to.
Can one of you guys give me some ideas on how to resolve this?
Unfortunately for you, when the server returns a "200 OK", then that means the URL does, in fact, exist and has the contents returned. Those contents might be a page that says "This doesn't exist". To identify that you would need to work on some artificial intelligence that can render and read the content that was returned and comprehend it like a human would.
I consider it bad web site design (and even worse for AJAX APIs) to always return "200 OK" and embed the "real" status in the payload, but that is how some people code it.
Try use requests lib:
import requests
def checkDir(checkDir_target):
breakurl = urlparse(target)
response = requests.get(breakurl.netloc, headers=checkDir_target)
complete = target + x
if response.status < 400:
print(" [X] " + complete)
global total_resp
total_resp += 1
found.append(complete)
else:
print(" [ ] " + complete)
I think this can works for you.
I am struggling getting a Rest API Post to work with a vendor api and hope someone can give me a pointer.
The intent is to feed a cli command to the post body and pass to a device which returns the output.
The call looks like this : ( this works for all other calls but this is different because of posting to body)
def __init__(self,host,username,password,sid,method,http_meth):
self.host=host
self.username= username
self.password= password
self.sid=sid
self.method=method
self.http_meth=http_meth
def __str__(self):
self.url = 'http://' + self.host + '/rest/'
self.authparams = urllib.urlencode({ "session_id":self.sid,"method": self.method,"username": self.username,
"password": self.password,
})
call = urllib2.urlopen(self.url.__str__(), self.authparams).read()
return (call)
No matter how I have tried this I cant get it to work properly. Here is an excerpt from the API docs that explains how to use this method:
To process these APIs, place your CLI commands in the HTTP post buffer, and then place the
method name, session ID, and other parameters in the URL.
Can anyone give me an idea of how to properly do this. I am not a developer and am trying to learn this correctly. For example if I wanted to send the command "help" in the post body?
Thanks for any guidance
Ok this was ridiculously simple and I was over-thinking this. I find that I can sometimes look at a much higher level than a problem really is and waist time. Anyway this is how it should work:
def cli(self,method):
self.url = ("http://" + str(self.host) + "/rest//?method=" +str(method)+ "&username=" +str(self.username)+ "&password=" +str(self.password)+ "&enable_password=test&session_id="+str(self.session_id))
data="show ver"
try:
req = urllib2.Request(self.url)
response = urllib2.urlopen(req,data)
result = response.read()
print result
except urllib2.URLError, e:
print e.reason
The cli commands are just placed in the buffer and not encoded....