RapidMiner

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.
"5 Minutes with Ingo" - Season 2