reticulate
얼마전에 reticulate
라는 라이브러리가 cran에 올라왔다. R Interface to Python이라는 짤막한 (하지만 강렬한!) 소개로 눈길을 끌었다. 이 라이브러리는 R에서 Python 모듈, 함수 등을 사용할 수 있도록 연동시키고 두 언어의 자료형을 변환시켜주는 역할을 한다. 정확하지는 않겠지만 단순하게 말하면 R에서 Python 코드를 바로 작성해버릴 수 있는 것이다.
flask on R
계기
R에서 flask를 돌려보겠다는 생각은 이렇게 시작되었다.
코딩은 R로 하고 싶지만 결과물을 웹으로 서빙할 때 shiny는 쓰기가 싫었다 (그냥). 또 웹서버는 flask가 손에 익어서 좋은데 막상 데이터 처리를 python으로 하는 것도 싫었다. (이것도 그냥.. pandas 종종 씁니다)
그런데 마침 얼마전에 공개된 reticulate
가 생각나 버렸다.
그래서 reticulate
를 가지고 R이 flask를 돌릴 수 있는지 확인해보기로 했다. 어짜피 실사용 목적으로 쓰지는 않을테니 /
페이지에 hello flask
문구를 띄울 수 있는지만 보기로 한다.
목표
목표는 다음과 같이 정했다.
아래 python 코드와 같은 구조로 R에서
reticulate
를 통해 작성한다.
웹브라우저에서 hello flask! 라는 문자열을 볼 수 있다면 성공!
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'hello flask!'
if __name__ == '__main__':
app.run()
삽질
우선 가장 먼저 접하게 된 난관은 데코레이터를 어떻게 적용하는가였다.
삽질 1
@app.route('/')
에 해당하는 데코레이터를 R에서 적용해야 했다. reticulate
의 vignettes 를 살펴보았지만 데코레이터에 대한 내용이 눈에 잘 띄지 않았다. 새벽시간이어서 빠르게 진행해야 잠을 잘 수 있다. 그래서 데코레이터는 버리고 다른 방법을 찾기로 했다.
flask의 api 문서 를 보다보니 app.add_url_rule
메서드를 쓰면 app.route
데코레이터를 대신할 수 있을 것 같다.
삽질2
index
부분을 구현하기 위해 함수를 만들어서 app$add_url_rule('/', index)
와 같은 형태로 구성했다.
그랬더니 app$run()
으로 서버는 뜨는데 자꾸 TypeError: argument of type 'function' is not iterable
와 같은 에러가 발생했다. iterable
이라는 에러 문구에 혹해서 reticulate
의 iterate
함수도 적용해보는 등 2차 삽질에 돌입했다. 하지만 허무하게도 파라미터 이름을 명시하지 않아서 엄한 위치에 index
함수가 들어가버린 문제로 밝혀진다.
그리고 그 결과.. 두둥
결과
hello flask! 문구를 브라우저에 띄우기 위해 사용한 R 코드는 다음과 같다.
library('reticulate')
flask = import('flask')
app = flask$Flask('__main__')
index = function() {return('hello flask!')}
app$add_url_rule('/', view_func = index)
app$run()
결론
실제로 이러한 목적으로 reticulate
를 사용하지는 않겠지만, 다양한 활용이 가능할 것으로 보인다.
그리고 자러가기 전에 궁금증을 해결할 수 있어서 다행이었다…
2017-05-26 내용 추가
위 코드는 다음과 같은 방식으로도 작성할 수 있다
library('reticulate')
flask = import('flask')
app = flask$Flask('__main__')
app$route('/')({
index = function() {return('hello flask!')}
})
app$run()