PEP 222 – 웹 라이브러리 개선
- Author:
- A.M. Kuchling <amk at amk.ca>
- Status:
- Deferred
- Type:
- Standards Track
- Created:
- 18-Aug-2000
- Python-Version:
- 2.1
- Post-History:
- 22-Dec-2000
Table of Contents
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
이 PEP는 파이썬 표준 라이브러리의 CGI 개발 기능에 대한 일련의 개선 사항을 제안합니다. 개선 사항은 새로운 기능, 쿠키 지원과 같은 작업을 위한 새 모듈, 또는 오래된 코드의 제거일 수 있습니다.
원래 의도는 파이썬 2.1을 개선하는 것이었습니다. 그러나 파이썬 커뮤니티의 관심이 거의 없어 보였고 시간도 부족하여, 이 PEP는 향후 파이썬 릴리스로 연기되었습니다.
미해결 문제
이 절은 제안되었지만 아직 확실한 결정이 내려지지 않은 변경 사항을 나열합니다. 이 PEP의 최종 버전에서는 모든 변경 사항이 승인 또는 거부로 분류되어야 하므로, 이 절은 비어 있어야 합니다.
cgi.py: 파일 업로드를 처리하기 위해서만 자체 서브클래스를 만들라는 요구를 받아서는 안 됩니다. 실질적인 문제로서, 저는 이를 제대로 처리할 시간을 아직 찾지 못했으며, 결국 cgi.py의 임시 파일을 기껏해야 또 다른 파일로 읽어들이게 됩니다. 저희의 일부 레거시 코드는 실제로 이를 두 번째 임시 파일로 읽어들인 다음, 최종 목적지로 다시 읽어들입니다! 그리고 설령 그렇게 하더라도, 이는 __init__ 호출과 그에 따른 오버헤드를 지닌 또 다른 객체를 생성하는 것을 의미하게 됩니다.
cgi.py: 현재, =가 없는 질의 데이터는 무시됩니다. keep_blank_values가 설정되어 있더라도, ...?value=&...와 같은 질의는 빈 값으로 반환되지만 ...?value&...와 같은 질의는 완전히 손실됩니다. 이러한 데이터가 None을 값으로 갖는 항목으로든, 별도의 리스트로든, FieldStorage 인터페이스를 통해 사용 가능하게 된다면 좋을 것입니다.
유틸리티 함수: 2-튜플 리스트로부터 쿼리 문자열을 만듭니다
딕셔너리 관련 유틸리티 클래스: NoKeyErrors(빈 문자열을 반환하며 KeyError는 절대 발생시키지 않음), PartialStringSubstitution(원래 키 문자열을 반환하며 KeyError는 절대 발생시키지 않음)
새 모듈
이 절에서는 파이썬 표준 라이브러리에 추가해야 할 완전히 새로운 패키지나 모듈에 대한 세부 사항을 나열합니다.
- fcgi.py : FastCGI 프로토콜 지원을 추가하는 새 모듈입니다. 다만 Robin Dunn의 코드는 Windows로 포팅해야 합니다.
기존 모듈에 대한 주요 변경 사항
이 절에서는 구현이든 인터페이스든 기존 모듈에 대한 주요 변경 사항의 세부 내용을 나열합니다. 따라서 이 절의 변경 사항은 버그를 유발하거나 하위 호환성을 깨뜨릴 위험이 더 큽니다.
cgi.py 모듈은 폐지될 예정입니다. (XXX 새 모듈이나 패키지 이름은 아직 정해지지 않았습니다: ‘web’? ‘cgilib’?)
기존 모듈에 대한 사소한 변경 사항
이 절에서는 기존 모듈에 대한 사소한 변경 사항의 세부 내용을 나열합니다. 이러한 변경 사항은 비교적 구현 규모가 작으며, 이전 버전과의 비호환성을 유발할 위험이 적습니다.
거부된 변경 사항
이 절에 나열된 변경 사항은 Python 2.1을 위해 제안되었으나, 부적합하다고 판단되어 거부되었습니다. 거부된 각 변경 사항에 대해, 왜 부적절하다고 판단되었는지를 설명하는 근거가 제시됩니다.
- HTML 생성 모듈은 이 PEP의 일부가 아닙니다. 이러한 모듈은 여러 가지가 존재하며, HTMLgen의 순수 프로그래밍 인터페이스부터 ASP에서 영감을 받은 간단한 템플릿 기능, DTML의 복잡한 템플릿 기능에 이르기까지 다양합니다. 어떤 템플릿 모듈을 표준 라이브러리에 채택해야 하는지에 대한 단서가 없으며, 이는 아마도 어떤 모듈도 선택되어서는 안 된다는 것을 의미합니다.
- cgi.py: 쿼리 데이터와 POST 데이터의 조합을 허용합니다. 이는 전혀 표준적이지 않은 것으로 보이며, 따라서 미심쩍은 관행입니다.
제안된 인터페이스
XXX 미해결 사안: 명명 규칙(studlycaps 방식인지 밑줄 구분 방식인지?); cgi.parse*() 함수들도 살펴보고 단순화할 수 있는지 확인할 필요가 있습니다.
파싱 함수: cgi.py의 parse* 함수 대부분을 그대로 가져옵니다.
# The Response class borrows most of its methods from Zope's
# HTTPResponse class.
class Response:
"""
Attributes:
status: HTTP status code to return
headers: dictionary of response headers
body: string containing the body of the HTTP response
"""
def __init__(self, status=200, headers={}, body=""):
pass
def setStatus(self, status, reason=None):
"Set the numeric HTTP response code"
pass
def setHeader(self, name, value):
"Set an HTTP header"
pass
def setBody(self, body):
"Set the body of the response"
pass
def setCookie(self, name, value,
path = '/',
comment = None,
domain = None,
max-age = None,
expires = None,
secure = 0
):
"Set a cookie"
pass
def expireCookie(self, name):
"Remove a cookie from the user"
pass
def redirect(self, url):
"Redirect the browser to another URL"
pass
def __str__(self):
"Convert entire response to a string"
pass
def dump(self):
"Return a string representation useful for debugging"
pass
# XXX methods for specific classes of error:serverError,
# badRequest, etc.?
class Request:
"""
Attributes:
XXX should these be dictionaries, or dictionary-like objects?
.headers : dictionary containing HTTP headers
.cookies : dictionary of cookies
.fields : data from the form
.env : environment dictionary
"""
def __init__(self, environ=os.environ, stdin=sys.stdin,
keep_blank_values=1, strict_parsing=0):
"""Initialize the request object, using the provided environment
and standard input."""
pass
# Should people just use the dictionaries directly?
def getHeader(self, name, default=None):
pass
def getCookie(self, name, default=None):
pass
def getField(self, name, default=None):
"Return field's value as a string (even if it's an uploaded file)"
pass
def getUploadedFile(self, name):
"""Returns a file object that can be read to obtain the contents
of an uploaded file. XXX should this report an error if the
field isn't actually an uploaded file? Or should it wrap
a StringIO around simple fields for consistency?
"""
def getURL(self, n=0, query_string=0):
"""Return the URL of the current request, chopping off 'n' path
components from the right. Eg. if the URL is
"http://foo.com/bar/baz/quux", n=2 would return
"http://foo.com/bar". Does not include the query string (if
any)
"""
def getBaseURL(self, n=0):
"""Return the base URL of the current request, adding 'n' path
components to the end to recreate more of the whole URL.
Eg. if the request URL is
"http://foo.com/q/bar/baz/qux", n=0 would return
"http://foo.com/", and n=2 "http://foo.com/q/bar".
Returned URL does not include the query string, if any.
"""
def dump(self):
"String representation suitable for debugging output"
pass
# Possibilities? I don't know if these are worth doing in the
# basic objects.
def getBrowser(self):
"Returns Mozilla/IE/Lynx/Opera/whatever"
def isSecure(self):
"Return true if this is an SSLified request"
# Module-level function
def wrapper(func, logfile=sys.stderr):
"""
Calls the function 'func', passing it the arguments
(request, response, logfile). Exceptions are trapped and
sent to the file 'logfile'.
"""
# This wrapper will detect if it's being called from the command-line,
# and if so, it will run in a debugging mode; name=value pairs
# can be entered on standard input to set field values.
# (XXX how to do file uploads in this syntax?)
Copyright
This document has been placed in the public domain.