Calling arbitrary k8s apis using the Python client - python

I'd like to call the openshift machine api (/apis/machine.openshift.io/v1beta1/machines). Is there a way to do this using the kubernetes Python module? I can create an api object like this:
>>> from kubernetes import client, config
>>> config.load_incluster_config()
>>> api = client.CoreV1API()
Of course, that's a core API client, which doesn't include native support for the machine api. But the object has all the endpoint and authentication information. There is a likely looking api.api_client.call_api method, but it doesn't seem to make use of the auth information embedded in the api_client object:
>>> api.api_client.call_api('/apis/machine.openshift.io/v1beta1/machines', 'GET')
[...]
kubernetes.client.rest.ApiException: (403)
Reason: Forbidden
I can explicitly pass in auth information, but then it doesn't seem to return any content:
>>> >>> api.api_client.call_api('/apis/machine.openshift.io/v1beta1/machines', 'GET', auth_settings=api.api_client.configuration.auth_settings())
(None, 200, HTTPHeaderDict({'Audit-Id': '6f6965b5-1ad7-4c5e-ab61-343e38718ff8', 'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'X-Kubernetes-Pf-Flowschema-Uid': '9
5848e47-b51c-46eb-aa4f-e25130d61e09', 'X-Kubernetes-Pf-Prioritylevel-Uid': '39391d77-7b32-4aa2-93c3-9915a302d361', 'Date': 'Fri, 04 Sep 2020 19:43:59 GMT', 'Transfer-Encoding': 'chunked'}))
I can of course just use requests:
>>> requests.get(f'{api.api_client.configuration.host}/apis/machine.openshift.io/v1beta1/machines', verify=False, headers=api.api_client.configuration.api_key)
<Response [200]>
That works fine, but it smells like I'm going about things the wrong way. What's the correct way to make arbitrary API requests using the Python kubernetes module?

Referring from here you could use api_client.call_api as below to call arbitrary APIs by passing a valid BearerToken which could be a service account token.
api_client.call_api('/apis/machine.openshift.io/v1beta1/machines', 'GET', auth_settings = ['BearerToken'], response_type='json', _preload_content=False)

Related

Getting Started with Square and Django

I'm trying to get a simple Square credit card form to work on our Django website. I'm new to using Square, but have used similar API's such as Stripe in the past.
To start, I followed along with their Square Payment Form walkthrough. I added their SqPaymentForm library and our own javascript file where I initialized a new SqPaymentForm.
The front-end appears to be working and is generating a unique card nonce every time I enter fake credentials.
Next, I submitted the form to our back-end (including the card nonce, in a hidden nonce field).
On the back-end, I've installed the Square Connect Python SDK. I copied their "Charge the card nonce" example as closely as possible, substituting our sandbox access token and location ID:
import uuid
import squareconnect
from squareconnect.rest import ApiException
from squareconnect.apis.transactions_api import TransactionsApi
# create an instance of the Transactions API class
api_instance = TransactionsApi()
# setup authorization
api_instance.api_client.configuration.access_token = 'sandbox-access-token'
location_id = 'sandbox-location-id'
nonce = request.POST.get('nonce', 'empty')
if (nonce == 'empty'): print("Throw error")
# print(nonce)
try:
# Charge
idempotency_key = str(uuid.uuid1())
amount = {'amount': 100, 'currency': 'USD'}
body = {'idempotency_key': idempotency_key, 'card_nonce': nonce, 'amount_money': amount}
api_response = api_instance.charge(location_id, body)
print (api_response.transaction)
except ApiException as e:
print ('Exception when calling TransactionApi->charge: %s\n' % e)
I've also tried reformatting this code slightly to fit the example demonstrated in Square's connect-api-examples on GitHub.
But, when I test it in localhost (http), using the different demo credentials provided by Square on their test values page, I consistently get an 'Unauthorized' error from the API:
Exception when calling TransactionApi->charge: (401)
Reason: Unauthorized
HTTP response headers: HTTPHeaderDict(
{'Content-Type': 'application/json', 'Vary': 'Origin, Accept-Encoding', 'X-Content-Type-Options': 'nosniff', 'X-Download-Options': 'noopen', 'X-Frame-Options': 'SAMEORIGIN', 'X-Permitted-Cross-Domain-Policies': 'none', 'X-Xss-Protection': '1; mode=block', 'Date': 'Wed, 31 Jul 2019 20:59:10 GMT', 'keep-alive': 'timeout=60', 'Strict-Transport-Security': 'max-age=631152000', 'content-length': '119'})
HTTP response body: {"errors":[{"category":"AUTHENTICATION_ERROR","code":"UNAUTHORIZED","detail":"This request could not be authorized."}]}
When I look through the Troubleshooting documentation, it says the likely cause for an Unauthorized error is an invalid OAuth token. Yet, none of Square's demos or examples utilize OAuth. I don't understand why OAuth would be necessary for a simple payment form that isn't behind a sign-up page?
I've tried uploading the code to our https website to see if an SSL cert was required, but I get the same error.
You need to set your access token, then your code will work. The location id is also not set, so square sends an error. I had the same problem, and I realized that it was because I forgot to add the access token. Hope that this helps.

Log in to mega.nz using python requests

So I'm learning my way around web crawlers and automatization. I'm trying to automate the login for mega.nz without using their official API (as far as I'm concerned it's even outdated for Python).
And this one is the code (currently not working since no data is really being sent). I don't want to use a browser.
loginURL = 'https://mega.nz/login'
requestURL = 'https://mega.nz/fm/dashboard'
payload = {
'login-name2': 'test#email.com',
'login-password2': 'password',
'login-check2': ''
}
with requests.session() as s:
s.post(loginURL, headers=headers, data=payload)
r = s.get(requestURL)
print(r.text)
Headers I am using:
{'Content-Type': 'text/html', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'MEGA-Chrome-Antileak', 'Access-Control-Max-Age': '86400', 'Content-Encoding': 'gzip', 'Content-Length': '934', 'Strict-Transport-Security': 'max-age=63072000; includeSubDomains; preload', 'X-Frame-Options': 'DENY', 'Set-Cookie': 'geoip=IT', 'Content-Security-Policy': "default-src 'self' data: blob: *.mega.co.nz *.mega.nz http://*.mega.co.nz http://*.mega.nz wss://*.karere.mega.nz *.karere.mega.nz:1380 http://127.0.0.1:6341 localhost.megasyncloopback.mega.nz:6342; script-src 'self' *.mega.co.nz *.mega.nz data: blob:; style-src 'self' 'unsafe-inline' *.mega.co.nz *.mega.nz data: blob:; frame-src 'self' mega: *.megaad.nz; img-src 'self' *.mega.co.nz *.mega.nz data: blob:", 'Connection': 'Keep-Alive'}
How can I automate signing into this?
Try this https://github.com/richardARPANET/mega.py/
It worked for me.
There is an example step by step on README.rst
You may want to read requests documentation about Authentication, it gives a few methods to authenticate through HTTP.
You can find it here.
I did not find any information about an HTTP API for Mega. Are you trying to get access to the site via the web interface that you would use in your browser? It could be very difficult or impossible to get your software working this way.
Usually you would only use plain HTTP requests when the service you try to access provides a working REST API. (see for example the Spotify API)
Maybe take a look at this example for accessing Mega from Python. This uses the official Mega C++ API which you can access from your Python script.

Python: HTTP caching using 'CacheControl` not working

I'm using python 3.6 with requests module for API consumption and CacheControl module for caching the API response. I'm using following code but cache does not seems to be working:
import requests
from cachecontrol import CacheControl
sess = requests.session()
cached_sess = CacheControl(sess)
response = cached_sess.get('https://jsonplaceholder.typicode.com/users')
Every request to this URL returns the 200 status code (instead of 304 status code) and the same resource is requested each time even though the ETag headers is same and max-age was still valid. The API returns following cache related headers:
'Cache-Control': 'public, max-age=14400'
'Expires': 'Sat, 04 Feb 2017 22:23:28 GMT' (time of original request)
'Etag': 'W/"160d-MxiAGkI3ZBrjm0xiEDfwqw"'
What could be the issue here?
UPDATE: I'm not sending If-None-Match header with any API call, do I manually have to do it or CacheControl module should take care of it automatically?
Use a cache implementation to persist the cache between runs of the program.
from cachecontrol.caches import FileCache
sess = requests.session()
cached_sess = CacheControl(sess, cache = FileCache('.web_cache'))
Also, ensure you're using a recent CacheControl release. CacheControl has only cached resources served as Transfer-Encoding: chunked since 0.11.7:
$ curl -si https://jsonplaceholder.typicode.com/users | fgrep -i transfer-encoding
Transfer-Encoding: chunked
Every request to this URL returns the 200 status code
This is what you'll see when CacheControl is working correctly. The return of a cached response, or use of a 304, is hidden from you as a client of the code. If you believe that a fresh request is being made to the upstream server, consider something like:
import logging
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
to see what cachecontrol.controller and requests.packages.urllib3.connectionpool are doing.

POST Request in Python 'requests' module not working properly

POST https://maxcvservices.dnb.com/rest/Authentication
x-dnb-user: MyUsername
x-dnb-pwd: MyPassword
is the documentation of the D&B API and hence I am trying to send a POST request using python requests module using the following line of code:
r = requests.post('https://maxcvservices.dnb.com/rest/Authentication',params={'x-dnb-user':userid,'x-dnb-pwd':pass})
the response I am getting is Response [500]
and the content of the response is : error processing request\r\n
My question is whether I am doing something wrong while passing the post request and the parameters or is it a problem with my username and password being invalid?
I feel the problem lies in the way I am passing the POST request as the API responds with a separate error 401 for incorrect userid, pass.
{'connection': 'Keep-Alive',
'content-encoding': 'gzip',
'content-length': '46',
'content-type': 'text/plain',
'date': 'Sat, 26 Oct 2013 17:43:22 GMT',
'server': '',
'vary': 'Accept-Encoding',
'x-correlationid': 'Id-d4c07ad3526bff3a03fb742e 0'}
my response header when I use:
r = requests.post('https://maxcvservices.dnb.com/rest/Authentication', headers={'x-dnb-user': 'userid', 'x-dnb-pwd': 'password'})
A random user-id and password.
But according to the API I am supposed to receive <Response [401]> .
I receive <Response [500]> instead.
Those are HTTP headers; quoting the API documentation:
Secure access to D&B Direct services is managed through the use of an Authentication Token, which can be obtained by sending an HTTP POST request to Authentication Service URL, passing a valid username and password in the HTTP header.
Add them as such:
r = requests.post(
'https://maxcvservices.dnb.com/rest/Authentication',
headers={'x-dnb-user': userid, 'x-dnb-pwd': password})
This works for me, albeit that I get a 401 response (as I don't have any valid credentials):
>>> import requests
>>> requests.__version__
'2.0.0'
>>> r = requests.post('https://maxcvservices.dnb.com/rest/Authentication',
... headers={'x-dnb-user': 'userid', 'x-dnb-pwd': 'password'})
>>> r
<Response [401]>
>>> r.headers['authorization']
'INVALID CREDENTIALS'
entirely as documented.

Google Data API authentication

I am trying to get my Django app (NOT using Google app engine) retrieve data from Google Contacts using Google Contacts Data API. Going through authentication documentation as well as Data API Python client docs
First step (AuthSubRequest) which is getting the single-use token works fine. The next step(AuthSubSessionToken), which is upgrade single-use token to a session token. The python API call UpgradeToSessionToken() simply didn't work for me it gave me NonAuthSubToken exception:
gd_client = gdata.contacts.service.ContactsService()
gd_client.auth_token = authsub_token
gd_client.UpgradeToSessionToken()
As an alternative I want to get it working by "manually" constructing the HTTP request:
url = 'https://www.google.com/accounts/AuthSubSessionToken'
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'AuthSub token=' + authsub_token,
'User-Agent': 'Python/2.6.1',
'Host': 'https://www.google.com',
'Accept': 'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2',
'Connection': 'keep-alive',
}
req = urllib2.Request(url, None, headers)
response = urllib2.urlopen(req)
this gives me a different error:
HTTP Error 302: The HTTP server returned a redirect error that would lead to an infinite loop. The last 30x error message was: Moved Temporarily
What am I doing wrong here? I'd appreciate help/advice/suggestions with either of the methods I am trying to use: Python API call (UpgradeToSessionToken) or manually constructing HTTP request with urllib2.
According to the 2.0 documentation here there is a python example set...
Running the sample code
A full working sample client, containing all the sample code shown in this document, is available in the Python client library distribution, under the directory samples/contacts/contacts_example.py.
The sample client performs several operations on contacts to demonstrate the use of the Contacts Data API.
Hopefully it will point you in the right direction.
I had a similar issue recently. Mine got fixed by setting "secure" to "true".
next = 'http://www.coolcalendarsite.com/welcome.pyc'
scope = 'http://www.google.com/calendar/feeds/'
secure = True
session = True
calendar_service = gdata.calendar.service.CalendarService()
There are four different ways to authenticate. Is it really that important for you to use AuthSub? If you can't get AuthSub to work, then consider the ClientLogin approach. I had no trouble getting that to work.

Categories

Resources