or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client.mderrors.mdindex.mdpathio.mdserver.mdstreaming.md

client.mddocs/

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

```