FAQ Python
FAQ PythonConsultez toutes les FAQ
Nombre d'auteurs : 11, nombre de questions : 188, dernière mise à jour : 14 juin 2021
- Comment gérer les déconnexions intempestives du serveur FTP ?
- Comment savoir si un fichier représente un répertoire sur un serveur FTP ?
- Comment se déplacer dans l'arborescence d'un serveur FTP ?
- Comment envoyer un fichier sur un serveur FTP ?
- Comment télécharger les fichiers d'une arborescence d'un répertoire?
Quand vous manipulez un objet FTP et que vous vous connectez à un serveur FTP, il arrive parfois qu'une déconnexion survienne (commandé par le serveur ou non), ce qui arrive souvent lorsque l'on reste trop longtemps connecté à un serveur sans rien faire. Ceci peut être gênant notamment lorsqu'on veut exécuter de nombreuses actions sans maîtriser le temps entre chaque. Une méthode serait de se reconnecter à chaque fois avant d'exécuter une requête sur le serveur. Une autre façon de faire est de se créer une petite classe qui va gérer la reconnexion quand la connexion est perdu au moment de l'exécution de la requête. Cette classe hérite de ftplib.FTP qui gère le client FTP. Nous avons ensuite la fonction Reconnect qui permet la connexion au serveur et la fonction Command(self, command, *args) qui exécute la requête command avec la liste de paramètres donnés par *args en se reconnectant si nécessaire au serveur.
import
ftplib
class
GDDFTP
(
ftplib.FTP):
def
__init__
(
self, adresse, port, user, password):
ftplib.FTP.__init__
(
self, ''
)
self.adresse =
adresse
self.port =
port
self.user =
user
self.password =
password
def
Reconnect
(
self):
self.connect
(
self.adresse, self.port) ## Recherche FTP
self.login
(
self.user, self.password) ## Connexion
def
Command
(
self, command, *
args):
try
: return
command
(*
args)
except
:
self.Reconnect
(
)
return
command
(*
args)
ftp =
GDDFTP
(
monadresse, monport, monlogin, monpassword)
print
ftp.Command
(
ftp.size, monfichier)
ftp.close
(
)
print
ftp.Command
(
ftp.size, monfichier)
Une instance ftplib.FTP ne possède pas de fonction permettant de savoir directement si un fichier est un répertoire ou non. Il n'y a à ma
connaissance non plus aucune commande FTP directe qui permettrait de nous l'indiquer. Une méthode pour obtenir cette information consiste
alors en la génération d'une erreur en fonction de la présence d'un fichier ou répertoire avec certaines requêtes. Toutes ces méthodes
ne fonctionnent aussi que si vous avez les droits d'accès à ces dossiers ou fichiers.
Par exemple, vous pouvez demander la taille du fichier par la commande ftp.size(filename) qui renvoie la taille du fichier
filename ou bien une erreur si ce fichier n'existe pas ou n'est pas un répertoire.
try
:
ftp.size
(
MyPath)
## Traitement si c'est un fichier
except
:
## Traitement si c'est un répertoire
On peut aussi tenter d'accéder au dossier ftp.cwd( pathname) qui générera une erreur si pathname ne représente pas un répertoire. Il faudra cependant penser à retourner dans le répertoire parent ensuite.
try
:
ftp.cwd
(
MyPath)
ftp.cwd
(
".."
)
## Traitement si c'est un répertoire
except
:
## Traitement si c'est un répertoire
Vous pouvez changer le répertoire courant, il vous suffit d'utiliser la commande ftp.cwd( pathname) où pathname est le chemin
relatif ou absolu du répertoire souhaité.
Ainsi pour remonter d'un niveau dans l'arborescence des dossiers, il suffit d'appliquer la méthode ftp.cwd('..'). On peut également utiliser
directement une commande FTP avec la méthode ftp.sendcmd('CDUP')
Pour envoyer un fichier sur un serveur FTP, il vous faut tout d'abord vous connecter à se serveur puis appliquer la fonction storbinary(command, file, blocksize = 8192) où command est une chaîne de caractères en général du type "STOR CheminFichierSurServeur" (CheminFichierSurServeur étant le fichier (accompagné de son chemin d'accès) qui sera créé sur le serveur), file le chemin d'accès du fichier à transférer ouvert en lecture binaire et blocksize la taille des blocks transférés au serveur (on se contente généralement de la valeur par défaut).
import
ftplib
ftp =
ftplib.FTP
(
''
)
ftp.connect
(
monadresse, monport)
ftp.login
(
monlogin, monpassword)
ftp.storbinary
(
'STOR fichiersurserveur'
, open(
fichieratransferer, 'rb'
))
Si vous voulez télécharger tous les fichiers d'un répertoire et de ses sous-répertoires, il vous suffit de parcourir récursivement chaque sous-dossier et de télécharger chaque fichier trouvé. La fonction ftp.nlst(path) renvoie la liste des fichiers/répertoires de path. ftp.size(path) permet de savoir si le fichier path étudié est un fichier ou un répertoire. ftp.retrbinary( command, callback[, maxblocksize[, rest]]) où command doit être du type 'RETR filename' et callback est un fichier ouvert en écriture. La fonction suivante ne gère pas par contre les déconnexions au serveur. En suivant les liens proposés, vous pourrez remédier à cela.
import
os
import
ftplib
def
download
(
pathsrc, pathdst):
lenpathsrc =
len(
pathsrc)
def
_download
(
pathsrc):
l =
ftp.nlst
(
pathsrc)
for
i in
l:
try
:
ftp.size
(
i)
print
i
ftp.retrbinary
(
'RETR '
+
i, open(
pathdst+
os.sep+
i[lenpathsrc:], 'wb'
).write)
except
:
try
: os.makedirs
(
pathdst+
os.sep+
os.path.dirname
(
i[lenpathsrc:]))
except
: pass
_download
(
i)
_download
(
pathsrc)
ftp =
ftplib.FTP
(
''
)
ftp.connect
(
monadresse, monport)
ftp.login
(
monlogin, monpassword)
download
(
cheminsource, chemindestination)
Lien : Comment gérer les déconnexions intempestives du serveur FTP ?
Lien : Comment savoir si un fichier représente un répertoire sur un serveur FTP ?