diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md new file mode 100644 index 0000000..533cbe1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -0,0 +1,33 @@ +--- +name: Bug Report +about: Create a report to help us improve the library +title: '' +labels: bug, triage +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**To Reproduce** +Steps to reproduce the bug: +1. (step 1) +2. (step 2) +3. (step 3) +4. ... + +**Screenshots** +If applicable, add screenshots to help explain the bug. + +**Library version number** +For example: 0.1.1 + +**Environmental details** +For example: +OS: Linux +Runtime version: Python 3.7 + +**Additional context** +Add any other context about the problem here. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..9278187 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,20 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "monthly" + labels: + - "dependency update" + commit-message: + prefix: "build" + include: "scope" + open-pull-requests-limit: 10 + rebase-strategy: "auto" + reviewers: + - "sufyankhanrao" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..c1ca470 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,32 @@ +## What +Write a summary of the changes made in the PR. + +## Why +Exlpain the reasons for the changes. + +## Type of change +Select multiple if applicable. + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause a breaking change) +- [ ] Tests (adds or updates tests) +- [ ] Documentation (adds or updates documentation) +- [ ] Refactor (style improvements, performance improvements, code refactoring) +- [ ] Revert (reverts a commit) +- [ ] CI/Build (adds or updates a script, change in external dependencies) + +## Dependency Change +If a new dependency is being added, please ensure that it adheres to the following guideline https://github.com/apimatic/apimatic-codegen/wiki/Policy-of-adding-new-dependencies-in-the-core-libraries + +## Breaking change +If the PR is introducing a breaking change, please ensure that it adheres to the following guideline https://github.com/apimatic/apimatic-codegen/wiki/Guidelines-for-maintaining-core-libraries + +## Testing +List the steps that were taken to test the changes + +## Checklist +- [ ] My code follows the coding conventions +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have added new unit tests diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 0000000..fe461b4 --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,20 @@ +# Dependency Review Action +# +# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging. +# +# Source repository: https://github.com/actions/dependency-review-action +# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement +name: 'Dependency Review' +on: [pull_request] + +permissions: + contents: read + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: 'Checkout Repository' + uses: actions/checkout@v3 + - name: 'Dependency Review' + uses: actions/dependency-review-action@v2 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c4089f1..e61a6cc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,16 +1,11 @@ name: Publish Package - +run-name: Publishing Package Version ${{ github.event.inputs.Version }} on: workflow_dispatch: inputs: Version: - description: "Version to be released in format: x.y.z, where x => major version, y => minor version and z => patch version" - required: true - default: "0.1.0" - Title: - description: "Title of the release" + description: "This input field requires version in format: x.y.z, where x => major version, y => minor version and z => patch version" required: true - default: "Improving API developer experience" jobs: publish-package: @@ -21,20 +16,24 @@ jobs: contents: write steps: - uses: actions/checkout@v3 + - name: Set up Python uses: actions/setup-python@v4 with: python-version: "3.x" + - name: Build source and wheel distributions run: | python -m pip install --upgrade build twine python -m build twine check --strict dist/* + - name: Publish distribution to PyPI id: release uses: pypa/gh-action-pypi-publish@v1.5.1 with: password: ${{ secrets.PYPI_TOKEN }} + - name: Create tag if: steps.release.outputs.exit_code == 0 id: tag_version @@ -43,10 +42,20 @@ jobs: github_token: ${{ secrets.TAGS_TOKEN }} custom_tag: ${{ github.event.inputs.Version }} tag_prefix: "" + - name: Create changelog for the release if: steps.release.outputs.exit_code == 0 uses: ncipollo/release-action@v1 with: tag: ${{ steps.tag_version.outputs.new_tag }} - name: Release ${{ github.event.inputs.Title }} + name: Release Version ${{ github.event.inputs.Version }} body: ${{ steps.tag_version.outputs.changelog }} + + - name: Send slack notification + id: slack + uses: slackapi/slack-github-action@v1.25.0 + with: + channel-id: 'C012YFE3D6D' + slack-message: "core-interfaces-python release has been triggered!" + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml index e7c5d4a..5dca571 100644 --- a/.github/workflows/pylint.yml +++ b/.github/workflows/pylint.yml @@ -1,6 +1,7 @@ name: Pylint Runner on: + workflow_dispatch: push: branches: [ "main" ] pull_request: @@ -16,7 +17,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.7", "3.8", "3.9", "3.10"] + python: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v3 - name: Setup Python @@ -26,6 +27,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip + pip install -r requirements.txt pip install pylint pip install pylint-fail-under - name: Analysing the code with pylint @@ -34,5 +36,5 @@ jobs: run: | for file in $(find -name '*.py') do - pylint --disable=R,C,W "$file" --fail-under=10; + pylint --disable=R,C,W "$file" --fail-under=10; done diff --git a/LICENSE b/LICENSE index ceb5126..7f3d500 100644 --- a/LICENSE +++ b/LICENSE @@ -1,26 +1,21 @@ -APIMATIC REFERENCE SOURCE LICENSE - -This license governs the use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. - -1. Definitions -The terms "reproduce," "reproduction" and "distribution" have the same meaning here as under U.S. copyright law. - -"You" means the licensee of the software. - -"Your company" means the company you worked for when you downloaded the software. - -"Reference use" means the use of the software within your company as a reference, in read-only form, for the sole purposes of debugging your products, maintaining your products, or enhancing the interoperability of your products with the software, and specifically excludes the right to distribute the software outside of your company. - -"Licensed patents" means any Licensor patent claims which read directly on the software as distributed by the Licensor under this license. - -2. Grant of Rights -(A) Copyright Grant- Subject to the terms of this license, the Licensor grants you a non-transferable, non-exclusive, worldwide, royalty-free copyright license to reproduce the software for reference use. - -(B) Patent Grant- Subject to the terms of this license, the Licensor grants you a non-transferable, non-exclusive, worldwide, royalty-free patent license under licensed patents for reference use. - -3. Limitations -(A) No Trademark License- This license does not grant you any rights to use the Licensor's name, logo, or trademarks. - -(B) If you begin patent litigation against the Licensor over patents that you think may apply to the software (including a cross-claim or counterclaim in a lawsuit), your license to the software ends automatically. - -(C) The software is licensed "as-is." You bear the risk of using it. The Licensor gives no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the Licensor excludes the implied warranties of merchantability, fitness for a particular purpose and non-infringement. \ No newline at end of file +MIT License + +Copyright (c) 2023 APIMatic Ltd + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 52f4997..39b2024 100644 --- a/README.md +++ b/README.md @@ -5,22 +5,24 @@ ## Introduction This project contains the abstract layer for APIMatic's core library. The purpose of creating interfaces is to separate out the functionalities needed by APIMatic's core library module. The goal is to support scalability and feature enhancement of the core library and the SDKs along with avoiding any breaking changes by reducing tight coupling between modules through the introduction of interfaces. -## Version supported -Currenty APIMatic supports `Python version 3.7 - 3.10` hence the apimatic-core-interfaces will need the same versions to be supported. +## Version supported +Currenty APIMatic supports `Python version 3.7+` hence the apimatic-core-interfaces will need the same versions to be supported. -## Installation +## Installation Simply run the command below in your SDK as the apimatic-core-interfaces will be added as a dependency in the SDK. ```python pip install apimatic-core-interfaces ``` ## Interfaces -| Name | Description | -|--------------------------------------------------------------------------- |------------------------------------------------------------------------------------------| -| [`HttpClient`](apimatic_core_interfaces/client/http_client.py) | To save both Request and Response after the completion of response | -| [`ResponseFactory`](apimatic_core_interfaces/factories/response_factory.py)| To convert the client-adapter response into a custom HTTP response | -| [`Authentication`](apimatic_core_interfaces/types/authentication.py) | To setup methods for the validation and application of the required authentication scheme| - +| Name | Description | +|-----------------------------------------------------------------------------|-------------------------------------------------------------------------------------------| +| [`HttpClient`](apimatic_core_interfaces/client/http_client.py) | To save both Request and Response after the completion of response | +| [`ResponseFactory`](apimatic_core_interfaces/factories/response_factory.py) | To convert the client-adapter response into a custom HTTP response | +| [`Authentication`](apimatic_core_interfaces/types/authentication.py) | To setup methods for the validation and application of the required authentication scheme | +| [`UnionType`](apimatic_core_interfaces/types/union_type.py) | To setup methods for the validation and deserialization of OneOf/AnyOf union types | +| [`Logger`](apimatic_core_interfaces/logger/logger.py) | An interface for the generic logger facade | +| [`ApiLogger`](apimatic_core_interfaces/logger/api_logger.py) | An interface for logging API requests and responses | ## Enumerations | Name | Description | @@ -28,5 +30,5 @@ pip install apimatic-core-interfaces | [`HttpMethodEnum`](apimatic_core_interfaces/types/http_method_enum.py ) | Enumeration containig HTTP Methods (GET, POST, PATCH, DELETE) | [pypi-version]: https://img.shields.io/pypi/v/apimatic-core-interfaces -[license-badge]: https://img.shields.io/badge/licence-APIMATIC-blue +[license-badge]: https://img.shields.io/badge/licence-MIT-blue [license-url]: LICENSE diff --git a/apimatic_core_interfaces/__init__.py b/apimatic_core_interfaces/__init__.py index 225a1c8..94e6598 100644 --- a/apimatic_core_interfaces/__init__.py +++ b/apimatic_core_interfaces/__init__.py @@ -1,5 +1,6 @@ __all__ = [ 'client', 'factories', - 'types' + 'types', + 'logger' ] \ No newline at end of file diff --git a/apimatic_core_interfaces/logger/__init__.py b/apimatic_core_interfaces/logger/__init__.py new file mode 100644 index 0000000..4e1589c --- /dev/null +++ b/apimatic_core_interfaces/logger/__init__.py @@ -0,0 +1,4 @@ +__all__=[ + "api_logger", + "logger" +] \ No newline at end of file diff --git a/apimatic_core_interfaces/logger/api_logger.py b/apimatic_core_interfaces/logger/api_logger.py new file mode 100644 index 0000000..34ba62d --- /dev/null +++ b/apimatic_core_interfaces/logger/api_logger.py @@ -0,0 +1,25 @@ +from abc import abstractmethod + +class ApiLogger: + """An interface for logging API requests and responses. + + This class should not be instantiated but should be used as a base class + for API Logger classes.""" + + @abstractmethod + def log_request(self, http_request): + """Logs the given HTTP request. + + Args: + http_request (HttpRequest): The HTTP request to log. + """ + ... + + @abstractmethod + def log_response(self, http_response): + """Logs the given HTTP response. + + Args: + http_response (HttpRequest): The HTTP request to log. + """ + ... \ No newline at end of file diff --git a/apimatic_core_interfaces/logger/logger.py b/apimatic_core_interfaces/logger/logger.py new file mode 100644 index 0000000..1090f66 --- /dev/null +++ b/apimatic_core_interfaces/logger/logger.py @@ -0,0 +1,19 @@ +from abc import abstractmethod + + +class Logger: + """An interface for the generic logger facade. + + This class should not be instantiated but should be used as a base class + for Logger classes.""" + + @abstractmethod + def log(self, level, message, params): + """Logs a message with a specified log level and additional parameters. + + Args: + level (int): The log level of the message. + message (str): The message to log. + params (dict): Additional parameters to include in the log message. + """ + ... \ No newline at end of file diff --git a/apimatic_core_interfaces/types/__init__.py b/apimatic_core_interfaces/types/__init__.py index a4622c6..04023ac 100644 --- a/apimatic_core_interfaces/types/__init__.py +++ b/apimatic_core_interfaces/types/__init__.py @@ -1,4 +1,5 @@ __all__ = [ 'http_method_enum', - 'authentication' + 'authentication', + 'union_type' ] \ No newline at end of file diff --git a/apimatic_core_interfaces/types/union_type.py b/apimatic_core_interfaces/types/union_type.py new file mode 100644 index 0000000..0c6f740 --- /dev/null +++ b/apimatic_core_interfaces/types/union_type.py @@ -0,0 +1,22 @@ +from abc import ABC, abstractmethod + + +class UnionType(ABC): + NATIVE_TYPES = [int, str, float, bool] + + def __init__(self, union_types, union_type_context): + self._union_types = union_types + self._union_type_context = union_type_context + self.is_valid = False + self.error_messages = set() + + @abstractmethod + def validate(self, value): + ... + + @abstractmethod + def deserialize(self, value): + ... + + def get_context(self): + return self._union_type_context diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..0fefbd5 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +setuptools>=68.0.0 \ No newline at end of file diff --git a/setup.py b/setup.py index aec24fc..881af1a 100644 --- a/setup.py +++ b/setup.py @@ -12,13 +12,14 @@ setup( name='apimatic-core-interfaces', - version='0.1.1', + version='0.1.6', description='An abstract layer of the functionalities provided by apimatic-core-library, requests-client-adapter ' 'and APIMatic SDKs.', long_description=long_description, long_description_content_type="text/markdown", author='APIMatic', author_email='support@apimatic.io', + license='MIT', url='https://github.com/apimatic/core-interfaces-python', packages=find_packages(), )