diff --git a/base_api_connection/README.rst b/base_api_connection/README.rst new file mode 100644 index 0000000..abe4f9d --- /dev/null +++ b/base_api_connection/README.rst @@ -0,0 +1,58 @@ +=================== +Base API Connection +=================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-qrtl%2Faxls--oca-lightgray.png?logo=github + :target: https://github.com/qrtl/axls-oca/tree/16.0/base_api_connection + :alt: qrtl/axls-oca + +|badge1| |badge2| |badge3| + +This module facilitates API connections between Odoo and other web services. It is not usable on its own; rather, it is a low-level module intended to serve as a base for others. An example of such a module is 'project_task_capture'. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +1. Go to Settings > API Connection > API Configuration. +2. Create an API configuration record with 'base_url', 'header_api_key_string', 'code', and 'x_api_key'. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Quartile Limited + +Maintainers +~~~~~~~~~~~ + +This module is part of the `qrtl/axls-oca `_ project on GitHub. + +You are welcome to contribute. diff --git a/base_api_connection/__init__.py b/base_api_connection/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/base_api_connection/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/base_api_connection/__manifest__.py b/base_api_connection/__manifest__.py new file mode 100644 index 0000000..68315c2 --- /dev/null +++ b/base_api_connection/__manifest__.py @@ -0,0 +1,16 @@ +# Copyright 2023 Quartile (https://www.quartile.co) +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). +{ + "name": "Base API Connection", + "version": "15.0.1.0.0", + "category": "API", + "website": "https://www.quartile.co", + "author": "Quartile, Odoo Community Association (OCA)", + "license": "LGPL-3", + "depends": ["base"], + "data": [ + "security/ir.model.access.csv", + "views/api_config_views.xml", + ], + "installable": True, +} diff --git a/base_api_connection/models/__init__.py b/base_api_connection/models/__init__.py new file mode 100644 index 0000000..fbd76e5 --- /dev/null +++ b/base_api_connection/models/__init__.py @@ -0,0 +1,2 @@ +from . import api_config +from . import api_call_mixin diff --git a/base_api_connection/models/api_call_mixin.py b/base_api_connection/models/api_call_mixin.py new file mode 100644 index 0000000..2974b9b --- /dev/null +++ b/base_api_connection/models/api_call_mixin.py @@ -0,0 +1,68 @@ +# Copyright 2023 Quartile (https://www.quartile.co) +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). + +import logging + +import requests + +from odoo import _, models +from odoo.exceptions import UserError + +_logger = logging.getLogger(__name__) + + +class APICallMixin(models.AbstractModel): + _name = "api.call.mixin" + _description = "API Call Mixin" + + def get_api_key(self, config): + if config.token_type: + return f"{config.token_type} {config.api_key}" + return config.api_key + + def make_api_call( + self, + code, + external_system="generic", + endpoint=None, + custom_headers=None, + params=None, + json=None, + http_method="get", + ): + config = self.env["api.config"].search( + [("external_system", "=", external_system), ("code", "=", code)], limit=1 + ) + if not config: + raise UserError(_("API configuration not found.")) + url = f"{config.base_url.rstrip('/')}" + if endpoint: + url = f"{url}/{endpoint}" + headers = {"Content-Type": "application/json"} + if custom_headers: + headers.update(custom_headers) + api_key = self.get_api_key(config) + headers[config.header_api_key_string] = api_key + function = getattr(requests, http_method) + kwargs = {"headers": headers} + if params: + kwargs["params"] = params + if json is not None: + kwargs["json"] = json + try: + response = function(url, **kwargs) + response.raise_for_status() # Raises HTTPError for bad responses + _logger.info( + f"Successful API call to {url}. Response status code: {response.status_code}" + ) + except requests.exceptions.HTTPError as e: + _logger.error( + "HTTP Error: %s \n%s", + e.response.status_code, + e.response.text[:500], + exc_info=True, + ) + raise UserError(f"HTTP Error: {str(e)}") from e + except requests.exceptions.RequestException as e: + raise UserError(f"Request Error: {str(e)}") from e + return response diff --git a/base_api_connection/models/api_config.py b/base_api_connection/models/api_config.py new file mode 100644 index 0000000..9f9b332 --- /dev/null +++ b/base_api_connection/models/api_config.py @@ -0,0 +1,36 @@ +# Copyright 2023 Quartile (https://www.quartile.co) +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + + +class ApiConfig(models.Model): + _name = "api.config" + _description = "API Configuration" + + name = fields.Char(required=True) + code = fields.Char( + required=True, + help="Expected to act as an identifier of the API configuration " + "record along with External System.", + ) + base_url = fields.Char(string="URL") + header_api_key_string = fields.Char( + required=True, + help="This string will be used as the key in the API header for the API key value.", + ) + external_system = fields.Selection( + [("generic", "Generic")], default="generic", required=True + ) + token_type = fields.Char("Api Token Type") + api_key = fields.Char(string="Api Key or Token", required=True) + + @api.constrains("code") + def _check_code(self): + for record in self: + existing_rec = self.search( + [("code", "=", record.code), ("id", "!=", record.id)], + ) + if existing_rec: + raise ValidationError(_("Code must be unique.")) diff --git a/base_api_connection/readme/CONFIGURE.rst b/base_api_connection/readme/CONFIGURE.rst new file mode 100644 index 0000000..930d150 --- /dev/null +++ b/base_api_connection/readme/CONFIGURE.rst @@ -0,0 +1,2 @@ +1. Go to Settings > API Connection > API Configuration. +2. Create an API configuration record with 'base_url', 'header_api_key_string', 'code', and 'x_api_key'. diff --git a/base_api_connection/readme/DESCRIPTION.rst b/base_api_connection/readme/DESCRIPTION.rst new file mode 100644 index 0000000..7eb3c25 --- /dev/null +++ b/base_api_connection/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +This module facilitates API connections between Odoo and other web services. It is not usable on its own; rather, it is a low-level module intended to serve as a base for others. An example of such a module is 'project_task_capture'. diff --git a/base_api_connection/security/ir.model.access.csv b/base_api_connection/security/ir.model.access.csv new file mode 100644 index 0000000..cdaee61 --- /dev/null +++ b/base_api_connection/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_api_config_manager,api.config,model_api_config,base.group_system,1,1,1,1 diff --git a/base_api_connection/static/description/index.html b/base_api_connection/static/description/index.html new file mode 100644 index 0000000..36c315c --- /dev/null +++ b/base_api_connection/static/description/index.html @@ -0,0 +1,415 @@ + + + + + + +Base API Connection + + + +
+

Base API Connection

+ + +

Beta License: LGPL-3 qrtl/axls-oca

+

This module facilitates API connections between Odoo and other web services. It is not usable on its own; rather, it is a low-level module intended to serve as a base for others. An example of such a module is ‘project_task_capture’.

+

Table of contents

+ +
+

Configuration

+
    +
  1. Go to Settings > API Connection > API Configuration.
  2. +
  3. Create an API configuration record with ‘base_url’, ‘header_api_key_string’, ‘code’, and ‘x_api_key’.
  4. +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Quartile Limited
  • +
+
+
+

Maintainers

+

This module is part of the qrtl/axls-oca project on GitHub.

+

You are welcome to contribute.

+
+
+
+ + diff --git a/base_api_connection/views/api_config_views.xml b/base_api_connection/views/api_config_views.xml new file mode 100644 index 0000000..05ffedd --- /dev/null +++ b/base_api_connection/views/api_config_views.xml @@ -0,0 +1,50 @@ + + + + api.config.tree + api.config + + + + + + + + api.config.form + api.config + +
+ + + + + + + + + + + +
+
+
+ + API Configuration + api.config + tree,form + {} + [] + + + +
diff --git a/setup/base_api_connection/odoo/addons/base_api_connection b/setup/base_api_connection/odoo/addons/base_api_connection new file mode 120000 index 0000000..ff04bc6 --- /dev/null +++ b/setup/base_api_connection/odoo/addons/base_api_connection @@ -0,0 +1 @@ +../../../../base_api_connection \ No newline at end of file diff --git a/setup/base_api_connection/setup.py b/setup/base_api_connection/setup.py new file mode 100644 index 0000000..28c57bb --- /dev/null +++ b/setup/base_api_connection/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)