[First Ripple] [I am] Call JavaScript (Node.js) from Python and process Ripple

Introduction

Recently, so-called Fintech people have often become followers on Twitter.

When I look at tweets, there are quite a few stories about Ripple. There are many big stories about Mizuho Bank, so I was wondering if I, who is a digital Hijikata (I'm not familiar with it recently), have nothing to do with it.

However, when I look at the Developper site, it may be natural these days, but it is an open source product, and I was able to drop APIs for free. It seems that you can access the live Ripple network by using the API provided by Node.js.

I'm a sad programmer who's ruined every language these days, but Python is used reasonably well among them. Also, with Python, machine learning systems and calculation systems are also substantial, so I thought that it would be quite fun to use automatic contracts from AI using Ripple. This time, the basic part of calling JavaScript from Python to access the Ripple API has been completed, so I will post it with the meaning of a reminder.

So what do you do

I'm sorry that the prototype this time has little meaning as a function. It is like this.

Based on this deliverable, I think that it will be possible to increase the production of RippleAPI calls and connect with TensorFlow, and so on.

What is Ripple

It is a payment protocol that applies blockchain. Well, I think it will be a trendy technology. The head family is here.

Regarding the explanation of Ripple, Giant Gox's following site is very well organized. http://gtgox.com/

I think that you can understand the outline if you look at "What is Ripple" in ↑.

What is Ripple API?

Developer site is here. Below is a quote from it.

_Ripple's decentralized payment network is built on open source technology that is available to everyone. Here are the tools available to developers to create solutions on open source platforms. _

The Ripple API seems to be one of the "available tools" mentioned above, and it seems that you can access the Ripple server with JavaScript and move money.

The Ripple API runs on node_js and uses ECMAScript 6 (ES2015). In other words, it seems that you can access the system by executing it using babel-node.

See the following site for API specifications. https://ripple.com/build/rippleapi/

The script is written like this here. https://ripple.com/build/rippleapi/#boilerplate

This time, according to the above, we will use the API called getLedger to get the data called totalDrops. The API description is here. https://ripple.com/build/rippleapi/#getledger

Construction of execution environment

There is a Beginner's Guide for Ripple, so it's a good idea to look at it. Here are some supplements.

As I wrote in the explanation of API, you need an environment where node_js can be executed. I think there is a lot of information about setting up node_js, so I will omit it. When using RippleAPI, 0.12, 4.x or higher is required at the time of writing (August 2016), so please build such an environment.

I built it on MacOSX node_js 0.12.4.

If you make node_js work, it seems that you will be ready if you put babel in the following procedure (this is a sale of Beginner's Guide)

  1. Create a suitable folder and move it.
  2. Git init if needed (I didn't).
  3. Write package.json there. The contents can be found in the Beginner's Guide, so you can copy and paste it.
  4. If you do `npm install`, babel etc. will come in.
  5. As you can see in the guide, a Warning appears at the time of npm install, but it seems that you can feel "yes" there.

After that, you can write a JavaScript program and execute it as follows to make it work.

./node_modules/.bin/babel-node script name

Call Ripple API in JavaScript

This time, we only call one API, so the RIpple sample is almost the same. So I think it's easier to understand by looking at the code than by explaining it.

"use strict";
const RippleAPI = require("ripple-lib").RippleAPI;

const api = new RippleAPI({
  server: "Enter the URL of the Ripple API here" // Public rippled server
});

api.connect().then(() => {
  //The processing after connecting to Ripple Network is written here.

  //Specifically, it calls the API.
  return api.getLedger()

}).then(info => {

  //You will be here when the API processing is complete.
  // info(There is a return value (the name seems to be free).

  //This time, totalDrops is taken out and output.
  //→ This is defined in "Return Value" in the API documentation.
  //It's like passing the string that you put out to the console to Python.
  console.log(info.totalDrops);

}).then(() => {

  //Now that I've done it, I'm disconnecting from Ripple.
  return api.disconnect();

}).then(() => {

}).catch(console.error);

All you have to do is call the API, output the result in console.log and notify Python.

Enter the URL of the Ripple API in place of __server. __

You can find the URL at the following site. https://ripple.com/build/rippled-apis/#websocket-api

Or, since the URL is written in the sample below, I think that you can copy and paste from there. https://ripple.com/build/rippleapi/#boilerplate

In this article, I will proceed on the assumption that the above JavaScript is handled in the "get_totalDrops.js" file. If you execute it alone, the total Drops number will appear like this (it will take a few seconds to 10 seconds to appear)

$ ./node_modules/.bin//babel-node get_totalDrops.js 
99997222654452897

Call JavaScript from Python.

I wrote that, but this time it is a very sloppy method.

Since the data to be acquired this time is a number, it will be functionalized like this.

import commands

RIPPLE_API_COMMAND = "./node_modules/.bin//babel-node get_totalDrops.js"
def get_totalDrops():
    return long(commands.getoutput(RIPPLE_API_COMMAND))

Execute get_totalDrops.js which calls RIppleAPI with commands.getoutput. The result comes as a string. Since only the numerical value is output this time, it is converted to long and used as the return value.

This time there was only one return value, but if you want to return multiple results, you can use csv or something like this. For bulk data, I think we need another logic.

Python side specifications

This time

I will try all the steps. Therefore, I will try with the following requirements.

  1. Call RippleAPI / getLedger the specified number of times at the specified time.
  2. Calculate the difference from the previous time from the return value (totalDrops).
  3. Accumulate total Drops and differences.
  4. After calling the specified number of times, two CSV files will be generated based on the accumulated results.

This time I will try to output the result with R, so I will output the following two CSV files.

CSV for analysis parameters

Enter the start time and the interval (unit: seconds) of each data here. The following is an example.

time, by
2016/8/20 7:59, 300

The first line is the title, and the second line is the start time and interval.

Data CSV

Put the actual result (totalDrops and difference) here. The following is an example.

total, diff
99997224489730292,0
99997224488731486,998806
99997224487789148,942338
99997224487350204,438944
99997224486780979,569225

Similarly, the first line is the title, and from the second line, put in one after another with the feeling of totalDrops, difference. The above example is an example of 5 times.

Python side code

This is not so complicated, so I will post the code suddenly.

#!/usr/bin/python
# coding: UTF-8

import commands
import time
import datetime

# ---------You may change the following as appropriate.

#How many seconds to call the Ripple API
RIPPLE_WAIT_SECS   = 300

#How many times to call the RIpple API.
RIPPLE_NUM_OF_GET_TOTALDROPS = 10

# ---------

#Parameter CSV file name
RIPPLE_PARA_CSV_FILENAME = "ripple_para.csv"
#csv file name with totalDrops data and differences
RIPPLE_DROP_CSV_FILENAME = "ripple_drops.csv"
#Get made this time_totalDrops.js execution command operation
RIPPLE_API_COMMAND = "./node_modules/.bin//babel-node get_totalDrops.js"
#Line feed code definition
RIPPLE_CR = "\r\n"

#Call getLedger on the Ripple API. It returns with a numerical value.
def get_totalDrops():
    return long(commands.getoutput(RIPPLE_API_COMMAND))

#It's troublesome, so I made it into a class.
class RippleTotalDros:

    def __init__(self):
        self.total = long(0)
        self.diff = long(-1)
        self.start_time = ""
        self.drop_csv = ""
        self.para_csv = ""

    #String generation based on current time
    # need_seconed =True example: 2016/8/15 12:27:5
    # need_seconed =False example: 2016/8/15 12:27
    def get_date_time(self, need_second):
        d = datetime.datetime.today()
        text = str(d.year) + "/" + str(d.month) + "/" + str(d.day)
        text += " " + str(d.hour) + ":" + str(d.minute)
        if (need_second == True):
            text += ":" + str(d.second)
        return text

    #Calculate the difference from the return value (totalDrops) of getLedger
    #Save to each member variable
    def calc_drop_data(self, result):
        if self.diff >= 0:
            self.diff = self.total - result
        else:
            self.diff = 0
        self.total = result

    #CSV for parameter setting is a member variable para_Created in csv
    def make_para_csv(self):
        self.start_time = self.get_date_time(False)
        self.para_csv = "time, by" + RIPPLE_CR
        self.para_csv += self.start_time + "," + str(RIPPLE_WAIT_SECS) + RIPPLE_CR

    #Call RippleAPI to collect data
    #Call the API and create CSV data of the data based on the result.
    #This process takes a specified amount of time x a specified number of times, so it takes time.
    def collect_totalDrops(self):
        self.drop_csv = "total, diff" + RIPPLE_CR
        print "start to correct " + self.start_time
        for i in xrange(RIPPLE_NUM_OF_GET_TOTALDROPS):
            result = get_totalDrops()
            self.calc_drop_data(result)
            date_time = self.get_date_time(True)
            print i , " :" + date_time + " total=" , self.total , " diff=" , self.diff
            self.drop_csv += str(self.total) + "," + str(self.diff) + RIPPLE_CR
            if i < RIPPLE_NUM_OF_GET_TOTALDROPS - 1:
                time.sleep(RIPPLE_WAIT_SECS) #If it is the last, you can exit without waiting.

    #Make the created CSV file a file.
    def write_csv(self):
        f = open(RIPPLE_PARA_CSV_FILENAME, "w")
        f.write(self.para_csv)
        f.close()
        f = open(RIPPLE_DROP_CSV_FILENAME, "w")
        f.write(self.drop_csv)
        f.close()


# ---Main
print "Ripple Collet totalDrops."
ripple = RippleTotalDros()
ripple.make_para_csv()          #Parameter CSV data creation
ripple.collect_totalDrops()     #Data collection & CSV data creation
ripple.write_csv()              #Write CSV to file
print "Complete. csv -> " + RIPPLE_DROP_CSV_FILENAME

It was written by a person with low skills, so I think that you can understand the contents if you look at it while referring to w, comments, etc. In this example, run it about 10 times every 5 minutes.

As I wrote a while ago, it is assumed that get_totalDrops.js is placed in the same folder and there is an environment where both node_js & rippleAPI and python can be executed, so please be careful. When I run this Python, it looks like this:

$ python ./get_totalDrops.py 
Ripple Collet totalDrops.
start to correct 2016/8/21 13:7
0  :2016/8/21 13:8:1 total= 99997222541580190  diff= 0
1  :2016/8/21 13:13:33 total= 99997222534612330  diff= 6967860
2  :2016/8/21 13:19:6 total= 99997222528462961  diff= 6149369
3  :2016/8/21 13:24:36 total= 99997222523885100  diff= 4577861
4  :2016/8/21 13:30:4 total= 99997222514133479  diff= 9751621
5  :2016/8/21 13:35:36 total= 99997222505328424  diff= 8805055
6  :2016/8/21 13:41:7 total= 99997222500019477  diff= 5308947
7  :2016/8/21 13:46:37 total= 99997222496816135  diff= 3203342
8  :2016/8/21 13:52:5 total= 99997222493532687  diff= 3283448
9  :2016/8/21 13:57:35 total= 99997222488190979  diff= 5341708
Complete. csv -> ripple_drops.csv

In addition, you will have two CSV files, ripple_para.csv and ripple_drops.csv.

Check the result with R

I'm almost an amateur in Python, but R is more amateur (what this Japanese w). This time, it is more about confirming whether it can be visualized rather than a significant analysis. In creating the code, I referred to Mr. Okumura's site below.

https://oku.edu.mie-u.ac.jp/~okumura/stat/timeseries.html

__Plot data creation __

I made the original data of plot like this.

ripple.para = read.csv("ripple_para.csv")
ripple.by_csv = as.numeric(ripple.para[1,2])
ripple.start_time = as.character(ripple.para[1,1])

ripple.drops = read.csv("ripple_drops.csv")
ripple.matrix <- as.matrix(ripple.drops)

base_time = as.POSIXct(ripple.start_time)
time_scale = seq(base_time, by=ripple.by_csv,  along.with=ripple.matrix[,2])

In short, read csv and matrix the data. Since time is on the horizontal axis, it feels like I have adjusted it.

__total Drops visualization __

The plot of totalDrops looks like this. Since it is totalDrpos, diff, the y-axis is [, 1].

plot(time_scale, ripple.matrix[,1], type="o", pch=16, xlab="time(sec)", ylab="total drops")

The result is like this. totalDrops.PNG

The numbers are gradually dropping.

__ Visualization of differences __

The difference plot looks like this. Since it is totalDrpos, diff, the y-axis is [, 2].

plot(time_scale, ripple.matrix[,2], type="o", pch=16, xlab="time(sec)", ylab="drops")

The result is this. diff.PNG It's a difference, so it feels like it's working.

license

I used it below. Thank you for providing the wonderful software.

that's all.

Recommended Posts

[First Ripple] [I am] Call JavaScript (Node.js) from Python and process Ripple
I made a Docker image that can call FBX SDK Python from Node.js
[Python] I installed the game from pip and played it
Go language to see and remember Part 8 Call GO language from Python
Call CPLEX from Python (DO cplex)
I compared Java and Python!
Install mecab on Sakura shared server and call it from python
Simple code to call a python program from Javascript on EC2
I tried to make a periodical process with Selenium and Python
I compared Node.js and Python in creating thumbnails using AWS Lambda
I tried to deliver mail from Node.js and Python using the mail delivery service (SendGrid) of IBM Cloud!
Call Matlab from Python to optimize
Call a Python function from p5.js.
Call C from Python with DragonFFI
AM modulation and demodulation with python
Python, yield, return, and sometimes yield from
Call popcount from Ruby / Python / C #
Read and use Python files from Python
About Python, from and import, as
Python (from first time to execution)
I played with PyQt5 and Python3
Call python from nim with Nimpy
Compare Python and JavaScript array loops
Call C / C ++ from Python on Mac
Call c language from python (python.h)
C language to see and remember Part 2 Call C language from Python (argument) string
C language to see and remember Part 1 Call C language from Python (hello world)
C language to see and remember Part 4 Call C language from Python (argument) double
C language to see and remember Part 5 Call C language from Python (argument) Array