or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

channel-management.mddns-queries.mderror-handling.mdhost-resolution.mdindex.mdutilities.md

utilities.mddocs/

0

# Utility Functions

1

2

String encoding and domain name processing utilities for handling international domain names, proper ASCII encoding, and data conversion within pycares operations.

3

4

## Capabilities

5

6

### String Encoding

7

8

Convert various string and bytes types to appropriate formats for DNS operations.

9

10

```python { .api }

11

def ascii_bytes(data):

12

"""

13

Convert string or bytes data to ASCII bytes.

14

15

Args:

16

data: Union[str, bytes] - Input data to convert

17

18

Returns:

19

bytes: ASCII-encoded bytes

20

21

Raises:

22

TypeError: If data is neither str nor bytes

23

"""

24

25

def maybe_str(data):

26

"""

27

Convert bytes to string if possible, otherwise return as-is.

28

29

Attempts to decode bytes data to ASCII string. If decoding fails,

30

returns the original bytes object.

31

32

Args:

33

data: Union[str, bytes] - Input data to convert

34

35

Returns:

36

Union[str, bytes]: String if decodable to ASCII, otherwise bytes

37

38

Raises:

39

TypeError: If data is neither str nor bytes

40

"""

41

```

42

43

**Usage Example:**

44

45

```python

46

import pycares

47

48

# Convert string to ASCII bytes

49

hostname_bytes = pycares.ascii_bytes("example.com")

50

print(hostname_bytes) # b'example.com'

51

52

# Convert bytes to string if possible

53

result = pycares.maybe_str(b"example.com")

54

print(result) # 'example.com'

55

56

# Binary data stays as bytes

57

binary_data = b'\x00\x01\x02'

58

result = pycares.maybe_str(binary_data)

59

print(type(result)) # <class 'bytes'>

60

```

61

62

### Domain Name Processing

63

64

Process domain names for DNS queries, including support for internationalized domain names (IDNA).

65

66

```python { .api }

67

def parse_name(name):

68

"""

69

Parse and encode domain name for DNS queries.

70

71

Handles both ASCII and internationalized domain names. For ASCII names,

72

performs direct encoding. For international domain names, uses IDNA 2008

73

encoding if the idna package is available, otherwise falls back to

74

built-in IDNA 2003 encoding.

75

76

Args:

77

name: Union[str, bytes] - Domain name to parse

78

79

Returns:

80

bytes: Properly encoded domain name for DNS queries

81

82

Raises:

83

TypeError: If name is neither str nor bytes

84

RuntimeError: If domain part exceeds 253 characters

85

"""

86

```

87

88

**Usage Example:**

89

90

```python

91

import pycares

92

93

# ASCII domain name

94

ascii_domain = pycares.parse_name("example.com")

95

print(ascii_domain) # b'example.com'

96

97

# International domain name (requires idna package for IDNA 2008)

98

try:

99

intl_domain = pycares.parse_name("例え.テスト")

100

print(intl_domain) # Encoded bytes representation

101

except RuntimeError as e:

102

print(f"Domain name too long: {e}")

103

104

# Bytes input passes through

105

bytes_domain = pycares.parse_name(b"example.org")

106

print(bytes_domain) # b'example.org'

107

```

108

109

## IDNA Support

110

111

pycares provides enhanced internationalized domain name support when the optional `idna` package is installed:

112

113

```python

114

# Install with IDNA 2008 support

115

# pip install pycares[idna]

116

```

117

118

### IDNA 2008 vs IDNA 2003

119

120

- **With idna package**: Uses modern IDNA 2008 standard for better Unicode support

121

- **Without idna package**: Falls back to Python's built-in IDNA 2003 codec

122

- **ASCII domains**: No difference, processed efficiently in both cases

123

124

### Domain Length Limits

125

126

The `parse_name` function enforces DNS domain length limits:

127

128

- Individual labels (parts between dots) must be ≤ 253 characters after encoding

129

- Total domain name length should comply with DNS standards

130

131

**Example with Error Handling:**

132

133

```python

134

import pycares

135

136

def safe_parse_name(domain):

137

"""Safely parse domain name with error handling."""

138

try:

139

return pycares.parse_name(domain)

140

except TypeError:

141

print(f"Invalid domain type: {type(domain)}")

142

return None

143

except RuntimeError as e:

144

print(f"Domain name error: {e}")

145

return None

146

147

# Test with various inputs

148

domains = [

149

"example.com", # ASCII domain

150

"例え.テスト", # International domain

151

b"binary.domain", # Bytes input

152

123, # Invalid type

153

"a" * 300 + ".com" # Too long

154

]

155

156

for domain in domains:

157

result = safe_parse_name(domain)

158

if result:

159

print(f"Parsed: {domain} -> {result}")

160

else:

161

print(f"Failed to parse: {domain}")

162

```

163

164

## Integration with DNS Operations

165

166

These utility functions are used internally by pycares but can also be used directly when working with domain names and DNS data:

167

168

```python

169

import pycares

170

171

def custom_dns_query(channel, raw_name, query_type, callback):

172

"""Example showing manual name processing."""

173

try:

174

# Process domain name using utility function

175

encoded_name = pycares.parse_name(raw_name)

176

177

# Use processed name in query

178

# (Note: pycares.Channel.query() handles this internally)

179

channel.query(encoded_name.decode('ascii'), query_type, callback)

180

181

except (TypeError, RuntimeError, UnicodeDecodeError) as e:

182

# Handle name processing errors

183

callback(None, pycares.errno.ARES_EBADNAME)

184

185

# Usage

186

channel = pycares.Channel()

187

custom_dns_query(channel, "example.com", pycares.QUERY_TYPE_A, lambda r, e: print(r, e))

188

```

189

190

## Module Exports

191

192

The utilities module exports the following functions in its `__all__` list:

193

194

```python { .api }

195

__all__ = ['ascii_bytes', 'maybe_str', 'parse_name']

196

```

197

198

These functions are also available directly from the main pycares module after import.