├── LICENSE ├── README.md └── yahooapi.py /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Darren Kempiners 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | python-yahooapi 2 | =============== 3 | 4 | Python class for accessing Yahoo's Fantasy API 5 | 6 | Uses the rauth library. 7 | 8 | Reads consumer key and secret key from a file (separated by whitespace). 9 | 10 | Optionally, saves access token to a file. 11 | -------------------------------------------------------------------------------- /yahooapi.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | 4 | from rauth import OAuth2Service 5 | 6 | 7 | class ClientKey(object): 8 | def __init__(self, client_id, client_secret): 9 | self.client_id = client_id 10 | self.client_secret = client_secret 11 | 12 | @classmethod 13 | def from_file(cls, key_file): 14 | with open(key_file, "r") as f: 15 | keys = f.read().splitlines() 16 | 17 | if len(keys) != 2: 18 | raise RuntimeError("Incorrect number of keys found") 19 | 20 | return cls(*keys) 21 | 22 | 23 | class Token(object): 24 | def __init__(self, access_token=None, refresh_token=None): 25 | self.access_token = access_token 26 | self.refresh_token = refresh_token 27 | self.expiration_time = 0 28 | 29 | @property 30 | def expires_in(self): 31 | return self.expiration_time - time.time() 32 | 33 | @property 34 | def is_expired(self): 35 | return self.expires_in <= 0 36 | 37 | def get(self, oauth_service): 38 | if self.refresh_token: 39 | data = { 40 | "refresh_token": self.refresh_token, 41 | "redirect_uri": "oob", 42 | "grant_type": "refresh_token", 43 | } 44 | else: 45 | data = { 46 | "code": self._get_code(oauth_service), 47 | "redirect_uri": "oob", 48 | "grant_type": "authorization_code", 49 | } 50 | 51 | self._get_token(oauth_service, data) 52 | 53 | def _get_code(self, oauth_service): 54 | params = { 55 | "redirect_uri": "oob", 56 | "response_type": "code", 57 | } 58 | authorize_url = oauth_service.get_authorize_url(**params) 59 | 60 | print "Sign in here: " + str(authorize_url) 61 | return raw_input("Enter code: ") 62 | 63 | def _get_token(self, oauth_service, data): 64 | raw_token = oauth_service.get_raw_access_token(data=data) 65 | 66 | parsed_token = raw_token.json() 67 | self.access_token = parsed_token["access_token"] 68 | self.refresh_token = parsed_token["refresh_token"] 69 | self.expiration_time = time.time() + parsed_token["expires_in"] 70 | 71 | @classmethod 72 | def from_file(cls, token_file): 73 | with open(token_file, "r") as f: 74 | token = f.read().strip() 75 | 76 | if len(token.splitlines()) != 1: 77 | raise RuntimeError("Incorrect token format") 78 | 79 | return cls(refresh_token=token) 80 | 81 | def save(self, token_file): 82 | with open(token_file, "w") as f: 83 | f.write(self.refresh_token) 84 | 85 | 86 | class YahooAPI(object): 87 | def __init__(self, keyfile, tokenfile=None, 88 | base_url="https://fantasysports.yahooapis.com", 89 | request_period=0): 90 | 91 | self.key = ClientKey.from_file(keyfile) 92 | 93 | self.tokenfile = tokenfile 94 | if self.tokenfile and os.path.exists(self.tokenfile): 95 | self.token = Token.from_file(self.tokenfile) 96 | else: 97 | self.token = Token() 98 | 99 | self.oauth = OAuth2Service( 100 | client_id=self.key.client_id, 101 | client_secret=self.key.client_secret, 102 | name="yahoo", 103 | authorize_url="https://api.login.yahoo.com/oauth2/request_auth", 104 | access_token_url="https://api.login.yahoo.com/oauth2/get_token", 105 | base_url=base_url, 106 | ) 107 | 108 | self.session = None 109 | 110 | self._update_token() 111 | 112 | self.session = self.oauth.get_session(self.token.access_token) 113 | 114 | self.last_request = time.time() 115 | self.request_period = request_period 116 | 117 | def _update_token(self): 118 | self.token.get(self.oauth) 119 | 120 | if self.tokenfile: 121 | self.token.save(self.tokenfile) 122 | 123 | if self.session: 124 | self.session.access_token = self.token.access_token 125 | 126 | def request(self, request_str, params={}): 127 | """get json instead of xml like this params={'format': 'json'}""" 128 | 129 | tdiff = max(0, time.time() - self.last_request) 130 | if tdiff >= 0 and tdiff < self.request_period: 131 | time.sleep(self.request_period - tdiff) 132 | 133 | self.last_request = time.time() 134 | 135 | # refresh access token 60 seconds before it expires 136 | if self.token.expires_in < 60: 137 | self._update_token() 138 | 139 | return self.session.get(url=request_str, params=params) 140 | --------------------------------------------------------------------------------