Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for advanced yaml constructors #150

Closed
signebedi opened this issue Apr 4, 2024 · 9 comments
Closed

Add support for advanced yaml constructors #150

signebedi opened this issue Apr 4, 2024 · 9 comments

Comments

@signebedi
Copy link
Owner

I think that we can probably refer to these callables as plugins and define a plugin path as an app config... something like PLUGIN_PATH. We should consider allowing users what kwargs should be passed to the plugin callables. We probably can't get around enumerating the supported kwargs.. something like:

  1. doc_db
  2. user_list
  3. group_list
  4. signing_list

Or maybe we allow admins to request all relational and document database data. I don't think we should automatically pass this data to all plugin callables, that would be bad security practice.

Originally posted by @signebedi in #37 (comment)

@signebedi
Copy link
Owner Author

This probably also necessitates that we provide a set of builtins that administrators can access immediately, as in the case of the list above. User list, document list by form name, and group list are probably all important. Relationship lists and relationship type lists are probably also important.

@signebedi
Copy link
Owner Author

signebedi commented Jun 21, 2024

It may make sense to externalize the constructor factory to a separate script so that we can do more complex things without bloating the pydantic script. For example, we can create some logic to ingest custom logic from end users this way... as well as to test this logic at app startup.

Importantly, custom user logic should not be changeable from the UI, though it perhaps can be permitted to be changed at runtime without daemon restarts...

It's this assumption (custom logic not changeable from UI) that makes it questionable whether we want plotly (#247) to be managed through this same system, or if we want to give users much more restricted ways to build plotly visualizations...

@signebedi signebedi changed the title Add support for plugin callables for field options and custom visualizations Add support for custom yaml constructors for field options and custom visualizations Jun 22, 2024
@signebedi
Copy link
Owner Author

signebedi commented Jun 23, 2024

We've added the basic functionality - quite a bit of complexity, but worthwhile, I think. This is very basic, though. To make these internal lookups useful, we need to add a handful of other form field parameters. For example:

# a list of string fields (if the field doesn't exist, then just ignore them) to show as options.
form_display_fields: str | List[str] | None, 

# if a str, then this should do a lookup and render the form in an iframe. Note this only really 
# works for radio or select fields.
links_to_form: str | None, 

# if True and config.OTHER_PROFILES_ENABLED=True, then render the other user's profile as 
# a clickable badge. Note this works for radio or select fields, as well as for checkboxes.
links_to_user: bool, 

I think we should also add some way to limit the users by group. So, instead of running !all_usernames, we find a way to run !all_usernames_{group_name}. This may be achievable using the same dynamic logic as with forms.

@signebedi
Copy link
Owner Author

I think we've determined that visualizations are out of scope for this and should be handled separately. As we implement the items above, we should also add hooks for end users to add their own plugins.

@signebedi signebedi changed the title Add support for custom yaml constructors for field options and custom visualizations Add support for custom yaml constructors and plugins Jun 23, 2024
@signebedi signebedi changed the title Add support for custom yaml constructors and plugins Add support for custom yaml constructors Jun 23, 2024
@signebedi
Copy link
Owner Author

Add support for custom plugins
We should implement a plugin class that end users can make use of. Something like (and I'm making this up right now):

from abc import ABC, abstractmethod

class Plugin(ABC):

    def __init__(self):
        pass

    @abstractmethod
    def setup(self):
        """
        Setup the plugin with the application config.
        This method needs to be implemented by all plugin subclasses.
        """
        pass

    @abstractmethod
    def execute(self, data):
        """
        Execute the plugin functionality.
        This method needs to be implemented by all plugin subclasses.
        """
        pass

That we store in libreforms_fastapi/utils/plugins.py, and then an app config PLUGIN_PATH that, when set, imports the custom plugin library using sys. We need to think through this a little more.

@signebedi signebedi changed the title Add support for custom yaml constructors Add support for advanced yaml constructors Jun 23, 2024
@signebedi
Copy link
Owner Author

signebedi commented Jun 23, 2024

Add support for form_display_fields in form config field params
When we have a form lookup, we should enable end users to pass the following field parameter to the form config:

form_display_fields: str | List[str] | None, 

This should be a list of string fields (if the field doesn't exist, then just ignore them) to show as options instead of the (admittedly not very user friendly) document ID.

@signebedi
Copy link
Owner Author

Add support for links_to_form in form config field params
When we have a form lookup, we should enable end users to pass the following field parameter to the form config:

links_to_form: str | None, 

If a str, then this should do a lookup and render the form in an iframe. Note this only really works for radio or select fields. Multiselect fields will struggle with it.

@signebedi
Copy link
Owner Author

Add support for links_to_user in form config field params
When we have a user lookup, we should enable end users to pass the following field parameter to the form config:

links_to_user: bool, 

If True and config.OTHER_PROFILES_ENABLED=True, then render the other user's profile as a clickable badge. Note this works for radio or select fields, as well as for checkboxes.

@signebedi
Copy link
Owner Author

[bug] write_form_config_yaml allows unsupported constructors
This is because we added logic to permit all unknown constructors when initialize_full_loader=False... This is not quite the granular level of control that we want. Maybe the fix is to add a separate param that initializes the list of constructors but links them to nulls or empty strings, which we pass as part of the write_form_config_yaml function to ensure only supported constructors are allowed through.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant