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
- HTTP Authentication, scheme: bearer
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 |