Working with session cookies in Python - python

I am trying to get access to the Kerio Connect (mailserver) api which uses jsonrpc as a standard for their api.
There is Session.login method that works just fine, I get back a SESSION_CONNECT_WEBADMIN cookie that gets saved in the session:
SESSION_CONNECT_WEBADMIN=2332a56d0203f27972ebbe74c09a7f41262e5b224bc6a05e53e62e5872e9b698; \
path=/admin/; domain=<server>; Secure; HttpOnly; Expires=Tue, 19 Jan 2038 03:14:07 GMT;
But when I then do my next request with the same session, I get back a message that tells me, that my session has expired:
{
"jsonrpc": "2.0",
"id": 2,
"error": {
"code": -32001,
"message": "Session expired.",
"data": {
"messageParameters": {
"positionalParameters": [],
"plurality": 1
}
}
}
}
So here's the Python script leading to that message
import json
import requests
userName = "username"
password = "password"
n=1
application = {}
application["name"] = "Log in"
application["vendor"] = "My Company"
application["version"] = "1.0"
params = {}
params["userName"] = userName
params["password"] = password
params["application"] = application
payload = {}
payload["jsonrpc"] = "2.0"
payload["id"] = n
n += 1
payload["method"] = "Session.login"
payload["params"] = params
headers = {}
headers["Content-Type"] = "application/json-rpc"
json_payload =json.dumps(payload, sort_keys=True, indent=2)
url = "https://<server>:4040/admin/api/jsonrpc/"
session = requests.Session()
response = session.post(url, headers=headers, data=json_payload, verify=False)
# Results in a token / a cookie with that token
payload2 = {}
payload2["jsonrpc"] = "2.0"
payload2["id"] = n
n += 1
payload2["method"] = "Users.get"
json_payload2 = json.dumps(payload2, sort_keys=True, indent=2)
response2 = session.post(url, data=json_payload2, verify=False)
print(response2.text)
What am I missing here because of my lack of experience?
[EDIT]:
I just now realise that when I log in with a browser, two cookies are actually created, each with another token, whereas I get only one cookie back when I try to access the api with Python. Why is that?
Cookies received with Chrome:
TOKEN_CONNECT_WEBADMIN
SESSION_CONNECT_WEBADMIN
Cookie received with Python:
SESSION_CONNECT_WEBADMIN

Working example:
import json
import urllib.request
import http.cookiejar
import ssl
jar = http.cookiejar.CookieJar()
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(jar))
urllib.request.install_opener(opener)
server = "https://mail.smkh.ru:4040"
username = "admin"
password = "pass"
ssl._create_default_https_context = ssl._create_unverified_context # disable ssl cert error
def callMethod(method, params, token=None):
"""
Remotely calls given method with given params.
:param: method string with fully qualified method name
:param: params dict with parameters of remotely called method
:param: token CSRF token is always required except login method. Use method "Session.login" to obtain this token.
"""
data = {"jsonrpc": "2.0", "id": 1, "method": method, "params": params}
req = urllib.request.Request(url=server + '/admin/api/jsonrpc/')
req.add_header('Content-Type', 'application/json')
if token is not None:
req.add_header('X-Token', token)
httpResponse = opener.open(req, json.dumps(data).encode())
if httpResponse.status == 200:
body = httpResponse.read().decode()
return json.loads(body)
session = callMethod("Session.login", {"userName": username, "password": password, "application": {"vendor":"Kerio", "name":"Control Api Demo", "version":"8.4.0"}})
token = session["result"]["token"]
sessions = callMethod("Users.get",
{"query": {
"fields": [
"id",
"loginName",
"fullName",
"description",
"authType",
"itemSource",
"isEnabled",
"isPasswordReversible",
"emailAddresses",
"emailForwarding",
"userGroups",
"role",
"itemLimit",
"diskSizeLimit",
"consumedItems",
"consumedSize",
"hasDomainRestriction",
"outMessageLimit",
"effectiveRole",
"homeServer",
"migration",
"lastLoginInfo",
"accessPolicy"
],
"start": 0,
"limit": 200,
"orderBy": [
{
"columnName": "loginName",
"direction": "Asc"
}
]
},
"domainId": Example:"keriodb://domain/908c1118-94ef-49c0-a229-ca672b81d965"
},
token)
try:
user_names = []
for user in users["result"]["list"]:
print(user["fullName"], " (", user["loginName"], ")", sep="")
user_names.append(user["fullName"])
call_method("Session.logout", {}, token)
return users
except KeyError:
print('Error: {}'.format(users['error']['message']))
call_method("Session.logout", {}, token)
return None

Related

make an order kucoin API in python

import requests, json, time
url = 'https://api.kucoin.com/api/v1/orders'
headers = {
"KC-API-KEY": '',
"KC-API-PASSPHRASE": '',
"clientOid": "AAA",
"side": "sell",
"symbol": "BTC-USDT",
"type": "market",
"size": "0.001",
}
response = requests.post(url, headers=headers)
print(response.status_code)
print(response.json())
I am trying to place an order but it isn't working. Am I missing some parameters?
Error:
{'code': '400001', 'msg': 'Please check the header of your request for KC-API-KEY, KC-API-SIGN, KC-API-TIMESTAMP, KC-API-PASSPHRASE'}
According to the official docs, all private request must contain the following headers:
KC-API-KEY
KC-API-SIGN
KC-API-TIMESTAMP
KC-API-PASSPHRASE
KC-API-VERSION
Here is an example of the endpoint to place a order limit:
import base64, hmac, hashlib, json
# constants
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
API_PASSPHRASE = "YOUR_API_PASSPHRASE"
url = "https://api.kucoin.com/api/v1/orders"
now = int(time.time() * 1000)
data = {"clientOid": "AAA", "side": "sell", "symbol": "BTC-USDT", "type": "market", "size": "0.001"}
data_json = json.dumps(data)
str_to_sign = str(now) + 'POST' + '/api/v1/orders' + data_json
signature = base64.b64encode(hmac.new(API_SECRET.encode(
'utf-8'), str_to_sign.encode('utf-8'), hashlib.sha256).digest())
passphrase = base64.b64encode(hmac.new(API_SECRET.encode(
'utf-8'), API_PASSPHRASE.encode('utf-8'), hashlib.sha256).digest())
headers = {
"KC-API-SIGN": signature,
"KC-API-TIMESTAMP": str(now),
"KC-API-KEY": API_KEY,
"KC-API-PASSPHRASE": passphrase,
"KC-API-KEY-VERSION": "2",
"Content-Type": "application/json"
}
try:
res = requests.post(
url, headers=headers, data=data_json).json()
print(res)
except Exception as err:
print(err)
Hope it will help.
Did you consider using wrapped library like Python-kucoin ?
https://python-kucoin.readthedocs.io/en/stable/index.html
it is really great and will definitely help you. Have a look to the documentation
from kucoin.client import Client
api_key = '<api_key>'
api_secret = '<api_secret>'
api_passphrase = '<api_passphrase>'
client = Client(api_key, api_secret, api_passphrase)
# place a market buy order
order = client.create_market_order('BTC-USDT', Client.SIDE_BUY, size=0.001)
try removing the spaces from :
data = {"clientOid": "AAA", "side": "sell", "symbol": "BTC-USDT", "type": "market", "size": "0.001"}

how to attach the token to a graphql mutation request?

I create this function to update details of user, before this function I have to login and get the token that I have to use in the next call.
I use this for init:
# Select your transport with a defined url endpoint
transport = AIOHTTPTransport(url=HOSTNAME_GRAPHQL, headers={'Authorization': 'token'})
# Create a GraphQL client using the defined transport
client = Client(transport=transport, fetch_schema_from_transport=True)
and this funcion for call the mutation
def mutation_updateUser(client, id, username, firstName, lastName, access_token):
# headers = {
# #"X-Shopify-Storefront-Access-Token": access_token
# "Authorization": "Bearer " + access_token
# }
headers={'Authorization': f'Bearer ' + access_token}
query = gql(
"""
mutation updateUser($input: UpdateUserInput!) {
updateUser(input: $input) {
id
email
username
lastName
firstName
role
avatar
}
}
"""
)
params = {
"input": {
"id": id,
"username": username,
"firstName": firstName,
"lastName": lastName
}
}
request = client.execute(query, variable_values=params, headers=headers)
if request.status_code == 200:
return request.json()
else:
raise Exception("Query failed to run by returning code of {}. {}".format(request.status_code, query))
#return result
when I run the program I got this error:
**
Si è verificata un'eccezione: TypeError
execute() got an unexpected keyword argument 'headers'
File "D:\Python project\API ReadyTGo\mutation_updateUser.py", line 36, in mutation_updateUser
request = client.execute(query, variable_values=params, headers=headers)
**
SOLVED THE PROBLEM!!
I modify the function like this:
from gql.transport.aiohttp import AIOHTTPTransport
from gql import gql, Client
from gql.transport.requests import RequestsHTTPTransport
from questions import HOSTNAME_GRAPHQL
def mutation_updateUser(id, username, firstName, lastName, access_token):
# headers = {
# #"X-Shopify-Storefront-Access-Token": access_token
# "Authorization": "Bearer " + access_token
# }
#headers={'Authorization': f'Bearer ' + access_token}
headers = {"Authorization": f"Bearer {access_token}"}
_transport = RequestsHTTPTransport(url=HOSTNAME_GRAPHQL, use_json=True, headers=headers)
client = Client(transport=_transport, fetch_schema_from_transport=True)
query = gql(
"""
mutation updateUser($input: UpdateUserInput!) {
updateUser(input: $input) {
id
email
username
lastName
firstName
role
avatar
}
}
"""
)
params = {
"input": {
"id": id,
"username": username,
"firstName": firstName,
"lastName": lastName
}
}
request = client.execute(query, variable_values=params)
return request.json()
I hope to help someone

How to use API QR Monkey with post or get method on Python

I'm trying to use the free api https://www.qrcode-monkey.com and I can't find anywhere a valid example for python, I think I followed thru the documentation. I'm doing some trial and on POST I continue getting method errors and on GET I get a lot of 400 errors...
Here is the code with both, anyone knows what I'm doing wrong? Thank you!
import requests
from urllib.parse import quote, urlencode
class QrManager:
def __init__(self):
self.url = "https://qrcode-monkey.com/"
def get_data_post(self):
url = self.url + "qr/custom"
payload = {
"data": "https://www.google.com",
"config": {
"body": "circle",
},
"size": 300,
"download": False,
"file": "png"
}
req = requests.post(url, json=payload)
return req
def get_data_get(self):
template_url = self.url + "qr/custom/?{}"
params = {
"data": "https://www.google.com",
"config": {
"body": "circle",
},
"size": 300,
"download": False,
"file": "png"
}
url = template_url.format(urlencode(params, safe="()", quote_via=quote))
req = requests.get(url)
return req
qrm = QrManager()
# response = dm.get_data_post()
response = qrm.get_data_get()
print(response.status_code)
print(response.url)
print(response.text)
They didn't show it in documentation but it needs different URL - with api. instead of www.
https://api.qrcode-monkey.com/qr/custom
I used DevTools in Firefox/Chrome (tab:Network) to see url used when page generates QR.
There is other problem.
POST gives QR with circles but GET gives with normal squares.
GET needs to convert config to json to get circles
"config": json.dumps({"body": "circle"})
(but it doesn't need urlencode)
Full code.
import requests
#from urllib.parse import quote, urlencode
import json
class QrManager:
def __init__(self):
self.url = "https://api.qrcode-monkey.com/qr/custom"
def get_data_post(self):
# it converts `config` to `json` automatically (because it sends all `payload` as `json`)
payload = {
"data": "https://blog.furas.pl",
"config": {
"body": "circle",
},
"size": 300,
"download": False,
"file": "png"
}
response = requests.post(self.url, json=payload)
return response
def get_data_get(self):
# it needs to convert `config` to `json` manually
payload = {
"data": "https://blog.furas.pl",
"config": json.dumps({
"body": "circle"
}),
"size": 300,
"download": False,
"file": "png"
}
#payload = urlencode(payload, safe="()", quote_via=quote)
response = requests.get(self.url, params=payload)
return response
# --- main ---
qrm = QrManager()
print('\n--- GET ---\n')
response = qrm.get_data_get()
print('status:', response.status_code)
print('url:', response.url)
print(response.text[:100])
with open('QR_GET.png', 'wb') as f:
f.write(response.content)
print('\n--- POST ---\n')
response = qrm.get_data_post()
print('status:', response.status_code)
print('url:', response.url)
print(response.text[:100])
with open('QR_POST.png', 'wb') as f:
f.write(response.content)
Result:
--- GET ---
status: 200
url: https://api.qrcode-monkey.com/qr/custom?data=https%3A%2F%2Fblog.furas.pl&config=%7B%22body%22%3A+%22circle%22%7D&size=300&download=False&file=png
�PNG
IHDR\\t�{bKGD��������IDATx��ON[��š�6#�P��hŮ#H� ��[��M��T=3#J
--- POST ---
status: 200
url: https://api.qrcode-monkey.com/qr/custom
�PNG
IHDR\\t�{bKGD��������IDATx��ON[��š�6#�P��hŮ#H� ��[��M��T=3#J

Zoom api problem - invalid acces token - JWT

import requests
import json
import jwt
import datetime
APİ_KEY = "100 percent correct api key"
APİ_SECRET = "100 percent correct api secret"
payload = {
'iss':APİ_KEY,
'exp':datetime.datetime.now() + datetime.timedelta(hours=2)
}
token = jwt.encode(payload, APİ_SECRET)
print(token)
endpoint = "https://api.zoom.us/v2/users/my_e-mail_is_written_here/meetings"
myData = {
"headers": {
"authorization":"Bearer "+token,
"content-type":"application/json"
},
"body": {
"topic":"denemex",
"type":2,
"start_time":"2021-05-05T13:20",
"duration":"40",
"password":"1234"
}
}
zoom_r = requests.post(endpoint, data=json.dumps(myData))
print(zoom_r.status_code)
print(zoom_r.text)
I wanted to do a simple experiment with python like this, but I get an "invalid acces token" error, what could be the reason?
I thought a little more about my problem and solved the problem by changing the code as follows:
import requests
import json
import jwt
import datetime
APİ_KEY = "my api key"
APİ_SECRET = "my api secret"
payload = {
'iss':APİ_KEY,
'exp':datetime.datetime.now() + datetime.timedelta(hours=2)
}
token = jwt.encode(payload, APİ_SECRET)
endpoint = "https://api.zoom.us/v2/users/my_e-mail_is_written_here/meetings"
myData = {
"topic":"denemex",
"type":2,
"start_time":"2021-05-05T13:20",
"duration":"40",
"password":"1234"
}
headers = {"Content-Type":"application/json", "Authorization":"Bearer "+ token}
zoom_r = requests.post(endpoint, headers=headers, data=json.dumps(myData))
print(zoom_r.status_code)
print(zoom_r.text)

Why can I only make GET requests and not POST requests with this python code?

I'm trying to get this Etrade stuff up an running.... so far i have:
from rauth import OAuth1Service
import webbrowser
def getSession():
# Create a session
# Use actual consumer secret and key in place of 'foo' and 'bar'
service = OAuth1Service(
name = 'etrade',
consumer_key = 'cabf024eaXXXXXXXXX7a0243d8d',
consumer_secret = '3d05c41XXXXXXXXX1949d07c',
request_token_url =
'https://etws.etrade.com/oauth/request_token',
access_token_url =
'https://etws.etrade.com/oauth/access_token',
authorize_url = 'https://us.etrade.com/e/t/etws/authorize?
key={}&token={}',
base_url = 'https://etws.etrade.com')
# Get request token and secret
oauth_token, oauth_token_secret = service.get_request_token(params =
{'oauth_callback': 'oob',
'format': 'json'})
auth_url = service.authorize_url.format('cabf0XXXXXXXXXa0243d8d',
oauth_token)
webbrowser.open(auth_url)
verifier = raw_input('Please input the verifier: ')
return service.get_auth_session(oauth_token, oauth_token_secret,
params = {'oauth_verifier': verifier})
session = getSession()
This authentication process works perfectly fine and allows me to do get/delete requests but when I attempt to make post requests:
url =
'https://etwssandbox.etrade.com/order/sandbox/rest/previewoptionorder'
para = {
"PreviewOptionOrder": {
"-xmlns": "http://order.etws.etrade.com",
"OptionOrderRequest": {
"accountId": "83550325",
"quantity": "4",
"symbolInfo": {
"symbol": "AAPL",
"callOrPut": "CALL",
"strikePrice": "585",
"expirationYear": "2012",
"expirationMonth": "07",
"expirationDay": "21"
},
"orderAction": "BUY_OPEN",
"priceType": "MARKET",
"orderTerm": "GOOD_FOR_DAY"
}
}
}
resp = session.post(url,data=para)
resp.text
I get an error:
Unauthorized request: consumer key is missing.
I've tried numerous things (granted I am new to this stuff). I tried authenticating using just requests to no avail and I tried passing the oauth1 object to the posts function as a kw argument. Any ideas?

Categories

Resources