Openstack authenticate with python SDK v2 - python

I am a OpenStack noob here.
I try to use REST API to automate my openstack work. I can successfully authenticate my account and get token from curl with below command:
export AUTH_URL="https://my_url:5000/v2.0/tokens"
curl -v -X POST $AUTH_URL -d '{"auth":{"passwordCredentials":{"username": "myusername", "password":"myuser_password"}, "tenantId":"my_tenant_id"}}' -H 'Content-type: application/json' | python -m json.tool
But, when I try to use Pyton, with this code, it gave me this error:
Traceback (most recent call last):
File "./test.py", line 10, in <module>
keystone = ksclient.Client(auth_url=auth_url, username=user_name, password=user_pwd, tenant_name=tenant_name)
File "/usr/lib/python2.7/site-packages/keystoneclient/v2_0/client.py", line 176, in __init__
self.authenticate()
File "/usr/lib/python2.7/site-packages/positional/__init__.py", line 101, in inner
return wrapped(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/keystoneclient/httpclient.py", line 581, in authenticate
resp = self.get_raw_token_from_identity_service(**kwargs)
File "/usr/lib/python2.7/site-packages/keystoneclient/v2_0/client.py", line 220, in get_raw_token_from_identity_service
_("Authorization Failed: %s") % e)
keystoneauth1.exceptions.auth.AuthorizationFailure: Authorization Failed: The resource could not be found. (HTTP 404) (Request-ID:
My python code is below:
#!/usr/bin/env python
import keystoneclient.v2_0.client as ksclient
auth_url = "https://my_url:5000/v2.0/tokens"
user_name = "myusername"
user_pwd = "myuser_password"
tenant_name = "my_tenant_id"
keystone = ksclient.Client(auth_url=auth_url, username=user_name, password=user_pwd, tenant_name=tenant_name)
print keystone.auth_token
Can you please take a look at my code and see why the python code does not work?
Thanks!

You should only provide https://my_url:5000/v2.0 as the path when authenticating using the client.
See this documentation for more information.
You could also try something like this.
from keystoneauth1 import loading
from keystoneauth1 import session
from keystoneclient import client as keystoneclient
auth_url = 'https://my_url:5000'
user = '<user>'
password = '<password>'
tenant = '<tenant>'
loader = loading.get_plugin_loader('password')
keystone_auth = \
loader.load_from_options(
auth_url=auth_url,
username=user,
password=password,
user_domain_name=tenant
)
keystone_session = session.Session(
auth=keystone_auth,
verify=False
)
print(keystone_session.get_token())
Keep in mind that the Keystone V2 API has been deprecated, and removed in the latest versions of Openstack. If possible I would recommend moving over to the V3 API as soon as possible.

Related

IBM-Watson Text to Speech throws "403:Forbidden" Error

I am trying to use IBM watson api for text to speech service. The service works if I use curl command but when I try to use the srrvice using Python SDK, It throws me below error.
Traceback (most recent call last):
File "/anaconda3/lib/python3.6/site-packages/ibm_cloud_sdk_core/base_service.py", line 234, in send
response.status_code, error_message, http_response=response)
ibm_cloud_sdk_core.api_exception.ApiException: Error: Forbidden, Code: 403
Method failed with status code 403: Forbidden
Below is the curl command
curl -X GET -u "apikey:myapiKey" --output hello_world.wav "https://api.eu-de.text-to-speech.watson.cloud.ibm.com/text-to-speech/api/v1/synthesize?accept=audio/wav&text=Hallo%20Welt&voice=de-DE_DieterVoice"
Below is the python code
from ibm_watson import TextToSpeechV1
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
from ibm_watson import ApiException
import json
IBM_API_ENDPOINT = "https://api.eu-de.text-to-speech.watson.cloud.ibm.com/text-to-speech/api/v1/synthesize"
IBM_TTS_API_KEY = "myAPIKey"
authenticator = IAMAuthenticator(IBM_TTS_API_KEY)
text_to_speech = TextToSpeechV1(authenticator=authenticator)
text_to_speech.set_service_url(IBM_API_ENDPOINT)
try:
with open('IBM.wav', 'wb') as audio_file:
audio_file.write(text_to_speech.synthesize("Hallo world", voice='de-DE_DieterVoice', accept='audio/wav').get_result().content)
except ApiException as ex:
print("Method failed with status code " + str(ex.code) + ": " + ex.message)
Check the Current usage ( of 10000 Thousand char). I had the same issue when I reached the maximum limit of characters per month.
( Thousand char: Using 21091 of 10000)
This will because you are are tacking the method and the version at the end of the endpoint. As you are using the Python SDK for IBM-Watson the SDK take care of applying the method when you invoke synthesize. Consequently your endpoint should only be:
IBM_API_ENDPOINT = "https://api.eu-de.text-to-speech.watson.cloud.ibm.com"
Check the API documentation for further details - https://cloud.ibm.com/apidocs/text-to-speech/text-to-speech?code=python#service-endpoint

Access JIRA from python

I am trying to access jira from python at my work place and the basic operation I intend to do is to fetch/create/update jira issues. I looked at the template code online and am trying to use that, but no luck. I have already installed jira api using pip.
pip install jira
#!/usr/bin/python
from jira import JIRA
options = {'server' : 'https://jira.mycompany.com/rest/api/2'}
jira = JIRA(options)
projects = jira.projects()
print (projects)
And this is its output:
Traceback (most recent call last):
File "JiraTest.py", line 7, in <module>
jira = JIRA(options)
File "C:\Anaconda3\lib\site-packages\jira\client.py", line 317, in __init__
si = self.server_info()
File "C:\Anaconda3\lib\site-packages\jira\client.py", line 1771, in server_info
j = self._get_json('serverInfo')
File "C:\Anaconda3\lib\site-packages\jira\client.py", line 2172, in _get_json
r = self._session.get(url, params=params)
File "C:\Anaconda3\lib\site-packages\jira\resilientsession.py", line 150, in get
return self.__verb('GET', url, **kwargs)
File "C:\Anaconda3\lib\site-packages\jira\resilientsession.py", line 146, in __verb
raise_on_error(response, verb=verb, **kwargs)
File "C:\Anaconda3\lib\site-packages\jira\resilientsession.py", line 56, in raise_on_error
r.status_code, error, r.url, request=request, response=r, **kwargs)
jira.exceptions.JIRAError: JiraError HTTP 404 url:https://jira.mycompany.com/rest/api/2/rest/api/2/serverInfo
response headers = {'Date': 'Sat, 29 Jul 2017 22:42:31 GMT', 'Content-Length': '0', 'Server': 'Apache-Coyote/1.1'}
response text =
`
I know I am doing something wrong here and hence this are the things I want to ask:
How to determine jira server at your work place.
Do the jira administrator need to enable rest api calls or something else from admin login? Is there a way to determine if it is disabled from our code?
Is there anything else I have to install apart from just installing jira through pip.
How to deal with login credentials. I am sure there is a better way than specifying username/password in your .py file. Can someone point me on where to find that info.
Thanks.
I'm not sure what version of the jira-python client you're using but to instantiate a JIRA object, you don't pass the server inside the "options" parameter (and you definitely don't put the path to the REST api). According to the docs:
class jira.JIRA(server=None, options=None, basic_auth=None, oauth=None, jwt=None, kerberos=False, validate=False, get_server_info=True, async=False, logging=True, max_retries=3, proxies=None, timeout=None)
So your instantiation should look like:
from jira.client import JIRA
jira = JIRA('https://jira.mycompany.com')
If you need to auth, then it would be:
jira = JIRA('https://jira.mycompany.com', basic_auth=(username, password))
The server URL should not contain the REST endpoint, this is added automatically by python-jira.
If you check the error you're getting, you'll see that the rest path is listed twice, this is why you're getting the 404.
So, changing your code to:
#!/usr/bin/python
from jira import JIRA
options = {'server' : 'https://jira.mycompany.com'}
jira = JIRA(options)
projects = jira.projects()
print (projects)
should do the trick.
Please let me know if there are other problems.
To confirm you have the right JIRA server, browse to the root URL https://jira.mycompany.com and ensure you can see the login screen and log in (this confirms your username and password work too).
Access to the JIRA REST API must be enabled before you can use it. To test it, try communicating with it using curl, e.g.:
curl -u "username:password" -X GET -H "Content-Type: application/json" https://jira.mycompany.com/rest/api/2/issue/KEY-666
As long as Python can communicate with servers using GET and POST, you shouldn't need anything else.
For username and password I just have the script ask at the command line with an instruction that doesn't show the password. I use node.js but I am sure Python has something similar. Or keep them in a separate file the script reads in, but make sure you never check the file in!

How to send request to endpoint with Boto

I am trying to list items in a S3 container with the following code.
import boto.s3
from boto.s3.connection import OrdinaryCallingFormat
conn = boto.connect_s3(calling_format=OrdinaryCallingFormat())
mybucket = conn.get_bucket('Container001')
for key in mybucket.list():
print key.name.encode('utf-8')
Then I get the following error.
Traceback (most recent call last):
File "test.py", line 5, in <module>
mybucket = conn.get_bucket('Container001')
File "/usr/lib/python2.7/dist-packages/boto/s3/connection.py", line 370, in get_bucket
bucket.get_all_keys(headers, maxkeys=0)
File "/usr/lib/python2.7/dist-packages/boto/s3/bucket.py", line 358, in get_all_keys
'', headers, **params)
File "/usr/lib/python2.7/dist-packages/boto/s3/bucket.py", line 325, in _get_all
response.status, response.reason, body)
boto.exception.S3ResponseError: S3ResponseError: 301 Moved Permanently
<?xml version="1.0" encoding="UTF-8"?>
PermanentRedirectThe bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.99EBDB9DE3B6E3AF
Container001
<HostId>5El9MLfgHZmZ1UNw8tjUDAl+XltYelHu6d/JUNQsG3OaM70LFlpRchEJi9oepeMy</HostId><Endpoint>Container001.s3.amazonaws.com</Endpoint></Error>
I tried to search for how to send requests to the specified end point, but couldn't find useful information.
How do I avoid this error?
As #garnaat mentioned and #Rico answered in another question connect_to_region works with OrdinaryCallingFormat:
conn = boto.s3.connect_to_region(
region_name = '<your region>',
aws_access_key_id = '<access key>',
aws_secret_access_key = '<secret key>',
calling_format = boto.s3.connection.OrdinaryCallingFormat()
)
bucket = conn.get_bucket('<bucket name>')
in terminal run
nano ~/.boto
if there is some configs try to comment or rename file and connect again. (it helps me)
http://boto.cloudhackers.com/en/latest/boto_config_tut.html
there is boto config file directories. take a look one by one and clean them all, it will work by default configs. also configs may be in .bash_profile, .bash_source...
I guess you must allow only KEY-SECRET
also try to use
calling_format = boto.s3.connection.OrdinaryCallingFormat()

Trouble with getting xauth access token from Twitter

I have a problem with using creepymap.py
I try to get it to authorize Twitter account.. but I get error message:
/usr/share/creepy $ python creepymap.py
Traceback (most recent call last):
File "creepymap.py", line 515, in button_authorize_twitter
url = self.oauth.get_authorization_url(True)
File "/usr/lib/python2.7/dist-packages/tweepy/auth.py", line 103, in get_authorization_url
raise TweepError(e)
tweepy.error.TweepError: HTTP Error 401: Unauthorized
Ive looked in auth.py and I try to follow the code with the comments for example:
def get_authorization_url(self, signin_with_twitter=False):
"""Get the authorization URL to redirect the user"""
try:
# get the request token
self.request_token = self._get_request_token()
# build auth request and return as url
if signin_with_twitter:
url = self._get_oauth_url('authenticate')
else:
url = self._get_oauth_url('authorize')
request = oauth.OAuthRequest.from_token_and_callback(
token=self.request_token, http_url=url
)
later on I read this:
def get_xauth_access_token(self, username, password):
"""
Get an access token from an username and password combination.
In order to get this working you need to create an app at
http://twitter.com/apps, after that send a mail to api#twitter.com
and request activation of xAuth for it.
"""
try:
url = self._get_oauth_url('access_token', secure=True) # must use HTTPS
request = oauth.OAuthRequest.from_consumer_and_token(
oauth_consumer=self._consumer,
http_method='POST', http_url=url,
parameters = {
'x_auth_mode': 'client_auth',
'x_auth_username': username,
'x_auth_password': password
}
)
is there anything I should change in the code?
P.S Sorry for my english. It is not my native language.
Thank you!
EDIT:
I just wanted to close thread with answering my own question after some more research..
And follow instructions here on how get xAuth: https://dev.twitter.com/docs/oauth/xauth

Insert post Blogger API failing with Python

This code now works.
I'm having an issue inserting a new blog post on to google's Blogger site via python2.7 calling an API.
I have all the oauth2client modules from google to handle the authentication.
I have permission to use the Blogger V3 api - this is activated on the google developer console.
I have run simple api requests with the same credentials.dat that have worked:
this worked (full code not included)
service = build('blogger','v3', http=http)
try:
request = service.blogs().get(blogId="6814573853229626501")
response = request.execute()
print response
The google api discovery service leads me to believe this is what the code should look like to insert a post
https://developers.google.com/apis-explorer/#p/blogger/v3/blogger.posts.insert
service = build('blogger','v3', http=http)
try:
body = {
"kind": "blogger#post",
"id": "6814573853229626501",
"title": "posted via python",
"content":"<div>hello world test</div>"
}
request = service.posts().insert(blogId="6814573853229626501",body=body)
response = request.execute()
print response
I'm sure it's the body=body part that I'm messing up? Any clues?
here is the error that I get:
Traceback (most recent call last):
File "blogger.py", line 104, in <module>
main()
File "blogger.py", line 93, in main
response = request.execute()
File "/usr/local/lib/python2.7/dist-packages/google_api_python_client-1.0c2-py2.7.egg/apiclient/http.py", line 654, in execute
raise HttpError(resp, content, self.uri)
apiclient.errors.HttpError: <HttpError 400 when requesting https://www.googleapis.com/blogger/v3/blogs/6814573853229626501/posts?alt=json returned "Invalid Value">
If you're interested I'm experimenting with posting charts from my google fusion tables generated by eBay data that i'm interested in at the time.
You can post on any blogger somehow
__author__ = 'spandey2405#gmail.com (Saurabh Pandey)'
import sys
from oauth2client import client
from googleapiclient import sample_tools
# Authenticate and construct service.
service, flags = sample_tools.init(
argv, 'blogger', 'v3', __doc__, __file__,
scope='https://www.googleapis.com/auth/blogger')
try:
users = service.users()
# Retrieve this user's profile information
thisuser = users.get(userId='self').execute()
print('This user\'s display name is: %s' % thisuser['displayName'])
blogs = service.blogs()
# Retrieve the list of Blogs this user has write privileges on
thisusersblogs = blogs.listByUser(userId='self').execute()
for blog in thisusersblogs['items']:
print('The blog named \'%s\' is at: %s' % (blog['name'], blog['url']))
posts = service.posts()
body = {
"kind": "blogger#post",
"id": "6701167141462934671",
"title": "posted via python",
"content":"<div>hello world test</div>"
}
insert = posts.insert(blogId='6701167141462934671', body=body)
posts_doc = insert.execute()
print posts_doc
except client.AccessTokenRefreshError:
print ('The credentials have been revoked or expired, please re-run'
'the application to re-authorize')
You do not need the "data": object wrapper around your data, the client library will add that if the server needs it. This documentation shows the form of the object to use in the insert call:
https://google-api-client-libraries.appspot.com/documentation/blogger/v3/python/latest/blogger_v3.posts.html#insert

Categories