or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-models.mddashboard.mddata-connection.mddata-formatting.mdindex.mdplugin-system.mdtranslation.mdui-styling.mdvalidation-math.md

data-connection.mddocs/

0

# Data Connection

1

2

This module provides HTTP client functionality and API utilities for communicating with Superset backend services. It includes a comprehensive HTTP client with authentication, error handling, retry logic, and support for both singleton and instance-based usage patterns.

3

4

## Overview

5

6

The data connection module is built around three core components: the `SupersetClient` singleton for global API communication, the `SupersetClientClass` for instance-based usage, and the `callApi` function for direct HTTP requests. It supports CSRF token management, guest authentication, automatic retries, and comprehensive error handling.

7

8

## SupersetClient (Singleton)

9

10

### SupersetClient Interface { .api }

11

12

The main singleton interface for making API calls throughout your application:

13

14

```typescript

15

import { SupersetClient } from '@superset-ui/core';

16

17

interface SupersetClientInterface {

18

// Configuration

19

configure(config: ClientConfig): SupersetClientInterface;

20

reset(): void;

21

22

// HTTP Methods

23

get(request: RequestConfig): Promise<Response>;

24

post(request: RequestConfig): Promise<Response>;

25

put(request: RequestConfig): Promise<Response>;

26

delete(request: RequestConfig): Promise<Response>;

27

request(request: RequestConfig): Promise<Response>;

28

29

// Authentication

30

init(force?: boolean): Promise<void>;

31

isAuthenticated(): boolean;

32

reAuthenticate(): Promise<void>;

33

}

34

35

// Configuration interface

36

interface ClientConfig {

37

baseUrl?: string;

38

host?: string;

39

protocol?: 'http:' | 'https:';

40

headers?: Headers;

41

fetchRetryOptions?: FetchRetryOptions;

42

mode?: RequestMode;

43

timeout?: number;

44

credentials?: RequestCredentials;

45

csrfToken?: string;

46

guestToken?: string;

47

guestTokenHeaderName?: string;

48

handleUnauthorized?: () => void;

49

}

50

```

51

52

### SupersetClientClass { .api }

53

54

Instance-based HTTP client class for custom configurations:

55

56

```typescript

57

import { SupersetClientClass } from '@superset-ui/core';

58

59

class SupersetClientClass {

60

// Configuration properties

61

readonly credentials: RequestCredentials;

62

readonly baseUrl: string;

63

readonly protocol: Protocol;

64

readonly host: Host;

65

readonly headers: Headers;

66

readonly mode: RequestMode;

67

readonly timeout: ClientTimeout;

68

readonly fetchRetryOptions: FetchRetryOptions;

69

readonly guestTokenHeaderName: string;

70

readonly handleUnauthorized: () => void;

71

72

// Authentication state

73

csrfToken?: string;

74

guestToken?: string;

75

76

constructor(config: ClientConfig);

77

78

// HTTP Methods

79

get(request: RequestConfig): Promise<Response>;

80

post(request: RequestConfig): Promise<Response>;

81

put(request: RequestConfig): Promise<Response>;

82

delete(request: RequestConfig): Promise<Response>;

83

request(request: RequestConfig): Promise<Response>;

84

85

// Authentication management

86

init(force?: boolean): Promise<void>;

87

isAuthenticated(): boolean;

88

reAuthenticate(): Promise<void>;

89

ensureAuth(): Promise<void>;

90

91

// Internal utilities

92

getUrl(endpoint: string): string;

93

normalizeRequestConfig(request: RequestConfig): RequestConfig;

94

}

95

```

96

97

## Request Configuration

98

99

### RequestConfig Interface { .api }

100

101

Configuration options for individual API requests:

102

103

```typescript

104

interface RequestConfig extends RequestBase {

105

endpoint: string;

106

url?: string;

107

host?: string;

108

timeout?: ClientTimeout;

109

jsonPayload?: Payload;

110

postPayload?: Payload;

111

parseMethod?: ParseMethod;

112

stringify?: boolean;

113

fetchRetryOptions?: FetchRetryOptions;

114

}

115

116

interface RequestBase {

117

body?: RequestInit['body'];

118

credentials?: RequestCredentials;

119

headers?: Headers;

120

method?: RequestInit['method'];

121

mode?: RequestInit['mode'];

122

redirect?: RequestInit['redirect'];

123

signal?: RequestInit['signal'];

124

}

125

126

// Supported parse methods

127

type ParseMethod = 'json' | 'text' | 'raw' | null | undefined;

128

```

129

130

### Retry Configuration { .api }

131

132

Configuration for automatic request retries:

133

134

```typescript

135

interface FetchRetryOptions {

136

retries?: number;

137

retryDelay?: number | ((attempt: number, error: Error, response: Response) => number);

138

retryOn?: number[] | ((attempt: number, error: Error, response: Response) => boolean);

139

}

140

141

// Default retry configuration

142

const DEFAULT_FETCH_RETRY_OPTIONS: FetchRetryOptions = {

143

retries: 3,

144

retryDelay: 1000,

145

retryOn: [408, 429, 500, 502, 503, 504]

146

};

147

```

148

149

## Core API Function

150

151

### callApi Function { .api }

152

153

Direct API calling utility with timeout support:

154

155

```typescript

156

import { callApi } from '@superset-ui/core';

157

158

function callApi(config: {

159

url: string;

160

method?: RequestInit['method'];

161

body?: RequestInit['body'];

162

headers?: HeadersInit;

163

credentials?: RequestCredentials;

164

mode?: RequestInit['mode'];

165

timeout?: number;

166

signal?: AbortSignal;

167

parseMethod?: ParseMethod;

168

}): Promise<Response>;

169

```

170

171

## Type Definitions

172

173

### Core Types { .api }

174

175

Essential type definitions for the connection module:

176

177

```typescript

178

// Basic types

179

type Host = string;

180

type Endpoint = string;

181

type Headers = { [key: string]: string };

182

type Protocol = 'http:' | 'https:';

183

type ClientTimeout = number | undefined;

184

185

// JSON types

186

type JsonPrimitive = string | number | boolean | null;

187

type JsonValue = JsonPrimitive | JsonObject | JsonArray;

188

type JsonArray = JsonValue[];

189

type JsonObject = { [member: string]: any };

190

191

// Strict JSON types for type safety

192

type StrictJsonValue = JsonPrimitive | StrictJsonObject | StrictJsonArray;

193

type StrictJsonArray = StrictJsonValue[];

194

type StrictJsonObject = { [member: string]: StrictJsonValue };

195

196

// Request payload types

197

type Payload = JsonObject | string | null;

198

type Body = RequestInit['body'];

199

200

// Authentication types

201

type CsrfToken = string;

202

type CsrfPromise = Promise<CsrfToken>;

203

```

204

205

## Usage Examples

206

207

### Basic Configuration and Usage

208

209

```typescript

210

import { SupersetClient } from '@superset-ui/core';

211

212

// Configure the global client

213

SupersetClient.configure({

214

host: 'http://localhost:8088',

215

headers: {

216

'Content-Type': 'application/json'

217

},

218

fetchRetryOptions: {

219

retries: 3,

220

retryDelay: 1000

221

}

222

});

223

224

// Initialize authentication

225

await SupersetClient.init();

226

227

// Make API calls

228

const dashboards = await SupersetClient.get({

229

endpoint: '/api/v1/dashboard/'

230

});

231

232

const newChart = await SupersetClient.post({

233

endpoint: '/api/v1/chart/',

234

jsonPayload: {

235

slice_name: 'My Chart',

236

viz_type: 'table'

237

}

238

});

239

```

240

241

### Error Handling and Retries

242

243

```typescript

244

import { SupersetClient } from '@superset-ui/core';

245

246

// Configure with custom retry logic

247

SupersetClient.configure({

248

host: 'http://localhost:8088',

249

fetchRetryOptions: {

250

retries: 5,

251

retryDelay: (attempt, error, response) => {

252

// Exponential backoff

253

return Math.pow(2, attempt) * 1000;

254

},

255

retryOn: (attempt, error, response) => {

256

// Retry on network errors or 5xx status codes

257

return !response || response.status >= 500;

258

}

259

},

260

handleUnauthorized: () => {

261

// Custom unauthorized handler

262

window.location.href = '/login';

263

}

264

});

265

266

// Make request with error handling

267

try {

268

const response = await SupersetClient.get({

269

endpoint: '/api/v1/dataset/',

270

timeout: 30000 // 30 second timeout

271

});

272

273

const data = await response.json();

274

console.log('Datasets:', data.result);

275

} catch (error) {

276

console.error('Failed to fetch datasets:', error);

277

}

278

```

279

280

### Custom Client Instance

281

282

```typescript

283

import { SupersetClientClass } from '@superset-ui/core';

284

285

// Create custom client for specific API

286

const analyticsClient = new SupersetClientClass({

287

baseUrl: 'https://analytics-api.example.com',

288

headers: {

289

'Authorization': 'Bearer ' + apiToken,

290

'X-API-Version': '2.0'

291

},

292

timeout: 60000,

293

fetchRetryOptions: {

294

retries: 2,

295

retryDelay: 2000

296

}

297

});

298

299

// Use custom client

300

const metrics = await analyticsClient.get({

301

endpoint: '/metrics',

302

parseMethod: 'json'

303

});

304

```

305

306

### Direct API Calls

307

308

```typescript

309

import { callApi } from '@superset-ui/core';

310

311

// Direct API call without client configuration

312

const response = await callApi({

313

url: 'http://localhost:8088/api/v1/chart/1',

314

method: 'GET',

315

headers: {

316

'Authorization': 'Bearer token123'

317

},

318

timeout: 10000,

319

parseMethod: 'json'

320

});

321

322

const chartData = await response.json();

323

```

324

325

### Authentication Management

326

327

```typescript

328

import { SupersetClient } from '@superset-ui/core';

329

330

// Check authentication status

331

if (!SupersetClient.isAuthenticated()) {

332

// Force re-authentication

333

await SupersetClient.reAuthenticate();

334

}

335

336

// Manual CSRF token handling

337

SupersetClient.configure({

338

csrfToken: 'manual-csrf-token',

339

guestToken: 'guest-session-token',

340

guestTokenHeaderName: 'X-GuestToken'

341

});

342

```

343

344

### File Upload with FormData

345

346

```typescript

347

import { SupersetClient } from '@superset-ui/core';

348

349

// Upload CSV file

350

const formData = new FormData();

351

formData.append('csv_file', file);

352

formData.append('table_name', 'my_dataset');

353

354

const uploadResponse = await SupersetClient.post({

355

endpoint: '/api/v1/dataset/upload',

356

body: formData,

357

// Don't set Content-Type header for FormData - let browser set it

358

headers: {}

359

});

360

```

361

362

### Query Execution

363

364

```typescript

365

import { SupersetClient } from '@superset-ui/core';

366

367

// Execute SQL query

368

const queryResult = await SupersetClient.post({

369

endpoint: '/api/v1/sqllab/',

370

jsonPayload: {

371

sql: 'SELECT * FROM my_table LIMIT 100',

372

database_id: 1,

373

schema: 'public',

374

runAsync: false

375

}

376

});

377

378

// Long-running query with polling

379

const asyncQuery = await SupersetClient.post({

380

endpoint: '/api/v1/sqllab/',

381

jsonPayload: {

382

sql: 'SELECT COUNT(*) FROM large_table',

383

database_id: 1,

384

runAsync: true

385

}

386

});

387

388

// Poll for results

389

const pollResults = async (queryId: string) => {

390

let status = 'running';

391

while (status === 'running') {

392

const statusResponse = await SupersetClient.get({

393

endpoint: `/api/v1/sqllab/${queryId}/status`

394

});

395

396

const statusData = await statusResponse.json();

397

status = statusData.status;

398

399

if (status === 'running') {

400

await new Promise(resolve => setTimeout(resolve, 1000));

401

}

402

}

403

404

return SupersetClient.get({

405

endpoint: `/api/v1/sqllab/${queryId}/results`

406

});

407

};

408

```

409

410

## Advanced Usage

411

412

### Custom Response Processing

413

414

```typescript

415

import { SupersetClient } from '@superset-ui/core';

416

417

// Custom response processor

418

const processApiResponse = async (endpoint: string) => {

419

const response = await SupersetClient.get({

420

endpoint,

421

parseMethod: 'raw' // Get raw Response object

422

});

423

424

// Custom processing based on content type

425

const contentType = response.headers.get('content-type');

426

427

if (contentType?.includes('application/json')) {

428

const json = await response.json();

429

return json.result || json;

430

} else if (contentType?.includes('text/csv')) {

431

const text = await response.text();

432

return text.split('\n').map(row => row.split(','));

433

} else {

434

return response.blob();

435

}

436

};

437

```

438

439

### Request Interceptors Pattern

440

441

```typescript

442

import { SupersetClientClass } from '@superset-ui/core';

443

444

class InterceptedClient extends SupersetClientClass {

445

async request(config: RequestConfig): Promise<Response> {

446

// Pre-request processing

447

console.log(`Making request to: ${config.endpoint}`);

448

449

// Add timing

450

const startTime = Date.now();

451

452

try {

453

const response = await super.request(config);

454

455

// Post-request processing

456

const duration = Date.now() - startTime;

457

console.log(`Request completed in ${duration}ms`);

458

459

return response;

460

} catch (error) {

461

console.error(`Request failed after ${Date.now() - startTime}ms:`, error);

462

throw error;

463

}

464

}

465

}

466

467

const client = new InterceptedClient({

468

host: 'http://localhost:8088'

469

});

470

```

471

472

### Bulk Operations

473

474

```typescript

475

import { SupersetClient } from '@superset-ui/core';

476

477

// Batch API calls with concurrency control

478

const batchApiCalls = async <T>(

479

requests: RequestConfig[],

480

concurrency: number = 5

481

): Promise<T[]> => {

482

const results: T[] = [];

483

484

for (let i = 0; i < requests.length; i += concurrency) {

485

const batch = requests.slice(i, i + concurrency);

486

const batchResults = await Promise.all(

487

batch.map(async (request) => {

488

const response = await SupersetClient.request(request);

489

return response.json();

490

})

491

);

492

results.push(...batchResults);

493

}

494

495

return results;

496

};

497

498

// Usage

499

const chartRequests = chartIds.map(id => ({

500

endpoint: `/api/v1/chart/${id}`

501

}));

502

503

const charts = await batchApiCalls(chartRequests, 3);

504

```

505

506

## Related Documentation

507

508

- [Query System](./query.md) - Query building and processing

509

- [Core Models & Utilities](./core-models.md) - Registry system and utilities

510

- [Dashboard Components](./dashboard.md) - Dashboard API integration