mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 05:05:42 +00:00 
			
		
		
		
	Merge branch 'matmair/issue2519' of https://github.com/matmair/InvenTree into matmair/issue2519
This commit is contained in:
		| @@ -323,185 +323,3 @@ class AppMixin: | |||||||
|         this plugin is always an app with this plugin |         this plugin is always an app with this plugin | ||||||
|         """ |         """ | ||||||
|         return True |         return True | ||||||
|  |  | ||||||
|  |  | ||||||
| class ActionMixin: |  | ||||||
|     """ |  | ||||||
|     Mixin that enables custom actions |  | ||||||
|     """ |  | ||||||
|     ACTION_NAME = "" |  | ||||||
|  |  | ||||||
|     class MixinMeta: |  | ||||||
|         """ |  | ||||||
|         meta options for this mixin |  | ||||||
|         """ |  | ||||||
|         MIXIN_NAME = 'Action' |  | ||||||
|  |  | ||||||
|     def __init__(self): |  | ||||||
|         super().__init__() |  | ||||||
|         self.add_mixin('action', 'has_action', __class__) |  | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def has_action(self): |  | ||||||
|         """ |  | ||||||
|         Does this plugin have everything needed for an action? |  | ||||||
|         """ |  | ||||||
|         return True |  | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def action_name(self): |  | ||||||
|         """ |  | ||||||
|         Return the action name for this plugin. |  | ||||||
|         If the ACTION_NAME parameter is empty, |  | ||||||
|         look at the PLUGIN_NAME instead. |  | ||||||
|         """ |  | ||||||
|         if self.ACTION_NAME: |  | ||||||
|             return self.ACTION_NAME |  | ||||||
|         return self.name |  | ||||||
|  |  | ||||||
|     def init(self, user, data=None): |  | ||||||
|         """ |  | ||||||
|         An action plugin takes a user reference, and an optional dataset (dict) |  | ||||||
|         """ |  | ||||||
|         self.user = user |  | ||||||
|         self.data = data |  | ||||||
|  |  | ||||||
|     def perform_action(self): |  | ||||||
|         """ |  | ||||||
|         Override this method to perform the action! |  | ||||||
|         """ |  | ||||||
|  |  | ||||||
|     def get_result(self): |  | ||||||
|         """ |  | ||||||
|         Result of the action? |  | ||||||
|         """ |  | ||||||
|  |  | ||||||
|         # Re-implement this for custom actions |  | ||||||
|         return False |  | ||||||
|  |  | ||||||
|     def get_info(self): |  | ||||||
|         """ |  | ||||||
|         Extra info? Can be a string / dict / etc |  | ||||||
|         """ |  | ||||||
|         return None |  | ||||||
|  |  | ||||||
|     def get_response(self): |  | ||||||
|         """ |  | ||||||
|         Return a response. Default implementation is a simple response |  | ||||||
|         which can be overridden. |  | ||||||
|         """ |  | ||||||
|         return { |  | ||||||
|             "action": self.action_name(), |  | ||||||
|             "result": self.get_result(), |  | ||||||
|             "info": self.get_info(), |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class APICallMixin: |  | ||||||
|     """ |  | ||||||
|     Mixin that enables easier API calls for a plugin |  | ||||||
|  |  | ||||||
|     Steps to set up: |  | ||||||
|     1. Add this mixin before (left of) SettingsMixin and PluginBase |  | ||||||
|     2. Add two settings for the required url and token/passowrd (use `SettingsMixin`) |  | ||||||
|     3. Save the references to keys of the settings in `API_URL_SETTING` and `API_TOKEN_SETTING` |  | ||||||
|     4. (Optional) Set `API_TOKEN` to the name required for the token by the external API - Defaults to `Bearer` |  | ||||||
|     5. (Optional) Override the `api_url` property method if the setting needs to be extended |  | ||||||
|     6. (Optional) Override `api_headers` to add extra headers (by default the token and Content-Type are contained) |  | ||||||
|     7. Access the API in you plugin code via `api_call` |  | ||||||
|  |  | ||||||
|     Example: |  | ||||||
|     ``` |  | ||||||
|     from plugin import IntegrationPluginBase |  | ||||||
|     from plugin.mixins import APICallMixin, SettingsMixin |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     class SampleApiCallerPlugin(APICallMixin, SettingsMixin, IntegrationPluginBase): |  | ||||||
|         ''' |  | ||||||
|         A small api call sample |  | ||||||
|         ''' |  | ||||||
|         PLUGIN_NAME = "Sample API Caller" |  | ||||||
|  |  | ||||||
|         SETTINGS = { |  | ||||||
|             'API_TOKEN': { |  | ||||||
|                 'name': 'API Token', |  | ||||||
|                 'protected': True, |  | ||||||
|             }, |  | ||||||
|             'API_URL': { |  | ||||||
|                 'name': 'External URL', |  | ||||||
|                 'description': 'Where is your API located?', |  | ||||||
|                 'default': 'reqres.in', |  | ||||||
|             }, |  | ||||||
|         } |  | ||||||
|         API_URL_SETTING = 'API_URL' |  | ||||||
|         API_TOKEN_SETTING = 'API_TOKEN' |  | ||||||
|  |  | ||||||
|         def get_external_url(self): |  | ||||||
|             ''' |  | ||||||
|             returns data from the sample endpoint |  | ||||||
|             ''' |  | ||||||
|             return self.api_call('api/users/2') |  | ||||||
|     ``` |  | ||||||
|     """ |  | ||||||
|     API_METHOD = 'https' |  | ||||||
|     API_URL_SETTING = None |  | ||||||
|     API_TOKEN_SETTING = None |  | ||||||
|  |  | ||||||
|     API_TOKEN = 'Bearer' |  | ||||||
|  |  | ||||||
|     class MixinMeta: |  | ||||||
|         """meta options for this mixin""" |  | ||||||
|         MIXIN_NAME = 'API calls' |  | ||||||
|  |  | ||||||
|     def __init__(self): |  | ||||||
|         super().__init__() |  | ||||||
|         self.add_mixin('api_call', 'has_api_call', __class__) |  | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def has_api_call(self): |  | ||||||
|         """Is the mixin ready to call external APIs?""" |  | ||||||
|         if not bool(self.API_URL_SETTING): |  | ||||||
|             raise ValueError("API_URL_SETTING must be defined") |  | ||||||
|         if not bool(self.API_TOKEN_SETTING): |  | ||||||
|             raise ValueError("API_TOKEN_SETTING must be defined") |  | ||||||
|         return True |  | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def api_url(self): |  | ||||||
|         return f'{self.API_METHOD}://{self.get_setting(self.API_URL_SETTING)}' |  | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def api_headers(self): |  | ||||||
|         return { |  | ||||||
|             self.API_TOKEN: self.get_setting(self.API_TOKEN_SETTING), |  | ||||||
|             'Content-Type': 'application/json' |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     def api_build_url_args(self, arguments): |  | ||||||
|         groups = [] |  | ||||||
|         for key, val in arguments.items(): |  | ||||||
|             groups.append(f'{key}={",".join([str(a) for a in val])}') |  | ||||||
|         return f'?{"&".join(groups)}' |  | ||||||
|  |  | ||||||
|     def api_call(self, endpoint, method: str = 'GET', url_args=None, data=None, headers=None, simple_response: bool = True): |  | ||||||
|         if url_args: |  | ||||||
|             endpoint += self.api_build_url_args(url_args) |  | ||||||
|  |  | ||||||
|         if headers is None: |  | ||||||
|             headers = self.api_headers |  | ||||||
|  |  | ||||||
|         # build kwargs for call |  | ||||||
|         kwargs = { |  | ||||||
|             'url': f'{self.api_url}/{endpoint}', |  | ||||||
|             'headers': headers, |  | ||||||
|         } |  | ||||||
|         if data: |  | ||||||
|             kwargs['data'] = json.dumps(data) |  | ||||||
|  |  | ||||||
|         # run command |  | ||||||
|         response = requests.request(method, **kwargs) |  | ||||||
|  |  | ||||||
|         # return |  | ||||||
|         if simple_response: |  | ||||||
|             return response.json() |  | ||||||
|         return response |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user