2017-03-14 4 views
0

Cette API simple Falcon prendra HTTP POST avec enctype=multipart/form-data et un téléchargement de fichier dans le paramètre file et imprimer le contenu du fichier sur la console:Simuler multipart/upload de fichiers sous forme de données avec le module d'essai de Falcon

# simple_api.py 
import cgi 
import falcon 

class SomeTestApi(object): 
    def on_post(self, req, resp): 
     upload = cgi.FieldStorage(fp=req.stream, environ=req.env) 
     upload = upload['file'].file.read() 
     print(upload) 


app = falcon.API() 
app.add_route('/', SomeTestApi()) 

One peut également utiliser le middleware falcon-multipart pour atteindre le même objectif.

Pour l'essayer, exécutez-le par ex. avec gunicorn (pip install gunicorn),

gunicorn simple_api.py

puis utilisez cURL (ou tout client reste de choix) pour télécharger un fichier texte:

# sample.txt 
this is some sample text 

curl -F "[email protected]" localhost:8000 

Je voudrais tester cette API maintenant avec Falcon de testing helpers en simulant un téléchargement de fichier. Cependant, je ne comprends pas encore comment faire cela (si c'est possible du tout?). Le simulate_request method a un paramètre file_wrapper qui pourrait être utile mais de la documentation je ne comprends pas comment cela est censé être rempli.

Des suggestions?

Répondre

2

Voici ce que j'ai trouvé, qui essaie de simuler ce que fait mon Chrome. Notez que cela simule le cas lorsque vous téléchargez un seul fichier, mais vous pouvez simplement modifier cette fonction pour télécharger plusieurs fichiers, séparés par deux nouvelles lignes.

def create_multipart(data, fieldname, filename, content_type): 
    """ 
    Basic emulation of a browser's multipart file upload 
    """ 
    boundry = '----WebKitFormBoundary' + random_string(16) 
    buff = io.BytesIO() 
    buff.write(b'--') 
    buff.write(boundry.encode()) 
    buff.write(b'\r\n') 
    buff.write(('Content-Disposition: form-data; name="%s"; filename="%s"' % \ 
       (fieldname, filename)).encode()) 
    buff.write(b'\r\n') 
    buff.write(('Content-Type: %s' % content_type).encode()) 
    buff.write(b'\r\n') 
    buff.write(b'\r\n') 
    buff.write(data) 
    buff.write(b'\r\n') 
    buff.write(boundry.encode()) 
    buff.write(b'--\r\n') 
    headers = {'Content-Type': 'multipart/form-data; boundary=%s' %boundry} 
    headers['Content-Length'] = str(buff.tell()) 
    return buff.getvalue(), headers 

Vous pouvez alors utiliser cette fonction comme ce qui suit:

with open('test/resources/foo.pdf', 'rb') as f: 
    foodata = f.read() 

# Create the multipart data 
data, headers = create_multipart(foodata, fieldname='uploadFile', 
           filename='foo.pdf', 
           content_type='application/pdf') 

# Post to endpoint 
client.simulate_request(method='POST', path=url, 
         headers=headers, body=data)