"No DSS URL or API key found from any location" when using dataiku.api_client() in plugin

Options
jarchen
jarchen Dataiku DSS Core Designer, Registered Posts: 3 ✭✭✭

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

  • VitaliyD
    VitaliyD Dataiker, Dataiku DSS Core Designer, Dataiku DSS Adv Designer Posts: 102 Dataiker
    edited July 17 Answer ✓
    Options

    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:

    Screenshot 2021-10-29 at 13.52.11.png

    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:

    Screenshot 2021-10-29 at 14.04.15.png

    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

  • VitaliyD
    VitaliyD Dataiker, Dataiku DSS Core Designer, Dataiku DSS Adv Designer Posts: 102 Dataiker
    Options

    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?

  • jarchen
    jarchen Dataiku DSS Core Designer, Registered Posts: 3 ✭✭✭
    edited July 17
    Options

    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.

  • jarchen
    jarchen Dataiku DSS Core Designer, Registered Posts: 3 ✭✭✭
    Options

    Thanks! This helped a lot.

Setup Info
    Tags
      Help me…