get url from python - python

good day!
I need to send a request via the api to the https server. the documentation describes that this must be done via curl.
example request:
everything works out through curl. the request is sent, the response comes ok.
but if I try to send the same request with a python script, I get a 401 error.
here is my code.
import requests
def main():
token = 'my_token'
# url = 'https://api-ip.fssp.gov.ru/api/v1.0/'
url = 'https://api-ip.fssp.gov.ru/api/v1.0/search/physical'
region = '48'
lastname = 'Иванов'
firstname = 'Валерий'
secondname = 'Викторович'
birthdate = '02.07.1970'
data = {
'token': token,
'region': region,
'lastname': lastname,
'firstname': firstname,
'birthdate': birthdate,
'secondname': secondname
}
response = requests.get(url=url, data=data)
print(response.status_code)
if __name__ == '__main__':
main()
here is the content of the response from the server
b'{"status":"error","code":401,"exception":"token not exist","response":[]}'
What am I doing wrong?

Try using the params argument instead of data to URL encode the values:
response = requests.get(url=url, params=data)

Related

{'error': 'RESTEASY003650: No resource method found for PUT, return 405 with Allow header'} when updating user data in Keycloak

I am trying to update user info in keycloak by sending put request. Get request is working fine I am getting all the users but Whenever I tried to send put request to update the user data I get this error "{'error': 'RESTEASY003650: No resource method found for PUT, return 405 with Allow header'}" while searching for the solution I find somewhere that I should add 'HTTP_X_HTTP_METHOD_OVERRIDE' in headers I also tried this but still, I am facing same error, how can I fix it.
code:
def update_user(user_id, user_data):
import requests
headers = dict()
headers['HTTP_X_HTTP_METHOD_OVERRIDE'] = 'PUT'
headers['content_type'] = 'application/json'
data = {
"grant_type": "password",
"username": "admin",
"password": os.getenv("KEYCLOAK_ADMIN_KEY"),
"client_id": "admin-cli"
}
token = _request("POST", f"{server_internal_url}realms/master/protocol/openid-connect/token", None, data=data).json()["access_token"]
# token = admin_token()
headers["Authorization"] = f"Bearer {token}"
headers["Host"] = kc_host
# here = _request("PUT", admin_url+f"/users"+"/".format(user_id=user_id), token, data=json.dumps(user_data)).json()
response = requests.put(admin_url+f"/users"+"/".format(user_id=user_id), headers=headers, data=data, verify=VERIFY)
print(response.json())
server_internal_url = "https://keycloak:8443/auth/"
admin_url = "https://keycloak:8443/auth/admin/realms/{realm_name}"
It looks like you request has wrong URL:
response = requests.put(admin_url+f"/users"+"/".format(user_id=user_id), headers=headers, data=data, verify=VERIFY)
I guess it should be:
response = requests.put(admin_url+"/users/"+user_id, headers=headers, data=data, verify=VERIFY)

Can not fill form using python requests

I am trying to fill html form and get the intended result as i get when i fill manually. But I fail.
I am trying to fill the site https://www.desco.org.bd/ebill/login.php with value 32000001. So far my try is as below-
import requests
#LOGIN_URL = 'https://www.desco.org.bd/ebill/login.php'
#LOGIN_URL = 'https://www.desco.org.bd/ebill/authentication.php'
LOGIN_URL = 'https://www.desco.org.bd/ebill/billinformation.php'
payload = {
'username': '32000001',
'login':'Login',
'login':'true'
}
with requests.Session() as s:
p = s.post(LOGIN_URL, data=payload)#, verify=False)
# print the html returned or something more intelligent to see if it's a successful login page.
print (p.text)
I have found that login.php redirects to authentication.php and it further redirects to billinformation.php which delivers the true data i needed.
Thanks in advance.
N.B. I am not planning to use selenium since it is too slow for my case i.e. collect huge data from this site.
i am working for similar case, may be you would try using websockets:
import websockets
def process_function(message):
# process the message
def server(ws:str, path:int):
while True:
message_received = await ws.recv() # receive from ui
print(f'Msg [{message_received}]')
message_to_send = process_function(message)
await ws.send(message_to_send) # send feedback to ui
server = websockets.serve(server, '127.0.0.1', 5678) # set the html to run in the same ip:port
another try:
import json, requests
def do_auth(url):
headers = {"Content-Type": "application/json", "Accept":'*/*'}
body = json.dumps({'username': 'user', 'password': 'pass'})
r = requests.post(url=url, headers=headers, data=body, verify=False)
print(r.status_code);
d = json.loads(r.text);
print(d['access_token']);
print(d['refresh_token'])
return d['access_token'], d['refresh_token']
do_auth(url_auth) # authorization
requests.get(url_content, headers=headers, verify=False) # get data

Pass files with json payload in single requests to web2py endpoint

I wrote endpoint called foobar in default.py controller of web2py, it looks like
#service.json
def foobar(*args, **vars):
payload = request.vars.student
print(payload)
#Above payload prints [rollNo, firstName, lastName]
#Expected is {"rollNo": 6299857, "FirstName": Prasad, "LastName": Telkikar}
fileObj= request.vars.video
studentActivity = fileObj.file.read()
#Currently I am unable to do it from unit test, but it works from postman
print(f"Student's Roll number = {payload.rollNo} \n FirstName = {payload.firstName}, \n lastName = {payload.lastName}, fileSize = {fileObj.file.tell()}")
#storing studentActivity video to specific location
#Doing business logic
Now I am writing unit test for this endpoint, where i am trying to call this endpoint using requests,
import requests
import unittest
...
class TestStudentsData(unittest.TestCase):
def test_Individual_student(self):
payload = dict(rollNo=6299857, firstName="Prasad", lastName="Telkikar")
url = "http://127.0.0.1:8000/v1/foobar"
header = dict(Authorization="Bearer <Token>")
response = requests.post(url,files={'studentActivity':open("Activity.mp4", 'rb')}, data=payload, headers=headers)
self.assertEqual(response.status_code, 200)
if __name__ == '__main__':
unittest.main(verbosity=2)
Here I am unable to pass student payload as a json.
How can I pass json payload with studentActivity file using requests?
What I tried so far?
I tried both the approaches given in this SO answer.
I read requests documentation where it says "the json parameter is ignored if either data or files is passed" requests documentation
I resolved this problem by adding proper content-type to payload,
import os
...
filePath = os.getcwd()
files = {'studentActivity':open(filePath, "Activity.mp4", 'rb'),
'payload':(None, payload, 'application/json')}
#^^^^^^^^^^^^^^^^^ This was missing
response = requests.post(url,files={'studentActivity':open("Activity.mp4", 'rb')}, data=payload, headers=headers)

How to decline a pull request on Bitbucket from Python?

How do you use Bitbucket's 2.0 API to decline a pull request via Python?
According to their documentaion, it should be something like:
import requests
kwargs = {
'username': MY_BITBUCKET_ACCOUNT,
'repo_slug': MY_BITBUCKET_REPO,
'pull_request_id': pull_request_id
}
url = 'https://api.bitbucket.org/2.0/repositories/{username}/{repo_slug}/pullrequests/{pull_request_id}/decline'.format(**kwargs)
headers = {'Content-Type': 'application/json'}
response = requests.post(url, auth=(USERNAME, PASSWORD), headers=headers)
However, this fails with response.text simply saying "Bad Request".
This similar code works for me with their other API endpoints, so I'm not sure why the decline method is failing.
What am I doing wrong?
You have to authenticate with Oath. I wrote a wrapper for making these requests. Here is a simple example that works. The only thing I couldn't figure out was how to add a reason it was declined. I ended up making a request before I declined the PR that added a comment on why it was declined.
import os
from oauthlib.oauth2 import BackendApplicationClient
from requests_oauthlib import OAuth2Session
class Bitbucket(object):
def __init__(self, client_id, client_secret, workplace, repo_slug):
self.workplace = workplace # username or company username
self.repo_slug = repo_slug
self.token_url = 'https://bitbucket.org/site/oauth2/access_token'
self.api_url = 'https://api.bitbucket.org/2.0/'
self.max_pages = 10
self.client = BackendApplicationClient(client_id=client_id)
self.oauth = OAuth2Session(client=self.client)
self.oauth.fetch_token(
token_url=self.token_url,
client_id=client_id,
client_secret=client_secret
)
def get_api_url(self, endpoint):
return f'{self.api_url}repositories/{self.workplace}/{self.repo_slug}/{endpoint}'
bitbucket = Bitbucket(os.environ['BITBUCKET_KEY'], os.environ['BITBUCKET_SECRET'], workplace='foo', repo_slug='bar')
pr_id = 1234
resp = bitbucket.oauth.post(f"{bitbucket.get_api_url('pullrequests')}/{pr_id}/decline")
if resp.status_code == 200:
print('Declined')
else:
print('Someting went wrong.')

MailChimp bad request JSONParseError with Python

I am trying to hook up to MailChimp's api, in my Django application, to add an email to one of my lists. Seems pretty simple enough. I add my api key to the header of the request, with the email address and other variable in the body of the request. every time I try and connect though, I get a response status code of 400. The message says there is a JSON parsing error, and that my JSON is either formatted incorrectly, or there is missing data required for the request. I am making this same api call however with Postman, and am getting a good response back.
view function
import requests
def join_newsletter(request, email):
# hash the user's email for mailchimp's API
# m = hashlib.md5()
# c_email = email
# m.update(c_email.encode('utf-8'))
# email_hash = m.hexdigest()
api_key = 'apikey ' + settings.MAILCHIMP_API
api_endpoint = api_endpoint
data = {
"email_address": email,
"status": "subscribed"
}
header = {
'Authorization': api_key
}
r = requests.post(api_endpoint, data=data, headers=header)
message = r.content
return message

Categories