I've really been struggling with getting OAuth to work with the WiThings API lately, using Python 3.3. For reference, here is the documentation for WiThings: http://www.withings.com/api
Now... As I've said, I have been working with the WiThings API in Python, using the requests library (http://docs.python-requests.org/en/latest/). Supposedly, this has built in support for OAuth 1.0.
Using this, when I put in my consumer key and consumer secret, then perform the token request, I get this response...
b'<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">\n<html><head>\n<title>413 Request Entity Too Large</title>\n</head><body>\n<h1>Request Entity Too Large</h1>\nThe requested resource<br />/index.php<br />\ndoes not allow request data with POST requests, or the amount of data provided in\nthe request exceeds the capacity limit.\n<hr>\n<address>Apache Server at oauth.withings.com Port 80</address>\n</body></html>\n'
Any idea what could be causing this? I have a feeling its WiThings specific... but their support is horrible.
Next, I did some more research, and found this: https://github.com/maximebf/python-withings
While also rather poorly documented, I installed it, and have this code:
from __future__ import unicode_literals
from urllib.parse import parse_qs
import requests
from requests_oauthlib import OAuth1
import withings
CONSUMER_KEY = "omitted"
CONSUMER_SECRET = "omitted"
auth = WithingsAuth(CONSUMER_KEY, CONSUMER_SECRET)
authorize_url = auth.get_authorize_url()
print("Go to %s allow the app and copy your oauth_verifier" %authorize_url)
oauth_verifier = raw_input('Please enter your oauth_verifier: ')
creds = auth.get_credentials(oauth_verifier)
client = WithingsApi(creds)
measures = client.get_measures(limit=1)
print("Your last measured weight: %skg" % measures[0].weight)
And get the following error...
File "withings.py", line 5, in <module>
import withjings
File C:\User_Directory\withings.py", line 11, in <module>
auth = WithingsAuth(CONSUMER_KEY, CONSUMER_SECRET)
NameError: name 'WithingsAuth' is not defined
Any help on either of these issues? Has anyone had success working with Withings in python?
Thanks for the help guys
It should be
from withings import WithingsAuth, WithingsApi
For me it works well I was able to extract my last measured weight.
You either need to import WithingsAuth from withings, or specify that you want to use the withings.WithingsAuth. Changing your code it becomes:
from __future__ import unicode_literals
try:
from urllib.parse import parse_qs
except:
import urlparse as parse_qs
try:
input_method = raw_input
except:
input_method = input
import requests
from requests_oauthlib import OAuth1
import withings
CONSUMER_KEY = "omitted"
CONSUMER_SECRET = "omitted"
auth = withings.WithingsAuth(CONSUMER_KEY, CONSUMER_SECRET)
authorize_url = auth.get_authorize_url()
print("Go to %s allow the app and copy your oauth_verifier" %authorize_url)
oauth_verifier = input_method('Please enter your oauth_verifier: ')
creds = auth.get_credentials(oauth_verifier)
client = withings.WithingsApi(creds)
measures = client.get_measures(limit=1)
print("Your last measured weight: %skg" % measures[0].weight)
Related
from time import sleep
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import requests
plt.style.use("fivethirtyeight")
import alpaca_trade_api as tradeapi
import threading
from bs4 import BeautifulSoup
import datetime
import logging
api_key = 'YOUR API KEY'
api_secret = 'YOUR API SECRET KEY'
base_url = 'https://paper-api.alpaca.markets'
data_url = 'wss://data.alpaca.markets'
ws_url = 'wss://data.alpaca.markets'
# instantiate REST API
api = tradeapi.REST(api_key, api_secret, base_url, api_version='v2')
# init WebSocket
conn = tradeapi.stream2.StreamConn(
api_key,
api_secret,
base_url=base_url,
data_url=data_url,
data_stream='alpacadatav1',
)
I get the error
conn = tradeapi.stream2.StreamConn(
AttributeError: module 'alpaca_trade_api' has no attribute 'stream2'
This code is coming from https://algotrading101.com/learn/alpaca-trading-api-guide/ on the part where he shows how he made a trading algorithm near the end of the page.
Do I need to import any extra libraries or am I wrong somewhere In the code.
That tutorial is slightly out of date. Newer versions of alpaca_trade_api are using the Stream class:
conn = tradeapi.stream.Stream(
key_id=api_key,
secret_key=api_secret,
base_url='https://paper-api.alpaca.markets',
data_feed='iex'
)
Note that the free data feed is 'iex' and the paid data feed is 'sip'. Once you establish a connection, you will need to subscribe to trades or quotes using conn.subscribe_trades() or conn.subscribe_quotes(). See the github page for details.
I'm running into this issue where with my script and I'm a bit stumped. I've been running this script with no problems for the past few weeks and now I'm getting a KeyError for the token.
Here's my code:
# IMPORTS
import os
import re
import requests
import json
import numpy as np
import pandas as pd
import time
from pprint import pprint as pp
import datetime as dt
import sys
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
acc_path = "../../access/"
sys.path.append(acc_path)
pd.set_option('display.max_rows', 10000)
pd.set_option('display.max_columns', 100)
pd.set_option('display.max_colwidth', -1)
# Spotify Credentials
sp_url = 'https://api.spotify.com/v1/'
client_id = os.environ.get('SPOT_CLIENT_ID')
client_secret = os.environ.get('SPOT_CLIENT_SECRET')
output_data = '/users/Desktop/file_date.csv'
spot_scopes = os.environ.get('SPOT_SCOPES')
spot_user_name = os.environ.get('SPOT_USER_NAME') # spotify account username
sp_acc = requests.post('https://accounts.spotify.com/api/token', data = {'grant_type' : 'client_credentials'},
auth = (client_id, client_secret))
sp_bear_head = {'Authorization' : 'Bearer' + str(sp_acc.json()['access_token'])}
KeyERROR
---> 31 sp_bear_head = {'Authorization' : 'Bearer' + str(sp_acc.json()['access_token'])}
KeyError: 'access_token'
I checked my bash to make sure client id, secret scopes etc. are all correct and can confirm that is not the issue. Any direction here would be very helpful!
The reason why it worked before and not now is due to the expiration of the access token.
The token's expiration time is determined by Spotify so you just have to work around their set constraints.
That being said, you can anticipate when a new token will need to be generated/used based on the property expires_in which Spotify sends back in the response when you request a token (https://accounts.spotify.com/api/token). The expires_in property is an integer and it tells you how many seconds the token will be good for. As seen in their authorization documentation, the expires_in property is returned with the value 3600 (seconds) or, 1 hour.
After that hour is up, use your refresh_token to request a new token.
Edit: Updated code. Just keep getting API errors.
How do I post an image from a URL with a status update to twitter using twython and python 3x? I've read the docs, but it only outlines opening local files in directories, and I've looked at a few threads on SO. Here's what I have so far, I'm getting error codes I don't know how to solve.
What do I change to get this image to post? This gives me twython.exceptions.TwythonAuthError: Twitter API returned a 401 (Unauthorized), Could not authenticate you.
the minute it hits twitter.upload
from twython import Twython, TwythonError
import os
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
import urllib
import requests
CONSUMER_KEY = os.environ['CONSUMER_KEY']
CONSUMER_SECRET = os.environ['CONSUMER_SECRET']
ACCESS_TOKEN = os.environ['ACCESS_TOKEN']
ACCESS_TOKEN_SECRET = os.environ['ACCESS_TOKEN_SECRET']
twitter = Twython(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
twitter.verify_credentials()
url = "https://farm2.staticflickr.com/1127/4605090363_4a96e64ff1.jpg"
response = requests.get(url)
photo = requests.get(response.url).content
response = twitter.upload_media(media=photo)
twitter.update_status(status='Checkout this cool image!', media_ids=[response['media_id']])
This solution: twitter.post('/statuses/update_with_media', params = {'status': 'Testing New Status'}, files = {'media': StringIO(photo)})
Gives me a TypeError: initial_value must be str or None, not bytes
I can not get this to work. I have no idea anymore why. Its a primary account. I'm not using "sign in with twitter", its not a web app. Just a worker bot.
I am baffled, I can not figure out what I am doing wrong. It will post text statuses fine, I can search, get user timelines, send DMS, etc. What am I doing wrong?
This turns out to be a type error with respect to what twython expects when uploading media. Pulling an image down remotely and calling content on it gives us a bytes but twython wants an io object.
That there's a 401 in the stack trace is a red herring, but we can give twython what it wants by adding io and reading the request content into a BytesIO.
from twython import Twython, TwythonError
from io import BytesIO
import os
import urllib
import requests
CONSUMER_KEY = os.environ['CONSUMER_KEY']
CONSUMER_SECRET = os.environ['CONSUMER_SECRET']
ACCESS_TOKEN = os.environ['ACCESS_TOKEN']
ACCESS_TOKEN_SECRET = os.environ['ACCESS_TOKEN_SECRET']
twitter = Twython(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
twitter.verify_credentials()
url = "https://farm2.staticflickr.com/1127/4605090363_4a96e64ff1.jpg"
response = requests.get(url)
photo = BytesIO(response.content)
response = twitter.upload_media(media=photo)
twitter.update_status(status='Checkout this cool image!', media_ids=[response['media_id']])
I am using the Spotipy python library to interact with the Spotify web api. I have worked through the API and docs but I do not see a clear example that shows how the library supports the Authorization code flow ( https://developer.spotify.com/web-api/authorization-guide/#authorization-code-flow ).
I implemented a simple Authorization Code flow with the help of Spotipy. Maybe this is helpful for other people as well. Also on github: https://github.com/perelin/spotipy_oauth_demo
Here is the code:
from bottle import route, run, request
import spotipy
from spotipy import oauth2
PORT_NUMBER = 8080
SPOTIPY_CLIENT_ID = 'your_client_id'
SPOTIPY_CLIENT_SECRET = 'your_client_secret'
SPOTIPY_REDIRECT_URI = 'http://localhost:8080'
SCOPE = 'user-library-read'
CACHE = '.spotipyoauthcache'
sp_oauth = oauth2.SpotifyOAuth( SPOTIPY_CLIENT_ID, SPOTIPY_CLIENT_SECRET,SPOTIPY_REDIRECT_URI,scope=SCOPE,cache_path=CACHE )
#route('/')
def index():
access_token = ""
token_info = sp_oauth.get_cached_token()
if token_info:
print "Found cached token!"
access_token = token_info['access_token']
else:
url = request.url
code = sp_oauth.parse_response_code(url)
if code:
print "Found Spotify auth code in Request URL! Trying to get valid access token..."
token_info = sp_oauth.get_access_token(code)
access_token = token_info['access_token']
if access_token:
print "Access token available! Trying to get user information..."
sp = spotipy.Spotify(access_token)
results = sp.current_user()
return results
else:
return htmlForLoginButton()
def htmlForLoginButton():
auth_url = getSPOauthURI()
htmlLoginButton = "<a href='" + auth_url + "'>Login to Spotify</a>"
return htmlLoginButton
def getSPOauthURI():
auth_url = sp_oauth.get_authorize_url()
return auth_url
run(host='', port=8080)
If someone needs the working code here is my current.
Just remember to change the client_id, etc. I put them in config.py.
import spotipy
import spotipy.util as util
from config import CLIENT_ID, CLIENT_SECRET, PLAY_LIST, USER
import random
token = util.oauth2.SpotifyClientCredentials(client_id=CLIENT_ID, client_secret=CLIENT_SECRET)
cache_token = token.get_access_token()
spotify = spotipy.Spotify(cache_token)
results1 = spotify.user_playlist_tracks(USER, PLAY_LIST, limit=100, offset=0)
When I was trying to do this none of these answers really got me there unfortunately. When I ended up figuring it out I detailed how in this post: https://stackoverflow.com/a/42443878/2963703
I was using Django as my backend but all the spotify api oauth stuff is done in javascript so it should still be very useful for you.
The Spotipy library supports the Authorization Code flow, as documented here. For more information, you could also check out Spotipy's oAuth2 module and Util module.
I have the following code:
import urlparse
import oauth2 as oauth
PROXY_DOMAIN = "twitter1-ewizardii.apigee.com"
consumer_key = '...'
consumer_secret = '...'
consumer = oauth.Consumer(consumer_key, consumer_secret)
oauth_token = '...'
oauth_token_secret = '...'
token = oauth.Token(oauth_token, oauth_token_secret)
client = oauth.Client(consumer, token)
request_token_url = "https://twitter1-ewizardii.apigee.com/1/account/rate_limit_status.json"
resp, content = client.request(request_token_url, "GET", PROXY_DOMAIN)
print resp
print content
However I continue to get the error "error":"Incorrect signature" this was working earlier, and I tried out solutions people have suggested online, generated new credentials etc, but it doesn't seem to work anymore after working for a week like this.
Thanks,
Although I have switched to tweepy for anyone who finds this question this may be of use to you:
http://dev.twitter.com/pages/libraries
It could have been a glitch on the day I was testing as I didn't go back to trying out the oauth-python module since tweepy has been working for me. But that link list all the possible libraries available and is a valuable resource if such a problem arises again.