or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-programming-patterns.mdauthentication-and-credentials.mdconfiguration-and-settings.mddistributed-tracing-and-diagnostics.mderror-handling-and-exceptions.mdhttp-pipeline-and-policies.mdindex.mdpaging-and-result-iteration.mdpolling-and-long-running-operations.mdrest-api-abstraction.mdtransport-and-networking.mdutilities-and-helpers.md

rest-api-abstraction.mddocs/

0

# REST API Abstraction

1

2

Azure Core's REST API abstraction provides a high-level, transport-agnostic interface for making HTTP requests. These classes offer a unified API that works across different HTTP transport implementations while handling content types, serialization, and response processing automatically.

3

4

## Core Components

5

6

### HttpRequest

7

8

Represents an HTTP request with support for various content types, headers, and parameters.

9

10

```python { .api }

11

from azure.core.rest import HttpRequest

12

13

class HttpRequest:

14

def __init__(

15

self,

16

method: str,

17

url: str,

18

*,

19

params: Optional[ParamsType] = None,

20

headers: Optional[MutableMapping[str, str]] = None,

21

json: Any = None,

22

content: Optional[ContentType] = None,

23

data: Optional[Dict[str, Any]] = None,

24

files: Optional[FilesType] = None,

25

**kwargs: Any

26

): ...

27

28

@property

29

def url(self) -> str: ...

30

31

@property

32

def method(self) -> str: ...

33

34

@property

35

def headers(self) -> MutableMapping[str, str]: ...

36

37

@property

38

def content(self) -> Any: ...

39

```

40

41

#### Basic Usage

42

43

```python

44

from azure.core.rest import HttpRequest

45

46

# Simple GET request

47

request = HttpRequest('GET', 'https://api.example.com/data')

48

49

# GET with query parameters

50

request = HttpRequest(

51

'GET',

52

'https://api.example.com/search',

53

params={'query': 'azure', 'limit': 10}

54

)

55

56

# POST with headers

57

request = HttpRequest(

58

'POST',

59

'https://api.example.com/items',

60

headers={'Authorization': 'Bearer token'},

61

json={'name': 'item1', 'value': 42}

62

)

63

```

64

65

#### Content Types

66

67

**JSON Content**:

68

```python

69

request = HttpRequest(

70

'POST',

71

'/api/data',

72

json={'key': 'value', 'count': 10}

73

)

74

```

75

76

**Form Data**:

77

```python

78

request = HttpRequest(

79

'POST',

80

'/api/form',

81

data={'field1': 'value1', 'field2': 'value2'}

82

)

83

```

84

85

**Raw Content**:

86

```python

87

# String content

88

request = HttpRequest('PUT', '/api/text', content='raw text data')

89

90

# Binary content

91

request = HttpRequest('PUT', '/api/binary', content=b'binary data')

92

93

# Stream content

94

request = HttpRequest('PUT', '/api/stream', content=file_stream)

95

```

96

97

**File Uploads**:

98

```python

99

# Single file

100

with open('document.pdf', 'rb') as f:

101

request = HttpRequest('POST', '/api/upload', files={'file': f})

102

103

# Multiple files

104

files = {

105

'doc1': open('file1.txt', 'rb'),

106

'doc2': open('file2.txt', 'rb')

107

}

108

request = HttpRequest('POST', '/api/upload', files=files)

109

110

# File with metadata

111

request = HttpRequest(

112

'POST',

113

'/api/upload',

114

files={'file': ('filename.txt', file_content, 'text/plain')}

115

)

116

```

117

118

### HttpResponse

119

120

Abstract base class for HTTP responses with support for various content access patterns and stream management.

121

122

```python { .api }

123

from azure.core.rest import HttpResponse

124

125

class HttpResponse:

126

@property

127

def request(self) -> HttpRequest: ...

128

129

@property

130

def status_code(self) -> int: ...

131

132

@property

133

def headers(self) -> MutableMapping[str, str]: ...

134

135

@property

136

def reason(self) -> str: ...

137

138

@property

139

def content_type(self) -> Optional[str]: ...

140

141

@property

142

def is_closed(self) -> bool: ...

143

144

@property

145

def is_stream_consumed(self) -> bool: ...

146

147

@property

148

def encoding(self) -> Optional[str]: ...

149

150

@property

151

def url(self) -> str: ...

152

153

@property

154

def content(self) -> bytes: ...

155

156

def text(self, encoding: Optional[str] = None) -> str: ...

157

158

def json() -> Any: ...

159

160

def raise_for_status() -> None: ...

161

162

def close() -> None: ...

163

164

def read() -> bytes: ...

165

166

def iter_raw(**kwargs) -> Iterator[bytes]: ...

167

168

def iter_bytes(**kwargs) -> Iterator[bytes]: ...

169

170

def __enter__(self) -> "HttpResponse": ...

171

172

def __exit__(self, *args) -> None: ...

173

```

174

175

#### Response Usage

176

177

**Basic Response Handling**:

178

```python

179

response = client.send_request(request)

180

181

# Check status

182

if response.status_code == 200:

183

print("Success!")

184

185

# Raise exception for error status codes

186

response.raise_for_status()

187

188

# Access response data

189

content = response.content # bytes

190

text = response.text() # string

191

data = response.json() # parsed JSON

192

```

193

194

**Headers and Metadata**:

195

```python

196

# Access headers (case-insensitive)

197

content_type = response.headers['Content-Type']

198

content_length = response.headers.get('Content-Length')

199

200

# Response metadata

201

print(f"Status: {response.status_code} {response.reason}")

202

print(f"URL: {response.url}")

203

print(f"Encoding: {response.encoding}")

204

```

205

206

**Context Manager Usage**:

207

```python

208

with client.send_request(request) as response:

209

response.raise_for_status()

210

data = response.json()

211

# Response is automatically closed when exiting context

212

```

213

214

**Streaming Responses**:

215

```python

216

# For large responses, use streaming

217

request = HttpRequest('GET', '/api/large-file')

218

response = client.send_request(request, stream=True)

219

220

# Iterate over raw bytes (no decompression)

221

for chunk in response.iter_raw():

222

process_raw_chunk(chunk)

223

224

# Iterate over bytes (with decompression)

225

for chunk in response.iter_bytes():

226

process_chunk(chunk)

227

228

# Always close streaming responses

229

response.close()

230

```

231

232

### AsyncHttpResponse

233

234

Asynchronous version of HttpResponse with async context manager support and async iteration methods.

235

236

```python { .api }

237

from azure.core.rest import AsyncHttpResponse

238

239

class AsyncHttpResponse(HttpResponse):

240

async def read() -> bytes: ...

241

242

async def iter_raw(**kwargs) -> AsyncIterator[bytes]: ...

243

244

async def iter_bytes(**kwargs) -> AsyncIterator[bytes]: ...

245

246

async def close() -> None: ...

247

248

async def __aenter__(self) -> "AsyncHttpResponse": ...

249

250

async def __aexit__(self, *args) -> None: ...

251

```

252

253

#### Async Usage

254

255

**Basic Async Response Handling**:

256

```python

257

async def handle_response():

258

response = await async_client.send_request(request)

259

260

# Async context manager

261

async with async_client.send_request(request) as response:

262

response.raise_for_status()

263

content = await response.read()

264

return response.json()

265

```

266

267

**Async Streaming**:

268

```python

269

async def stream_large_file():

270

request = HttpRequest('GET', '/api/large-download')

271

response = await async_client.send_request(request, stream=True)

272

273

try:

274

async for chunk in response.iter_bytes():

275

await process_chunk(chunk)

276

finally:

277

await response.close()

278

```

279

280

## Type Definitions

281

282

```python { .api }

283

from typing import Union, Optional, Mapping, Sequence, Iterable, AsyncIterable, IO, Tuple

284

285

# Content types

286

ContentType = Union[str, bytes, Iterable[bytes], AsyncIterable[bytes]]

287

288

# Parameter types for query strings

289

PrimitiveData = Optional[Union[str, int, float, bool]]

290

ParamsType = Mapping[str, Union[PrimitiveData, Sequence[PrimitiveData]]]

291

292

# File upload types

293

FileContent = Union[str, bytes, IO[str], IO[bytes]]

294

FileType = Union[

295

FileContent,

296

Tuple[Optional[str], FileContent], # (filename, content)

297

Tuple[Optional[str], FileContent, Optional[str]] # (filename, content, content_type)

298

]

299

FilesType = Union[Mapping[str, FileType], Sequence[Tuple[str, FileType]]]

300

```

301

302

## Integration with PipelineClient

303

304

The REST API classes are designed to work seamlessly with PipelineClient's `send_request` method:

305

306

```python

307

from azure.core import PipelineClient

308

from azure.core.rest import HttpRequest

309

310

client = PipelineClient(base_url="https://api.example.com")

311

312

# Create request using REST API abstraction

313

request = HttpRequest('GET', '/users', params={'page': 1})

314

315

# Send through pipeline

316

response = client.send_request(request)

317

318

# Use REST response methods

319

response.raise_for_status()

320

users = response.json()

321

```

322

323

## Key Advantages

324

325

**Transport Agnostic**: Works with any HTTP transport (requests, aiohttp, etc.) without changing your code.

326

327

**Automatic Content Handling**: Automatically sets appropriate headers and serializes content based on the type you provide.

328

329

**Unified Interface**: Consistent API across synchronous and asynchronous operations.

330

331

**Stream Management**: Proper handling of response streams with automatic resource cleanup.

332

333

**Error Handling**: Built-in status code checking with `raise_for_status()`.

334

335

**Backward Compatibility**: Maintains compatibility with older Azure SDK patterns while providing modern conveniences.

336

337

The REST API abstraction simplifies HTTP operations while maintaining the full power and flexibility of the underlying pipeline system, making it the recommended approach for most HTTP interactions in Azure SDK applications.