RapidMiner

Execute Script vs Java Extension coding

SOLVED
Highlighted
Community Manager Community Manager
Community Manager

Execute Script vs Java Extension coding

OK I think I am just a glutton for punishment but I keep trying to create a simple extension that executes API GET requests.  I thought I had it clinched this weekend using the nice "unirest" library.  In fact it works perfectly when using the Execute Script operator:

 

<?xml version="1.0" encoding="UTF-8"?><process version="7.6.001">
<context>
<input/>
<output/>
<macros/>
</context>
<operator activated="true" class="process" compatibility="7.6.001" expanded="true" name="Process">
<process expanded="true">
<operator activated="true" class="generate_data_user_specification" compatibility="7.6.001" expanded="true" height="68" name="Generate Data by User Specification" width="90" x="179" y="187">
<list key="attribute_values"/>
<list key="set_additional_roles"/>
</operator>
<operator activated="true" class="execute_script" compatibility="7.6.001" expanded="true" height="82" name="Execute Script" width="90" x="313" y="187">
<parameter key="script" value="import com.mashape.unirest.http.*;&#10;import com.mashape.unirest.http.exceptions.UnirestException;&#10;import com.rapidminer.tools.Ontology;&#10;&#10;IOObject inputData = input[0];&#10;&#10;Attributes attributes = inputData.getAttributes();&#10;&#10;Attribute jsonOutput = AttributeFactory.createAttribute(&quot;jsonOutput&quot;, Ontology.STRING);&#10;&#10;attributes.addRegular(jsonOutput);&#10;&#10;inputData.getExampleTable().addAttribute(jsonOutput);&#10;&#10;for (Example example : inputData) {&#10;&#9;&#10;&#9;HttpResponse&lt;JsonNode&gt; response = Unirest.get(&quot;https://community-bitcointy.p.mashape.com/convert/10/USD&quot;)&#10;&#9;&#9;.header(&quot;X-Mashape-Key&quot;, &quot;izQxTY0KZ4mshmrBq7DmXQvlC3hcp16709BjsngW8gm71mH39j&quot;)&#10;&#9;&#9;.header(&quot;X-Mashape-Host&quot;, &quot;community-bitcointy.p.mashape.com&quot;)&#10;&#9;&#9;.asJson();&#10;&#9;JsonNode foo = response.getBody();&#9;&#10;&#9;String jsonText = foo.toString();&#10;&#9;example.setValue(jsonOutput, jsonText);&#10;}&#10;&#10;return inputData;&#10;"/>
<description align="center" color="transparent" colored="false" width="126">this works</description>
</operator>
<connect from_op="Generate Data by User Specification" from_port="output" to_op="Execute Script" to_port="input 1"/>
<connect from_op="Execute Script" from_port="output 1" to_port="result 1"/>
<portSpacing port="source_input 1" spacing="0"/>
<portSpacing port="sink_result 1" spacing="0"/>
<portSpacing port="sink_result 2" spacing="0"/>
</process>
</operator>
</process>

However when I try to put this in the "extension template", I can never get this to compile:

 

package com.rapidminer.apitoolbox;

import java.util.logging.Level;
import com.rapidminer.example.Attribute;
import com.rapidminer.example.Attributes;
import com.rapidminer.example.Example;
import com.rapidminer.example.ExampleSet;
import com.rapidminer.example.table.AttributeFactory;
import com.rapidminer.example.utils.ExampleSetBuilder;
import com.rapidminer.example.utils.ExampleSets;
import com.rapidminer.operator.Operator;
import com.rapidminer.operator.OperatorDescription;
import com.rapidminer.operator.OperatorException;
import com.rapidminer.operator.ports.InputPort;
import com.rapidminer.operator.ports.OutputPort;
import com.rapidminer.operator.ports.metadata.AttributeMetaData;
import com.rapidminer.operator.ports.metadata.ExampleSetMetaData;
import com.rapidminer.operator.ports.metadata.GenerateNewExampleSetMDRule;
import com.rapidminer.operator.ports.metadata.MetaData;
import com.rapidminer.parameter.ParameterType;
import com.rapidminer.parameter.ParameterTypeBoolean;
import com.rapidminer.parameter.ParameterTypeInt;
import com.rapidminer.parameter.UndefinedParameterError;
import com.rapidminer.tools.LogService;
import com.mashape.unirest.http.*;
import com.mashape.unirest.http.exceptions.UnirestException;
import com.rapidminer.tools.Ontology;

/**
* This operator calls the Bitcointy API (via RapidAPI/Mashape)
* and gets the current USD/BTC exchange rate.
*
* @author S. Genzer on 1 Oct 2017
*
*/

public class bitcoin extends Operator {

	/**
	 * @param description
	 */

	public InputPort exampleSetInput = getInputPorts()
			.createPort("exa");
	public OutputPort exampleSetOutput = getOutputPorts()
			.createPort("exa");
	
	public bitcoin(OperatorDescription description) {
		super(description);
	}
		
	@Override
	
	public void doWork() throws OperatorException {
		LogService.getRoot().log(Level.INFO, "Doing something...");
				
		ExampleSet exampleSet = exampleSetInput.getData(ExampleSet.class);
		
		Attributes attributes = exampleSet.getAttributes();

		Attribute jsonOutput = AttributeFactory.createAttribute("jsonOutput", Ontology.STRING);

		attributes.addRegular(jsonOutput);

		exampleSet.getExampleTable().addAttribute(jsonOutput);
		
		for (Example example : exampleSet) {
			
			HttpResponse<JsonNode> response = Unirest.get("https://community-bitcointy.p.mashape.com/convert/10/USD")
				.header("X-Mashape-Key", "key")
				.header("X-Mashape-Host", "community-bitcointy.p.mashape.com")
				.asJson();
			JsonNode foo = response.getBody();	
			String jsonText = foo.toString();
			example.setValue(jsonOutput, jsonText);
		}
		
		exampleSetOutput.deliver(exampleSet);
		
	}
}

Help?  This is maddening.

 

Scott

 

Scott Genzer
Senior Community Manager
RapidMiner, Inc.
2 REPLIES
RM Staff
RM Staff
Solution

Re: Execute Script vs Java Extension coding

Scott,

 

i've added the class to a branch of operatortoolbox. A few things:

 

1. Have you added

compile 'com.mashape.unirest:unirest-java:1.3.1'

to your gradle dependencies?

2.

response = Unirest.get("https://community-bitcointy.p.mashape.com/convert/10/USD") ...

needs a try catch.

3. you added two different implementations of JsonNode. One from mashable the other from

com.fasterxml.jackson.databind.

that screwed it up.

 

Here the code i was able to compile (but not tested the operator though):

 

//package com.rapidminer.apitoolbox;
package com.rapidminer.extension.operator.blending;
//import com.fasterxml.jackson.databind.JsonNode;
import com.mashape.unirest.http.*;
import com.mashape.unirest.http.exceptions.UnirestException;
import com.rapidminer.example.Attribute;
import com.rapidminer.example.Attributes;
import com.rapidminer.example.Example;
import com.rapidminer.example.ExampleSet;
import com.rapidminer.example.table.AttributeFactory;
import com.rapidminer.operator.Operator;
import com.rapidminer.operator.OperatorDescription;
import com.rapidminer.operator.OperatorException;
import com.rapidminer.operator.ports.InputPort;
import com.rapidminer.operator.ports.OutputPort;
import com.rapidminer.tools.LogService;
import com.rapidminer.tools.Ontology;

import java.util.logging.Level;

/**
 * This operator calls the Bitcointy API (via RapidAPI/Mashape)
 * and gets the current USD/BTC exchange rate.
 *
 * @author S. Genzer on 1 Oct 2017
 *
 */

public class BitCoin extends Operator {

    /**
     * @param description
     */

    public InputPort exampleSetInput = getInputPorts()
            .createPort("exa");
    public OutputPort exampleSetOutput = getOutputPorts()
            .createPort("exa");

    public BitCoin(OperatorDescription description) {
        super(description);
    }

    @Override

    public void doWork() throws OperatorException {
        LogService.getRoot().log(Level.INFO, "Doing something...");

        ExampleSet exampleSet = exampleSetInput.getData(ExampleSet.class);

        Attributes attributes = exampleSet.getAttributes();

        Attribute jsonOutput = AttributeFactory.createAttribute("jsonOutput", Ontology.STRING);

        attributes.addRegular(jsonOutput);

        exampleSet.getExampleTable().addAttribute(jsonOutput);

        for (Example example : exampleSet) {

            HttpResponse<com.mashape.unirest.http.JsonNode> response = null;
            try {
                response = Unirest.get("https://community-bitcointy.p.mashape.com/convert/10/USD")
                        .header("X-Mashape-Key", "key")
                        .header("X-Mashape-Host", "community-bitcointy.p.mashape.com")
                        .asJson();
            } catch (UnirestException e) {
                e.printStackTrace();
            }
            JsonNode foo = response.getBody();
            String jsonText = foo.toString();
            example.setValue(jsonOutput, jsonText);
        }

        exampleSetOutput.deliver(exampleSet);

    }
}
--------------------------------------------------------------------------
Head of Data Science Services at RapidMiner
Community Manager Community Manager
Community Manager

Re: Execute Script vs Java Extension coding

@mschmitz, a.k.a. "the man with the cape" comes through again.  Thank you.  I knew it was some conflict with that JsonNode call but could not find it.  Yes I had put the compile statement in the dependencies in build.gradle.  Not bad for an EE major, right?  Smiley Happy


Scott

 

Scott Genzer
Senior Community Manager
RapidMiner, Inc.