9
votes

Comment copier wsgi.input si je veux traiter des données de poste plus d'une fois?

dans WSGI, la publication de données est consommée en lisant l'objet Environ ['wsgi.input'] . Si un deuxième élément de la pile veut également lire les données post-de-pièces, il peut accrocher le programme en lisant quand il n'y a rien de plus à lire.

Comment devrais-je copier les données de poste afin qu'il puisse être traité plusieurs fois?


0 commentaires

3 Réponses :


1
votes

Si vous allez le lire dans un swoop châpé, vous pouvez toujours le lire, créer un objet de type CStringio, comme celui que vous avez lu, puis vous l'attribue, comme ceci:

import cStringIO
import copy
lines = []
for line in environ['wsgi.input']:
    lines.append(line)
newlines = copy.copy(lines)
environ['wsgi.input'] = cStringIO.StringIO(''.join(newlines))


2 commentaires

Et Bobince est la façon la plus efficace de le faire :)


Utilisation d'une boucle pour / en boucle sur wsgi.input comme celle-ci pourrait être une mémoire très mémoire / temps inefficace. En effet, si dans le pire des cas, vous avez eu un fichier important où toutes les données étaient composées de lignes vides, vous finiriez par créer une très grande liste dans laquelle chaque entrée est un seul caractère. Je ne sais pas non plus pourquoi vous vous inquiétez de copy.copy () vous avez été rejoigné tout de suite de toute façon.



12
votes

Vous pouvez essayer de mettre une réplique de type de fichier du flux dans l'environnement:

from cStringIO import StringIO

length = int(environ.get('CONTENT_LENGTH', '0'))
body = StringIO(environ['wsgi.input'].read(length))
environ['wsgi.input'] = body


5 commentaires

Vous ne devriez pas compter sur la longueur de contenu par défaut à -1. Il n'y a rien dans la spécification WSGI qui dit qu'une implémentation devrait accepter -1 comme argument à lire () pour signifier lire toutes les intrants. Une mise en œuvre peut décider de soulever une exception dans cette circonstance. En fait, la spécification dit probablement même que si le contenu_length n'est pas présent ou vide qu'elle doit être interprétée pour signifier «0», ou non une entrée disponible.


Ah Yeh ... Pas tout à fait sûr pourquoi je mets ça, mon propre code actuel utilise 0 :-) C'est votre intention de changer ce comportement dans WSGI, n'est-ce pas?


Je doute quelque peu que WSGI verra des modifications maintenant.


Notez que si vous souhaitez utiliser le WSGI.Input deux fois, vous devez faire un Body.Sek (0) avant la deuxième utilisation (évidemment)


WSGI garantit-il la présence de longueur de contenu? (Puisque HTTP n'est pas, si le transfert est chunqué)



8
votes

aller jeter un coup d'œil sur package WebOb . Il fournit des fonctionnalités qui permettent de désigner que WSGI.Input doit être demandé. Cela a pour effet de vous permettre de rembobiner le flux d'entrée tel que le contenu peut être rejoué via un gestionnaire différent. Même si vous n'utilisez pas Webob, la façon dont cela doit être instructif, comme cela ferait confiance à Ian de l'avoir fait de manière appropriée. Pour obtenir des résultats de la recherche dans la documentation Go ici .


0 commentaires