This module implements an asynchronous FTP client. It allows you to connect to an FTP server and perform operations on it such as for example:
In order to begin any sort of transfer of files you must first connect to an FTP server. You can do so with the connect procedure.
import asyncdispatch, asyncftpclient
proc main() {.async.} =
var ftp = newAsyncFtpClient("example.com", user = "test", pass = "test")
await ftp.connect()
echo("Connected")
waitFor(main()) A new main async procedure must be declared to allow the use of the await keyword. The connection will complete asynchronously and the client will be connected after the await ftp.connect() call.
After a connection is made you can use the store procedure to upload a new file to the FTP server. Make sure to check you are in the correct working directory before you do so with the pwd procedure, you can also instead specify an absolute path.
import asyncdispatch, asyncftpclient
proc main() {.async.} =
var ftp = newAsyncFtpClient("example.com", user = "test", pass = "test")
await ftp.connect()
let currentDir = await ftp.pwd()
assert currentDir == "/home/user/"
await ftp.store("file.txt", "file.txt")
echo("File finished uploading")
waitFor(main()) The progress of either a file upload or a file download can be checked by specifying a onProgressChanged procedure to the store or retrFile procedures.
import asyncdispatch, asyncftpclient
proc onProgressChanged(total, progress: BiggestInt,
speed: float): Future[void] =
echo("Uploaded ", progress, " of ", total, " bytes")
echo("Current speed: ", speed, " kb/s")
proc main() {.async.} =
var ftp = newAsyncFtpClient("example.com", user = "test", pass = "test")
await ftp.connect()
await ftp.store("file.txt", "/home/user/file.txt", onProgressChanged)
echo("File finished uploading")
waitFor(main()) AsyncFtpClientObj = FtpBaseObj[AsyncSocket]
AsyncFtpClient = ref AsyncFtpClientObj
ProgressChangedProc = proc (total, progress: BiggestInt; speed: float): Future[void] {...}{.
closure, gcsafe.}proc send(ftp: AsyncFtpClient; m: string): Future[TaintedString] {...}{.
raises: [FutureError], tags: [RootEffect].}Send a message to the server, and wait for a primary reply. \c\L is added for you.
Note: The server may return multiple lines of coded replies.
proc connect(ftp: AsyncFtpClient): Future[void] {...}{.raises: [FutureError],
tags: [RootEffect].}ftp. proc pwd(ftp: AsyncFtpClient): Future[TaintedString] {...}{.raises: [FutureError],
tags: [RootEffect].}proc cd(ftp: AsyncFtpClient; dir: string): Future[void] {...}{.raises: [FutureError],
tags: [RootEffect].}dir. proc cdup(ftp: AsyncFtpClient): Future[void] {...}{.raises: [FutureError],
tags: [RootEffect].}proc listDirs(ftp: AsyncFtpClient; dir = ""): Future[seq[string]] {...}{.
raises: [FutureError], tags: [RootEffect].}dir is "", the current directory is used. If async is true, this function will return immediately and it will be your job to use asyncio's poll to progress this operation. proc existsFile(ftp: AsyncFtpClient; file: string): Future[bool] {...}{.
raises: [FutureError], tags: [RootEffect].}file exists. proc createDir(ftp: AsyncFtpClient; dir: string; recursive = false): Future[void] {...}{.
raises: [FutureError], tags: [RootEffect].}dir. If recursive is true, the topmost subdirectory of dir will be created first, following the secondmost... etc. this allows you to give a full path as the dir without worrying about subdirectories not existing. proc chmod(ftp: AsyncFtpClient; path: string; permissions: set[FilePermission]): Future[
void] {...}{.raises: [FutureError], tags: [RootEffect].}path to permissions. proc list(ftp: AsyncFtpClient; dir = ""): Future[string] {...}{.raises: [FutureError],
tags: [RootEffect].}dir. If dir is "", uses the current working directory. proc retrText(ftp: AsyncFtpClient; file: string): Future[string] {...}{.
raises: [FutureError], tags: [RootEffect].}file. File must be ASCII text. proc defaultOnProgressChanged(total, progress: BiggestInt; speed: float): Future[void] {...}{.
nimcall, gcsafe, procvar, raises: [FutureError, Exception], tags: [RootEffect].}onProgressChanged handler. Does nothing. proc retrFile(ftp: AsyncFtpClient; file, dest: string;
onProgressChanged: ProgressChangedProc = defaultOnProgressChanged): Future[
void] {...}{.raises: [FutureError], tags: [RootEffect, TimeEffect, WriteIOEffect].}file and saves it to dest. The EvRetr event is passed to the specified handleEvent function when the download is finished. The event's filename field will be equal to file. proc store(ftp: AsyncFtpClient; file, dest: string;
onProgressChanged: ProgressChangedProc = defaultOnProgressChanged): Future[
void] {...}{.raises: [FutureError], tags: [RootEffect, ReadIOEffect, TimeEffect].}file to dest on the remote FTP server. Usage of this function asynchronously is recommended to view the progress of the download. The EvStore event is passed to the specified handleEvent function when the upload is finished, and the filename field will be equal to file. proc rename(ftp: AsyncFtpClient; nameFrom: string; nameTo: string): Future[void] {...}{.
raises: [FutureError], tags: [RootEffect].}name_from to new name name_to proc removeFile(ftp: AsyncFtpClient; filename: string): Future[void] {...}{.
raises: [FutureError], tags: [RootEffect].}filename on the remote FTP server proc removeDir(ftp: AsyncFtpClient; dir: string): Future[void] {...}{.
raises: [FutureError], tags: [RootEffect].}dir on the remote FTP server proc newAsyncFtpClient(address: string; port = Port(21); user, pass = ""): AsyncFtpClient {...}{.
raises: [OSError, Exception], tags: [RootEffect].}AsyncFtpClient object.
© 2006–2018 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/asyncftpclient.html