import logging import requests from odoo import models, fields, api _logger = logging.getLogger(__name__) # Sentinel values for token count status _NO_KEY = -1 _ERROR = -2 class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' otoolkit_api_key = fields.Char( string="O'Toolkit API Key", config_parameter='otoolkit_api_key', help="API key from your O'Solutions portal (portal.osolutions.app).", ) otoolkit_api_token_count = fields.Integer( string='Token Balance', compute='_compute_token_count', config_parameter='otoolkit_api_token_count', readonly=True, default=_NO_KEY, ) otoolkit_key_status = fields.Selection( [('valid', 'Valid'), ('invalid', 'Invalid'), ('error', 'Connection Error'), ('none', 'No Key')], string='Key Status', compute='_compute_token_count', ) def _get_token_balance(self, api_key): """Fetch token balance from O'Toolkit API (which validates via FastAPI).""" api_endpoint = self.env['ir.config_parameter'].sudo().get_param( 'otoolkit.api.endpoint', 'https://api.otoolkit.app' ) if not api_key: return _NO_KEY, 'none' headers = { 'Odoo-Api-Key': api_key, 'Content-Type': 'application/json', } try: response = requests.get( f"{api_endpoint.rstrip('/')}/api/get-token-count/", headers=headers, timeout=10, ) except requests.exceptions.RequestException as e: _logger.warning("O'Toolkit API connection error: %s", e) return _ERROR, 'error' if response.status_code == 200: data = response.json() return data.get('token_count', 0), 'valid' if response.status_code == 401: return 0, 'invalid' _logger.warning("O'Toolkit API returned %s: %s", response.status_code, response.text[:200]) return _ERROR, 'error' @api.depends('otoolkit_api_key') def _compute_token_count(self): for record in self: api_key = record.otoolkit_api_key count, status = record._get_token_balance(api_key) record.otoolkit_api_token_count = count record.otoolkit_key_status = status self.env['ir.config_parameter'].sudo().set_param( 'otoolkit_api_token_count', str(count) ) def refresh_token_count(self): self._compute_token_count()