Python Forum
How do I organize my simple ftp modules?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How do I organize my simple ftp modules?
#1
HI,
i'm very new to python, I'm trying to write some ftp modules for reuse.

Here are my modules/files list:
my_ftp.py: contains definition of my ftp functions
test_ftp.py: simple test script to use the ftp functions above
config.ini: a config file containing ftp parameters such as address, username and password

my_ftp.py :
from ftplib import FTP
import os
import configparser

ftpAddress = ''
ftpUserName = ''
ftpPassword = ''

def initFtpParameters(parametersFileName):
    config = configparser.ConfigParser()
    config.read(parametersFileName)     

    global ftpAddress
    global ftpUserName 
    global ftpPassword

    ftpAddress = config.get("myvars",'ftpAddress')
    ftpUserName = config.get("myvars",'ftpUserName')
    ftpPassword = config.get("myvars",'ftpPassword')

def downloadAll(localPath):

    print('user:' + ftpUserName + ' ' + ftpPassword + ' ' + ftpAddress) #here i'm checking if the variable's value are ok

    ftp = FTP(ftpAddress)
    ftp.login(user=ftpUserName, passwd=ftpPassword)

    ftpFileNames = ftp.nlst()

    for ftpfileName in ftpFileNames:

        if not isDir(ftp,ftpfileName) :
            localFileName = os.path.join(localPath, ftpfileName)
            localFile = open(localFileName, 'wb')
            ftp.retrbinary('RETR ' + ftpfileName, localFile.write, 1024 )
            localFile.close()

    ftp.quit()
test_ftp.py:
import my_ftp

my_ftp.initFtpParameters('C:\\Users\\Python\\config.ini')
my_ftp.downloadAll('C:\\Users\\Python\\')
config.ini
[myvars]
ftpAddress: 'ftp.myaddress.it'
ftpUserName: 'myUserName'
ftpPassword: '123456'
It seems there is some issue with the variables scope. I'm getting this error:
socket.gaierror: [Errno 11001] getaddrinfo failed

Can you give me some hints about "organizing" these variables and this config file in order to reuse my code by simply selecting a different config file in my "test_ftp.py" script?
Note: it all works fine if I explicitly assign the variable values inside my downloadAll function
Reply
#2
What is the output of the print statement in your code? Does it show the correct values?
« We can solve any problem by introducing an extra level of indirection »
Reply
#3
(Jan-05-2024, 11:11 AM)Gribouillis Wrote: What is the output of the print statement in your code? Does it show the correct values?

Yes, there was actually an issue in the way I written the config file. But, anyway, is this a correct usage of the keyword global? Or such a behaviour should be avoided? Are the any better best practices to organize such config files and call them inside the code?
Reply
#4
(Jan-05-2024, 11:25 AM)blobdx7 Wrote: But, anyway, is this a correct usage of the keyword global?
Normally people try to avoid the global keyword by not assigning to global variables, and when they use it they tend to minimize the number of variables using global. This is normally achieved by encapsulating variables in classes. Here is how you could write the same code without this keyword by introducing a FtpUser class for example
from ftplib import FTP
import os
import configparser


class FtpUser:
    def __init__(self, address, name, password):
        self.address = address
        self.name = name
        self.password = password

    def download_all(self, localPath):
        ftp = FTP(self.address)
        ftp.login(user=self.name, passwd=self.password)

        ftpFileNames = ftp.nlst()

        for ftpfileName in ftpFileNames:
            if not isDir(ftp, ftpfileName):
                localFileName = os.path.join(localPath, ftpfileName)
                localFile = open(localFileName, "wb")
                ftp.retrbinary("RETR " + ftpfileName, localFile.write, 1024)
                localFile.close()

        ftp.quit()

    def __repr__(self):
        return f"{type(self).__name__}({self.address!r}, {self.name!r}, {self.password!r})"

    @classmethod
    def from_init_file(cls, parametersFileName, section="myvars"):
        config = configparser.ConfigParser()
        config.read(parametersFileName)

        return cls(
            config.get(section, "ftpAddress"),
            config.get(section, "ftpUserName"),
            config.get(section, "ftpPassword"),
        )
import my_ftp

ftp_user = my_ftp.FtpUser.from_init_file("C:\\Users\\Python\\config.ini")
print(ftp_user)  # here i'm checking if the variable's value are ok
ftp_user.download_all("C:\\Users\\Python\\")
As a bonus, this code allows you to enter several ftp addresses and users in the config file under different section names.

Read PEP 8 to learn about variables and functions naming conventions usually chosen in Python code.
« We can solve any problem by introducing an extra level of indirection »
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How can I organize my code according to output that I want ilknurg 1 1,183 Mar-11-2022, 09:24 AM
Last Post: perfringo
Star Split and organize my Pandas Dataframe brunolelli 4 2,723 Apr-18-2021, 03:00 AM
Last Post: brunolelli
  Counting number of words and organize for the bigger frequencies to the small ones. valeriorsneto 1 1,684 Feb-05-2021, 03:49 PM
Last Post: perfringo
  Best way(s) to organize and use "global" values? pjfarley3 6 2,660 Sep-03-2020, 12:27 AM
Last Post: pjfarley3
  Modules issue, pip3 download modules only to pyhton3.5.2 not the latest 3.6.1 bmohanraj91 6 8,464 May-25-2017, 08:15 AM
Last Post: wavic

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020