Source code for fakturownia.core

# coding=utf-8
import json
import logging
import sys

import requests
import six
from requests import HTTPError
from requests.structures import CaseInsensitiveDict
from urllib3.util import parse_url

from fakturownia import endpoints
from fakturownia.exceptions import FakturowniaException, HttpException

log = logging.getLogger(__file__)


[docs]class ApiClient(object): """ Fakturownia API client Here is an example of how to crete an invoice. But first make sure you have set `FAKTUROWNIA_API_TOKEN` environment variable. >>> import os >>> os.environ.get('FAKTUROWNIA_API_TOKEN', 'Missing key') '...' >>> from fakturownia import get_api_client >>> api = get_api_client() >>> invoice = api.invoices.create( ... seller_name='Kabaret Starszych Panów', ... buyer_name='Odrażający drab', ... positions=[{ ... 'name': 'Smolna szczapa', ... 'quantity': 5, ... 'total_price_gross': 7.33, ... }], ... ) This instance is only partially updated as create returns only subset of data properties, to get all we need to update our instance. This shows payment_url but only if you have payments enabled. >>> invoice.get() <fakturownia.endpoints.Invoice object at 0x...> >>> invoice.payment_url # doctest: +SKIP '...' We can mark this invoice as paid. >>> invoice.mark_paid() <fakturownia.endpoints.Invoice object at 0x...> You can chain your calls >>> invoice.put(buyer_email='kominek@niepodam.pl').send_by_email() <fakturownia.endpoints.Invoice object at 0x...> """ def __init__(self, api_token, base_url=None, request_timeout=10): self.request_timeout = request_timeout self.api_token = api_token if base_url is not None: self.base_url = base_url else: self.base_url = 'https://{}.fakturownia.pl/'.format(self.api_token.split('/')[1]) from . import __version__ as version self.default_headers = { 'accept': "application/json", 'content-type': "application/json", 'user-agent': "Fakturownia Python/" + version } log.info("Fakturownia: base_url: %s api_token: ***%s", self.base_url, self.api_token[self.api_token.index('/'):] if '/' in self.api_token else '') self.invoices = endpoints.Invoices(self) self.clients = endpoints.Clients(self) @property def base_url(self): return self._base_url @base_url.setter def base_url(self, url): log.debug("url: %s", url) parsed = parse_url(url) if parsed.scheme is None or parsed.hostname is None: raise ValueError("Invalid url: {}".format(url)) # noinspection PyAttributeOutsideInit self._base_url = url # noinspection PyMethodMayBeStatic
[docs] def request_factory(self, *args, **kwargs): return requests.request(*args, **kwargs)
[docs] def post(self, endpoint, data=None, headers=None): payload = self.build_payload(data) payload = json.dumps(payload) return self.request('POST', endpoint, payload=payload, headers=headers)
[docs] def put(self, endpoint, data=None, headers=None): payload = self.build_payload(data) payload = json.dumps(payload) return self.request('PUT', endpoint, payload=payload, headers=headers)
[docs] def delete(self, endpoint, data=None, headers=None): params = self.build_payload(data) return self.request('DELETE', endpoint, params=params, headers=headers)
[docs] def get(self, endpoint, data=None, headers=None): params = self.build_payload(data) return self.request('GET', endpoint, params=params, headers=headers)
[docs] def request(self, method, endpoint, params=None, payload=None, headers=None): url = self.base_url + endpoint log.debug("url: %s", url) log.debug("payload: %s", payload) resp = self.request_factory( method=method, url=url, headers=self.build_headers(headers), data=payload, params=params, timeout=self.request_timeout, ) log.debug("response: %s", resp) log.debug("response: %s", resp.text) self.validate_response(resp) return resp.json()
[docs] def build_payload(self, data=None): payload = { 'api_token': self.api_token, } if data: payload.update(data) return payload
[docs] def build_headers(self, items=None): headers = CaseInsensitiveDict(self.default_headers) if items: headers.update(items) return headers
# noinspection PyMethodMayBeStatic
[docs] def validate_response(self, response): try: response.raise_for_status() except HTTPError as ex: data = response.json() if 'code' in data and data['code'] == 'error': msg = str(ex) + " - " + str(data['message']) six.reraise(HttpException, HttpException(msg, response), sys.exc_info()[2]) raise six.reraise(HttpException, HttpException(ex, response), sys.exc_info()[2])
[docs]def get_api_client(): """ Factory function for Fakturownia API client with configuration options taken from environment :return: ApiClient instance """ import os from fakturownia import settings api_token = os.environ.get('FAKTUROWNIA_API_TOKEN', None) if api_token is None: api_token = settings.get_key_from_file() if api_token is None: raise FakturowniaException('Please set FAKTUROWNIA_API_TOKEN environment variable') base_url = os.environ.get('FAKTUROWNIA_BASE_URL', None) request_timeout = os.environ.get('FAKTUROWNIA_TIMEOUT', None) if request_timeout: request_timeout = float(request_timeout) return ApiClient(api_token=api_token, base_url=base_url, request_timeout=request_timeout)