or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/pypi-aioftp

Asynchronous FTP client and server implementation for Python's asyncio framework

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/aioftp@0.26.x

To install, run

npx @tessl/cli install tessl/pypi-aioftp@0.26.0

0

# aioftp

1

2

A comprehensive asynchronous FTP client and server implementation for Python's asyncio framework. aioftp provides both client and server functionality with support for modern FTP commands including MLSD/MLST for machine-readable directory listings, passive mode transfers, resumable downloads/uploads, SSL/TLS encryption, and customizable path I/O abstractions.

3

4

## Package Information

5

6

- **Package Name**: aioftp

7

- **Language**: Python

8

- **Installation**: `pip install aioftp`

9

- **Optional Dependencies**: `pip install aioftp[socks]` for SOCKS proxy support

10

11

## Core Imports

12

13

```python

14

import aioftp

15

```

16

17

Common patterns for specific functionality:

18

19

```python

20

# Client operations

21

from aioftp import Client

22

23

# Server operations

24

from aioftp import Server, User, Permission

25

26

# Errors and exceptions

27

from aioftp import AIOFTPException, StatusCodeError

28

29

# Path I/O abstractions

30

from aioftp import PathIO, AsyncPathIO, MemoryPathIO

31

32

# Throttling and utilities

33

from aioftp import Throttle, StreamThrottle

34

35

# Type imports (for type annotations)

36

from pathlib import Path, PurePosixPath

37

from typing import Union, Optional, Dict, List, Tuple, AsyncIterator, AsyncIterable, Generator

38

```

39

40

## Basic Usage

41

42

### FTP Client

43

44

```python

45

import aioftp

46

import asyncio

47

48

async def client_example():

49

# Using context manager (recommended)

50

async with aioftp.Client.context("ftp.example.com") as client:

51

# Upload a file

52

await client.upload("local_file.txt", "remote_file.txt")

53

54

# Download a file

55

await client.download("remote_file.txt", "downloaded_file.txt")

56

57

# List directory contents

58

async for path, info in client.list():

59

print(f"{path}: {info['type']} ({info.get('size', 'unknown')} bytes)")

60

61

# Directory operations

62

await client.make_directory("new_folder")

63

await client.change_directory("new_folder")

64

current_dir = await client.get_current_directory()

65

print(f"Current directory: {current_dir}")

66

67

asyncio.run(client_example())

68

```

69

70

### FTP Server

71

72

```python

73

import aioftp

74

import asyncio

75

from pathlib import Path

76

77

async def server_example():

78

# Create users with permissions

79

users = [

80

aioftp.User(

81

login="admin",

82

password="secret",

83

base_path=Path("/srv/ftp"),

84

permissions=[

85

aioftp.Permission("/", readable=True, writable=True),

86

]

87

),

88

aioftp.User( # Anonymous user

89

base_path=Path("/srv/ftp/public"),

90

permissions=[

91

aioftp.Permission("/", readable=True, writable=False),

92

]

93

)

94

]

95

96

# Create and run server

97

server = aioftp.Server(users=users)

98

await server.run(host="localhost", port=2121)

99

100

asyncio.run(server_example())

101

```

102

103

## Architecture

104

105

aioftp follows a modular design with distinct layers:

106

107

- **Client Layer**: BaseClient provides protocol implementation, Client adds high-level operations

108

- **Server Layer**: Server handles protocol, User/Permission system manages access control

109

- **Transport Layer**: StreamIO and ThrottleStreamIO provide connection abstractions with speed limiting

110

- **Path I/O Layer**: AbstractPathIO enables filesystem abstraction (local, async, in-memory)

111

- **Protocol Layer**: Code class and command handlers implement FTP protocol semantics

112

113

The library supports both traditional blocking I/O (PathIO) and fully asynchronous I/O (AsyncPathIO), with a memory-based implementation (MemoryPathIO) for testing. Connection throttling and SSL/TLS are supported throughout.

114

115

## Capabilities

116

117

### FTP Client Operations

118

119

High-level FTP client functionality including connection management, authentication, file transfers, directory operations, and listing. Supports context managers, streaming operations, and various connection options.

120

121

```python { .api }

122

class Client(BaseClient):

123

@classmethod

124

async def context(host: str, port: int = 21, user: str = "anonymous",

125

password: str = "anon@", account: str = "",

126

upgrade_to_tls: bool = False, **kwargs) -> AsyncGenerator[Client]:

127

"""Async context manager for FTP client connections."""

128

129

async def connect(host: str, port: int = 21) -> list[str]:

130

"""Connect to FTP server and return greeting."""

131

132

async def login(user: str = "anonymous", password: str = "anon@",

133

account: str = "") -> None:

134

"""Authenticate with the FTP server."""

135

136

async def upload(source, destination: str = "", write_into: bool = False,

137

block_size: int = 8192) -> None:

138

"""Upload a file to the server."""

139

140

async def download(source, destination: str = "", write_into: bool = False,

141

block_size: int = 8192) -> None:

142

"""Download a file from the server."""

143

144

def list(path: str = "", recursive: bool = False,

145

raw_command: str = None) -> AbstractAsyncLister:

146

"""List directory contents."""

147

```

148

149

[FTP Client](./client.md)

150

151

### FTP Server Implementation

152

153

Complete FTP server with user management, permission system, connection limiting, and protocol command handlers. Supports SSL/TLS, custom path I/O backends, and extensive configuration options.

154

155

```python { .api }

156

class Server:

157

def __init__(users=None, block_size: int = 8192, socket_timeout=None,

158

idle_timeout=None, wait_future_timeout: int = 1, path_timeout=None,

159

path_io_factory=PathIO, maximum_connections=None,

160

read_speed_limit=None, write_speed_limit=None, **kwargs):

161

"""Initialize FTP server with configuration."""

162

163

async def start(host: str = None, port: int = 0, **kwargs) -> None:

164

"""Start the FTP server."""

165

166

async def run(host: str = None, port: int = 0, **kwargs) -> None:

167

"""Start server and run forever."""

168

169

async def close() -> None:

170

"""Close the server and all connections."""

171

172

class User:

173

def __init__(login: str = None, password: str = None,

174

base_path: Path = Path("."), home_path: PurePosixPath = PurePosixPath("/"),

175

permissions: list[Permission] = None, maximum_connections: int = None,

176

read_speed_limit: int = None, write_speed_limit: int = None):

177

"""User account with credentials and permissions."""

178

179

class Permission:

180

def __init__(path: str = "/", readable: bool = True, writable: bool = True):

181

"""Path permission specification."""

182

```

183

184

[FTP Server](./server.md)

185

186

### Error Handling

187

188

Exception hierarchy for FTP operations including protocol errors, path validation, and I/O errors. All exceptions inherit from AIOFTPException for consistent error handling.

189

190

```python { .api }

191

class AIOFTPException(Exception):

192

"""Base exception for all aioftp errors."""

193

194

class StatusCodeError(AIOFTPException):

195

"""Raised when FTP server returns unexpected status code."""

196

expected_codes: tuple[Code, ...]

197

received_codes: tuple[Code, ...]

198

info: Union[list[str], str]

199

200

class PathIsNotAbsolute(AIOFTPException):

201

"""Raised when path is not absolute but should be."""

202

203

class PathIOError(AIOFTPException):

204

"""Universal exception for path I/O operations."""

205

reason: Union[tuple, None] # Original exception info

206

207

class NoAvailablePort(AIOFTPException, OSError):

208

"""Raised when no data ports are available."""

209

```

210

211

[Error Handling](./errors.md)

212

213

### Stream and Throttling

214

215

Stream wrappers with timeout and throttling support for controlling data transfer rates. Includes both simple streams and throttled streams with configurable read/write limits.

216

217

```python { .api }

218

class StreamIO:

219

def __init__(reader: asyncio.StreamReader, writer: asyncio.StreamWriter,

220

timeout: float = None, read_timeout: float = None,

221

write_timeout: float = None):

222

"""Basic stream wrapper with timeout support."""

223

224

async def read(count: int = -1) -> bytes:

225

"""Read data from stream."""

226

227

async def write(data: bytes) -> None:

228

"""Write data to stream."""

229

230

class Throttle:

231

def __init__(limit: int = None, reset_rate: int = 10):

232

"""Speed throttling mechanism."""

233

234

async def wait() -> None:

235

"""Wait if throttling is needed."""

236

237

class ThrottleStreamIO(StreamIO):

238

def __init__(reader: asyncio.StreamReader, writer: asyncio.StreamWriter,

239

throttles: dict[str, StreamThrottle] = {}, **kwargs):

240

"""Stream with throttling support."""

241

```

242

243

[Streaming and Throttling](./streaming.md)

244

245

### Path I/O Abstractions

246

247

Filesystem abstraction layer supporting synchronous, asynchronous, and in-memory implementations. Enables custom backends and testing with memory-based filesystems.

248

249

```python { .api }

250

class AbstractPathIO(Generic[PathType]):

251

"""Abstract base class for filesystem operations."""

252

253

async def exists(path: PathType) -> bool:

254

"""Check if path exists."""

255

256

async def is_file(path: PathType) -> bool:

257

"""Check if path is a file."""

258

259

async def is_dir(path: PathType) -> bool:

260

"""Check if path is a directory."""

261

262

def open(path: PathType, mode: str = "rb") -> AsyncPathIOContext:

263

"""Open file for reading/writing."""

264

265

class PathIO(AbstractPathIO[Path]):

266

"""Synchronous filesystem operations using pathlib.Path."""

267

268

class AsyncPathIO(AbstractPathIO[Path]):

269

"""Asynchronous filesystem operations via executor."""

270

271

class MemoryPathIO(AbstractPathIO[PurePosixPath]):

272

"""In-memory filesystem for testing."""

273

```

274

275

[Path I/O](./pathio.md)

276

277

### Common Utilities

278

279

Core utility functions, decorators, and classes for FTP operations including status code handling, timeouts, locale management, and async context management.

280

281

```python { .api }

282

class Code(str):

283

"""Representation of server status code with template matching."""

284

def matches(self, mask: str) -> bool:

285

"""Template comparison for status codes (e.g., '2xx', '4xx')."""

286

287

class Connection(defaultdict[str, asyncio.Future]):

288

"""Connection state container for async coordination between components."""

289

290

class SSLSessionBoundContext:

291

"""SSL context bound to existing session for connection reuse."""

292

293

def with_timeout(func, timeout: float = None):

294

"""Decorator adding timeout to async methods."""

295

296

def async_enterable(func):

297

"""Decorator to bring coroutine result up for async context usage."""

298

299

def setlocale(name: str) -> Generator[str, None, None]:

300

"""Thread-safe locale context manager for system locale changes."""

301

302

def wrap_with_container() -> Callable:

303

"""Utility function for container wrapping operations."""

304

305

def wrap_into_codes() -> Callable:

306

"""Utility to wrap iterables into Code tuples for status handling."""

307

```

308

309

## Constants and Utilities

310

311

```python { .api }

312

# Default values

313

DEFAULT_PORT: int = 21

314

DEFAULT_USER: str = "anonymous"

315

DEFAULT_PASSWORD: str = "anon@"

316

DEFAULT_ACCOUNT: str = ""

317

DEFAULT_BLOCK_SIZE: int = 8192

318

END_OF_LINE: str = "\\r\\n"

319

320

# Version information

321

__version__: str # Package version string

322

version: tuple[int, ...] # Version as tuple of integers

323

```