memorandums

日々の生活で問題解決したこと、知ってよかったことなどを自分が思い出すために記録しています。

写経:「paiza.IO の API を優しく触ってみる」

はじめに

ゼミ生と卒研テーマの打ち合わせをしていたところ、個人的に困ったこととしてプログラミングの学習を挙げてくれました。では、プログラミングを学ぶ環境を作ってみては?となりまして、とりあえずオンラインでプログラムを実行できる環境が必要となり調査してもらっていました。

オンラインジャッジシステムはOSSでもいくつか公開されていますが、素人が読むのはなかなか辛いようでして。。。まだまだ時間があるのでとりあえずやってみたら?といいたいところでしたが、まずは少しでも動かしてやる気を保ってもらいたいと思い、2人でやれそうな入口を調べていました。

オンラインコンパイラ?をいくつか発見しました。paiza IO APIとideoneです。ideoneは有料のようですのでとりあえずpaizaの方を使わせていただこうと。

とりあえず入門記事を探したところ、以下の素晴らしい記事を見つけました。非常にシンプルに書いてくださっています。

qiita.com

今日はオンラインで打ち合わせだったので、画面共有しながらサクッと動かして見せてあげました。pythonの実行環境を用意するのもあまりやったことがないようなのでちょっと戸惑っていましたができる範囲と思います。とりあえず、すぐに動かせたのでとりあえず忘れても思い出しやすいようにメモしておきます。

タイトルの通り、元ネタの要約版ですので(環境さえ合えばコピペで動かせる)。ご了承ください。ではスタート。

手順(paiza.IO API をとりあえず動かす)

環境は、macOS、pipenvです(pipenvのインストール手順はあちこちにあるのでご参照ください)

準備

まず、デスクトップあたりにaとか適当なディレクトリを作成して、その中に以下の2つのファイルを作ります。

paiza.py

#!/usr/bin/env python

import sys
import time

import requests

url = 'http://api.paiza.io'
# 実行する言語
language = sys.argv[1]
# 実行するファイルを読み込む
with open(sys.argv[2], 'r') as f:
    source = f.read()
# API に送る JSON を辞書で指定
params = {
    'source_code': source,
    'language': language,
    'input': '',
    'api_key': 'guest',
}
# /runners/create に POST リクエストを送る
response = requests.post(
    url + '/runners/create',
    json=params
)
id = response.json()['id']

time.sleep(2.0)

# API に送る JSON を辞書で指定
params = {
    'id': id,
    'api_key': 'guest',
}
# /runners/get_details に GET リクエストを送る
response = requests.get(
    url + '/runners/get_details',
    json=params
)
# 結果を辞書にする
result = response.json()

print('--stdout--')
print(result['stdout'])
print('--build_stderr--')
print(result['build_stderr'])
print('--stderr--')
print(result['stderr'])

hello.py

print('hello world')

実行

ターミナルを開き、以下のコマンドをコピペで実行します(デスクトップ直下にaというディレクトリがあり、上記の2つのファイルがその中に入っていることを前提とします)

cd ~/Desktop/a
chmod +x paiza.py
pipenv install requests
pipenv run ./paiza.py python hello.py

実行結果として以下のような表示がでれば成功です。

--stdout--
hello world

--build_stderr--
None
--stderr--

無料で使わせてもらえますが、サービスの保証はありませんとのことです。そりゃそうですね。。。ご厚意で公開してくれているのでしょうから。とらあえずこれで動かして何となくそれっぽいのができたら、コンパイルするところは自分で作って差し替えていけばいいような気がしますね。

はい。

■ちょい追記

pipenvで簡単に環境が構築できるとはいえバッテリーを入れなければ動かないpythonの良さと面倒さがあります。Rubyはmacに標準で入っているので(そのうち状況が変わりそうですが)、上記のコード(paiza.py)をRubyで書いてきました。こちらはmacであればpipenvなどの環境構築は不要です。あまりこういうプログラムを書かないので色々と引っかかって勉強になりました。エラー処理は何もしていません。とりあえず動けばいいという感じです(paizaさんに迷惑がかかるかな💦) それにしてもこういうAPI呼び出し系は開発者登録させてからトークンを取得してそのトークンをつけて呼び出す感じが多いのかなと思っていましたが、こちらは一度、あるURLにアクセスしてIDをゲットしてからそのIDをつけてAPIを呼び出す感じの設計でした。これってカッコいいですね。個人的にいいなと思いました。トークンの期限とか管理するの開発する人としても面倒だし。利用者が少ないからできることなのかな?とりあえず。

#!/usr/bin/env ruby

require 'uri'
require 'net/http'
require 'json'

url = 'http://api.paiza.io'

# 実行する言語
language = ARGV[0]

# 実行するファイルを読み込む
source = File.open(ARGV[1]).read

# API に送る JSON を辞書で指定
params = {
    'source_code': source,
    'language': language,
    'input': '',
    'api_key': 'guest',
}

# /runners/create に POST リクエストを送る
res = JSON.parse(Net::HTTP.post_form(URI(url + '/runners/create'), params).body)

id = res['id']

sleep(2.0)

# API に送る JSON を辞書で指定
params = {
    'id': res['id'],
    'api_key': 'guest',
}

# /runners/get_details に GET リクエストを送る
uri = URI(url + '/runners/get_details?' + URI.encode_www_form(params))
res = JSON.parse(Net::HTTP.get_response(uri).body)

puts('--stdout--')
puts(res['stdout'])
puts('--build_stderr--')
puts(res['build_stderr'])
puts('--stderr--')
puts(res['stderr'])