Skip to content

Instantly share code, notes, and snippets.

@gudmundurh
Created September 25, 2018 21:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gudmundurh/57cb1597ca9d32e11dd6e0733400f6c1 to your computer and use it in GitHub Desktop.
Save gudmundurh/57cb1597ca9d32e11dd6e0733400f6c1 to your computer and use it in GitHub Desktop.
Quick'n'dirty Python 3 class converting Mine Spiir into an API
import requests
import json
from urllib.parse import urlencode
import time
import logging
import datetime
logger = logging.getLogger("espiir")
def die(reason):
logger.error("DIED: " + reason)
sys.exit(-1)
class SpiirApi(object):
"""
Quick-n-dirty wrapper around the web version of Spiir to access postings and transactions.
No guarantee whatsoever for anything, but it should work.
Usage:
api = SpiirApi({ "email": "your@email.com", "password": "yourpass" })
postings = api.get_postings()
"""
def __init__(self, config):
self.baseUrl = "https://mine.spiir.dk"
self.s = requests.Session()
self.config = config
self.verify = False
self.loggedIn = False
def login(self):
r = self.post('/log-ind', {
"Email": self.config['email'],
"Password": self.config['password'],
"RememberEmail": "false"
},
ensure_login=False)
if not 'sessionKey' in r:
die('Login failed')
self.loggedIn = True
def ensure_logged_in(self):
if self.loggedIn:
return
self.login()
def get(self, path, ensure_login=True):
if ensure_login:
self.ensure_logged_in()
logger.info("-> GET to " + path)
t = time.time()
r = self.s.get(self.baseUrl + path, verify=self.verify)
if 'json' in r.headers["Content-Type"]:
j = r.json()
else:
j = r.text
logger.info("<- GET returned " + str(r.status_code) + " in %.2f" % (time.time() - t,))
logger.debug('Headers: %s' % r.headers)
logger.debug('Response: %s' % j)
if r.status_code != 200:
die("Request failed!")
return j
def post(self, path, data, json=False, files=None, ensure_login=True):
if ensure_login:
self.ensure_logged_in()
logger.info("-> POST to " + path)
t = time.time()
if json:
r = self.s.post(self.baseUrl + path, json=data, verify=self.verify, files=files)
else:
r = self.s.post(self.baseUrl + path, data=data, verify=self.verify, files=files)
if 'json' in r.headers["Content-Type"]:
j = r.json()
else:
j = r.text
logger.info("<- POST returned " + str(r.status_code) + " in %.2f" % (time.time() - t,))
logger.debug('Headers: %s' % r.headers)
logger.debug('Response: %s' % j)
if r.status_code != 200:
die("Request failed!")
return j
def get_postings(self, query={}):
"""
'query' is an hash which accepts the same arguments as the posting page in Spiir
does, e.g. {"textQuery": "mastercard", "fromMonth": "201006", "toMonth": "201807"}
"""
qs = urlencode(query)
return self.get('/Posting/GetPostings?useStandardJson=true&_t=' + str(time.time()) + '&' + qs)
def get_budgets(self, year=None):
if year is None:
year = datetime.datetime.now().year
return self.get('/Budget/GetBudgetSummaryForYear?_t=' + str(time.time()) + '&year=' + str(year))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment