Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
5820 connectés 

  FORUM HardWare.fr
  Programmation
  Python

  HTTPConnection et barre de progression

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

HTTPConnection et barre de progression

n°966542
KrisCool
“Verbeux„
Posté le 31-01-2005 à 10:35:44  profilanswer
 

Je suis en train de développer un programme dont le but est d'identifier un fichier particulier sur le disque dur, d'en extraire certaines informations et d'envoyer ces données à un script php au moyen d'une requête POST.
 
J'utilise httplib pour me connecter au serveur web et construire la requête POST, avec les en-têtes et l'encodage qui vont bien. Je passe donc par l'objet HTTPConnection pour l'envoi, puis par HTTPResponse pour valider qu'il a été effectué correctement.
 
Jusqu'ici c'est parfait, mais j'aimerais afficher une barre de progression visuelle de l'envoi de la requête. En effet, la quantité de données peut être relativement importante, et j'aimerais informer l'utilisateur de la bonne progression de l'envoi.
 
Le problème, c'est que je ne sais pas de quelle façon je peux obtenir les informations sur la progression de l'envoi. J'ai regardé de près les classes mises en jeu:
- HTTPConnection ne propose pas de méthode ou d'attribut concernant les données déjà envoyées
- Socket.send() renvoie le nombre d'octets envoyés
 
Je pressents que si je veux pouvoir afficher une barre de progression je vais devoir me passer de HTTPConnection et d'opérer directement au niveau du socket.
A moins de dériver HTTPConnection et de modifier la bonne méthode pour gérer cette progression ?
 
Si quelqu'un a une idée à ajouter, une confirmation ou une infirmation de mes hypothèses je suis preneur.
Merci d'avance.


---------------
Loose Change Lies | Bars | Last.fm
mood
Publicité
Posté le 31-01-2005 à 10:35:44  profilanswer
 

n°969510
Valeriand
Posté le 02-02-2005 à 15:33:11  profilanswer
 

Effectivement telle qu'est faite la classe HTTPConnection tu ne pourras pas faire grand chose, quand tu fais request() c'est la méthode sendall() du socket qui est utilisée et on ne peut rien faire avec si ce n'est espérer qu'elle ne se plante pas...
A la limite tu pourrais peut être essayer de créer une nouvelle classe dérivée de HTPPConnection dans laquelle tu redéfinis la méthode send. Au lieu d'envoyer tout d'un bloc on pourrait découper les données en blocs de 1024 octets et à chaque envoi réussi mettre à jour une variable. Il ne resterait alors qu'à lire cette variable à intervalles réguliers pour voir où on en est.
Je n'ai pas testé mais c'est ce qui me paraitrait le plus simple à mettre en oeuvre, ça évite de devoir réimplémenter tout le protocole HTTP au niveau socket...

n°969593
KrisCool
“Verbeux„
Posté le 02-02-2005 à 16:32:26  profilanswer
 

Voui c'est un peu ce que je me suis dit, je pense que je vais me retourner vers cette solution, parce qu'effectivement sinon c'est assez galère :)
 
Merci !


---------------
Loose Change Lies | Bars | Last.fm
n°970528
KrisCool
“Verbeux„
Posté le 03-02-2005 à 13:55:31  profilanswer
 

Pour plus de flexibilité, j'ai implémenté une classe HTTPProgressConnection qui dérive de HTTPConnection en redéfinissant sa commande send()
 
Je fais l'envoi en passant par socket.send() au lieu de socket.sendall(), et j'ai ajouté la possibilité de mettre un callback à chaque appel de socket.send() pour renvoyer le nombre d'octets déjà envoyés et le nombre total d'octets.
 

Code :
  1. import httplib, urllib
  2. class HTTPProgressConnection(httplib.HTTPConnection):
  3. def __init__(self, host, port=None, strict=None):
  4.  httplib.HTTPConnection.__init__(self, host, port, strict)
  5.  self.progress_callback = None
  6.  self.send_buffer_size = 1024
  7. def send(self, str):
  8.  """Send `str' to the server and calls self.progress_callback() when data is actually sent"""
  9.  if self.sock is None:
  10.   if self.auto_open:
  11.    self.connect()
  12.   else:
  13.    raise NotConnected()
  14.  if self.debuglevel > 0:
  15.   print "send:", repr(str)
  16.  try:
  17.   # Start of modification to the original HTTPConnection.send()
  18.   # Set the callback
  19.   if callable(self.progress_callback):
  20.    callback = self.progress_callback
  21.   else:
  22.    callback = lambda c,t: 0
  23.   total_bytecount = 0
  24.   total_size = len(str)
  25.   while total_bytecount < total_size:
  26.    total_bytecount += self.sock.send(str[total_bytecount:self.send_buffer_size])
  27.    callback(total_bitecount, total_size)
  28.   # End of the modification or the original HTTPConnection.send()
  29.  except socket.error, v:
  30.   if v[0] == 32:      # Broken pipe
  31.    self.close()
  32.   raise
  33. if __name__ == "__main__":
  34. def simple_callback(current, total):
  35.  print "%(current)d / %(total)" % (current, total)
  36. params = urllib.urlencode({'q': 'python c\'est bon !'})
  37. hpc = HTTPProgressConnection('www.google.fr', 80)
  38. hpc.progress_callback = simple_callback
  39. print 'hpc.request():'
  40. hpc.request('GET', '/search', params)


 
Le constructeur de HTTPProgressConnection est le même que celui de HTTPConnection, et définit deux attributs supplémentaires:
- progress_callback, qui est la fonction de callback à appeler lors de chaque envoi de données, et qui doit recevoir deux arguments
- send_buffer_size, qui est un nom trompeur (à changer) qui définit la taille des données envoyées par appel à socket.send()
 
J'ai pas pu tester en l'état parce que cette classe ne supporte pas les proxies, et que j'en ai un à ma boîte.


---------------
Loose Change Lies | Bars | Last.fm
n°971174
KrisCool
“Verbeux„
Posté le 04-02-2005 à 00:18:29  profilanswer
 

Après tests, il savère qu'il y avait un bug idiot:
 
A la ligne 29, il faut remplacer:
 

Code :
  1. total_bytecount += self.sock.send(str[total_bytecount:self.send_buffer_size])


Par  

Code :
  1. total_bytecount += self.sock.send(str[total_bytecount:total_bytecount + self.send_buffer_size])


 
Sinon évidemment ça risque pas de marcher des masses dès lors qu'il y a plus de données que la taille d'envoi [:huit]


---------------
Loose Change Lies | Bars | Last.fm
n°972099
Valeriand
Posté le 04-02-2005 à 17:43:04  profilanswer
 

Joli, c'est en voyant ça qu'on se dit que c'est bien le Python...
Par contre pour le proxy tu risques de te faire chier, j'avais commencé à regarder pour le boulot et je n'ai pas réussi à faire fonctionner pour les proxies avec authentification. Certes je n'avais pas trop recherché mais bon...

n°973824
KrisCool
“Verbeux„
Posté le 07-02-2005 à 10:42:21  profilanswer
 

De ce que j'ai pu voir, les proxies sont gérés avec urllib et urllib2, la seconde ayant une interface un peu plus pratique d'utilisation avec la classe request. Pour l'authentification y'a pas mal de choses, mais j'ai pas le temps ni l'opportunité de m'y plonger.


---------------
Loose Change Lies | Bars | Last.fm

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Python

  HTTPConnection et barre de progression

 

Sujets relatifs
suppression barre de scrolling horizontaleModifier l'adresse de la barre
créer une barre de défilement dans un tableauintegrer un programme dans la barre des taches...
Image dans la barre d'adressePersonnalisation de la barre défilante
Indicateur de progression dans une JFrame[js]afficher du texte dans la barre d'etat (compatible firefox 1.0)
Couper la fin d'une image dans une table pour faire une barre de % ?Pb barre de progression
Plus de sujets relatifs à : HTTPConnection et barre de progression


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)