<commit_before>import json
from datetime import date, datetime

import requests

from fakturoid.models import Account, Subject, Invoice, Generator
from fakturoid.paging import PagedResource

__all__ = ['Fakturoid']


class Fakturoid(object):
    subdomain = None
    api_key = None
    user_agent = 'python-fakturoid (https://github.com/farin/python-fakturoid)'

    _sections = None

    def __init__(self, subdomain=None, api_key=None, user_agent=None):
        self.subdomain = subdomain
        self.api_key = api_key
        self.user_agent = user_agent or self.user_agent

        self._sections = {
            Account: AccountApi(self),
            Subject: SubjectsApi(self),
            Invoice: InvoicesApi(self),
            Generator: GeneratorsApi(self),
        }

    def account(self):
        return self._sections[Account].load()

    def subject(self, id):
        return self._sections[Subject].load(id)

    def subjects(self, *args, **kwargs):
        return self._sections[Subject].find(*args, **kwargs)

    def invoice(self, id):
        return self._sections[Invoice].load(id)

    def invoices(self, *args, **kwargs):
        return self._sections[Invoice].find(*args, **kwargs)

    def generator(self, id):
        return self._sections[Generator].load(id)

    def generators(self, *args, **kwargs):
        return self._sections[Generator].find(*args, **kwargs)

    def save(self, obj):
        section = self._sections.get(type(obj))
        if not section or not hasattr(section, 'save'):
            raise TypeError('save is not supported for {0}'.format(type(obj).__name__))
        section.save(obj)

    def delete(self, obj):
        section = self._sections.get(type(obj))
        if not section or not hasattr(section, 'delete'):
            raise TypeError('delete is not supported for {0}'.format(type(obj).__name__))
        section.delete(obj)

    def _make_request(self, method, success_status, endpoint, **kwargs):
        url = "https://{0}.fakturoid.cz/api/v1/{1}.json".format(self.subdomain, endpoint)
        headers = {'User-Agent': self.user_agent}
        headers.update(kwargs.pop('headers', {}))
        r = getattr(requests, method)(url, auth=('', self.api_key), headers=headers, **kwargs)
        try:
            json_result = r.json()
        except:
            json_result = None

        if r.status_code == success_status:
            return json_result

        if json_result and "errors" in json_result:
            raise ValueError(json_result["errors"])

        r.raise_for_status()

    def _get(self, endpoint, params=None):
        return self._make_request('get', 200, endpoint, params=params)

    def _post(self, endpoint, data):
        return self._make_request('post', 201, endpoint, headers={'Content-Type': 'application/json'}, data=json.dumps(data))

    def _put(self, endpoint, data):
        return self._make_request('put', 200, endpoint,  headers={'Content-Type': 'application/json'}, data=json.dumps(data))

    def _delete(self, endpoint):
        return self._make_request('delete', 204, endpoint)


class Section(object):
    api = None

    def __init__(self, api):
        self.api = api

    def __str__(self):
        return str(self.get)

    def extract_id(self, model_type, value):
        if isinstance(value, int):
            return value
        if not isinstance(value, model_type):
            raise TypeError("int or {0} expected".format(model_type.__name__.lower()))
        if not getattr(value, 'id', None):
            raise ValueError("object wit unassigned id")
        return value.id

    def unpack(self, model_type, endpoint, **kwargs):
        result = self.api._get(endpoint, **kwargs)
        if isinstance(result, list):
            return map(lambda fields: model_type(**fields), result)
        else:
            return model_type(**result)


class CrudSection(Section):
    model_type = None
    endpoint = None

    def load(self, id):
        if not isinstance(id, int):
            raise TypeError('id must be int')<commit_msg>subjects and generators api returns pure list instead of iterable map object<commit_after>import json
from datetime import date, datetime

import requests

from fakturoid.models import Account, Subject, Invoice, Generator
from fakturoid.paging import PagedResource

__all__ = ['Fakturoid']


class Fakturoid(object):
    subdomain = None
    api_key = None
    user_agent = 'python-fakturoid (https://github.com/farin/python-fakturoid)'

    _sections = None

    def __init__(self, subdomain=None, api_key=None, user_agent=None):
        self.subdomain = subdomain
        self.api_key = api_key
        self.user_agent = user_agent or self.user_agent

        self._sections = {
            Account: AccountApi(self),
            Subject: SubjectsApi(self),
            Invoice: InvoicesApi(self),
            Generator: GeneratorsApi(self),
        }

    def account(self):
        return self._sections[Account].load()

    def subject(self, id):
        return self._sections[Subject].load(id)

    def subjects(self, *args, **kwargs):
        return self._sections[Subject].find(*args, **kwargs)

    def invoice(self, id):
        return self._sections[Invoice].load(id)

    def invoices(self, *args, **kwargs):
        return self._sections[Invoice].find(*args, **kwargs)

    def generator(self, id):
        return self._sections[Generator].load(id)

    def generators(self, *args, **kwargs):
        return self._sections[Generator].find(*args, **kwargs)

    def save(self, obj):
        section = self._sections.get(type(obj))
        if not section or not hasattr(section, 'save'):
            raise TypeError('save is not supported for {0}'.format(type(obj).__name__))
        section.save(obj)

    def delete(self, obj):
        section = self._sections.get(type(obj))
        if not section or not hasattr(section, 'delete'):
            raise TypeError('delete is not supported for {0}'.format(type(obj).__name__))
        section.delete(obj)

    def _make_request(self, method, success_status, endpoint, **kwargs):
        url = "https://{0}.fakturoid.cz/api/v1/{1}.json".format(self.subdomain, endpoint)
        headers = {'User-Agent': self.user_agent}
        headers.update(kwargs.pop('headers', {}))
        r = getattr(requests, method)(url, auth=('', self.api_key), headers=headers, **kwargs)
        try:
            json_result = r.json()
        except:
            json_result = None

        if r.status_code == success_status:
            return json_result

        if json_result and "errors" in json_result:
            raise ValueError(json_result["errors"])

        r.raise_for_status()

    def _get(self, endpoint, params=None):
        return self._make_request('get', 200, endpoint, params=params)

    def _post(self, endpoint, data):
        return self._make_request('post', 201, endpoint, headers={'Content-Type': 'application/json'}, data=json.dumps(data))

    def _put(self, endpoint, data):
        return self._make_request('put', 200, endpoint,  headers={'Content-Type': 'application/json'}, data=json.dumps(data))

    def _delete(self, endpoint):
        return self._make_request('delete', 204, endpoint)


class Section(object):
    api = None

    def __init__(self, api):
        self.api = api

    def __str__(self):
        return str(self.get)

    def extract_id(self, model_type, value):
        if isinstance(value, int):
            return value
        if not isinstance(value, model_type):
            raise TypeError("int or {0} expected".format(model_type.__name__.lower()))
        if not getattr(value, 'id', None):
            raise ValueError("object wit unassigned id")
        return value.id

    def unpack(self, model_type, endpoint, **kwargs):
        result = self.api._get(endpoint, **kwargs)
        if isinstance(result, list):
            objects = []
            for fields in result:
                objects.append(model_type(**fields))
            return objects
        else:
            return model_type(**result)


class CrudSection(Section):
    model_type = None
    endpoint = None

    def load(self, id):
        if not isinstance(id, int):
            raise TypeError('id must be int')
{'fraction_non_alphanumeric': 0.12242174229555933, 'fraction_numerical': 0.004367871875758311, 'mean_word_length': 2.8056325023084026, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3343945', 'n_tokens_mistral': 2448, 'n_tokens_neox': 2351, 'n_words': 599}