Skip to content

Commit b0c379e

Browse files
Added FTP tasks
1 parent f988444 commit b0c379e

File tree

3 files changed

+167
-0
lines changed

3 files changed

+167
-0
lines changed

tasks/ftp/__init__.py

Whitespace-only changes.

tasks/ftp/retrieve_from_ftp.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import os
2+
from ftplib import FTP, error_perm
3+
4+
from netunicorn.base import Failure, Result, Success, Task
5+
6+
7+
class RetrieveFromFTP(Task):
8+
"""
9+
Task for retrieving a file from an FTP server to a local directory. Establishes a connection to the specified FTP server, navigates to the desired remote directory and downloads the specified file to a local directory.
10+
"""
11+
12+
def __init__(
13+
self,
14+
ftp_remote_filepath: str,
15+
ftp_url: str,
16+
username: str,
17+
password: str,
18+
local_dir: str = "./",
19+
*args,
20+
**kwargs,
21+
):
22+
"""
23+
Initializes the RetrieveFromFTP task with parameters.
24+
25+
Parameters:
26+
ftp_remote_filepath (str): Full path of the file on the FTP server to retrieve.
27+
ftp_url (str): URL or IP address of the FTP server.
28+
username (str): Username for FTP authentication.
29+
password (str): Password for FTP authentication.
30+
local_dir (str, optional): Local directory to save the retrieved file. Defaults to "./".
31+
*args: Variable length argument list.
32+
**kwargs: Arbitrary keyword arguments.
33+
"""
34+
super().__init__(*args, **kwargs)
35+
self.ftp_remote_filepath = ftp_remote_filepath
36+
self.ftp_url = ftp_url
37+
self.username = username
38+
self.password = password
39+
self.local_dir = local_dir
40+
41+
def run(self) -> Result:
42+
"""
43+
Run the FTP file retrieval process.
44+
45+
Steps:
46+
1. Connects to FTP server using provided credentials.
47+
2. Navigates to the directory containing the target file.
48+
3. Downloads the specified file to the local directory. Defaults to "./".
49+
50+
Returns:
51+
Result:
52+
Success: Contain success message upon successful download.
53+
--OR--
54+
Failure: Contains an error message if the download fails.
55+
56+
"""
57+
try:
58+
ftp = FTP(self.ftp_url, timeout=30) # Modify timeout as needed
59+
ftp.login(user=self.username, passwd=self.password)
60+
61+
remote_dir, remote_filename = os.path.split(self.ftp_remote_filepath)
62+
if remote_dir:
63+
ftp.cwd(remote_dir)
64+
65+
if not os.path.isdir(self.local_dir):
66+
return Failure(f"Local directory does not exist: {self.local_dir}")
67+
68+
local_filepath = os.path.join(self.local_dir, remote_filename)
69+
with open(local_filepath, "wb") as f:
70+
ftp.retrbinary(f"RETR {remote_filename}", f.write)
71+
72+
ftp.quit()
73+
74+
return Success(
75+
f"Successfully downloaded {self.ftp_remote_filepath} to {local_filepath}"
76+
)
77+
78+
except FileNotFoundError:
79+
return Failure(f"File not found: {self.ftp_remote_filepath}")
80+
81+
except error_perm as e:
82+
return Failure(f"FTP permission error: {e}")
83+
84+
except Exception as e:
85+
return Failure(f"An unexpected error occurred: {str(e)}")

tasks/ftp/upload_to_ftp.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import os
2+
from ftplib import FTP, error_perm
3+
4+
from netunicorn.base import Failure, Result, Success, Task
5+
6+
7+
class UploadToFTP(Task):
8+
"""
9+
Task for uploading a local file to an FTP Server. Establishes a connection to the specified FTP server, navigates to the desired remote directory, and uploads the specified local file.
10+
"""
11+
12+
def __init__(
13+
self,
14+
local_filepath: str,
15+
ftp_url: str,
16+
username: str,
17+
password: str,
18+
destination_dir: str = "/",
19+
*args,
20+
**kwargs,
21+
):
22+
"""
23+
Initializes the UploadToFTP task with parameters.
24+
25+
Parameters:
26+
local_filepath (str): Path to local file to upload.
27+
ftp_url (str): URL or IP address of FTP.
28+
username (str): Username credential for FTP auth.
29+
password (str): Password credential for FTP auth.
30+
destination_dir (str): Destination directory on the FTP server where the file will be uploaded to. Defaults to "/".
31+
"""
32+
super().__init__(*args, **kwargs)
33+
self.local_filepath = local_filepath
34+
self.ftp_url = ftp_url
35+
self.username = username
36+
self.password = password
37+
self.destination_dir = destination_dir
38+
39+
def run(self) -> Result:
40+
"""
41+
Uploads the local file to FTP server.
42+
43+
Steps:
44+
1. Finds the specified local file.
45+
2. Connects to FTP server using provided credentials.
46+
3. Sets remote directory if specified, else defaults to "/".
47+
4. Uploads the local file to FTP server and closes connection.
48+
49+
Returns:
50+
Result:
51+
Success: Contains a success message if successful upload.
52+
--OR--
53+
Failure: Contains an error message if upload fails.
54+
55+
"""
56+
try:
57+
if not os.path.isfile(self.local_filepath):
58+
return Failure(f"Local file does not exist: {self.local_filepath}")
59+
60+
ftp = FTP(self.ftp_url, timeout=30) # Modify timeout as needed
61+
ftp.login(user=self.username, passwd=self.password)
62+
63+
if self.destination_dir:
64+
ftp.cwd(self.destination_dir)
65+
66+
with open(self.local_filepath, "rb") as f:
67+
remote_filename = os.path.basename(self.local_filepath)
68+
ftp.storbinary(f"STOR {remote_filename}", f)
69+
70+
ftp.quit()
71+
return Success(
72+
f"Successfully uploaded {self.local_filepath} to {self.ftp_url}/{self.destination_dir}"
73+
)
74+
75+
except FileNotFoundError:
76+
return Failure(f"File not found: {self.local_filepath}")
77+
78+
except error_perm as e:
79+
return Failure(f"FTP permission error: {e}")
80+
81+
except Exception as e:
82+
return Failure(f"An unexpected error occurred: {str(e)}")

0 commit comments

Comments
 (0)