betodealmeida opened a new pull request #12635: URL: https://github.com/apache/superset/pull/12635
### SUMMARY <!--- Describe the change below, including rationale and design decisions --> This PR adds a decorator called `guard`, used to protect public APIs from breaking changes without a major version bump (see https://github.com/apache/superset/issues/12566). if the API is changed the user receives a warning. For example, we allow people to specify a custom function called `SQL_QUERY_MUTATOR`. This is already broken, since the signature described in `superset/config.py` is out-of-sync with how it's actually called: ```python # superset/config.py # A function that intercepts the SQL to be executed and can alter it. # The use case is can be around adding some sort of comment header # with information such as the username and worker node information # # def SQL_QUERY_MUTATOR(sql, username, security_manager): # dttm = datetime.now().isoformat() # return f"-- [SQL LAB] {username} {dttm}\n{sql}" SQL_QUERY_MUTATOR = None ``` If we look at where the function is called we can see that the signature should be slightly different: ```python SQL_QUERY_MUTATOR = config["SQL_QUERY_MUTATOR"] ... if SQL_QUERY_MUTATOR: sql = SQL_QUERY_MUTATOR(sql, user_name, security_manager, database) ``` Notice the extra `database` argument, and the small difference between `username` and `user_name`. This was probably changed at some point without updating the config, breaking and any existing `SQL_QUERY_MUTATOR` that don't expect the `database` argument! To prevent this in the future, we create a dummy function and protect it: ```python @guard("W}V8JTUVzx4ur~{CEhT?") def dummy_sql_query_mutator( sql: str, user_name: str, security_manager: SupersetSecurityManager, database: Database, ) -> str: """A no-op version of SQL_QUERY_MUTATOR""" return sql ``` We change the code a little bit so that the function is always called (either the custom or the dummy one): ```python SQL_QUERY_MUTATOR = config.get("SQL_QUERY_MUTATOR") or dummy_sql_query_mutator ... sql = SQL_QUERY_MUTATOR(sql, user_name, security_manager, database) ``` Now what happens if we change the signature of the function? Let's try it: ```python @guard("W}V8JTUVzx4ur~{CEhT?") def dummy_sql_query_mutator( sql: str, user_name: str, security_manager: SupersetSecurityManager, database: Database, foo: int, ) -> str: """A no-op version of SQL_QUERY_MUTATOR""" return sql ``` Changing the code like this will print the following warning: ``` /Users/beto/Projects/incubator-superset/superset/utils/decorators.py:125: UserWarning: The decorated object `dummy_sql_query_mutator` (in /Users/beto/Projects/incubator-superset/superset/sql_lab.py line 54) has a public interface which has currently been modified. This MUST only be released in a new major version of Superset according to SIP-57. To remove this warning message update the hash in the `guard` decorator to ';>K{8wd)&8!=9?1qR@Ja'. @guard("W}V8JTUVzx4ur~{CEhT?") def dummy_sql_query_mutator( sql: str, user_name: str, security_manager: SupersetSecurityManager, database: Database, foo: int, ) -> str: """A no-op version of SQL_QUERY_MUTATOR""" return sql ``` ### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF <!--- Skip this if not applicable --> N/A ### TEST PLAN <!--- What steps should be taken to verify the changes --> Changed signature and run unit tests, it printed the warning message above. ### ADDITIONAL INFORMATION <!--- Check any relevant boxes with "x" --> <!--- HINT: Include "Fixes #nnn" if you are fixing an existing issue --> - [ ] Has associated issue: - [ ] Changes UI - [ ] Requires DB Migration. - [ ] Confirm DB Migration upgrade and downgrade tested. - [ ] Introduces new feature or API - [ ] Removes existing feature or API ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
