0
# FTP Client
1
2
High-level FTP client functionality providing comprehensive file transfer operations, directory management, and connection handling. The client supports context managers, streaming operations, SSL/TLS encryption, and various authentication methods.
3
4
## Capabilities
5
6
### Connection Management
7
8
Establish and manage FTP connections with support for various authentication methods, SSL/TLS encryption, and connection configuration.
9
10
```python { .api }
11
class Client(BaseClient):
12
"""High-level FTP client with file operations and directory management."""
13
14
@classmethod
15
def context(host: str, port: int = 21, user: str = "anonymous",
16
password: str = "anon@", account: str = "",
17
upgrade_to_tls: bool = False, **kwargs) -> AsyncGenerator[Client]:
18
"""
19
Async context manager for FTP client connections.
20
21
Parameters:
22
- host: FTP server hostname or IP address
23
- port: FTP server port (default: 21)
24
- user: Username for authentication (default: "anonymous")
25
- password: Password for authentication (default: "anon@")
26
- account: Account for authentication (default: "")
27
- upgrade_to_tls: Whether to upgrade connection to TLS (default: False)
28
- **kwargs: Additional arguments passed to Client constructor
29
30
Yields:
31
Connected and authenticated Client instance
32
"""
33
34
async def connect(self, host: str, port: int = 21) -> list[str]:
35
"""
36
Connect to FTP server and return greeting message.
37
38
Parameters:
39
- host: FTP server hostname or IP address
40
- port: FTP server port (default: 21)
41
42
Returns:
43
List of greeting message lines from server
44
"""
45
46
async def login(self, user: str = "anonymous", password: str = "anon@",
47
account: str = "") -> None:
48
"""
49
Authenticate with the FTP server.
50
51
Parameters:
52
- user: Username for authentication
53
- password: Password for authentication
54
- account: Account for authentication (rarely used)
55
"""
56
57
async def upgrade_to_tls(self, sslcontext: ssl.SSLContext = None) -> None:
58
"""
59
Upgrade connection to TLS encryption.
60
61
Parameters:
62
- sslcontext: SSL context for encryption (uses default if None)
63
"""
64
65
async def quit(self) -> None:
66
"""Gracefully close FTP connection."""
67
68
def close(self) -> None:
69
"""Force close FTP connection immediately."""
70
```
71
72
### File Transfer Operations
73
74
Upload and download files with support for streaming, resuming transfers, and various transfer modes.
75
76
```python { .api }
77
class Client:
78
async def upload(self, source, destination: str = "", write_into: bool = False,
79
block_size: int = 8192) -> None:
80
"""
81
Upload a file to the FTP server.
82
83
Parameters:
84
- source: Local file path (str/Path) or file-like object to upload
85
- destination: Remote destination path (uses source name if empty)
86
- write_into: If True, write into existing remote directory
87
- block_size: Transfer block size in bytes
88
"""
89
90
async def download(self, source, destination: str = "", write_into: bool = False,
91
block_size: int = 8192) -> None:
92
"""
93
Download a file from the FTP server.
94
95
Parameters:
96
- source: Remote file path to download
97
- destination: Local destination path (uses source name if empty)
98
- write_into: If True, write into existing local directory
99
- block_size: Transfer block size in bytes
100
"""
101
102
def upload_stream(self, destination: str, offset: int = 0) -> AsyncEnterableInstanceProtocol[DataConnectionThrottleStreamIO]:
103
"""
104
Get upload stream for writing data to remote file.
105
106
Parameters:
107
- destination: Remote file path to upload to
108
- offset: Byte offset to start upload (for resume)
109
110
Returns:
111
Async context manager yielding writable stream
112
"""
113
114
def download_stream(self, source: str, offset: int = 0) -> AsyncEnterableInstanceProtocol[DataConnectionThrottleStreamIO]:
115
"""
116
Get download stream for reading data from remote file.
117
118
Parameters:
119
- source: Remote file path to download from
120
- offset: Byte offset to start download (for resume)
121
122
Returns:
123
Async context manager yielding readable stream
124
"""
125
126
def append_stream(self, destination: str, offset: int = 0) -> AsyncEnterableInstanceProtocol[DataConnectionThrottleStreamIO]:
127
"""
128
Get append stream for appending data to remote file.
129
130
Parameters:
131
- destination: Remote file path to append to
132
- offset: Byte offset to start append
133
134
Returns:
135
Async context manager yielding writable stream
136
"""
137
```
138
139
### Directory Operations
140
141
Navigate and manipulate remote directory structure including creating, removing, and changing directories.
142
143
```python { .api }
144
class Client:
145
async def get_current_directory(self) -> PurePosixPath:
146
"""
147
Get current working directory on remote server.
148
149
Returns:
150
Current directory path as PurePosixPath
151
"""
152
153
async def change_directory(self, path: str = "..") -> None:
154
"""
155
Change current working directory on remote server.
156
157
Parameters:
158
- path: Directory path to change to (default: ".." for parent)
159
"""
160
161
async def make_directory(self, path: str, parents: bool = True) -> None:
162
"""
163
Create directory on remote server.
164
165
Parameters:
166
- path: Directory path to create
167
- parents: Create parent directories if they don't exist
168
"""
169
170
async def remove_directory(self, path: str) -> None:
171
"""
172
Remove directory from remote server.
173
174
Parameters:
175
- path: Directory path to remove (must be empty)
176
"""
177
```
178
179
### Directory Listing
180
181
List and inspect remote directory contents with support for detailed file information and recursive listing.
182
183
```python { .api }
184
class Client:
185
def list(self, path: str = "", recursive: bool = False,
186
raw_command: str = None) -> AbstractAsyncLister:
187
"""
188
List directory contents on remote server.
189
190
Parameters:
191
- path: Directory path to list (current directory if empty)
192
- recursive: List subdirectories recursively
193
- raw_command: Raw FTP command to use instead of default
194
195
Returns:
196
Async iterator yielding (path, info) tuples
197
"""
198
199
async def stat(self, path: str) -> Union[BasicListInfo, UnixListInfo]:
200
"""
201
Get detailed information about remote path.
202
203
Parameters:
204
- path: Remote path to inspect
205
206
Returns:
207
Dictionary with file/directory information
208
"""
209
210
async def exists(self, path: str) -> bool:
211
"""
212
Check if remote path exists.
213
214
Parameters:
215
- path: Remote path to check
216
217
Returns:
218
True if path exists, False otherwise
219
"""
220
221
async def is_file(self, path: str) -> bool:
222
"""
223
Check if remote path is a file.
224
225
Parameters:
226
- path: Remote path to check
227
228
Returns:
229
True if path is a file, False otherwise
230
"""
231
232
async def is_dir(self, path: str) -> bool:
233
"""
234
Check if remote path is a directory.
235
236
Parameters:
237
- path: Remote path to check
238
239
Returns:
240
True if path is a directory, False otherwise
241
"""
242
```
243
244
### File Operations
245
246
Manipulate individual files including renaming, deleting, and generic removal operations.
247
248
```python { .api }
249
class Client:
250
async def rename(self, source: str, destination: str) -> None:
251
"""
252
Rename/move remote file or directory.
253
254
Parameters:
255
- source: Current path of file/directory
256
- destination: New path for file/directory
257
"""
258
259
async def remove_file(self, path: str) -> None:
260
"""
261
Remove file from remote server.
262
263
Parameters:
264
- path: File path to remove
265
"""
266
267
async def remove(self, path: str) -> None:
268
"""
269
Remove file or directory from remote server.
270
271
Parameters:
272
- path: Path to remove (file or empty directory)
273
"""
274
```
275
276
### Connection Control
277
278
Advanced connection operations including abort and low-level protocol access.
279
280
```python { .api }
281
class Client:
282
async def abort(self, wait: bool = True) -> None:
283
"""
284
Abort current FTP operation.
285
286
Parameters:
287
- wait: Wait for abort confirmation from server
288
"""
289
```
290
291
## Usage Examples
292
293
### Basic File Transfer
294
295
```python
296
import aioftp
297
import asyncio
298
299
async def basic_transfer():
300
async with aioftp.Client.context("ftp.example.com", user="username", password="password") as client:
301
# Upload a file
302
await client.upload("local_file.txt", "remote_file.txt")
303
304
# Download a file
305
await client.download("remote_file.txt", "downloaded_file.txt")
306
307
# Check if file exists
308
if await client.exists("remote_file.txt"):
309
print("File exists on server")
310
311
asyncio.run(basic_transfer())
312
```
313
314
### Directory Management
315
316
```python
317
import aioftp
318
import asyncio
319
320
async def directory_operations():
321
async with aioftp.Client.context("ftp.example.com") as client:
322
# Get current directory
323
current = await client.get_current_directory()
324
print(f"Current directory: {current}")
325
326
# Create a new directory
327
await client.make_directory("new_folder")
328
329
# Change to the new directory
330
await client.change_directory("new_folder")
331
332
# List contents
333
async for path, info in client.list():
334
file_type = "DIR" if info.get("type") == "dir" else "FILE"
335
size = info.get("size", "unknown")
336
print(f"{file_type}: {path} ({size} bytes)")
337
338
asyncio.run(directory_operations())
339
```
340
341
### Streaming Transfers
342
343
```python
344
import aioftp
345
import asyncio
346
347
async def streaming_transfer():
348
async with aioftp.Client.context("ftp.example.com") as client:
349
# Stream upload
350
async with client.upload_stream("remote_file.txt") as stream:
351
await stream.write(b"Hello, ")
352
await stream.write(b"World!")
353
354
# Stream download
355
async with client.download_stream("remote_file.txt") as stream:
356
data = await stream.read()
357
print(f"Downloaded: {data.decode()}")
358
359
asyncio.run(streaming_transfer())
360
```
361
362
### SSL/TLS Connection
363
364
```python
365
import aioftp
366
import asyncio
367
import ssl
368
369
async def secure_connection():
370
# Create SSL context
371
context = ssl.create_default_context()
372
373
async with aioftp.Client.context(
374
"ftps.example.com",
375
port=990, # FTPS implicit port
376
user="username",
377
password="password",
378
ssl=context
379
) as client:
380
await client.upload("local_file.txt", "secure_file.txt")
381
382
asyncio.run(secure_connection())
383
```
384
385
## Types
386
387
```python { .api }
388
# Type aliases and protocols
389
PathWithInfo = tuple[PurePosixPath, Union[BasicListInfo, UnixListInfo]]
390
391
class BasicListInfo(TypedDict):
392
"""Basic file information from directory listing."""
393
type: str # "file" or "dir"
394
size: int # File size in bytes
395
modify: str # Modification time string
396
397
class UnixListInfo(BasicListInfo):
398
"""Extended Unix-style file information."""
399
permissions: str # Permission string (e.g., "rwxr-xr-x")
400
owner: str # Owner name
401
group: str # Group name
402
links: int # Number of hard links
403
404
class DataConnectionThrottleStreamIO:
405
"""Throttled stream for FTP data connections."""
406
407
async def read(count: int = -1) -> bytes:
408
"""Read data from stream."""
409
410
async def write(data: bytes) -> None:
411
"""Write data to stream."""
412
413
async def finish(expected_codes: str = "2xx", wait_codes: str = "1xx") -> None:
414
"""Finish data transfer and wait for server confirmation."""
415
```