In order to automate call of an endpoint "/v1/TimeEntries" first I need to provide token. To log in I am calling "/v1/authenticate" is POST endpoint and there is nothing in response. (I have expected to find token here) After that there is another POST endpoint "/connect/token" with response {"id_token":"eyJhbGciOiJSUzI... which is exactly what I need.
How to fetch id_token from "/connect/token" endpoint and pass it to headers of "TimeEntries" endpoint?
example of endpoint "/connect/token":tokenPNG
trying this code to run...
import requests
import json
def login(email, password):
s = requests.Session()
headers = {'Content-type': 'application/json'}
payload = {"username": email,
"password": password,
"returnUrl": "https://identity.prod....",
"rememberLogin": "true"}
a = requests.post('https://identity.prod.jibble.io/v1/authenticate',
json=payload, headers=headers)
print(a.content, a.status_code)
return s
session = login('userExample', 'passExample')
t = requests.post("https://identity.prod.jibble.io/connect/token",
headers={'Content-type': 'application/json'})
tokenId = t.content["id_token"]
headersAuth = {"Authorization": "Bearer " + tokenId}
r = session.post("https://time-tracking.prod.jibble.io/v1/TimeEntries",
headers=headersAuth, json={"type": "In", "personId": "ce3...."})
and getting error message
Traceback (most recent call last): File "C:\Users....Start.py", line 25, in
tokenId = t.content["id_token"] TypeError: byte indices must be integers or sli
ces, not str
Related
I tried to create a simple trading execution code for one-time spot market buy order in Python (using Pycharm).
The code is provided below. API key, API passphrase and API secret key are correct, as well as a signature encoded in base64. The problem seems to be with the order URL. I use this one (provided by Kucoin API documentation): api/v1/orders
The error I'm getting is:
Traceback (most recent call last):
File "C:\Users\xxxx\PycharmProjects\pythonProject11\main 2.py", line 57, in <module>
response = client.request('POST', url, body=body_str, headers=headers)
File "C:\Users\xxxx\PycharmProjects\pythonProject11\venv\lib\site-packages\ccxt\base\exchange.py", line 2801, in request
return self.fetch2(path, api, method, params, headers, body, config, context)
File "C:\Users\xxxx\PycharmProjects\pythonProject11\venv\lib\site-packages\ccxt\base\exchange.py", line 2797, in fetch2
request = self.sign(path, api, method, params, headers, body)
File "C:\Users\xxxx\PycharmProjects\pythonProject11\venv\lib\site-packages\ccxt\kucoin.py", line 3259, in sign
url = self.urls['api'][api]
KeyError: '/api/v1/orders'
Process finished with exit code 1
Code:
import ccxt
import base64
import hashlib
import hmac
import json
from datetime import datetime
# Replace these with your own API key, secret key, and passphrase
api_key = ''
api_secret = ''
api_passphrase = ''
# Set up the Kucoin client
client = ccxt.kucoin()
client.apiKey = api_key
client.secret = api_secret
client.version = 'v1'
# Set the request parameters -- I know there should be a specific token in place of XXXX
symbol = 'XXXX/USDT'
side = 'buy'
type = 'market'
amount = 1.0
# Generate the timestamp in ISO 8601 format
timestamp = datetime.utcnow().isoformat() + 'Z'
# Construct the request body
body = {
'clientOid': 'YOUR_UNIQUE_ID',
'size': amount,
'side': side,
'symbol': symbol,
'type': type
}
# Encode the request body as a JSON string
body_str = json.dumps(body)
# Set the request URL
url = '/api/v1/orders'
# Construct the signature
message = timestamp + 'POST' + url + body_str
signature = base64.b64encode(hmac.new(bytes(api_secret, 'latin-1'), bytes(message, 'latin-1'), digestmod=hashlib.sha256).digest())
# Set the request headers
headers = {
'KC-API-KEY': api_key,
'KC-API-SIGN': signature,
'KC-API-TIMESTAMP': timestamp,
'KC-API-PASSPHRASE': api_passphrase,
'Content-Type': 'application/json'
}
# Send the POST request to the "POST /api/v1/orders" URL
response = client.request('POST', url, body=body_str, headers=headers)
# Print the response
print(response)
I tried various URLs but it doesn't seem to work. What is causing the problem?
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)
I am writing a python script to send a mail using the Microsoft Graph API. The mail is sent to only those IDs which exists in our AAD.
I wrote the code:
from adal import AuthenticationContext
import adal
import string
import urllib
import json
import requests
import pprint
import base64
import mimetypes
API_VERSION = 'beta'
RESOURCE = 'https://graph.microsoft.com'
TENANT = <my tenant ID>
CLIENTID = <Client ID>
CLIENTSECRET = <sescret>
DOMAIN = <mydomain>
# AUTHENTICATION - get access token and update session header
def get_session():
authority_host_url = 'https://login.windows.net'
tenant = TENANT
authority_url = authority_host_url + '/' + tenant
service_endpoint = "https://graph.microsoft.com/"
client_id = CLIENTID
client_secret = CLIENTSECRET
# Retrieves authentication tokens from Azure Active Directory and creates a new AuthenticationContext object.
context = AuthenticationContext(authority_url, validate_authority=True, cache=None, api_version=None, timeout=300, enable_pii=False)
# Gets a token for a given resource via client credentials.
token_response = context.acquire_token_with_client_credentials(service_endpoint, client_id, client_secret)
# Create a persistent session with the access token
session = requests.Session()
session.headers.update({'Authorization': f'Bearer {token_response["accessToken"]}', 'SdkVersion': 'python-adal', 'x-client-SKU': 'DynaAdmin'})
#session.headers.update({'Authorization': f'Bearer {token_response["accessToken"]}'})
return session
def build_uri(url):
if 'https' == urllib.parse.urlparse(url).scheme:
return url
result = urllib.parse.urljoin(f'{RESOURCE}/{API_VERSION}/', url.lstrip('/'))
print("\nURL:\n")
print(result)
return result
def sendmail(*, session, subject=None, recipients=None, body='',
content_type='HTML', attachments=None):
"""Helper to send email from current user.
session = user-authenticated session for graph API
subject = email subject (required)
recipients = list of recipient email addresses (required)
body = body of the message
content_type = content type (default is 'HTML')
attachments = list of file attachments (local filenames)
Returns the response from the POST to the sendmail API.
"""
# Verify that required arguments have been passed.
if not all([session, subject, recipients]):
raise ValueError('sendmail(): required arguments missing')
# Create recipient list in required format.
recipient_list = [{'EmailAddress': {'Address': address}}
for address in recipients]
# Create list of attachments in required format.
attached_files = []
if attachments:
for filename in attachments:
b64_content = base64.b64encode(open(filename, 'rb').read())
mime_type = mimetypes.guess_type(filename)[0]
mime_type = mime_type if mime_type else ''
attached_files.append( \
{'#odata.type': '#microsoft.graph.fileAttachment',
'ContentBytes': b64_content.decode('utf-8'),
'ContentType': mime_type,
'Name': filename})
# Create email message in required format.
email_msg = {'Message': {'Subject': subject,
'Body': {'ContentType': content_type, 'Content': body},
'ToRecipients': recipient_list,
'Attachments': attached_files},
'SaveToSentItems': 'true'}
print("\nBody:\n")
print(email_msg)
# Do a POST to Graph's sendMail API and return the response.
resp = session.post(build_uri('/users/8368b7b5-b337ac267220/sendMail'), data=email_msg, stream=True, headers={'Content-Type': 'application/json'})
return resp
# ------------ RUN CODE ------------
session = get_session()
myRecipients = "sea.chen#mydomain.com;anj.dy#mydomain.com"
response = sendmail(session=session,
subject= "hai",
recipients=myRecipients.split(';'),
body="hai this is a new mail")
print("\nRequest headers: \n")
print(response.request.headers)
print("\nResponse: \n")
print(response)
print(response.text)
The output I got is :
Body:
{'Message': {'Subject': 'hai', 'Body': {'ContentType': 'HTML', 'Content': 'hai this is a new mail'}, 'ToRecipients': [{'EmailAddress': {'Address': 'sea.chen#mydomain.com'}}, {'EmailAddress': {'Address': 'anj.dy#mydomain.com'}}], 'Attachments': []}, 'SaveToSentItems': 'true'}
URL:
https://graph.microsoft.com/beta/users/8368b7b5-b337ac267220/sendMail
Request headers:
{'User-Agent': 'python-requests/2.22.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6IkFRQUJBQUFBQUFEQ29NcGpKWHJ4VHE5Vkc5dGUtN0ZYVzRQOWpybFRZWXdIVmZieWJxd0dUVUtNRThqUG5Va0hFSlowU2JyUFRaaDlaSjdURklVMjRwV1RpOTQxZU5kaXpIeHdXdDk0ODNlYmY1OWE5IiwiYXBwaWRhY3IiOiIxIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvOWFmYjFmOGEtMjE5Mi00NWJhLWIwYTEtNmIxOTNjNzU4ZTI0LyIsIm9pZCI6ImI3NDY4ZDQxLTkxMWMtNGU4ZS1iMzA4LWY5NmM1ZGQ4MDVmMyIsInJvbGVzIjpbIlVzZXIuUmVhZFdyaXRlLkFsbCIsIkdyb3VwLlJlYWQuQWxsIiwiRGlyZWN0b3J5LlJlYWRXcml0ZS5BbGwiLCJHcm91cC5SZWFkV3JpdGUuQWxsIiwiRGlyZWN0b3J5LlJlYWQuQWxsIiwiVXNlci5SZWFkLkFsbCIsIk1haWwuU2VuZCJdLCJzdWIiOiJiNzQ2OGQ0MS05MTFjLTRlOGUtYjMwOC1mOTZjNWRkODA1ZjMiLCJ0aWQiOiI5YWZiMWY4YS0yMTkyLTQ1YmEtYjBhMS02YjE5M2M3NThlMjQiLCJ1dGkiOiJWX1d6UHJjUDhrQ000MGNPM0xZZkFBIiwidmVyIjoiMS4wIiwieG1zX3RjZHQiOjE0NTY0Nzc5MzB9.Nq0qdmfd4qAQWdnaFLVNKYWQ__t52jRYC09IsDlrSOoAhZU6d2M6ePAAaKFSR-Ss_NJ4o21FAbxRM8mRUumW3n1TFvARN0FDzjtZMG9mgIrPmYndfRQtcD3s7f5Q5JOQdtd5QDRVhPqVRNAwmC-o_TW5mm0p40oIR2Mc2MN_MB3dp-_0xH7fN3xsPzWi9yRR1-iHnvEjLmhKecY5pxCBO3RW5QVcAR6DH6kw0koV49cmjpIu-_gau4SFlF4kFdwEVXdv1jTeJj91lA02Ar9tR-2hQiPOaqsloSmKpaH0Tb4LwGQJBk2O8fiwy5Sv2NoKbi6QE2EPFck7jZPVBDh35g', 'SdkVersion': 'python-adal', 'x-client-SKU': 'DynaAdmin', 'Content-Type': 'application/json', 'Content-Length': '90'}
Response:
<Response [400]>
{
"error": {
"code": "BadRequest",
"message": "Unable to read JSON request payload. Please ensure Content-Type header is set and payload is of valid JSON format.",
"innerError": {
"request-id": "26ef0c0b-c362-401c-b8ed-48755a45d086",
"date": "2019-06-24T07:10:53"
}
}
}
The error I got is :
Unable to read JSON request payload. Please ensure Content-Type header
is set and payload is of valid JSON format.
So I tried the request in Graph Explorer and used the same URL and body I got printed in the above output. The request sent from Graph Explorer was successful and the mail was sent to the correct recipients. That means the content-body is valid.
It is obvious from the above output that the bearer token, and 'Content-Type': 'application/json' were passed as the header.
Then why I am getting the error while running the script?
Can anyone please help me?
Most likely the body of your POST is not properly formatted. When I did this with the requests library, I found I needed to set data like so:
data = json.dumps(email_msg)
The default for data is to form-encode, not pass as JSON. Have a look at https://learn.microsoft.com/outlook/rest/python-tutorial#contents-of-tutorialoutlookservicepy
Thanks for sharing this.
I had different issue when I was trying to get Graph API to send one-on-one chat message to Microsoft Teams. I could run the following code using http.client and get most of the messages posted in chat.
import http.client
headers = {'Content-type':'application/json',
"Authorization": f"Bearer {getGraphAccessToken()}"
}
body = {
"body": {
"contentType": "text",
"charset" : "utf-8",
"content": text
}}
connection = http.client.HTTPSConnection("graph.microsoft.com")
connection.request("POST",f"/v1.0/chats/{chatId}/messages",headers=headers, body = str(body))
However when I had certain emojis inside the text I got the following error:
"Unable to read JSON request payload. Please ensure Content-Type header is set and payload is of valid JSON format."
By switching the library to requests I was able to send the message with special emojis to work.
import requests
import json
headers = {'Content-type':'application/json',
"Authorization": f"Bearer {getGraphAccessToken()}"
}
body = {
"body": {
"contentType": "text",
"content": text
}}
requests.post(f"https://graph.microsoft.com/v1.0/chats/{chatId}/messages",headers=headers,data =json.dumps(body) )
I'm using Python 2.7.10 64-bit.
In the update_jira_field method, I'm getting the following error:
TypeError: post() takes at least 1 argument (1 given)
I tried also requests.put(), combination of json = payload while declaring the payload as a json, but still got the same error.
I'm not sure what am I doing wrong, never experienced this error while using the requests module.
import requests
import json
import urllib2
auth = *****
propertKey = 'customfield_13557'
headers = {'Accept':'application/json','Bearer':****'}
def get_jira_real_id(jiraKey):
endpoint = 'https://****.atlassian.net/rest/api/3/issue/{0}'.format(jiraKey)
response = requests.get(endpoint, headers = headers, auth = auth)
if response.status_code == 200:
print "Success getting Jira Id"
response = json.loads(response.text)
return response['id']
def update_jira_field(jiraId,jiraKey):
endpoint = 'https://****.atlassian.net/rest/api/3/issue/{0}'.format(jiraId)
payload = dict({"fields": {"customfield_13557":{"self": "https://****.atlassian.net/rest/api/3/customFieldOption/14915", "value": "Yes", "id": "14915"}}})
response = requests.post(endpoint = endpoint, headers = headers, auth = auth, data = payload)
if response.status_code == 200:
print "Success! Updated", jiraId, jiraKey
jiraList = ['****']
for jiraKey in jiraList:
jiraId = get_jira_real_id(jiraKey)
update_jira_field(jiraId, jiraKey)
print "Done Done Done"
Any idea why I get this error? and how do I fix it?
You try to pass in a named parameter named endpoint, but the correct name is url. It whould work if you change the line to
response = requests.post(endpoint, headers = headers, auth = auth, data = payload)
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