2017-11-22 20 views
1

Ich versuche, einen Twisted Webserver in Python 3.6 zu schreiben, die mehrere Dateien hochladen kann, aber ziemlich neu zu sowohl Python und Dinge Web Ich habe ein Problem lief ich verstehe nicht und ich auch finde keine guten Beispiele zum Hochladen mehrerer Dateien.Twisted upload multiple Dateien Schlüsselfehler

Mit dem folgenden Code ich

from twisted.web import server, resource 
from twisted.internet import reactor, endpoints 
import cgi 


class Counter(resource.Resource): 
    isLeaf = True 
    numberRequests = 0 

    def render_GET(self, request): 
     print("GET " + str(self.numberRequests)) 
     self.numberRequests += 1 
     # request.setHeader(b"content-type", b"text/plain") 
     # content = u"I am request #{}\n".format(self.numberRequests) 
     content = """<html> 
     <body> 
     <form enctype="multipart/form-data" method="POST"> 
      Text: <input name="text1" type="text" /><br /> 
      File: <input name="file1" type="file" multiple /><br /> 
      <input type="submit" /> 
     </form> 
     </body> 
     </html>""" 
     print(request.uri) 


     return content.encode("ascii") 

    def render_POST(selfself, request): 
     postheaders = request.getAllHeaders() 
     try: 
      postfile = cgi.FieldStorage(
       fp=request.content, 
       headers=postheaders, 
       environ={'REQUEST_METHOD': 'POST', 
         # 'CONTENT_TYPE': postheaders['content-type'], Gives builtins.KeyError: 'content-type' 
         } 
      ) 
     except Exception as e: 
      print('something went wrong: ' + str(e)) 

     filename = postfile["file"].filename #file1 tag also does not work 
     print(filename) 

     file = request.args["file"][0] #file1 tag also does not work 



endpoints.serverFromString(reactor, "tcp:1234").listen(server.Site(Counter())) 

reactor.run() 

Fehlerprotokoll

C:\Users\theuser\AppData\Local\conda\conda\envs\py36\python.exe C:/Users/theuser/PycharmProjects/myproject/twweb.py 
GET 0 
b'/' 
# My comment POST starts here 
Unhandled Error 
Traceback (most recent call last): 
    File "C:\Users\theuser\AppData\Local\conda\conda\envs\py36\lib\site-packages\twisted\web\http.py", line 1614, in dataReceived 
    finishCallback(data[contentLength:]) 
    File "C:\Users\theuser\AppData\Local\conda\conda\envs\py36\lib\site-packages\twisted\web\http.py", line 2029, in _finishRequestBody 
    self.allContentReceived() 
    File "C:\Users\theuser\AppData\Local\conda\conda\envs\py36\lib\site-packages\twisted\web\http.py", line 2104, in allContentReceived 
    req.requestReceived(command, path, version) 
    File "C:\Users\theuser\AppData\Local\conda\conda\envs\py36\lib\site-packages\twisted\web\http.py", line 866, in requestReceived 
    self.process() 
--- <exception caught here> --- 
    File "C:\Users\theuser\AppData\Local\conda\conda\envs\py36\lib\site-packages\twisted\web\server.py", line 195, in process 
    self.render(resrc) 
    File "C:\Users\theuser\AppData\Local\conda\conda\envs\py36\lib\site-packages\twisted\web\server.py", line 255, in render 
    body = resrc.render(self) 
    File "C:\Users\theuser\AppData\Local\conda\conda\envs\py36\lib\site-packages\twisted\web\resource.py", line 250, in render 
    return m(request) 
    File "C:/Users/theuser/PycharmProjects/myproject/twweb.py", line 42, in render_POST 
    filename = postfile["file"].filename #file1 tag also does not work 
    File "C:\Users\theuser\AppData\Local\conda\conda\envs\py36\lib\cgi.py", line 604, in __getitem__ 
    raise KeyError(key) 
builtins.KeyError: 'file' 

Ich verstehe nicht, wie halten die Datei oder Dateien bekommen, so kann ich sie hochgeladen speichern, nachdem das Formular abschicken in render_POST. Dieser Beitrag SO scheint dieses Problem nicht zu haben. Die finale App sollte das für mehrere Benutzer asynchron machen können, aber davor wäre ich glücklich, wenn nur eine einfache App funktioniert.

Mit Conda unter Windows 10 mit Python 3,6

Antwort

1

FieldStorage in Python 3 + gibt einen dict mit Schlüssel als Bytes, keine Strings. So müssen Sie Tasten wie folgt zugreifen:

postfile[ b"file" ] 

Beachten Sie, dass der Schlüssel mit b"" angehängt wird. Es ist ein bisschen verwirrend, wenn Sie neu in Python sind und die Änderungen zwischen Python 3 und 2 Zeichenfolgen nicht kennen.

Ich antwortete auch eine similar question vor einer Weile, aber konnte es nicht richtig auf Python 3.4 arbeiten, aber ich kann mich nicht erinnern, was genau nicht funktioniert hat. Hoffentlich treten Sie mit 3.6 keine Probleme auf.

+0

Mit dem b'content-type bekomme ich das Problem in cgi.FieldStorage. Aber ich kann es nicht schaffen, später die Felder für die Datei zu bekommen, es analysiert den Namen und den Dateinamen der zwei Schlüssel, die die Felder in sich haben, aber ich kann es nicht schaffen, sie herauszubekommen. Ich habe zu Python 2.7 gewechselt und dann kann ich das zum Laufen bringen, also denke ich immer noch, dass das Problem von 3.4 in 3.6 existiert – bits