Python/Bottle

[Python web framework: Bottle] 3. Routing 1 - 동적 라우트

컴닥 2019. 8. 31. 08:13
반응형

1. 2중으로 라우트를 할 수 있습니다. 

이제 http://localhost:8080/ 으로도 "Hello World!"를 볼 수 있습니다. 

from bottle import route, run


@route('/')  # 1
@route('/hello')
def hello():
    return "Hello World!"


run(host='localhost', port=8080, debug=True)

#1: route() 데코레이터를 2중으로 겹쳐 사용할 수 있습니다. bottle의 라우트 개념은 아주 직관적입니다. ㅎㅎㅎ. 브라우저로 어떤 주소의 요청을 하면 route() 데코레이터가 해당되는 함수를 연결해줍니다. 

 

* 자세히 알 필요는 없지만 데코레이터 자체는 함수이며 뒤에 따라오는 함수의 앞(이나 뒤)에서 뭔가를 추가로 실행해주는 기능을 합니다. 이때 뒤 따르는 함수를 콜백 함수라고 부릅니다. 콜백 함수는 '앞 함수의 끝 부분에서 호출되는' 함수라고 문자 그대로 이해해도 될 것 같습니다. 

 

2. 동적 라우트

wildcard를 가지는 라우트를 동적 라우트라고 합니다. 여기서는 #1의 <name>이 와일드카드입니다. 

* 와일드카드(wildcard)는 카드 게임에서 다른 카드들로 변신이 가능한 만능 카드(?)에서 유래된 개념일 겁니다. 아니면 말고!

from bottle import route, run


@route('/hello/<name>')  # 1
def greet(name):  # 2
    return f'Hello {name}, how are you?'  # 3


run(host='localhost', port=8080, debug=True)

#1: <name>은 와일드카드이며 변수와 비슷한 역할을 합니다. 

#2: name 와일드카드는 콜백 함수의 매개변수로 사용될 수 있습니다.

       * 사용되어야 합니다. 뒷 함수에 전달 안되면 뭐에 쓰겠습니까?

#3: 전달 받은 와일드카드를 문자열 포매팅에 사용했습니다.

       * 파이썬 3.6버전부터 지원하는 f포매팅을 이용했습니다. 쌔~ 기술이라 그런지 깔끔합니다. 

 

브라우저로 확인해 봅니다. 

http://localhost:8080/hello/min

Hello min, how are you?

만약 http://localhost:8080/hello 나 http://localhost:8080/hello/ 로 접속하면 에러가 나옵니다. 

Error: 404 Not Found
Sorry, the requested URL 'http://localhost:8080/hello/' caused an error:
Not found: '/hello/'

디폴트 값이 필요하겠죠? 

from bottle import route, run


@route('/hello/<name>')
def greet(name='Stranger'):  # 1
    return f'Hello {name}, how are you?'


run(host='localhost', port=8080, debug=True)

#1: 파이썬에서는 '매개변수 = 디폴트 값' 형식으로 디폴트 값을 지정할 수 있습니다. 

 

그런데 여전히 http://localhost:8080/hello 나 http://localhost:8080/hello/ 로 접속하면 에러가 나옵니다. 

이것은 '/hello'나 '/hello/'를 받아줄 라우트 데코레이터가 없기 때문입니다. 

* Bottle에서는 /hello와 /hello/가 다른 URL임을 기억해야 합니다. 마이크로 웹 프레임워크라 저런 걸 자동으로 처리해 주지 않습니다. 

from bottle import route, run


@route('/hello')  # 1
@route('/hello/')  # 2
@route('/hello/<name>')
def greet(name='Stranger'):
    return f'Hello {name}, how are you?'


run(host='localhost', port=8080, debug=True)

2개의 와일드카드를 사용할 수도 있습니다. 

@route('/<action>/<user>')
def user_api(action, user):
    ...

와일드카드에 필터를 걸 수도 있습니다. 

<name:filter> or <name:filter:config>
@route('/object/<id:int>')
def callback(id):
    assert isinstance(id, int)

@route('/show/<name:re:[a-z]+>')
def callback(name):
    assert name.isalpha()

@route('/static/<path:path>')
def callback(path):
    return static_file(path, ...)

필터는 4가지 입니다. 

정수, 실수(소수점을 가지는), 경로, 그리고 정규표현식~! 정규표현식이 지원되기 때문에 필요한 필터가 있다면 직접 만들 수 있습니다. 

  • :int matches (signed) digits only and converts the value to integer.
  • :float similar to :int but for decimal numbers.
  • :path matches all characters including the slash character in a non-greedy way and can be used to match more than one path segment.
  • :re allows you to specify a custom regular expression in the config field. The matched value is not modified.

assert는 뒤에 조건식이 false면 예외를 발생합니다. 테스트 시 'if'문보다 깔끔하기 때문에 많이 사용합니다. 

isinstance는 해당 인스턴스가 맞는지 확인하는 함수입니다.

파이썬 내장 함수 중 isdecimal을 써도 괜찮을 것 같네요. 파이썬의 숫자 판별 함수는 https://soooprmx.com/archives/10159 를 참고하시면 좋겠네요. 

isalpha함수는 문자열인지 확인해주는 함수입니다. 

반응형