Merge pull request #5 from eledio-helpers/feature/docs

Docs
This commit is contained in:
Richard Kubíček
2025-02-28 17:42:41 +01:00
committed by GitHub
25 changed files with 744 additions and 43 deletions

33
.github/workflows/deploy-docs.yml vendored Normal file
View File

@@ -0,0 +1,33 @@
name: Deploy Sphinx Documentation
on: [push]
permissions:
contents: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Install dependencies
run: |
pip install sphinx sphinx-rtd-theme
pip install -e .
- name: Build documentation
run: |
make -C docs html
touch docs/build/html/.nojekyll
- name: Deploy to GitHub Pages
uses: JamesIves/github-pages-deploy-action@v4
with:
branch: gh-pages
folder: docs/build/html

48
.github/workflows/pylint.yml vendored Normal file
View File

@@ -0,0 +1,48 @@
name: Pylint
on: [push]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pylint
- name: pylint
run: |
pylint $(git ls-files '*.py') --fail-under=9.0 --output-format=json > pylint-report.json
- name: Generate Pylint Score
id: pylint_score
run: |
SCORE=$(cat pylint-report.json | jq '[.[].score] | add / length' || echo 0)
echo "score=${SCORE:-0}" >> $GITHUB_ENV
- name: Upload Pylint Report
uses: actions/upload-artifact@v4
with:
name: pylint-report
path: pylint-report.json
- name: Create Pylint Badge
run: |
SCORE=$(echo "${{ env.score }}" | awk '{print int($1)}')
COLOR="red"
if [ "$SCORE" -ge 8 ]; then COLOR="green"; elif [ "$SCORE" -ge 5 ]; then COLOR="yellow"; fi
curl -o pylint-badge.svg "https://img.shields.io/badge/Pylint-$SCORE%2F10-$COLOR"
- name: Upload Pylint Badge
uses: actions/upload-artifact@v4
with:
name: pylint-badge
path: pylint-badge.svg

View File

@@ -1,5 +1,9 @@
# SuperFaktura API client
![Pylint Score](https://github.com/eledio-helpers/superfaktura-client/actions/workflows/pylint.yml/badge.svg)
[Online documentation](https://eledio-helpers.github.io/superfaktura-client)
Library for handling of SuperFaktura API.
Environment variables:

20
docs/Makefile Normal file
View File

@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

35
docs/make.bat Normal file
View File

@@ -0,0 +1,35 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)
if "%1" == "" goto help
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

34
docs/source/conf.py Normal file
View File

@@ -0,0 +1,34 @@
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
import os
import sys
sys.path.insert(0, os.path.abspath('../..'))
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
project = 'SuperFaktura API client'
copyright = '2025, Richard Kubíček, Eledio s.r.o.'
author = 'Richard Kubíček'
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.napoleon',
'sphinx.ext.autosummary',
]
templates_path = ['_templates']
exclude_patterns = []
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
html_theme = 'sphinx_rtd_theme'
html_static_path = ['_static']

8
docs/source/index.rst Normal file
View File

@@ -0,0 +1,8 @@
Welcome to SuperFaktura Client's documentation
=============================================
.. toctree::
:maxdepth: 2
superfaktura
installation

View File

@@ -0,0 +1,6 @@
Installation
====================
To install SuperFaktura Client, run the following command::
pip install git+https://github.com/eledio-helpers/superfaktura-client

View File

@@ -0,0 +1,7 @@
superfaktura.bank\_account module
=================================
.. automodule:: superfaktura.bank_account
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,7 @@
superfaktura.client\_contacts module
====================================
.. automodule:: superfaktura.client_contacts
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,7 @@
superfaktura.enumerations.currency module
=========================================
.. automodule:: superfaktura.enumerations.currency
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,21 @@
superfaktura.enumerations package
=================================
Submodules
----------
superfaktura.enumerations.currency module
-----------------------------------------
.. automodule:: superfaktura.enumerations.currency
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: superfaktura.enumerations
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,7 @@
superfaktura.invoice module
===========================
.. automodule:: superfaktura.invoice
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,35 @@
SuperFaktura API client
====================
Bank account
---------------------------------
.. automodule:: superfaktura.bank_account
:members:
:undoc-members:
:show-inheritance:
Client contacts
------------------------------------
.. automodule:: superfaktura.client_contacts
:members:
:undoc-members:
:show-inheritance:
Invoice
---------------------------
.. automodule:: superfaktura.invoice
:members:
:undoc-members:
:show-inheritance:
SuperFaktura API
-------------------------------------
.. automodule:: superfaktura.superfaktura_api
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,7 @@
superfaktura.superfaktura\_api module
=====================================
.. automodule:: superfaktura.superfaktura_api
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,7 @@
superfaktura.utils.country module
=================================
.. automodule:: superfaktura.utils.country
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,7 @@
superfaktura.utils.data\_types module
=====================================
.. automodule:: superfaktura.utils.data_types
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,29 @@
superfaktura.utils package
==========================
Submodules
----------
superfaktura.utils.country module
---------------------------------
.. automodule:: superfaktura.utils.country
:members:
:undoc-members:
:show-inheritance:
superfaktura.utils.data\_types module
-------------------------------------
.. automodule:: superfaktura.utils.data_types
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: superfaktura.utils
:members:
:undoc-members:
:show-inheritance:

View File

@@ -1,3 +1,36 @@
"""
Bank Account Module.
This module provides classes and functions for working with bank accounts in the SuperFaktura API.
It allows for retrieving, creating, updating, and deleting bank accounts.
Classes:
- BankAccountModel: Dataclass representing a bank account.
- BankAccount: Class for interacting with bank accounts.
Exceptions:
- NoDefaultBankAccountException: Exception for when no default bank account is found.
Functions:
- (none)
Usage:
import superfaktura.bank_account
# Create an instance of BankAccount
bank = superfaktura.bank_account.BankAccount()
# Retrieve a list of bank accounts
accounts = bank.list()
# Get the default bank account
default_account = bank.default()
# Create or update a bank account
data = {"account": "1234567890", "bank_code": "1234567890", "default": True}
bank.post(data)
"""
from dataclasses import dataclass, asdict
from typing import Optional
@@ -5,11 +38,13 @@ from superfaktura.superfaktura_api import SuperFakturaAPI
class NoDefaultBankAccountException(Exception):
pass
"""Exception for when no default bank account is found."""
@dataclass
class BankAccountModel:
"""Dataclass representing a bank account."""
account: Optional[str]
bank_code: Optional[str]
bank_name: Optional[str]
@@ -20,6 +55,7 @@ class BankAccountModel:
id: Optional[int]
def as_dict(self) -> dict:
"""Returns a dictionary representation of the BankAccountModel."""
data = asdict(self)
for key in list(data.keys()):
if data[key] is None:
@@ -28,24 +64,42 @@ class BankAccountModel:
@staticmethod
def from_dict(data: dict) -> "BankAccountModel":
"""Creates a BankAccountModel from a dictionary."""
return BankAccountModel(
**{
k: v
for k, v in data.items()
if k in BankAccountModel.__dataclass_fields__
}
**{k: v for k, v in data.items() if k in BankAccountModel.__annotations__}
)
class BankAccount(SuperFakturaAPI):
"""
Bank Account Class.
This class provides methods for interacting with bank accounts in the SuperFaktura API.
It allows for retrieving, creating, updating, and deleting bank accounts.
Methods:
- list: Retrieves a list of bank accounts.
- default: Retrieves the default bank account.
- post: Creates or updates a bank account.
Usage:
bank = BankAccount()
accounts = bank.list()
default_account = bank.default()
data = {"account": "1234567890", "bank_code": "1234567890", "default": True}
bank.post(data)
"""
def __init__(self):
super().__init__()
def list(self) -> dict:
"""Retrieves a list of bank accounts."""
url = "bank_accounts/index"
return self.get(url)
def default(self) -> Optional[BankAccountModel]:
"""Retrieves the default bank account."""
accounts = self.list()["BankAccounts"]
for account in accounts:
if account["BankAccount"]["default"]:

View File

@@ -1,3 +1,24 @@
"""
Module for interacting with client contacts in SuperFaktura.
This module provides classes and functions for working with client contacts,
including creating, reading, and updating contact information.
Classes:
ClientException: Base class for client exceptions.
ClientContactModel: Dataclass representing a client contact.
Functions:
(none)
Variables:
(none)
Notes:
This module uses the SuperFaktura API to interact with client contacts.
You must have a valid API key and credentials to use this module.
"""
import dataclasses
import json
from pprint import pprint
@@ -7,11 +28,13 @@ from superfaktura.superfaktura_api import SuperFakturaAPI
class ClientException(Exception):
pass
"""Base class for client exceptions."""
@dataclasses.dataclass
class ClientContactModel:
"""Client contact model."""
name: str
address: Optional[str] = None
bank_account: Optional[str] = None
@@ -48,6 +71,7 @@ class ClientContactModel:
id: Optional[int] = None
def as_dict(self) -> dict:
"""Returns a dictionary representation of the ClientContactModel."""
data = dataclasses.asdict(self)
for key in list(data.keys()):
if data[key] is None:
@@ -56,32 +80,34 @@ class ClientContactModel:
@staticmethod
def from_dict(data: dict) -> "ClientContactModel":
"""Creates a ClientContactModel from a dictionary."""
return ClientContactModel(
**{
k: v
for k, v in data.items()
if k in ClientContactModel.__dataclass_fields__
}
**{k: v for k, v in data.items() if k in ClientContactModel.__annotations__}
)
class ClientContact(SuperFakturaAPI):
"""Client contact class."""
def __init__(self):
super().__init__()
def add_contact(self, contact: ClientContactModel) -> bool:
"""Adds a new client contact."""
url = "clients/create"
data = {"Client": contact.as_dict()}
resp = self.post(endpoint=url, data=json.dumps(data))
if resp["error_message"] == "Client created":
response = self.post(endpoint=url, data=json.dumps(data))
if response["error_message"] == "Client created":
return True
return False
def list(self) -> dict:
"""Lists all exists client contacts."""
url = "clients/index.json"
return self.get(endpoint=url)
def get_client(self, client_id: int) -> ClientContactModel:
"""Gets a client contact by ID."""
url = f"clients/view/{client_id}"
data = self.get(endpoint=url)
if "Client" not in data:

View File

@@ -1,3 +1,30 @@
"""
Currency Enumeration.
This module provides an enumeration of currencies that can be used in the SuperFaktura API.
Classes:
- Currencies: Enumeration of currencies.
Usage:
from superfaktura.enumerations.currency import Currencies
currency = Currencies.CZK
"""
class Currencies:
"""
Currency Enumeration.
This enumeration represents the different currencies that can be used in the SuperFaktura API.
Values:
- CZK: Czech Koruna
- EUR: Euro
Usage:
currency = Currencies.CZK
"""
CZK = "CZK"
EUR = "EUR"

View File

@@ -1,3 +1,57 @@
"""
Invoice Module.
This module provides classes and functions for working with invoices in the SuperFaktura API.
It allows for retrieving, creating, updating, and deleting invoices.
Classes:
- InvoiceModel: Dataclass representing an invoice.
- InvoiceItem: Dataclass representing an invoice item.
- Invoice: Class for interacting with invoices.
Exceptions:
- NoDefaultBankAccountException: Exception for when no default bank account is found.
Functions:
- (none)
Usage:
import superfaktura.invoice
# Create an instance of Invoice
invoice = superfaktura.invoice.Invoice()
# Create an invoice
invoice.add(
invoice=superfaktura.invoice.InvoiceModel(
type=superfaktura.invoice.InvoiceType.PROFORMA,
name="Invoice 3",
due=superfaktura.invoice.Date("2025-02-01"),
invoice_currency=superfaktura.invoice.Currencies.CZK,
header_comment="We invoice you for services",
bank_accounts=[bank.default().as_dict()],
),
items=[
superfaktura.invoice.InvoiceItem(name="Services", unit_price=100, quantity=1,
unit="ks", tax=21),
superfaktura.invoice.InvoiceItem(name="SIM card", unit_price=50, quantity=1,
tax=21, unit="ks"),
superfaktura.invoice.InvoiceItem(
name="SIM card 2", unit_price=75, quantity=1, tax=21, unit="ks"
),
],
contact=superfaktura.client_contacts.ClientContactModel(
name="Richard Kubíček",
email="kubicekr@eledio.com",
phone="+420 123 456 789",
address="Jaroslava Foglara 861/1",
ico="123",
update=True,
country_id=57,
),
)
"""
from dataclasses import dataclass, asdict
from typing import Optional, List
import json
@@ -11,6 +65,8 @@ from superfaktura.utils.data_types import Date, DateEncoder
@dataclass
class InvoiceModel:
"""This dataclass represents an invoice in the SuperFaktura API."""
add_rounding_item: Optional[int] = 0
already_paid: Optional[int] = None
bank_accounts: Optional[List[dict]] = None
@@ -51,6 +107,7 @@ class InvoiceModel:
vat_transfer: Optional[int] = None
def as_dict(self) -> dict:
"""Returns a dictionary representation of the InvoiceModel."""
data = asdict(self)
for key in list(data.keys()):
if data[key] is None:
@@ -66,6 +123,8 @@ class InvoiceModel:
@dataclass
class InvoiceItem:
"""This dataclass represents an invoice item in the SuperFaktura API."""
name: str
unit_price: float
description: Optional[str] = None
@@ -80,6 +139,7 @@ class InvoiceItem:
use_document_currency: Optional[int] = 0
def as_dict(self) -> dict:
"""Returns a dictionary representation of the InvoiceItem."""
data = asdict(self)
for key in list(data.keys()):
if data[key] is None:
@@ -88,22 +148,74 @@ class InvoiceItem:
class InvoiceType:
""" "
Invoice Type Enumeration.
This enumeration represents the different types of invoices that can be created.
Usage:
invoice_type = InvoiceType.PROFORMA
"""
PROFORMA = "proforma"
INVOICE = "regular"
class Invoice(SuperFakturaAPI):
"""
Invoice Class.
This class provides methods for interacting with invoices in the SuperFaktura API.
It allows for retrieving, creating, updating, and deleting invoices.
Methods:
- add: Creates a new invoice.
- get: Retrieves an invoice by ID.
- list: Retrieves a list of invoices.
- update: Updates an existing invoice.
Usage:
invoice = Invoice()
invoice.add(
invoice=InvoiceModel(
type=InvoiceType.PROFORMA,
name="Invoice 3",
due=Date("2025-02-01"),
invoice_currency=Currencies.CZK,
header_comment="We invoice you for services",
bank_accounts=[bank.default().as_dict()],
),
items=[
InvoiceItem(name="Services", unit_price=100, quantity=1, unit="ks", tax=21),
InvoiceItem(name="SIM card", unit_price=50, quantity=1, tax=21, unit="ks"),
InvoiceItem(
name="SIM card 2", unit_price=75, quantity=1, tax=21, unit="ks"
),
],
contact=ClientContactModel(
name="Richard Kubíček",
email="kubicekr@eledio.com",
phone="+420 123 456 789",
address="Jaroslava Foglara 861/1",
ico="123",
update=True,
country_id=57,
),
)
"""
def __init__(self):
super().__init__()
def add(
self,
invoice: InvoiceModel,
invoice_model: InvoiceModel,
items: List[InvoiceItem],
contact: ClientContactModel,
):
"""Creates a new invoice."""
data = {
"Invoice": invoice.as_dict(),
"Invoice": invoice_model.as_dict(),
"InvoiceItem": [item.as_dict() for item in items],
"Client": contact.as_dict(),
}
@@ -116,7 +228,7 @@ if __name__ == "__main__":
invoice = Invoice()
bank = BankAccount()
invoice.add(
invoice=InvoiceModel(
invoice_model=InvoiceModel(
type=InvoiceType.PROFORMA,
name="Invoice 3",
due=Date("2025-02-01"),

View File

@@ -1,18 +1,49 @@
"""
SuperFaktura API Client.
This module provides classes and functions for working with the SuperFaktura API.
It allows for reading, creating, updating, and deleting data in SuperFaktura.
Classes:
- SuperFakturaAPI: The base class for working with the SuperFaktura API.
- SuperFakturaAPIException: An exception for errors when working with the SuperFaktura API.
- SuperFakturaAPIMissingCredentialsException: An exception for missing login credentials.
Functions:
- get: Retrieves data from the SuperFaktura API.
- post: Creates or updates data in the SuperFaktura API.
Usage:
import superfaktura.superfaktura_api
# Create an instance of SuperFakturaAPI
api = superfaktura.superfaktura_api.SuperFakturaAPI()
# Retrieve data from the SuperFaktura API
data = api.get('endpoint')
# Create or update data in the SuperFaktura API
api.post('endpoint', data)
"""
import os
from typing import Dict
import requests
import os
from dotenv import load_dotenv # type: ignore
class SuperFakturaAPIException(Exception):
pass
"""Exception for errors when working with the SuperFaktura API."""
class SuperFakturaAPIMissingCredentialsException(Exception):
pass
"""Exception for missing login credentials."""
class SuperFakturaAPI:
"""Base class for working with the SuperFaktura API."""
def __init__(self) -> None:
load_dotenv()
_api_key = os.getenv("SUPERFAKTURA_API_KEY")
@@ -20,28 +51,85 @@ class SuperFakturaAPI:
_api_mail = os.getenv("SUPERFAKTURA_API_EMAIL")
_api_company_id = os.getenv("SUPERFAKTURA_API_COMPANY_ID")
if not _api_key or not self._api_url or not _api_mail or not _api_company_id:
raise SuperFakturaAPIMissingCredentialsException('Please ensure, that necessary credentials are set. Please see README.md')
raise SuperFakturaAPIMissingCredentialsException(
"Please ensure, that necessary "
"credentials are set. Please see"
" README.md"
)
self._auth_header = {
"Authorization": f"SFAPI email={_api_mail}&apikey={_api_key}&company_id={_api_company_id}"
"Authorization": f"SFAPI email={_api_mail}&apikey={_api_key}&company_id="
f"{_api_company_id}"
}
def get(self, endpoint: str) -> Dict:
url = f"{self._api_url}/{endpoint}"
req = requests.get(url=url, headers=self._auth_header)
if req.status_code == 200:
return req.json()
else:
raise SuperFakturaAPIException(
f"Get status code: {req.status_code}; {req.json()}"
)
def get(self, endpoint: str, timeout: int = 5) -> Dict:
"""
Retrieves data from the SuperFaktura API.
def post(self, endpoint: str, data: str) -> Dict:
Retrieves data from the specified endpoint in the SuperFaktura API.
Args:
endpoint (str): The API endpoint to retrieve data from (e.g. 'invoices', 'clients',
etc.).
timeout (int, optional): The timeout for the API request in seconds. Defaults to 5.
Returns:
Dict: The retrieved data in JSON format.
Raises:
SuperFakturaAPIException: If the API request fails or returns an error.
Examples:
>>> api = SuperFakturaAPI()
>>> data = api.get('invoices')
>>> print(data)
Notes:
The available endpoints can be found in the SuperFaktura API documentation.
"""
url = f"{self._api_url}/{endpoint}"
req = requests.post(url=url, headers=self._auth_header, data={"data": data})
req = requests.get(url=url, headers=self._auth_header, timeout=timeout)
if req.status_code == 200:
return req.json()
else:
raise SuperFakturaAPIException(
f"Post status code: {req.status_code}; {req.json()}"
)
raise SuperFakturaAPIException(
f"Get status code: {req.status_code}; {req.json()}"
)
def post(self, endpoint: str, data: str, timeout: int = 5) -> Dict:
"""
Creates or updates data in the SuperFaktura API.
Creates or updates data in the specified endpoint in the SuperFaktura API.
Args:
endpoint (str): The API endpoint to create or update data in (e.g. 'invoices',
'clients', etc.).
data (str): The data to be created or updated in JSON format.
timeout (int, optional): The timeout for the API request in seconds. Defaults
to 5.
Returns:
Dict: The created or updated data in JSON format.
Raises:
SuperFakturaAPIException: If the API request fails or returns an error.
Examples:
>>> api = SuperFakturaAPI()
>>> data = '{"name": "Example Invoice", "amount": 100.0}'
>>> response = api.post('invoices', data)
>>> print(response)
Notes:
The available endpoints can be found in the SuperFaktura API documentation.
The data should be a valid JSON string.
"""
url = f"{self._api_url}/{endpoint}"
req = requests.post(
url=url, headers=self._auth_header, data={"data": data}, timeout=timeout
)
if req.status_code == 200:
return req.json()
raise SuperFakturaAPIException(
f"Post status code: {req.status_code}; {req.json()}"
)

View File

@@ -1,12 +1,33 @@
from pprint import pprint
"""
Country Module.
This module provides utilities for working with countries in the SuperFaktura API.
Functions:
- country_list: Retrieves a list of countries.
Usage:
from superfaktura.utils.country import country_list
countries = country_list()
print(countries)
"""
from superfaktura.superfaktura_api import SuperFakturaAPI
def country_list():
"""
Retrieves a list of countries.
This function returns a list of countries that can be used in the SuperFaktura API.
Returns:
- list: A list of countries.
Usage:
countries = country_list()
print(countries)
"""
api = SuperFakturaAPI()
url = "countries"
return api.get(url)
pprint(country_list())

View File

@@ -1,3 +1,22 @@
"""
Data Types Module.
This module provides data types and utilities for working with dates and other data types
in the SuperFaktura API.
Classes:
- Date: Represents a date in the format YYYY-MM-DD.
- DateTime: Represents a date and time in the format YYYY-MM-DD HH:MM:SS.
Functions:
- (none)
Usage:
from superfaktura.utils.data_types import Date, DateTime
date = Date("2022-01-01")
datetime = DateTime("2022-01-01 12:00:00")
"""
from datetime import datetime
from typing import Optional
@@ -5,6 +24,22 @@ import json
class Date:
"""
Date Class.
This class represents a date in the format YYYY-MM-DD.
Attributes:
- date (str): The date in the format YYYY-MM-DD.
Methods:
- __str__: Returns the date as a string.
Usage:
date = Date("2022-01-01")
print(date) # Output: 2022-01-01
"""
def __init__(self, date_str: Optional[str] = None):
"""
Creates a Date instance that supports typing and validation for the format YYYY-MM-DD.
@@ -25,8 +60,10 @@ class Date:
"""
try:
return datetime.strptime(date_str, "%Y-%m-%d")
except ValueError:
raise ValueError(f"Date must be in format YYYY-MM-DD, got: {date_str}")
except ValueError as exc:
raise ValueError(
f"Date must be in format YYYY-MM-DD, got: {date_str}"
) from exc
def __str__(self) -> str:
"""
@@ -56,6 +93,20 @@ class Date:
class DateEncoder(json.JSONEncoder):
"""
Date Encoder Class.
This class is a custom JSON encoder that converts Date objects to strings.
Methods:
- default: Encodes a Date object as a string.
Usage:
encoder = DateEncoder()
date = Date("2022-01-01")
json_string = json.dumps(date, cls=encoder)
"""
def default(self, o):
if isinstance(o, Date):
return o.to_json()