"No DSS URL or API key found from any location" when using dataiku.api_client() in plugin
Hi,
I am updating an in-house plugin where we want to access a login and password that are stored in an arbitrary project's variables. The plugin is a connector to read data from InfluxDB.
I first tested my code in a notebook, and the following does execute without error:
client = dataiku.api_client() project = client.get_default_project() project_variables = project.get_variables() username = project_variables['standard']['influxdb_username'] password = project_variables['standard']['influxdb_password'] print("username: ", username) print("password: ", password)
However when I put the same code (minus the two print statements) inside the plugin and then try to run it (i.e. create a new dataset, fill in the plugin-specific form and hit "TEST & GET SCHEMA"), I get the following error:
Test failed: Failed to initialize kernel : <class 'Exception'> : No DSS URL or API key found from any location
This error is caused by the line "dataiku.api_client()", however, as I understand it, it's supposed to inherit its API key from the user executing the plugin.
What am I doing wrong?
Best Answer
-
Hi,
It is not possible to call internal Dataiku API from the connector.py as the required context is not available there. Instead, you can move the credentials retrieval from project variables to the UI where it is available, and then you can set them as config params in the connector.json and access it from connector.py.
For this, you can utilise the python function used to get select params dynamically. Please refer to the example below:
1) Create resource folder under plugin root and a file(for example, helper.py) where the function will reside:
Sample function code for the file below:
import dataiku client = dataiku.api_client() project = client.get_default_project() project_variables = project.get_variables() def do(payload, config, plugin_config, inputs): if payload.get('parameterName') == 'influxdb_username': print(project_variables['standard']['influxdb_username']) result = [{ "value" : project_variables['standard']['influxdb_username'], "label" : project_variables['standard']['influxdb_username']}] if payload.get('parameterName') == 'influxdb_password': print(project_variables['standard']['influxdb_password']) result = [{ "value" : project_variables['standard']['influxdb_password'], "label" : project_variables['standard']['influxdb_password']}] return {"choices": result}
2) Specify a SELECT params with "getChoicesFromPython: true" and point to the python file created earlier in the connector.json file:
"paramsPythonSetup": "helper.py", "params": [ { "name": "influxdb_username", "label": "influxdb_username", "type": "SELECT", "getChoicesFromPython": true }, { "name": "influxdb_password", "label": "influxdb_password", "type": "SELECT", "getChoicesFromPython": true } ]
3) Then get the credentials from the config params in the connector.py file:
class MyConnector(Connector): def __init__(self, config, plugin_config): Connector.__init__(self, config, plugin_config) # pass the parameters to the base class self.username = self.config.get("influxdb_username", "defaultValue") self.password = self.config.get("influxdb_password", "defaultValue")
Now the credentials will be loaded from project variables and you will be able to select them on the connector page:
Unfortunately, you will still need to select the credentials manually. To fill them dynamically and make them hidden, you will need to use a fully custom form.
Hope this helps.
Answers
-
Hi,
From the description, it looks like you are using the Dataset plugin component, but I can be wrong. Could you provide more details like what plugin component you are using, the full or at least the relevant part of the code where you are trying to use Dataiku API, what is the DSS version, and whether your DSS instance has UIF enabled to understand the context better?
-
Hi,
Thank you for the quick reply. Yes I am using the Dataset plugin component, i.e. I am writing in connector.py. I am on a DSS 8.0.1 instance and User Isolation is set to "no" in Administration > License.
This is the beginning of connector.py:# This file is the actual code for the custom Python dataset first-plugin_influxdb from six.moves import xrange from dataiku.connector import Connector,CustomDatasetWriter from influxdb import InfluxDBClient,DataFrameClient import requests import dataiku """ A custom Python dataset is a subclass of Connector. The parameters it expects and some flags to control its handling by DSS are specified in the connector.json file. Note: the name of the class itself is not relevant. """ class MyConnector(Connector): def __init__(self, config, plugin_config): Connector.__init__(self, config, plugin_config) # pass the parameters to the base class client = dataiku.api_client() project = client.get_default_project() project_variables = project.get_variables() self.username = project_variables['standard']['influxdb_username'] self.password = project_variables['standard']['influxdb_password'] #self.username=plugin_config.get("username", None) #self.password = plugin_config.get("password",None)
With this code, if I then go to Datasets > + New Dataset > influxdb-plugin > influxdb read dataset, I then land on the configuration/test page for the dataset, and clicking on "Test & Get Schema" gives me the error listed in my previous post.
-
Thanks! This helped a lot.