반응형

Server OS: Ubuntu 16.04

Flask, Python 3.5.2

Browser: Mozilla Firefox


Flask를 써서 웹페이지로부터 GET, POST 등의 요청(request) 처리하는 코드를 만들었는데, 이상하게 웹페이지에서 form을 이용해서 POST 요청을 보낼 때마다 화면에 400 에러만 나오고 실행이 되지 않았다. 브라우저 화면에 출력되는 자세한 메세지는 다음과 같다:


400 Bad request. The browser (or proxy) sent a request that this server could not understand.


이 경우는 서버의 flask에서 받아들여야 하는 POST parameter가 없을 때 발생한다. 웹페이지의 form에서 실제로 만들어서 submit하는 name과 value의 조합 중에서, 정작 flask에서 실제로 파싱해야 하는 파라미터의 값이 없는 경우이다.


따라서 웹페이지에서 사용자 입력을 통해서 만들어 보내는 form에서 전송하는 파라미터 이름의 목록과 flask에서 request.form['파라미터_이름']으로 받아들이는 목록이 일치하는지 확인하자.



반응형
블로그 이미지

Bryan_

,
반응형

Tools: flask, Jinja2, python 3.5.2


플라스크(flask)에서 웹페이지 템플릿 엔진으로 Jinja2를 쓰는데, flask에서 넘겨 주는 데이터의 값은 분명히 숫자인데 다른 숫자 변수와 단순 비교(==)로 안되는 것이었다. 아마 스트링으로 바뀐 것 같은데, int(변수명)이 Jinja2에서는 안 된다.


Jinja2 에서 변수의 데이터 타입 캐스팅을 하려면 변수명 뒤에 vertical bar(수직선) 문자( | )를 쓰고 데이터 타입을 명시하면 된다.


만약 flask에서 넘겨 주는 변수가 아래와 같다면,

my_var = '1234'


html 파일에서는 아래와 같이 정수로 바꿀 수 있다.

{{ my_var|int }}


이제 숫자로 비교할 수 있다.

{% if my_var|int == 1234 %}

    <div> my_var 의 값은 1234입니다. </div>

{% endif %}




반응형
블로그 이미지

Bryan_

,
반응형

OS: Ubuntu 14.04 (amd64)

python version: 2.7.6


파이썬에서 firebase에 접근하는 코드를 테스트하던 중에 아래와 같이 경고 메세지가 길게 출력이 되면서 어쨌든 실행은 정상적으로 되었다:

usera@usera-Linux:~/git/firebase_test$ python test2.py 

/usr/local/lib/python2.7/dist-packages/urllib3/util/ssl_.py:339: SNIMissingWarning: An HTTPS request has been made, but the SNI (Subject Name Indication) extension to TLS is not available on this platform. This may cause the server to present an incorrect TLS certificate, which can cause validation failures. You can upgrade to a newer version of Python to solve this. For more information, see https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings

  SNIMissingWarning

/usr/local/lib/python2.7/dist-packages/urllib3/util/ssl_.py:137: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. You can upgrade to a newer version of Python to solve this. For more information, see https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings

  InsecurePlatformWarning

{요청했던 데이터}

usera@usera-Linux:~/git/firebase_test$ 


SSL 관련 라이브러리가 없어서 그런가 해서 pip install pyopenssl 설치를 시도해 보니 이미 설치되어 있었다.


인터넷을 뒤져 보니 사용하는 라이브러리의 버전이 낮아서 그럴 수도 있다는 댓글이 있어서 pyopenssl을 업그레이드 했더니 그 뒤로 경고 메세지가 뜨지 않고 문제가 해결되었다.


$ pip install pyopenssl --upgrade





반응형
블로그 이미지

Bryan_

,
반응형

OS: Ubuntu 16.04 server (amd64)

Python: 3.5.2

Flask-restful: 0.3.5


Flask-restful을 이용하면 하나의 클래스가 REST API 1개를 처리할 수 있도록 만들 수 있다. 처음에는 Quickstart 페이지에 있는 HelloWorld 예제 [1]를 따라하면서 API 여러 개를 만들면서 클래스도 여러 개 만들고, 각 클래스에서 argument 처리 등 점점 복잡한 작업을 추가하기 시작하면서 소스 파일이 1개뿐이면서 길이가 아주 많이 길어지는 상황이 되었다.


하나의 소스 파일이 너무 길면 보기도 불편하고, 무엇보다 여러 사람이 REST API를 조금씩 나눠서 병렬적으로 코딩하는 경우에는 하나의 파일에 동시에 수정이 발생하므로 협업 측면에서도 관리하기 어렵다. 따라서 여러 개의 파일로 나눠서 관리하는 것이 좋다. 사실 어떻게 나눠야 할 지 모르겠어서 고민하다가, 그냥 파이썬이 클래스를 다른 소스 파일에서 import해 오는 구조를 그대로 쓰기만 하면 되는 간단한 원리임을 알 수 있었다.


예를 들면, 아래와 같은 HelloWorld 예제를 main.py로 두고,


<main.py>

from flask import Flask

from flask_restful import Resource, Api


app = Flask(__name__)

api = Api(app)


class HelloWorld(Resource):

    def get(self):

        return {'hello': 'world'}


api.add_resource(HelloWorld, '/')


if __name__ == '__main__':

    app.run(debug=True)



여기서 main.py는 서버를 실행하는 시작 포인트로만 쓰고 실제 REST API 처리하는 부분을 분리한다면, 아래와 같이 할 수 있다.


<hello.py>

from flask_restful import Resource


class HelloWorld(Resource):

    def get(self):

        return {'hello': 'world'}



<main.py>

from flask import Flask

from flask_restful import Resource, Api

from hello import HelloWorld


app = Flask(__name__)

api = Api(app)


api.add_resource(HelloWorld, '/')


if __name__ == '__main__':

    app.run(debug=True)


이제 main.py 파일에서는 클래스를 import하고 API 정의만 나열해 주고, 실제 API 처리 파일은 hello.py에서 수정하는 구조가 되었다.



<참고자료>

[1] Flask-RESTful Quickstart, http://flask-restful.readthedocs.io/en/0.3.5/quickstart.html



반응형
블로그 이미지

Bryan_

,
반응형

OS: Ubuntu Server 16.04.2 (amd64)


우분투 서버 16.04를 설치하고 나면 기본으로 python3가 같이 설치되어 있는데, 쉘에서 python과 pip (파이썬 패키지 설치 도구)는 작동하지 않고 python3, pip3만 작동한다.


Bash 쉘을 쓸 경우, alias로 등록하는 것이 가장 간단하다.

~/.bash_aliases 파일을 만들고, 아래 내용을 작성한다.


alias python=python3

alias pip=pip3

alias sudo='sudo '


위와 같이 작성하여 저장하고 bash shell에 다시 로그인하면 된다.

마지막에 sudo를 추가하는 이유는 저게 없이 sudo pip install ... 명령을 치면 pip를 alias로 인식하지 못하기 때문이다.



반응형
블로그 이미지

Bryan_

,