From 18a302dcd411db05ab19f5c3b4163eb8fa53655d Mon Sep 17 00:00:00 2001 From: George Margaritis Date: Fri, 2 Feb 2024 18:50:42 +0200 Subject: [PATCH] Add documentation with `sphinx` (#4) Resolves #3 --- .gitignore | 1 + docs/Makefile | 20 +++ docs/source/conf.py | 31 ++++ docs/source/index.rst | 39 +++++ ergani/auth.py | 2 +- ergani/client.py | 51 +++++- ergani/exceptions.py | 6 +- ergani/models.py | 119 ++++++++++++++ ergani/utils.py | 86 +++++++++- poetry.lock | 355 +++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 2 + 11 files changed, 705 insertions(+), 7 deletions(-) create mode 100644 docs/Makefile create mode 100644 docs/source/conf.py create mode 100644 docs/source/index.rst diff --git a/.gitignore b/.gitignore index 778334a..e11b85d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ __pycache__/ *.py[cod] *.env .DS_Store +docs/build/ diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d0c3cbf --- /dev/null +++ b/docs/Makefile @@ -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) diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..98c4455 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,31 @@ +# 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 + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = "ergani-python-sdk" +copyright = "MIT" +author = "George Margaritis " +release = "1.0.0" + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.viewcode", + "sphinx.ext.napoleon", +] + +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 = "furo" +html_static_path = ["_static"] diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..bd0c8b2 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,39 @@ +.. ergani-python-sdk documentation master file, created by + sphinx-quickstart on Fri Feb 2 13:07:54 2024. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to ergani-python-sdk's documentation! +============================================= + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + +ergani.client +-------------------- + +.. automodule:: ergani.client + :members: + :show-inheritance: + +ergani.exceptions +------------------------ + +.. automodule:: ergani.exceptions + :members: + :show-inheritance: + +ergani.models +-------------------- + +.. automodule:: ergani.models + :members: + :show-inheritance: + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/ergani/auth.py b/ergani/auth.py index f435b7f..fcd4b92 100644 --- a/ergani/auth.py +++ b/ergani/auth.py @@ -10,7 +10,7 @@ class ErganiAuthentication(AuthBase): """ - Authentication handler for the Ergani API. + Authentication handler for the Ergani API """ def __init__( diff --git a/ergani/client.py b/ergani/client.py index edfc0da..678f187 100644 --- a/ergani/client.py +++ b/ergani/client.py @@ -15,6 +15,15 @@ class ErganiClient: + """ + A client for interacting with the Ergani API + + Args: + username str: The username for authentication with Ergani + password str: The password for authentication with Ergani + base_url str: The base URL of the Ergani API. Defaults to "https://trialeservices.yeka.gr/WebServicesAPI/api". + """ + def __init__( self, username: str, @@ -61,7 +70,17 @@ def submit_work_card( self, company_work_cards: List[CompanyWorkCard] ) -> Optional[Response]: """ - Submits work cards records (check-in, check-out) for employees to the Ergani API + Submits work card records (check-in, check-out) for employees to the Ergani API + + Args: + company_work_cards List[CompanyWorkCard]: A list of CompanyWorkCard instances to be submitted + + Returns: + An optional Response object from the Ergani API + + Raises: + APIError: An error occurred while communicating with the Ergani API + AuthenticationError: Raised if there is an authentication error with the Ergani API """ endpoint = "/Documents/WRKCardSE" @@ -83,6 +102,16 @@ def submit_overtime( ) -> Optional[Response]: """ Submits overtime records for employees to the Ergani API + + Args: + company_overtimes List[CompanyOvertime]: A list of CompanyOvertime instances to be submitted + + Returns: + An optional Response object from the Ergani API + + Raises: + APIError: An error occurred while communicating with the Ergani API + AuthenticationError: Raised if there is an authentication error with the Ergani API """ endpoint = "/Documents/OvTime" @@ -105,6 +134,16 @@ def submit_daily_schedule( ) -> Optional[Response]: """ Submits schedule records that are updated on a daily basis for employees to the Ergani API + + Args: + company_daily_schedules List[CompanyDailySchedule]: A list of CompanyDailySchedule instances to be submitted + + Returns: + An optional Response object from the Ergani API + + Raises: + APIError: An error occurred while communicating with the Ergani API + AuthenticationError: Raised if there is an authentication error with the Ergani API """ endpoint = "/Documents/WTODaily" @@ -124,6 +163,16 @@ def submit_weekly_schedule( ) -> Optional[Response]: """ Submits weekly schedule records for employees to the Ergani API + + Args: + company_weekly_schedules List[CompanyWeeklySchedule]: A list of CompanyWeeklySchedule instances to be submitted + + Returns: + An optional Response object from the Ergani API + + Raises: + APIError: An error occurred while communicating with the Ergani API + AuthenticationError: Raised if there is an authentication error with the Ergani API """ endpoint = "/Documents/WTOWeek" diff --git a/ergani/exceptions.py b/ergani/exceptions.py index b339a42..b9ea82e 100644 --- a/ergani/exceptions.py +++ b/ergani/exceptions.py @@ -5,7 +5,7 @@ class Error(Exception): """ - Base class for all API errors. + Base class for all API errors """ def __init__( @@ -33,7 +33,7 @@ def __str__(self) -> str: class AuthenticationError(Error): """ - Raised when an API request fails due to an authentication error. + Raised when an API request fails due to an authentication error """ pass @@ -41,7 +41,7 @@ class AuthenticationError(Error): class APIError(Error): """ - Raised when an API request fails due to an unknown error. + Raised when an API request fails due to an unknown error """ pass diff --git a/ergani/models.py b/ergani/models.py index 1342804..c9a6264 100644 --- a/ergani/models.py +++ b/ergani/models.py @@ -23,6 +23,19 @@ @dataclass class WorkCard: + """ + Represents a work card entry for an employee + + Attributes: + employee_tax_identification_number (str): The employee's tax identification number + employee_last_name (str): The last name of the employee + employee_first_name (str): The first name of the employee + work_card_movement_type (WorkCardMovementType): The type of work card movement + work_card_submission_date (date): The date the work card was submitted + work_card_movement_datetime (datetime): The exact date and time of the work card movement + late_declaration_justification (Optional[LateDeclarationJustificationType]): The justification for the late declaration of the work card movement + """ + employee_tax_identification_number: str employee_last_name: str employee_first_name: str @@ -47,6 +60,16 @@ def serialize(self): @dataclass class CompanyWorkCard: + """ + Represents work card entries that are issued on a single business branch + + Attributes: + employer_tax_identification_number (str): The employer's tax identification number + business_branch_number (int): The number identifying the specific business branch + comments (Optional[str]): Additional comments related to the work cards + card_details (List[WorkCard]): A list of `WorkCard` entries for the business branch + """ + employer_tax_identification_number: str business_branch_number: int comments: Optional[str] = "" @@ -67,6 +90,24 @@ def serialize(self): @dataclass class Overtime: + """ + Represents an overtime entry for an employee + + Attributes: + employee_tax_identification_number (str): The employee's tax identification number + employee_social_security_number (str): The employee's social security number + employee_last_name (str): The last name of the employee + employee_first_name (str): The first name of the employee + overtime_date (date): The date of the overtime + overtime_start_time (time): The start time of the overtime period + overtime_end_time (time): The end time of the overtime period + overtime_cancellation (bool): Indicates if the overtime was cancelled or not + employee_profession_code (str): The profession code of the employee + overtime_justification (OvertimeJustificationType): The justification for the overtime + weekly_workdays_number (Literal[5, 6]): The number of the employee's working days in a week + asee_approval (Optional[str]): The ASEE aproval + """ + employee_tax_identification_number: str employee_social_security_number: str employee_last_name: str @@ -101,6 +142,27 @@ def serialize(self): @dataclass class CompanyOvertime: + """ + Represents overtime entries that are issued on a single business branch + + Attributes: + business_branch_number (int): The number identifying the specific business branch + sepe_service_code (str): The SEPE service code + business_primary_activity_code (str): The primary activity code of the business + business_branch_activity_code (str): The activity code for the specific branch + kallikratis_municipal_code (str): The kallikratis municipal code + legal_representative_tax_identification_number (str): Tax identification number of the legal representative + employee_overtimes (List[Overtime]): A list of `Overtime` entries for employees + related_protocol_id (Optional[str]): Related protocol ID + related_protocol_date (Optional[date]): The date of the related protocol + employer_organization (Optional[str]): The employer's organization name + business_secondary_activity_code_1 (Optional[str]): Secondary activity code 1 + business_secondary_activity_code_2 (Optional[str]): Secondary activity code 2 + business_secondary_activity_code_3 (Optional[str]): Secondary activity code 3 + business_secondary_activity_code_4 (Optional[str]): Secondary activity code 4 + comments (Optional[str]): Additional comments related to the overtime entries + """ + business_branch_number: int sepe_service_code: str business_primary_activity_code: str @@ -143,6 +205,15 @@ def serialize(self): @dataclass class WorkdayDetails: + """ + Represents details of an employee's workday + + Attributes: + work_type (ScheduleWorkType): The type of an employee's work schedule + start_time (time): The start time of the workday + end_time (time): The end time of the workday + """ + work_type: ScheduleWorkType start_time: time end_time: time @@ -157,6 +228,17 @@ def serialize(self): @dataclass class EmployeeDailySchedule: + """ + Represents a daily schedule entry for an employee + + Attributes: + employee_tax_identification_number (str): The employee's tax identification number + employee_last_name (str): The employee's last name + employee_first_name (str): The employee's first name + schedule_date (date): The date of the schedule + workday_details (List[WorkdayDetails]): A list of workday detail entries for the employee + """ + employee_tax_identification_number: str employee_last_name: str employee_first_name: str @@ -180,6 +262,19 @@ def serialize(self): @dataclass class CompanyDailySchedule: + """ + Represents daily schedule entries that are issued on a single business branch + + Attributes: + business_branch_number (int): The number identifying the business branch + start_date (Optional[date]): The start date of the schedule + end_date (Optional[date]): The end date of the schedule period + employee_schedules (List[EmployeeDailySchedule]): A list of daily schedules for employees + related_protocol_id (Optional[str]): The ID of the related protocol + related_protocol_date (Optional[date]): The date of the related protocol + comments (Optional[str]): Additional comments regarding the daily schedule entries + """ + business_branch_number: int start_date: Optional[date] = None end_date: Optional[date] = None @@ -207,6 +302,17 @@ def serialize(self): @dataclass class EmployeeWeeklySchedule: + """ + Represents a weekly schedule entry for an employee + + Attributes: + employee_tax_identification_number (str): The employee's tax identification number + employee_last_name (str): The employee's last name + employee_first_name (str): The employee's first name + schedule_date (date): The date of the schedule + workday_details (List[WorkdayDetails]): A list of workday detail entries for the week + """ + employee_tax_identification_number: str employee_last_name: str employee_first_name: str @@ -230,6 +336,19 @@ def serialize(self): @dataclass class CompanyWeeklySchedule: + """ + Represents weekly schedule entries that are issued on a single business branch + + Attributes: + business_branch_number (int): The number identifying the business branch + start_date (date): The start date of the weekly schedule + end_date (date): The end date of the weekly schedule + employee_schedules (List[EmployeeWeeklySchedule]): A list of weekly schedules for employees + related_protocol_id (Optional[str]): The ID of the related protocol + related_protocol_date (Optional[date]): The date of the related protocol + comments (Optional[str]): Additional comments regarding the weekly schedule entries + """ + business_branch_number: int start_date: date end_date: date diff --git a/ergani/utils.py b/ergani/utils.py index da4ff02..17caa35 100644 --- a/ergani/utils.py +++ b/ergani/utils.py @@ -14,7 +14,13 @@ def extract_error_message(response: Response) -> str: """ - Extracts the error message from a requests Response object. + Extracts the error message from a requests Response object + + Args: + response: A Response object + + Returns: + The extracted error message """ content_type: str = response.headers.get("Content-Type", "") @@ -42,7 +48,14 @@ def extract_error_message(response: Response) -> str: def format_time(t: time) -> str: """ Formats a datetime.time instance to `HH:MM` + + Args: + t: The time that is going to be formatted + + Returns: + The formatted time """ + if not t: return "" @@ -52,7 +65,14 @@ def format_time(t: time) -> str: def format_date(d: Optional[date]) -> str: """ Formats a datetime.date instance to `dd/nm/YYYY"` + + Args: + d: The date that is going to be formatted + + Returns: + The formatted date """ + if not d: return "" @@ -62,7 +82,14 @@ def format_date(d: Optional[date]) -> str: def format_datetime(d: Optional[datetime]) -> str: """ Formats a datetime.datetime instance to an ISO 8601 format + + Args: + d: The datetime that is going to be formatted + + Returns: + The formatted datetime """ + if not d: return "" @@ -74,7 +101,14 @@ def get_day_of_week(d: Optional[date]) -> Union[int, str]: Returns the day of the week from a datetime.date instance 0 - Sunday, 6 - Saturday + + Args: + d: The date that is going to be evaluated + + Returns: + The day of the week """ + if not d: return "" @@ -83,6 +117,16 @@ def get_day_of_week(d: Optional[date]) -> Union[int, str]: def get_ergani_workcard_movement_type(movement_type: WorkCardMovementType) -> str: + """ + Returns the ergani value for workcard_movement_type + + Args: + workcard_movement_type: The movement type of a work card + + Returns: + The Ergani value that is going to be used with the Ergani API + """ + movement_type_mapping = { "ARRIVAL": "0", "DEPARTURE": "1", @@ -94,6 +138,16 @@ def get_ergani_workcard_movement_type(movement_type: WorkCardMovementType) -> st def get_ergani_late_declaration_justification( justification: LateDeclarationJustificationType, ) -> str: + """ + Returns the ergani value for late_declaration_justification + + Args: + late_declaration_justification: The justification for a late work card submission + + Returns: + The Ergani value that is going to be used with the Ergani API + """ + justification_mapping = { "POWER_OUTAGE": "001", "EMPLOYER_SYSTEMS_UNAVAILABLE": "002", @@ -104,10 +158,30 @@ def get_ergani_late_declaration_justification( def get_ergani_overtime_cancellation(cancellation: bool) -> str: + """ + Returns the ergani value for overtime_cancellation + + Args: + overtime_cancellation: A value representing if an overtime is going to to be cancelled or not + + Returns: + The Ergani value that is going to be used with the Ergani API + """ + return "0" if not cancellation else "1" def get_ergani_overtime_justification(justification: OvertimeJustificationType) -> str: + """ + Returns the ergani value for overtime_justification + + Args: + overtime_justification: The justification of an employee's overtime + + Returns: + The Ergani value that is going to be used with the Ergani API + """ + justification_mapping = { "ACCIDENT_PREVENTION_OR_DAMAGE_RESTORATION": "001", "URGENT_SEASONAL_TASKS": "002", @@ -124,6 +198,16 @@ def get_ergani_overtime_justification(justification: OvertimeJustificationType) def get_ergani_work_type(work_type: ScheduleWorkType) -> str: + """ + Returns the ergani value for work_type + + Args: + work_type: The work type of an employee's schedule + + Returns: + The Ergani value that is going to be used with the Ergani API + """ + work_type_mapping = { "WORK_FROM_OFFICE": "ΕΡΓ", "WORK_FROM_HOME": "ΤΗΛ", diff --git a/poetry.lock b/poetry.lock index 423e4bd..4e8463b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,51 @@ # This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +[[package]] +name = "alabaster" +version = "0.7.16" +description = "A light, configurable Sphinx theme" +optional = false +python-versions = ">=3.9" +files = [ + {file = "alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92"}, + {file = "alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65"}, +] + +[[package]] +name = "babel" +version = "2.14.0" +description = "Internationalization utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Babel-2.14.0-py3-none-any.whl", hash = "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287"}, + {file = "Babel-2.14.0.tar.gz", hash = "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363"}, +] + +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] + +[[package]] +name = "beautifulsoup4" +version = "4.12.3" +description = "Screen-scraping library" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, + {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, +] + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +cchardet = ["cchardet"] +chardet = ["chardet"] +charset-normalizer = ["charset-normalizer"] +html5lib = ["html5lib"] +lxml = ["lxml"] + [[package]] name = "black" version = "23.12.0" @@ -181,6 +227,34 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "docutils" +version = "0.20.1" +description = "Docutils -- Python Documentation Utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, + {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, +] + +[[package]] +name = "furo" +version = "2024.1.29" +description = "A clean customisable Sphinx documentation theme." +optional = false +python-versions = ">=3.8" +files = [ + {file = "furo-2024.1.29-py3-none-any.whl", hash = "sha256:3548be2cef45a32f8cdc0272d415fcb3e5fa6a0eb4ddfe21df3ecf1fe45a13cf"}, + {file = "furo-2024.1.29.tar.gz", hash = "sha256:4d6b2fe3f10a6e36eb9cc24c1e7beb38d7a23fc7b3c382867503b7fcac8a1e02"}, +] + +[package.dependencies] +beautifulsoup4 = "*" +pygments = ">=2.7" +sphinx = ">=6.0,<8.0" +sphinx-basic-ng = "*" + [[package]] name = "idna" version = "3.6" @@ -192,6 +266,17 @@ files = [ {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, ] +[[package]] +name = "imagesize" +version = "1.4.1" +description = "Getting image size from png/jpeg/jpeg2000/gif file" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, + {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, +] + [[package]] name = "isort" version = "5.13.2" @@ -206,6 +291,92 @@ files = [ [package.extras] colors = ["colorama (>=0.4.6)"] +[[package]] +name = "jinja2" +version = "3.1.3" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, + {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "markupsafe" +version = "2.1.4" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de8153a7aae3835484ac168a9a9bdaa0c5eee4e0bc595503c95d53b942879c84"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e888ff76ceb39601c59e219f281466c6d7e66bd375b4ec1ce83bcdc68306796b"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0b838c37ba596fcbfca71651a104a611543077156cb0a26fe0c475e1f152ee8"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac1ebf6983148b45b5fa48593950f90ed6d1d26300604f321c74a9ca1609f8e"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbad3d346df8f9d72622ac71b69565e621ada2ce6572f37c2eae8dacd60385d"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5291d98cd3ad9a562883468c690a2a238c4a6388ab3bd155b0c75dd55ece858"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a7cc49ef48a3c7a0005a949f3c04f8baa5409d3f663a1b36f0eba9bfe2a0396e"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b83041cda633871572f0d3c41dddd5582ad7d22f65a72eacd8d3d6d00291df26"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-win32.whl", hash = "sha256:0c26f67b3fe27302d3a412b85ef696792c4a2386293c53ba683a89562f9399b0"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-win_amd64.whl", hash = "sha256:a76055d5cb1c23485d7ddae533229039b850db711c554a12ea64a0fd8a0129e2"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9e9e3c4020aa2dc62d5dd6743a69e399ce3de58320522948af6140ac959ab863"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0042d6a9880b38e1dd9ff83146cc3c9c18a059b9360ceae207805567aacccc69"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55d03fea4c4e9fd0ad75dc2e7e2b6757b80c152c032ea1d1de487461d8140efc"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ab3a886a237f6e9c9f4f7d272067e712cdb4efa774bef494dccad08f39d8ae6"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abf5ebbec056817057bfafc0445916bb688a255a5146f900445d081db08cbabb"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e1a0d1924a5013d4f294087e00024ad25668234569289650929ab871231668e7"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e7902211afd0af05fbadcc9a312e4cf10f27b779cf1323e78d52377ae4b72bea"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c669391319973e49a7c6230c218a1e3044710bc1ce4c8e6eb71f7e6d43a2c131"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-win32.whl", hash = "sha256:31f57d64c336b8ccb1966d156932f3daa4fee74176b0fdc48ef580be774aae74"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-win_amd64.whl", hash = "sha256:54a7e1380dfece8847c71bf7e33da5d084e9b889c75eca19100ef98027bd9f56"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a76cd37d229fc385738bd1ce4cba2a121cf26b53864c1772694ad0ad348e509e"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:987d13fe1d23e12a66ca2073b8d2e2a75cec2ecb8eab43ff5624ba0ad42764bc"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5244324676254697fe5c181fc762284e2c5fceeb1c4e3e7f6aca2b6f107e60dc"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78bc995e004681246e85e28e068111a4c3f35f34e6c62da1471e844ee1446250"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4d176cfdfde84f732c4a53109b293d05883e952bbba68b857ae446fa3119b4f"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f9917691f410a2e0897d1ef99619fd3f7dd503647c8ff2475bf90c3cf222ad74"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f06e5a9e99b7df44640767842f414ed5d7bedaaa78cd817ce04bbd6fd86e2dd6"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:396549cea79e8ca4ba65525470d534e8a41070e6b3500ce2414921099cb73e8d"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-win32.whl", hash = "sha256:f6be2d708a9d0e9b0054856f07ac7070fbe1754be40ca8525d5adccdbda8f475"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-win_amd64.whl", hash = "sha256:5045e892cfdaecc5b4c01822f353cf2c8feb88a6ec1c0adef2a2e705eef0f656"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7a07f40ef8f0fbc5ef1000d0c78771f4d5ca03b4953fc162749772916b298fc4"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d18b66fe626ac412d96c2ab536306c736c66cf2a31c243a45025156cc190dc8a"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:698e84142f3f884114ea8cf83e7a67ca8f4ace8454e78fe960646c6c91c63bfa"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a3b78a5af63ec10d8604180380c13dcd870aba7928c1fe04e881d5c792dc4e"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:15866d7f2dc60cfdde12ebb4e75e41be862348b4728300c36cdf405e258415ec"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6aa5e2e7fc9bc042ae82d8b79d795b9a62bd8f15ba1e7594e3db243f158b5565"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:54635102ba3cf5da26eb6f96c4b8c53af8a9c0d97b64bdcb592596a6255d8518"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-win32.whl", hash = "sha256:3583a3a3ab7958e354dc1d25be74aee6228938312ee875a22330c4dc2e41beb0"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-win_amd64.whl", hash = "sha256:d6e427c7378c7f1b2bef6a344c925b8b63623d3321c09a237b7cc0e77dd98ceb"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:bf1196dcc239e608605b716e7b166eb5faf4bc192f8a44b81e85251e62584bd2"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4df98d4a9cd6a88d6a585852f56f2155c9cdb6aec78361a19f938810aa020954"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b835aba863195269ea358cecc21b400276747cc977492319fd7682b8cd2c253d"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23984d1bdae01bee794267424af55eef4dfc038dc5d1272860669b2aa025c9e3"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c98c33ffe20e9a489145d97070a435ea0679fddaabcafe19982fe9c971987d5"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9896fca4a8eb246defc8b2a7ac77ef7553b638e04fbf170bff78a40fa8a91474"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b0fe73bac2fed83839dbdbe6da84ae2a31c11cfc1c777a40dbd8ac8a6ed1560f"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c7556bafeaa0a50e2fe7dc86e0382dea349ebcad8f010d5a7dc6ba568eaaa789"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-win32.whl", hash = "sha256:fc1a75aa8f11b87910ffd98de62b29d6520b6d6e8a3de69a70ca34dea85d2a8a"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-win_amd64.whl", hash = "sha256:3a66c36a3864df95e4f62f9167c734b3b1192cb0851b43d7cc08040c074c6279"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:765f036a3d00395a326df2835d8f86b637dbaf9832f90f5d196c3b8a7a5080cb"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:21e7af8091007bf4bebf4521184f4880a6acab8df0df52ef9e513d8e5db23411"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5c31fe855c77cad679b302aabc42d724ed87c043b1432d457f4976add1c2c3e"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7653fa39578957bc42e5ebc15cf4361d9e0ee4b702d7d5ec96cdac860953c5b4"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47bb5f0142b8b64ed1399b6b60f700a580335c8e1c57f2f15587bd072012decc"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:fe8512ed897d5daf089e5bd010c3dc03bb1bdae00b35588c49b98268d4a01e00"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:36d7626a8cca4d34216875aee5a1d3d654bb3dac201c1c003d182283e3205949"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b6f14a9cd50c3cb100eb94b3273131c80d102e19bb20253ac7bd7336118a673a"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-win32.whl", hash = "sha256:c8f253a84dbd2c63c19590fa86a032ef3d8cc18923b8049d91bcdeeb2581fbf6"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-win_amd64.whl", hash = "sha256:8b570a1537367b52396e53325769608f2a687ec9a4363647af1cded8928af959"}, + {file = "MarkupSafe-2.1.4.tar.gz", hash = "sha256:3aae9af4cac263007fd6309c64c6ab4506dd2b79382d9d19a1994f9240b8db4f"}, +] + [[package]] name = "mypy" version = "1.7.1" @@ -301,6 +472,21 @@ files = [ docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] +[[package]] +name = "pygments" +version = "2.17.2" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, + {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, +] + +[package.extras] +plugins = ["importlib-metadata"] +windows-terminal = ["colorama (>=0.4.6)"] + [[package]] name = "requests" version = "2.31.0" @@ -322,6 +508,173 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "snowballstemmer" +version = "2.2.0" +description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +optional = false +python-versions = "*" +files = [ + {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, + {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, +] + +[[package]] +name = "soupsieve" +version = "2.5" +description = "A modern CSS selector implementation for Beautiful Soup." +optional = false +python-versions = ">=3.8" +files = [ + {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, + {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, +] + +[[package]] +name = "sphinx" +version = "7.2.6" +description = "Python documentation generator" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinx-7.2.6-py3-none-any.whl", hash = "sha256:1e09160a40b956dc623c910118fa636da93bd3ca0b9876a7b3df90f07d691560"}, + {file = "sphinx-7.2.6.tar.gz", hash = "sha256:9a5160e1ea90688d5963ba09a2dcd8bdd526620edbb65c328728f1b2228d5ab5"}, +] + +[package.dependencies] +alabaster = ">=0.7,<0.8" +babel = ">=2.9" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +docutils = ">=0.18.1,<0.21" +imagesize = ">=1.3" +Jinja2 = ">=3.0" +packaging = ">=21.0" +Pygments = ">=2.14" +requests = ">=2.25.0" +snowballstemmer = ">=2.0" +sphinxcontrib-applehelp = "*" +sphinxcontrib-devhelp = "*" +sphinxcontrib-htmlhelp = ">=2.0.0" +sphinxcontrib-jsmath = "*" +sphinxcontrib-qthelp = "*" +sphinxcontrib-serializinghtml = ">=1.1.9" + +[package.extras] +docs = ["sphinxcontrib-websupport"] +lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-simplify", "isort", "mypy (>=0.990)", "ruff", "sphinx-lint", "types-requests"] +test = ["cython (>=3.0)", "filelock", "html5lib", "pytest (>=4.6)", "setuptools (>=67.0)"] + +[[package]] +name = "sphinx-basic-ng" +version = "1.0.0b2" +description = "A modern skeleton for Sphinx themes." +optional = false +python-versions = ">=3.7" +files = [ + {file = "sphinx_basic_ng-1.0.0b2-py3-none-any.whl", hash = "sha256:eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b"}, + {file = "sphinx_basic_ng-1.0.0b2.tar.gz", hash = "sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9"}, +] + +[package.dependencies] +sphinx = ">=4.0" + +[package.extras] +docs = ["furo", "ipython", "myst-parser", "sphinx-copybutton", "sphinx-inline-tabs"] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "1.0.8" +description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_applehelp-1.0.8-py3-none-any.whl", hash = "sha256:cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4"}, + {file = "sphinxcontrib_applehelp-1.0.8.tar.gz", hash = "sha256:c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +standalone = ["Sphinx (>=5)"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "1.0.6" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_devhelp-1.0.6-py3-none-any.whl", hash = "sha256:6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f"}, + {file = "sphinxcontrib_devhelp-1.0.6.tar.gz", hash = "sha256:9893fd3f90506bc4b97bdb977ceb8fbd823989f4316b28c3841ec128544372d3"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +standalone = ["Sphinx (>=5)"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.0.5" +description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_htmlhelp-2.0.5-py3-none-any.whl", hash = "sha256:393f04f112b4d2f53d93448d4bce35842f62b307ccdc549ec1585e950bc35e04"}, + {file = "sphinxcontrib_htmlhelp-2.0.5.tar.gz", hash = "sha256:0dc87637d5de53dd5eec3a6a01753b1ccf99494bd756aafecd74b4fa9e729015"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +standalone = ["Sphinx (>=5)"] +test = ["html5lib", "pytest"] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +description = "A sphinx extension which renders display math in HTML via JavaScript" +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, + {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, +] + +[package.extras] +test = ["flake8", "mypy", "pytest"] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "1.0.7" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_qthelp-1.0.7-py3-none-any.whl", hash = "sha256:e2ae3b5c492d58fcbd73281fbd27e34b8393ec34a073c792642cd8e529288182"}, + {file = "sphinxcontrib_qthelp-1.0.7.tar.gz", hash = "sha256:053dedc38823a80a7209a80860b16b722e9e0209e32fea98c90e4e6624588ed6"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +standalone = ["Sphinx (>=5)"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "1.1.10" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_serializinghtml-1.1.10-py3-none-any.whl", hash = "sha256:326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7"}, + {file = "sphinxcontrib_serializinghtml-1.1.10.tar.gz", hash = "sha256:93f3f5dc458b91b192fe10c397e324f262cf163d79f3282c158e8436a2c4511f"}, +] + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +standalone = ["Sphinx (>=5)"] +test = ["pytest"] + [[package]] name = "tomli" version = "2.0.1" @@ -377,4 +730,4 @@ zstd = ["zstandard (>=0.18.0)"] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "a20815d41f52d9698921bb4d94233d93294bf6c47dfba3c8e5816048cff2056f" +content-hash = "2e427b0c93efefa5806f229638ab0407ba364ae4443ec38812654438c22cfe77" diff --git a/pyproject.toml b/pyproject.toml index 37e6ec6..e3dd2b4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,8 @@ black = "^23.12.0" isort = "^5.13.2" mypy = "^1.7.1" types-requests = "^2.31.0.10" +sphinx = "^7.2.6" +furo = "^2024.1.29" [build-system] requires = ["poetry-core>=1.0.0"]