NAV Navigation
Shell HTTP JavaScript Ruby Python PHP Java Go

Yinyo v1.0

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

A wonderfully simple API driven service to reliably execute many long running scrapers in a super scaleable way

Base URLs:

Authentication

Core

The minimum you'll need to use

Create run

Code samples

# You can also use wget
curl -X POST http://localhost:8080/runs \
  -H 'Accept: application/json'

POST http://localhost:8080/runs HTTP/1.1
Host: localhost:8080
Accept: application/json


const headers = {
  'Accept':'application/json'

};

fetch('http://localhost:8080/runs',
{
  method: 'POST',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json'
}

result = RestClient.post 'http://localhost:8080/runs',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.post('http://localhost:8080/runs', headers = headers)

print(r.json())

 'application/json',
    
    );

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','http://localhost:8080/runs', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("http://localhost:8080/runs");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "http://localhost:8080/runs", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /runs

Returns with the "run name" which uniquely identifies this run and the "run token" which is a secret to ensure that only you can access the run from here on in. You will need these values to subsequently start, track and access this run.

You can optionally provide a suggested "name prefix" which will be put at the beginning of the unique name for the run. This is only useful to give more human meaningful names to the runs if that's important in your application. However, you can not depend on the prefix being used exactly as you provide it as some characters are not possible in run names.

Parameters

Name In Type Required Description
name_prefix query string false Prefix used when generating run names

Example responses

200 Response

{
  "name": "run-lvg44",
  "token": "bMMT7MnU2QbFZbk0lkut401D4uFScUI2"
}

Responses

Status Meaning Description Schema
200 OK Created successfully Inline

Response Schema

Status Code 200

Name Type Required Restrictions Description
» name string false none Uniquely identifies this run. Needed for any subsequent API calls for this run.
» token string false none Secret value needed to access the run

Upload the code to be run and any local data

Code samples

# You can also use wget
curl -X PUT http://localhost:8080/runs/{name}/app \
  -H 'Content-Type: application/gzip' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

PUT http://localhost:8080/runs/{name}/app HTTP/1.1
Host: localhost:8080
Content-Type: application/gzip
Accept: application/json

const inputBody = 'string';
const headers = {
  'Content-Type':'application/gzip',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'

};

fetch('http://localhost:8080/runs/{name}/app',
{
  method: 'PUT',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/gzip',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.put 'http://localhost:8080/runs/{name}/app',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/gzip',
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.put('http://localhost:8080/runs/{name}/app', headers = headers)

print(r.json())

 'application/gzip',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
    
    );

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('PUT','http://localhost:8080/runs/{name}/app', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("http://localhost:8080/runs/{name}/app");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PUT");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/gzip"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
        
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PUT", "http://localhost:8080/runs/{name}/app", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PUT /runs/{name}/app

Take your directory with code, configuration and data to run. Tar and gzip compress it. Then use this to upload it to Yinyo.

If you're familiar with Heroku, you'll be familiar with the way different languages are recognised and compiled because Yinyo also uses the same underlying open source technology, Buildpacks.

For different languages you'll need to include different files that tell Yinyo what language you're using as well as which version of the language you want and which libraries you want installed.

Python

For Python include requirements.txt in the root of your code directory. pip automatically uses this file to install your required libraries.

For more information visit the Heroku Python documentation

Node.js / Javascript

For Node.js include package.json in the root of your code directory. npm then automatically installs required libraries from this file.

For more information visit the Heroku Node.js documentation

Ruby

For Ruby include Gemfile and Gemfile.lock in the root of your code directory. bundler installs your dependencies.

For more information visit the Heroku Ruby documentation

PHP

For PHP include composer.json and composer.lock in the root of your code directory. Composer installs your libraries.

For more information visit the Heroku PHP documentation

Perl

For Perl include cpanfile.

As this is a non-Heroku third-party buildpack no Heroku developer documentation is available. Instead take a look at the GitHub repo for the buildpack.

Body parameter

Parameters

Name In Type Required Description
name path string true The run name (as returned by creating a run)
body body string(binary) true none

Example responses

403 Response

{
  "error": "string"
}

Responses

Status Meaning Description Schema
200 OK Success None
403 Forbidden The run token was incorrect Error
404 Not Found Not found Error

Start the run

Code samples

# You can also use wget
curl -X POST http://localhost:8080/runs/{name}/start \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST http://localhost:8080/runs/{name}/start HTTP/1.1
Host: localhost:8080
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "output": "string",
  "env": [
    {
      "name": "string",
      "value": "string"
    }
  ],
  "callback": "http://example.com",
  "max_run_time": 0
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'

};

fetch('http://localhost:8080/runs/{name}/start',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post 'http://localhost:8080/runs/{name}/start',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.post('http://localhost:8080/runs/{name}/start', headers = headers)

print(r.json())

 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
    
    );

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','http://localhost:8080/runs/{name}/start', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("http://localhost:8080/runs/{name}/start");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
        
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "http://localhost:8080/runs/{name}/start", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /runs/{name}/start

Body parameter

{
  "output": "string",
  "env": [
    {
      "name": "string",
      "value": "string"
    }
  ],
  "callback": "http://example.com",
  "max_run_time": 0
}

Parameters

Name In Type Required Description
name path string true The run name (as returned by creating a run)
body body object false none
» output body string false Optional relative path (from the directory of the code for the run) to file you want access to later. This will usually be the output of the run.
» env body [Env] false Optionally set environment variables for the run.
»» name body string false Name of the environment variable
»» value body string false Value of the environment variable
» callback body string(uri) false Optionally provide a callback URL. For every event a POST to the URL will be made. To be able to authenticate the callback you'll need to specify a secret in the URL. Something like http://my-url-endpoint.com?key=special-secret-stuff would do the trick
» max_run_time body integer false Optionally set the maximum number of seconds the run is allowed to go for. If it exceeds this it will be automatically stopped.

Example responses

400 Response

{
  "error": "string"
}

Responses

Status Meaning Description Schema
200 OK Success None
400 Bad Request There was a problem with your request Error
403 Forbidden The run token was incorrect Error
404 Not Found Not found Error

Finalise scraper run

Code samples

# You can also use wget
curl -X DELETE http://localhost:8080/runs/{name} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

DELETE http://localhost:8080/runs/{name} HTTP/1.1
Host: localhost:8080
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'

};

fetch('http://localhost:8080/runs/{name}',
{
  method: 'DELETE',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.delete 'http://localhost:8080/runs/{name}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.delete('http://localhost:8080/runs/{name}', headers = headers)

print(r.json())

 'application/json',
    'Authorization' => 'Bearer {access-token}',
    
    );

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('DELETE','http://localhost:8080/runs/{name}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("http://localhost:8080/runs/{name}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("DELETE");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
        
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "http://localhost:8080/runs/{name}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /runs/{name}

This does final clean up of everything associated with a run. Make sure you always do this as the last API call for a run. After doing this it's not possible to get any more information about this run.

Parameters

Name In Type Required Description
name path string true The run name (as returned by creating a run)

Example responses

403 Response

{
  "error": "string"
}

Responses

Status Meaning Description Schema
200 OK Success None
403 Forbidden The run token was incorrect Error
404 Not Found Not found Error

Optional

Get access to more information about runs

Upload a build cache

Code samples

# You can also use wget
curl -X PUT http://localhost:8080/runs/{name}/cache \
  -H 'Content-Type: application/gzip' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

PUT http://localhost:8080/runs/{name}/cache HTTP/1.1
Host: localhost:8080
Content-Type: application/gzip
Accept: application/json

const inputBody = 'string';
const headers = {
  'Content-Type':'application/gzip',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'

};

fetch('http://localhost:8080/runs/{name}/cache',
{
  method: 'PUT',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/gzip',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.put 'http://localhost:8080/runs/{name}/cache',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/gzip',
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.put('http://localhost:8080/runs/{name}/cache', headers = headers)

print(r.json())

 'application/gzip',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
    
    );

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('PUT','http://localhost:8080/runs/{name}/cache', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("http://localhost:8080/runs/{name}/cache");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PUT");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/gzip"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
        
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PUT", "http://localhost:8080/runs/{name}/cache", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PUT /runs/{name}/cache

Body parameter

Parameters

Name In Type Required Description
name path string true The run name (as returned by creating a run)
body body string(binary) true none

Example responses

400 Response

{
  "error": "string"
}

Responses

Status Meaning Description Schema
200 OK Success None
400 Bad Request There was a problem with your request Error
403 Forbidden The run token was incorrect Error
404 Not Found Not found Error

Download a build cache

Code samples

# You can also use wget
curl -X GET http://localhost:8080/runs/{name}/cache \
  -H 'Accept: application/gzip' \
  -H 'Authorization: Bearer {access-token}'

GET http://localhost:8080/runs/{name}/cache HTTP/1.1
Host: localhost:8080
Accept: application/gzip


const headers = {
  'Accept':'application/gzip',
  'Authorization':'Bearer {access-token}'

};

fetch('http://localhost:8080/runs/{name}/cache',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/gzip',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'http://localhost:8080/runs/{name}/cache',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/gzip',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('http://localhost:8080/runs/{name}/cache', headers = headers)

print(r.json())

 'application/gzip',
    'Authorization' => 'Bearer {access-token}',
    
    );

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','http://localhost:8080/runs/{name}/cache', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("http://localhost:8080/runs/{name}/cache");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/gzip"},
        "Authorization": []string{"Bearer {access-token}"},
        
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://localhost:8080/runs/{name}/cache", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /runs/{name}/cache

Parameters

Name In Type Required Description
name path string true The run name (as returned by creating a run)

Example responses

200 Response

403 Response

{
  "error": "string"
}

Responses

Status Meaning Description Schema
200 OK Success string
403 Forbidden The run token was incorrect Error
404 Not Found Not found Error

Attach to run events stream

Code samples

# You can also use wget
curl -X GET http://localhost:8080/runs/{name}/events \
  -H 'Accept: application/ld+json' \
  -H 'Authorization: Bearer {access-token}'

GET http://localhost:8080/runs/{name}/events HTTP/1.1
Host: localhost:8080
Accept: application/ld+json


const headers = {
  'Accept':'application/ld+json',
  'Authorization':'Bearer {access-token}'

};

fetch('http://localhost:8080/runs/{name}/events',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/ld+json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'http://localhost:8080/runs/{name}/events',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/ld+json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('http://localhost:8080/runs/{name}/events', headers = headers)

print(r.json())

 'application/ld+json',
    'Authorization' => 'Bearer {access-token}',
    
    );

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','http://localhost:8080/runs/{name}/events', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("http://localhost:8080/runs/{name}/events");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/ld+json"},
        "Authorization": []string{"Bearer {access-token}"},
        
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://localhost:8080/runs/{name}/events", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /runs/{name}/events

Watch what is happening to a run in real-time as it gets built and runs. By default this will stream all events that have occurred from the very beginning until now and then as new events occur stream those in real-time.

Parameters

Name In Type Required Description
name path string true The run name (as returned by creating a run)
last_id query string false Restart stream immediately after the event with the given ID

Example responses

200 Response

{
  "id": "123",
  "time": "2019-12-17T03:45:00Z",
  "type": "log",
  "data": {
    "stage": "build",
    "stream": "stdout",
    "text": "Hello!"
  }
}

403 Response

{
  "error": "string"
}

Responses

Status Meaning Description Schema
200 OK Succesfully attached to stream Inline
403 Forbidden The run token was incorrect Error
404 Not Found Not found Error

Response Schema

Enumerated Values

Property Value
stage build
stage run
stream stdout
stream stderr
stream interr
stage build
stage run
stage build
stage run

Find out whether the run has finished and if so also return exit codes and usage metrics

Code samples

# You can also use wget
curl -X GET http://localhost:8080/runs/{name}/exit-data \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET http://localhost:8080/runs/{name}/exit-data HTTP/1.1
Host: localhost:8080
Accept: application/json


const headers = {
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'

};

fetch('http://localhost:8080/runs/{name}/exit-data',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'http://localhost:8080/runs/{name}/exit-data',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('http://localhost:8080/runs/{name}/exit-data', headers = headers)

print(r.json())

 'application/json',
    'Authorization' => 'Bearer {access-token}',
    
    );

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','http://localhost:8080/runs/{name}/exit-data', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("http://localhost:8080/runs/{name}/exit-data");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
        
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://localhost:8080/runs/{name}/exit-data", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /runs/{name}/exit-data

Returns a rag-bag of useful information about the progress and completion of a run. Find out whether the run has finished and if so find out whether the scraper ran succesfully or not. Also returns information about how much resources the run took.

Parameters

Name In Type Required Description
name path string true The run name (as returned by creating a run)

Example responses

200 Response

{
  "build": {
    "exit_code": 0,
    "usage": {
      "wall_time": 0,
      "cpu_time": 0,
      "max_rss": 0,
      "network_in": 0,
      "network_out": 0
    }
  },
  "run": {
    "exit_code": 0,
    "usage": {
      "wall_time": 0,
      "cpu_time": 0,
      "max_rss": 0,
      "network_in": 0,
      "network_out": 0
    }
  },
  "finished": true
}

Responses

Status Meaning Description Schema
200 OK Success ExitData
403 Forbidden The run token was incorrect Error
404 Not Found Not found Error

Get output file

Code samples

# You can also use wget
curl -X GET http://localhost:8080/runs/{name}/output \
  -H 'Accept: application/octet-stream' \
  -H 'Authorization: Bearer {access-token}'

GET http://localhost:8080/runs/{name}/output HTTP/1.1
Host: localhost:8080
Accept: application/octet-stream


const headers = {
  'Accept':'application/octet-stream',
  'Authorization':'Bearer {access-token}'

};

fetch('http://localhost:8080/runs/{name}/output',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/octet-stream',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'http://localhost:8080/runs/{name}/output',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/octet-stream',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('http://localhost:8080/runs/{name}/output', headers = headers)

print(r.json())

 'application/octet-stream',
    'Authorization' => 'Bearer {access-token}',
    
    );

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','http://localhost:8080/runs/{name}/output', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("http://localhost:8080/runs/{name}/output");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/octet-stream"},
        "Authorization": []string{"Bearer {access-token}"},
        
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "http://localhost:8080/runs/{name}/output", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /runs/{name}/output

Usually at the end of the run you want to grab the contents of a file which is probably the result of scraping. This allows you to do that. The path to the file needs to be given when the run is started.

Parameters

Name In Type Required Description
name path string true The run name (as returned by creating a run)

Example responses

200 Response

403 Response

{
  "error": "string"
}

Responses

Status Meaning Description Schema
200 OK Success string
403 Forbidden The run token was incorrect Error
404 Not Found Not found Error

Schemas

Error

{
  "error": "string"
}

Properties

Name Type Required Restrictions Description
error string false none none

Env

{
  "name": "string",
  "value": "string"
}

Properties

Name Type Required Restrictions Description
name string false none Name of the environment variable
value string false none Value of the environment variable

Stage

"build"

The stage of the life-cycle of the run

Properties

Name Type Required Restrictions Description
anonymous string false none The stage of the life-cycle of the run

Enumerated Values

Property Value
anonymous build
anonymous run

ExitData

{
  "build": {
    "exit_code": 0,
    "usage": {
      "wall_time": 0,
      "cpu_time": 0,
      "max_rss": 0,
      "network_in": 0,
      "network_out": 0
    }
  },
  "run": {
    "exit_code": 0,
    "usage": {
      "wall_time": 0,
      "cpu_time": 0,
      "max_rss": 0,
      "network_in": 0,
      "network_out": 0
    }
  },
  "finished": true
}

Properties

Name Type Required Restrictions Description
build ExitDataStage false none none
run ExitDataStage false none none
finished boolean false none True if the run has finished either by running succesfully or by failing in the build or run stage. This occurs when the "last" event is sent.

ExitDataStage

{
  "exit_code": 0,
  "usage": {
    "wall_time": 0,
    "cpu_time": 0,
    "max_rss": 0,
    "network_in": 0,
    "network_out": 0
  }
}

Properties

Name Type Required Restrictions Description
exit_code number false none Process exit code for build or run. If there was no error this should be 0.
usage Usage false none Resources used by a process. This information is recorded as part of the metrics for a run.

Usage

{
  "wall_time": 0,
  "cpu_time": 0,
  "max_rss": 0,
  "network_in": 0,
  "network_out": 0
}

Resources used by a process. This information is recorded as part of the metrics for a run.

Properties

Name Type Required Restrictions Description
wall_time number false none Wall clock (in seconds)
cpu_time number false none Total time spent executing by the CPU.
It's the sum of time spent in user and kernel mode (in seconds)
max_rss integer false none This is the maximum resident set size used (in bytes)
network_in integer false none Total received network traffic (in bytes)
network_out integer false none Total transmitted network traffic (in bytes)

Event

{
  "id": "string",
  "type": "string",
  "time": "2020-01-30T02:51:51Z"
}

Properties

Name Type Required Restrictions Description
id string true none none
type string true none none
time string(date-time) true none Date and time of event

StartEvent

{
  "id": "string",
  "type": "string",
  "time": "2020-01-30T02:51:51Z",
  "data": {
    "stage": "build"
  }
}

Signals the start of a stage

Properties

allOf - discriminator: Event.type

Name Type Required Restrictions Description
anonymous Event false none none

and

Name Type Required Restrictions Description
anonymous object false none none
» data object false none none
»» stage Stage false none The stage of the life-cycle of the run

FinishEvent

{
  "id": "string",
  "type": "string",
  "time": "2020-01-30T02:51:51Z",
  "data": {
    "stage": "build",
    "exit_data": {
      "exit_code": 0,
      "usage": {
        "wall_time": 0,
        "cpu_time": 0,
        "max_rss": 0,
        "network_in": 0,
        "network_out": 0
      }
    }
  }
}

Signals the end of a stage

Properties

allOf - discriminator: Event.type

Name Type Required Restrictions Description
anonymous Event false none none

and

Name Type Required Restrictions Description
anonymous object false none none
» data object false none none
»» stage Stage false none The stage of the life-cycle of the run
»» exit_data ExitDataStage false none none

LastEvent

{
  "id": "string",
  "type": "string",
  "time": "2020-01-30T02:51:51Z"
}

Signals the completion of the whole run

Properties

None

LogEvent

{
  "id": "string",
  "type": "string",
  "time": "2020-01-30T02:51:51Z",
  "data": {
    "stage": "build",
    "stream": "stdout",
    "text": "string"
  }
}

Console output event (from run)

Properties

allOf - discriminator: Event.type

Name Type Required Restrictions Description
anonymous Event false none none

and

Name Type Required Restrictions Description
anonymous object false none none
» data object false none none
»» stage Stage false none The stage of the life-cycle of the run
»» stream string false none Source of the message - standard output and standard error come from your code. In exceptional circumstances you might see a message from "internal error".
»» text string false none Console message

Enumerated Values

Property Value
stream stdout
stream stderr
stream interr