or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-handlers.mddata-utilities.mdindex.mdsync-handlers.md

data-utilities.mddocs/

0

# Data Structures and Utilities

1

2

Response objects, caching system, exception handling, and utility functions for data formatting, validation, and configuration management in the IPInfo Python library.

3

4

## Capabilities

5

6

### Details Response Object

7

8

The primary response object that encapsulates IP address information with attribute-based access and data enrichment functionality.

9

10

```python { .api }

11

class Details:

12

def __init__(self, details):

13

"""

14

Initialize Details object with IP information dictionary.

15

16

Parameters:

17

- details (dict): Dictionary containing IP address information

18

"""

19

20

def __getattr__(self, attr):

21

"""

22

Return attribute if it exists in details, else raise AttributeError.

23

24

Parameters:

25

- attr (str): Attribute name to access

26

27

Returns:

28

Any: Value of the requested attribute

29

30

Raises:

31

AttributeError: When attribute doesn't exist in details

32

"""

33

34

@property

35

def all(self):

36

"""

37

Return all details as dictionary.

38

39

Returns:

40

dict: Complete details dictionary

41

"""

42

```

43

44

### Exception Classes

45

46

Specialized exception classes for handling API errors, quota limits, and timeout conditions.

47

48

```python { .api }

49

class RequestQuotaExceededError(Exception):

50

"""

51

Error indicating that user's monthly request quota has been exceeded.

52

53

Raised when API returns 429 status code.

54

"""

55

56

class TimeoutExceededError(Exception):

57

"""

58

Error indicating that some timeout has been exceeded.

59

60

Raised when operation exceeds specified timeout limits.

61

"""

62

63

class APIError(Exception):

64

def __init__(self, error_code, error_json):

65

"""

66

General API error with status code and response details.

67

68

Parameters:

69

- error_code (int): HTTP status code

70

- error_json (dict): Error response JSON

71

"""

72

73

def __str__(self):

74

"""

75

Return formatted error string with code and JSON response.

76

77

Returns:

78

str: Formatted error message

79

"""

80

```

81

82

### Cache System

83

84

Abstract cache interface and default LRU implementation for efficient IP data caching.

85

86

```python { .api }

87

class CacheInterface:

88

"""Abstract interface for custom cache implementations."""

89

90

def __contains__(self, key):

91

"""Check if key exists in cache."""

92

93

def __setitem__(self, key, value):

94

"""Set cache value for key."""

95

96

def __getitem__(self, key):

97

"""Get cache value for key."""

98

99

def __delitem__(self, key):

100

"""Delete cache entry for key."""

101

102

class DefaultCache(CacheInterface):

103

def __init__(self, **cache_options):

104

"""

105

Default in-memory LRU cache with TTL support.

106

107

Parameters:

108

- **cache_options: Options passed to cachetools.TTLCache

109

- maxsize (int): Maximum cache entries (default: 4096)

110

- ttl (int): Time to live in seconds (default: 86400)

111

"""

112

113

def __contains__(self, key):

114

"""Check if key exists in cache."""

115

116

def __setitem__(self, key, value):

117

"""Set cache value for key."""

118

119

def __getitem__(self, key):

120

"""Get cache value for key."""

121

122

def __delitem__(self, key):

123

"""Delete cache entry for key."""

124

```

125

126

### Utility Functions

127

128

Helper functions for HTTP headers, data formatting, file I/O, and cache key management.

129

130

```python { .api }

131

def get_headers(access_token, custom_headers):

132

"""

133

Build headers for request to IPinfo API.

134

135

Parameters:

136

- access_token (str, optional): API access token

137

- custom_headers (dict, optional): Custom HTTP headers

138

139

Returns:

140

dict: Complete headers dictionary with user-agent, accept, and authorization

141

"""

142

143

def format_details(details, countries, eu_countries, countries_flags, countries_currencies, continents):

144

"""

145

Format details dictionary with additional country and geographic data.

146

147

Adds country_name, isEU, country_flag_url, country_flag,

148

country_currency, continent, latitude, and longitude fields.

149

150

Parameters:

151

- details (dict): Raw IP details to format

152

- countries (dict): Country code to name mappings

153

- eu_countries (list): List of EU country codes

154

- countries_flags (dict): Country flag data

155

- countries_currencies (dict): Country currency data

156

- continents (dict): Continent mappings

157

"""

158

159

def read_coords(location):

160

"""

161

Parse location string into latitude and longitude tuple.

162

163

Parameters:

164

- location (str): Location string in format "lat,lon"

165

166

Returns:

167

tuple: (latitude, longitude) as strings, or (None, None) if invalid

168

"""

169

170

def read_json_file(json_file):

171

"""

172

Read and parse JSON file from package data directory.

173

174

Parameters:

175

- json_file (str): Filename relative to package directory

176

177

Returns:

178

dict: Parsed JSON data

179

"""

180

181

def return_or_fail(raise_on_fail, e, v):

182

"""

183

Either raise exception or return value based on flag.

184

185

Parameters:

186

- raise_on_fail (bool): Whether to raise exception

187

- e (Exception): Exception to raise

188

- v (Any): Value to return if not raising

189

190

Returns:

191

Any: Returns v if raise_on_fail is False

192

193

Raises:

194

Exception: Raises e if raise_on_fail is True

195

"""

196

197

def cache_key(k):

198

"""

199

Transform user input key into versioned cache key.

200

201

Parameters:

202

- k (str): User input key

203

204

Returns:

205

str: Versioned cache key

206

"""

207

```

208

209

### Bogon Detection

210

211

Functions for identifying private and reserved IP address ranges.

212

213

```python { .api }

214

def is_bogon(ip_address):

215

"""

216

Check if IP address is a bogon (private/reserved address).

217

218

Parameters:

219

- ip_address (str): IP address to check

220

221

Returns:

222

bool: True if IP is in bogon networks, False otherwise

223

"""

224

225

# Predefined bogon networks

226

BOGON_NETWORKS = [

227

# IPv4 bogon networks

228

ipaddress.ip_network("0.0.0.0/8"), # This network

229

ipaddress.ip_network("10.0.0.0/8"), # Private-use

230

ipaddress.ip_network("127.0.0.0/8"), # Loopback

231

ipaddress.ip_network("169.254.0.0/16"), # Link-local

232

ipaddress.ip_network("172.16.0.0/12"), # Private-use

233

ipaddress.ip_network("192.168.0.0/16"), # Private-use

234

# ... additional bogon networks

235

]

236

```

237

238

### Data Constants

239

240

Pre-loaded geographic and internationalization data for response enrichment.

241

242

```python { .api }

243

# Geographic data mappings

244

continents = {

245

"US": {"code": "NA", "name": "North America"},

246

"GB": {"code": "EU", "name": "Europe"},

247

# ... complete country to continent mappings

248

}

249

250

countries = {

251

"US": "United States",

252

"GB": "United Kingdom",

253

# ... complete country code to name mappings

254

}

255

256

countries_currencies = {

257

"US": {"code": "USD", "symbol": "$"},

258

"GB": {"code": "GBP", "symbol": "£"},

259

# ... complete currency mappings

260

}

261

262

eu_countries = [

263

"AT", "BE", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR",

264

"DE", "GR", "HU", "IE", "IT", "LV", "LT", "LU", "MT", "NL",

265

"PL", "PT", "RO", "SK", "SI", "ES", "SE"

266

]

267

268

countries_flags = {

269

"US": {"emoji": "🇺🇸", "unicode": "U+1F1FA U+1F1F8"},

270

"GB": {"emoji": "🇬🇧", "unicode": "U+1F1EC U+1F1E7"},

271

# ... complete flag mappings

272

}

273

274

# API endpoints and configuration

275

API_URL = "https://ipinfo.io"

276

LITE_API_URL = "https://api.ipinfo.io/lite"

277

COUNTRY_FLAGS_URL = "https://cdn.ipinfo.io/static/images/countries-flags/"

278

BATCH_MAX_SIZE = 1000

279

CACHE_MAXSIZE = 4096

280

CACHE_TTL = 86400 # 24 hours

281

REQUEST_TIMEOUT_DEFAULT = 2

282

BATCH_REQ_TIMEOUT_DEFAULT = 5

283

```

284

285

## Usage Examples

286

287

### Custom Cache Implementation

288

289

```python

290

import ipinfo

291

from ipinfo.cache.interface import CacheInterface

292

import redis

293

294

class RedisCache(CacheInterface):

295

"""Redis-based cache implementation"""

296

297

def __init__(self, redis_client, ttl=86400):

298

self.redis = redis_client

299

self.ttl = ttl

300

301

def __contains__(self, key):

302

return self.redis.exists(key)

303

304

def __setitem__(self, key, value):

305

import json

306

self.redis.setex(key, self.ttl, json.dumps(value))

307

308

def __getitem__(self, key):

309

import json

310

value = self.redis.get(key)

311

if value is None:

312

raise KeyError(key)

313

return json.loads(value)

314

315

def __delitem__(self, key):

316

self.redis.delete(key)

317

318

# Use custom cache

319

redis_client = redis.Redis()

320

custom_cache = RedisCache(redis_client)

321

handler = ipinfo.getHandler('token', cache=custom_cache)

322

```

323

324

### Working with Details Object

325

326

```python

327

import ipinfo

328

329

handler = ipinfo.getHandler('your_token')

330

details = handler.getDetails('8.8.8.8')

331

332

# Access individual attributes

333

print(details.city) # Mountain View

334

print(details.country) # US

335

print(details.country_name) # United States

336

print(details.isEU) # False

337

print(details.latitude) # 37.3860

338

print(details.longitude) # -122.0838

339

340

# Access all data as dictionary

341

all_data = details.all

342

print(all_data['hostname']) # dns.google

343

344

# Handle missing attributes

345

try:

346

print(details.nonexistent_field)

347

except AttributeError as e:

348

print(f"Field not available: {e}")

349

```

350

351

### Error Handling

352

353

```python

354

import ipinfo

355

from ipinfo.exceptions import RequestQuotaExceededError, TimeoutExceededError

356

from ipinfo.error import APIError

357

358

handler = ipinfo.getHandler('invalid_token')

359

360

try:

361

details = handler.getDetails('8.8.8.8')

362

except RequestQuotaExceededError:

363

print("Quota exceeded - upgrade your plan")

364

except APIError as e:

365

print(f"API Error {e.error_code}")

366

print(f"Details: {e.error_json}")

367

except TimeoutExceededError:

368

print("Request timed out")

369

```

370

371

### Bogon Detection

372

373

```python

374

from ipinfo.bogon import is_bogon

375

376

# Check if IP is private/reserved

377

print(is_bogon('192.168.1.1')) # True (private)

378

print(is_bogon('8.8.8.8')) # False (public)

379

print(is_bogon('127.0.0.1')) # True (loopback)

380

```

381

382

### Custom Data Files

383

384

```python

385

import ipinfo

386

387

# Custom country names (e.g., for localization)

388

custom_countries = {

389

"US": "États-Unis",

390

"FR": "France",

391

"DE": "Allemagne"

392

}

393

394

# Custom EU country list

395

custom_eu = ["FR", "DE", "IT", "ES"] # Subset for example

396

397

handler = ipinfo.getHandler(

398

'your_token',

399

countries=custom_countries,

400

eu_countries=custom_eu

401

)

402

403

details = handler.getDetails('8.8.8.8')

404

print(details.country_name) # Uses custom mapping

405

print(details.isEU) # Uses custom EU list

406

```

407

408

## Types

409

410

```python { .api }

411

# Details object structure

412

DetailsDict = {

413

# Core API fields

414

'ip': str,

415

'hostname': str,

416

'city': str,

417

'region': str,

418

'country': str,

419

'loc': str, # "latitude,longitude"

420

'org': str,

421

'postal': str,

422

'timezone': str,

423

424

# Enhanced fields (added by library)

425

'country_name': str,

426

'latitude': str,

427

'longitude': str,

428

'isEU': bool,

429

'country_flag': dict, # {"emoji": str, "unicode": str}

430

'country_currency': dict, # {"code": str, "symbol": str}

431

'continent': dict, # {"code": str, "name": str}

432

'country_flag_url': str,

433

434

# Optional fields (may be present)

435

'asn': dict, # ASN information

436

'company': dict, # Company information

437

'carrier': dict, # Mobile carrier info

438

'privacy': dict, # Privacy/VPN detection

439

'abuse': dict, # Abuse contact info

440

'domains': dict # Associated domains

441

}

442

443

# Cache interface type

444

CacheInterface = {

445

'__contains__': callable,

446

'__getitem__': callable,

447

'__setitem__': callable,

448

'__delitem__': callable

449

}

450

451

# Geographic data types

452

CountryMapping = dict # Country code -> name

453

ContinentMapping = dict # Country code -> {"code": str, "name": str}

454

FlagMapping = dict # Country code -> {"emoji": str, "unicode": str}

455

CurrencyMapping = dict # Country code -> {"code": str, "symbol": str}

456

```