WSGI 가 뭐 예요?

7604 단어 pythonwebappserver
WSGI 가 뭐 예요?
        한두 달 을 더 듬 었 지만 아직 잘 알 지 못 했다.WSGI 가 얼마나 복잡 한 지 알 지 못 한 이 유 는 WSGI 의 프레임 워 크 (예 를 들 어 Django) 와 응용 서비스 (예 를 들 어 openstack) 가 너무 복잡 하 다 는 것 이다.게다가 이들 은 보조 적 인 Lib 라 이브 러 리 (예 를 들 어 Route, webob, eventlet 등) 를 사용 하여 학습 이 너무 복잡 하 다.본능 적 인 호기심 으로 인해 코드 를 볼 때 모 르 는 라 이브 러 리 를 만 났 고 모 르 는 함수 도 계속 할 수 없 으 며 끝까지 생각해 보 았 다.그러나 이런 호기심 은 게 으 름 에 게 좋 은 인 터 페 이 스 를 주 었 다. 모 르 는 함수 에 부 딪 힐 때마다 관련 문 서 를 찾 아 간다. 보통 영어 로 되 어 있 는데 보면 모 르 고 중국 어 를 보면 조금 알 고 멍 하 게 있다. 왜 그런 지 모르겠다.그리고 밥 먹고 잘 수 있어...자, 주제 로 돌아 가자!
        WSGI (Web Server Gateway Interface) 는 python 으로 작 성 된 웹 app 과 웹 server 간 인터페이스 형식 을 정의 하여 웹 app 과 웹 server 간 의 디 결합 을 실현 하 는 규범 입 니 다.WSGI 는 2003 년 에 python 으로 웹 애플 리 케 이 션 을 만 들 었 습 니 다. 웹 애플 리 케 이 션 자체 의 구조 와 기능 뿐만 아니 라 웹 서버 의 선택 도 고려 해 야 합 니 다. 서로 다른 웹 서버 가 웹 애플 리 케 이 션 에 제공 하 는 인터페이스 가 다 르 기 때 문 입 니 다.웹 서버 에 특정 웹 앱 을 썼 다 면 다른 웹 서버 를 통 해 발표 하기 어 려 울 것 입 니 다. 그렇지 않 으 면 많은 수정 과 디 버 깅 이 필요 합 니 다.WSGI 의 등장 은 이러한 어려움 을 해결 하기 위해 서 입 니 다. 웹 server 와 웹 app 이 모두 WSGI 규범 을 따 르 면 웹 app 의 작성 은 웹 server 의 영향 을 고려 하지 않 아 도 모든 웹 server 를 통 해 발표 되 고 디 결합 을 실현 할 수 있 습 니 다.
        위 에서 언급 한 웹 서버 와 웹 앱 은 모두 WSGI 규범 을 따라 야 한다. 그러면 WSGI 는 반드시 웹 서버 의 인터페이스 규범 과 웹 앱 의 인터페이스 규범 을 포함 할 것 이다.이 두 개의 인터페이스 규범 을 제외 하고 Middleware 규범 도 포함 되 어 있 으 므 로 무시 할 수 있 습 니 다.웹 서버 의 인터페이스 규범 은 웹 서버 가 실 현 될 때 고려 해 야 할 것 입 니 다.웹 앱 을 실현 할 때 앱 엔 드 인터페이스 규범 을 따라 야 합 니 다. 그러나 url 의 배포, 대형 웹 앱 의 복잡 함 과 소형 웹 앱 의 재 활용 성 을 고려 하여 현재 직접 발 표 된 웹 앱 을 직접 작성 하 는 사람 이 별로 없습니다. Flask, pecan 과 같은 프레임 워 크 를 사용 하여 웹 앱 을 실현 하 는 것 은 기본적으로 WSGI 를 고려 하지 않 아 도 됩 니 다.다행히 WSGI 는 비교적 간단 해서 호기심 을 만족 시 키 는 대가 가 크 지 않다.
웹 app 엔 드 인터페이스 규범
        웹 app 은 실제 python 호출 가능 한 대상 (함수, 호출 가능 한 인 스 턴 스, class 등) 입 니 다. HTTP 요청 이 있 을 때 이 대상 은 호출 됩 니 다.웹 app 엔 드 인터페이스 규범 은 이 대상 의 매개 변 수 를 어떻게 생 겼 는 지 규정 합 니 다. 그 반환 결 과 는 어떻게 생 겼 습 니까?이 대상 함수 의 이름과 기능 이 어떤 지 에 대해 서 는 상관없다.쉽게 말 하면 WSGI 는 처리 함수 의 입 출력 형식 을 규정 한 것 이다.다음은 간단 한 웹 앱 인터페이스 가 어떻게 올 랐 는 지 살 펴 보 겠 습 니 다!
def simple_app(environ, start_response):
    """Simplest possible application object"""
    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)
    return ['Hello world!
']
       웹 app 은 두 개의 인자 environ 과 start 를 받 습 니 다.response, 특정 HTTP 요청 이 발생 했 을 때 웹 서버 에서 호출 합 니 다.environ 은 dict 대상 으로 현재 HTTP 요청 변 수 를 포함 합 니 다. 예 를 들 어: REQUESTMETHOD (HTTP 요청 방식, 예 를 들 어 GET, POST), SCRIPT NAME (처 리 된 url 의 path 경로), PATH INFO (처리 되 지 않 은 url 의 path 경로), QUERY STRING (url 에서? 문자 뒤의 문자열), CONTENT TYPE (요청 내용 유형, 예 를 들 어 application / json, application / xml), CONTENT LENGTH (요청 내용 길이), SERVER NAME(요청 한 서버 이름, 예: www. jd. com), SERVER PORT (요청 한 포트 번호) SERVER PROTOCOL (HTTP 요청 버 전, "HTTP / 1.0" or "HTTP / 1.1"), HTTP XXXX (http 요청 header 정보) 는 어떤 매개 변수 와 정 의 를 구체 적 으로 포함 하 는 지 에 대해 CGI 프로 토 콜 (참고 문헌 [2]) 을 참고 할 수 있다.
       environ 은 WSGI 가 정의 하 는 일부 변 수 를 포함 합 니 다. wsgi. version (이 요청 이 준수 하 는 WSGI 버 전 정보, tuple 형식), wsgi. url scheme (HTTP 요청 프로 토 콜: https or http), wsgi. input (file 대상 과 유사 한 입력 흐름, 사용자 전송 을 읽 는 body), wsgi. errors (오류 처리 정 보 를 출력 하 는 데 사용), wsgi. mlithread(bool 형식, True 일 때 이 웹 app 이 여러 스 레 드 로 동시에 호출 될 수 있 음 을 나타 낸다), wgi. mliprocess (bool 형식, True 일 때 이 웹 app 이 여러 프로 세 스 로 동시에 호출 될 수 있 음 을 나타 낸다), wgi. run once (bool 형식, True 일 때 이 웹 app 은 웹 server 서비스 시간 에 한 번 만 호출 될 수 있 음 을 나타 낸다).
       start response 는 호출 가능 한 대상 입 니 다. 웹 server 에서 매개 변수 로 웹 app 에 전 달 됩 니 다. 웹 app 은 start response 를 호출 하여 HTTP 응답 의 status 와 headers 를 되 돌려 줍 니 다. start response 가 어떻게 실현 되 는 지 궁금 하 십 니까? 다음은 웹 server 엔 드 인터페이스 규범 에서 start response 의 간단 한 실현 이 있 습 니 다. 단 서 를 볼 수 있 습 니 다!
       웹 app 은 해당 environ 에 따라 해당 기능 을 수행 합 니 다. 마지막 으로 start response 를 통 해 해당 status 와 headers 를 되 돌려 주 고 마지막 으로 종료 할 때 iterable 대상 으로 body 를 되 돌려 줍 니 다.
웹 서버 엔 드 인터페이스 규범
       우 리 는 일반적으로 웹 서버 를 스스로 실현 하 지 는 않 지만, 웹 앱 을 작성 할 때, 항상 내 가 되 돌아 온 status 와 headers 가 어떻게 처리 되 었 는 지, 되 돌아 온 body 는 어떻게 처리 되 었 는 지 생각 합 니 다. 다음 코드 를 보고 가장 간단 한 것 을 실 현 했 습 니 다. CGI 의 server 를 따 릅 니 다. 웹 서버 의 대략적인 원 리 를 이해 합 니 다.
import os, sys

def run_with_cgi(application):

    environ = dict(os.environ.items())
    environ['wsgi.input']        = sys.stdin
    environ['wsgi.errors']       = sys.stderr
    environ['wsgi.version']      = (1, 0)
    environ['wsgi.multithread']  = False
    environ['wsgi.multiprocess'] = True
    environ['wsgi.run_once']     = True

    if environ.get('HTTPS', 'off') in ('on', '1'):
        environ['wsgi.url_scheme'] = 'https'
    else:
        environ['wsgi.url_scheme'] = 'http'

    headers_set = []
    headers_sent = []

    def write(data):
        if not headers_set:
             raise AssertionError("write() before start_response()")

        elif not headers_sent:
             # Before the first output, send the stored headers
             status, response_headers = headers_sent[:] = headers_set
             sys.stdout.write('Status: %s\r
' % status) for header in response_headers: sys.stdout.write('%s: %s\r
' % header) sys.stdout.write('\r
') sys.stdout.write(data) sys.stdout.flush() def start_response(status, response_headers, exc_info=None): if exc_info: try: if headers_sent: # Re-raise original exception if headers sent raise exc_info[0], exc_info[1], exc_info[2] finally: exc_info = None # avoid dangling circular ref elif headers_set: raise AssertionError("Headers already set!") headers_set[:] = [status, response_headers] return write result = application(environ, start_response) try: for data in result: if data: # don't send headers until body appears write(data) if not headers_sent: write('') # send headers now if body was empty finally: if hasattr(result, 'close'): result.close()

        위 에서 실 현 된 웹 app 과 웹 server (위 에서 실 현 된 것 은 웹 server 가 아 닙 니 다. HTTP 요청 을 처리 할 수 없 기 때문에 스스로 구성 하여 HTTP 요청 을 모방 할 뿐 입 니 다). 가장 간단 한 app 발표 절 차 를 볼 수 있 습 니 다.
run_with_cgi(simple_app)
        이렇게 간단 합 니 다. 맞습니다. 이렇게 간단 합 니 다. 하지만 HTTP 요청 을 제대로 받 아들 일 수 없습니다. python 자체 라 이브 러 리 wgiref 에서 간단 한 WSGI server 를 제공 하여 wgi app 을 발표 할 수 있 습 니 다.
#!/usr/bin/env python

from wsgiref.simple_server importmake_server
#        environ,  server    ,    request     。start_response
# server    ,    status headers。
def simple_app(environ, start_response):
    status = '200OK'
    headers = [('Content-type','text/plain')]
    print environ
    start_response(status,headers) #     status headers
    #       list  
    return ["helloworld"]
  
httpd = make_server('',                  #listen ip
                    8000,                #listen port
                    simple_app)      #appilication name
 
print"Serving on port 8000..."
httpd.serve_forever()

       이 스 크 립 트 를 실행 하면 브 라 우 저 로 localhost: 8000 을 방문 하면 hello World 를 얻 을 수 있 습 니 다. WSGI 규범 에 대해 더 자세 한 소 개 는 참고 문헌 [1] 을 참고 할 수 있 습 니 다.
참고 문헌
【1】 http://legacy.python.org/dev/peps/pep-0333/
【2】 http://ken.coar.org/cgi/draft-coar-cgi-v11-03.txt

좋은 웹페이지 즐겨찾기