Technology sharing

WSGI server tutorial: `start_response` methodo analysis

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Python WSGI servo doceo;start_response Methodus analysis

In hoc articulo, servo WSGI singillatim exponemus start_response modum.Haec methodus responsabilis est in codice status dispensandi et responsionis capitis responsionis HTTP ac reddentis awrite Munus mittere solebat responsio data. Explicabimus quomodo methodus per lineam rectam operatur et aliquod subiectum praebeat ad adiuvandum eius facultates intelligendas.

background scientia

WSGI (Servo Web Portus Interface) signum interfaciei est iungi interretialem usum cum applicatione vel compage interretialem. Per WSGI, communicare potes inter servitorem et applicationem et petitiones HTTP ac responsa pertractare.

WSGI cum servo exsequendo;start_response Methodus est pars clavis quae ab applicatione WSGI appellatur ut status responsionis HTTP responsionis capitis constituatur, et munus reddit ad data responsionis scribendae.

start_response Exsequendam methodum

Hoc est typicam start_response Modus exsecutionis:

def start_response(status, response_headers, exc_info=None):
    if exc_info:
        try:
            if headers_sent:
                reraise(*exc_info)
        finally:
            exc_info = None
    elif headers_set:
        raise AssertionError("Headers already set")
    headers_set[:] = [status, response_headers]
    return write
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Gradatim explicandum

  1. fac cum exc_info modulus
if exc_info:
    try:
        if headers_sent:
            reraise(*exc_info)
    finally:
        exc_info = None
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • exc_info Argumentum plerumque exceptionem tuple in forma continet(type, value, traceback) pro exceptione tractans.siexc_info Non enimNoneexceptio quae tractanda est indicans.
  • try In-obstructionum compescitheaders_sent Num responsum header missum est.Si responsio capitis missi sunt, vocareraise(*exc_info) Retrahe exceptionem.
  • finally impedimentum efficit ut post tractantem exceptionem, theexc_info set adNonead vitare duplicationem processus.
  1. Reprehendo si responsio header positus est
elif headers_set:
    raise AssertionError("Headers already set")
  • 1
  • 2
  • si headers_set Elenchus valores iam continet (i.e. responsionis caput positum est), raisesAssertionError abnormis.Hoc reprehendo ensuresstart_response Solum semel vocari potest ad caput capitis responsum.
  1. Set responsio status et responsio capitis
headers_set[:] = [status, response_headers]
  • 1
  • Usus scalpere assignationem status etresponse_headers assignataheaders_set indicet.Propositum hoc est retinereheaders_set referat, sed contentum suum updates.
  • status est filum repraesentans HTTP responsio status code ac nuntium, exempli gratia"200 OK"
  • response_headers est index tuples continens, quodlibet tuple valorem clavem repraesentat par responsionis caput, eg[("Content-Type", "text/html"), ("Content-Length", "123")]
  1. reditus write officium
return write
  • 1
  • start_response Modus redit awrite officium. Hoc munus vocatur ab applicatione WSGI ut notitias responsionis mittat.

Exemplum usus

Hic exemplum integrum ostendens quomodo utatur start_response Methodi WSGI respondeo tractare:

import socketserver

class MyTCPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        self.headers_set = []
        self.headers_sent = []

        def start_response(status, response_headers, exc_info=None):
            if exc_info:
                try:
                    if self.headers_sent:
                        raise exc_info[1]
                finally:
                    exc_info = None
            elif self.headers_set:
                raise AssertionError("Headers already set")
            self.headers_set[:] = [status, response_headers]
            return self.write

        def write(data):
            assert self.headers_set, "write() before start_response"
            if not self.headers_sent:
                status, response_headers = self.headers_sent[:] = self.headers_set
                try:
                    code, msg = status.split(None, 1)
                except ValueError:
                    code, msg = status, ""
                code = int(code)
                self.send_response(code, msg)
                header_keys = set()
                for key, value in response_headers:
                    self.send_header(key, value)
                    key = key.lower()
                    header_keys.add(key)
                if not (
                    "content-length" in header_keys
                    or self.environ["REQUEST_METHOD"] == "HEAD"
                    or code < 200
                    or code in (204, 304)
                ):
                    self.close_connection = True
                    self.send_header("Connection", "close")
                if "server" not in header_keys:
                    self.send_header("Server", self.version_string())
                if "date" not in header_keys:
                    self.send_header("Date", self.date_time_string())
                self.end_headers()

            assert isinstance(data, bytes), "applications must write bytes"
            self.wfile.write(data)
            self.wfile.flush()

        self.write = write
        self.environ = self.make_environ()

        try:
            result = self.server.app(self.environ, start_response)
            try:
                for data in result:
                    write(data)
                if not self.headers_sent:
                    write(b"")
            finally:
                if hasattr(result, "close"):
                    result.close()
        except Exception as e:
            self.send_error(500, str(e))

if __name__ == "__main__":
    HOST, PORT = "localhost", 9999
    with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server:
        print("Server started at {}:{}".format(HOST, PORT))
        server.serve_forever()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

Summatim

Per hoc doceo, WSGI serverin singillatim exponere start_response Methodus quae explicat quomodo statum codicem et responsionem praefecti responsionis HTTP tractat, et munus reddit pro notitia responsionis scribendae. His contentis comprehensis melius te capiet WSGI specificationem et efficiendi a servo nativus WSGI. Spero hoc consequat tibi utile est.Pro plura singularia et exempla placere adDocumenta officialis