Flask on R (w. reticulate)

by Minho Lee — on  ,  , 

cover-image

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에서 적용해야 했다. reticulatevignettes 를 살펴보았지만 데코레이터에 대한 내용이 눈에 잘 띄지 않았다. 새벽시간이어서 빠르게 진행해야 잠을 잘 수 있다. 그래서 데코레이터는 버리고 다른 방법을 찾기로 했다.

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 이라는 에러 문구에 혹해서 reticulateiterate 함수도 적용해보는 등 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()

Comments