0
# Low-Level Operations
1
2
Direct HTTP-level functions for Swift operations providing fine-grained control over requests, custom headers, and response handling. These functions operate at the HTTP level and require manual authentication and connection management.
3
4
## Capabilities
5
6
### Account Operations
7
8
Direct HTTP operations for account-level functionality including metadata retrieval and container listings.
9
10
```python { .api }
11
def get_account(
12
url,
13
token,
14
marker=None,
15
limit=None,
16
prefix=None,
17
end_marker=None,
18
http_conn=None,
19
full_listing=False,
20
service_token=None,
21
headers=None,
22
delimiter=None
23
):
24
"""
25
Get a listing of containers for the account.
26
27
Parameters:
28
- url: str, storage URL
29
- token: str, auth token
30
- marker: str, marker query for pagination
31
- limit: int, limit query for number of containers
32
- prefix: str, prefix query to filter container names
33
- end_marker: str, end marker query for pagination
34
- http_conn: tuple, (parsed_url, HTTPConnection) or None for new connection
35
- full_listing: bool, return complete listing with multiple requests if needed
36
- service_token: str, service auth token
37
- headers: dict, additional headers to include
38
- delimiter: str, delimiter query for hierarchical listings
39
40
Returns:
41
tuple: (response_headers dict, containers list)
42
43
Raises:
44
ClientException: HTTP GET request failed
45
"""
46
47
def head_account(url, token, http_conn=None, headers=None, service_token=None):
48
"""
49
Get account stats and metadata.
50
51
Parameters:
52
- url: str, storage URL
53
- token: str, auth token
54
- http_conn: tuple, (parsed_url, HTTPConnection) or None for new connection
55
- headers: dict, additional headers to include
56
- service_token: str, service auth token
57
58
Returns:
59
dict: response headers with account metadata (all lowercase keys)
60
61
Raises:
62
ClientException: HTTP HEAD request failed
63
"""
64
65
def post_account(
66
url,
67
token,
68
headers,
69
http_conn=None,
70
response_dict=None,
71
service_token=None,
72
query_string=None,
73
data=None
74
):
75
"""
76
Update account metadata.
77
78
Parameters:
79
- url: str, storage URL
80
- token: str, auth token
81
- headers: dict, headers to set as account metadata
82
- http_conn: tuple, (parsed_url, HTTPConnection) or None for new connection
83
- response_dict: dict, optional dict to store response info
84
- service_token: str, service auth token
85
- query_string: str, query string to append to path
86
- data: bytes, optional message body for request
87
88
Returns:
89
tuple: (response_headers dict, response_body bytes)
90
91
Raises:
92
ClientException: HTTP POST request failed
93
"""
94
```
95
96
### Container Operations
97
98
Direct HTTP operations for container management including creation, listing, metadata, and deletion.
99
100
```python { .api }
101
def get_container(
102
url,
103
token,
104
container,
105
marker=None,
106
limit=None,
107
prefix=None,
108
delimiter=None,
109
end_marker=None,
110
version_marker=None,
111
path=None,
112
http_conn=None,
113
full_listing=False,
114
service_token=None,
115
headers=None,
116
query_string=None
117
):
118
"""
119
Get a listing of objects for the container.
120
121
Parameters:
122
- url: str, storage URL
123
- token: str, auth token
124
- container: str, container name to get listing for
125
- marker: str, marker query for pagination
126
- limit: int, limit query for number of objects
127
- prefix: str, prefix query to filter object names
128
- delimiter: str, delimiter to group objects hierarchically
129
- end_marker: str, end marker query for pagination
130
- version_marker: str, version marker query for versioned objects
131
- path: str, path query (equivalent to delimiter='/' and prefix=path/)
132
- http_conn: tuple, (parsed_url, HTTPConnection) or None for new connection
133
- full_listing: bool, return complete listing with multiple requests if needed
134
- service_token: str, service auth token
135
- headers: dict, additional headers to include
136
- query_string: str, query string to append to path
137
138
Returns:
139
tuple: (response_headers dict, objects list)
140
141
Raises:
142
ClientException: HTTP GET request failed
143
"""
144
145
def head_container(url, token, container, http_conn=None, headers=None, service_token=None):
146
"""
147
Get container stats and metadata.
148
149
Parameters:
150
- url: str, storage URL
151
- token: str, auth token
152
- container: str, container name to get stats for
153
- http_conn: tuple, (parsed_url, HTTPConnection) or None for new connection
154
- headers: dict, additional headers to include
155
- service_token: str, service auth token
156
157
Returns:
158
dict: response headers with container metadata (all lowercase keys)
159
160
Raises:
161
ClientException: HTTP HEAD request failed
162
"""
163
164
def put_container(
165
url,
166
token,
167
container,
168
headers=None,
169
http_conn=None,
170
response_dict=None,
171
service_token=None,
172
query_string=None
173
):
174
"""
175
Create a container.
176
177
Parameters:
178
- url: str, storage URL
179
- token: str, auth token
180
- container: str, container name to create
181
- headers: dict, additional headers to set on container
182
- http_conn: tuple, (parsed_url, HTTPConnection) or None for new connection
183
- response_dict: dict, optional dict to store response info
184
- service_token: str, service auth token
185
- query_string: str, query string to append to path
186
187
Raises:
188
ClientException: HTTP PUT request failed
189
"""
190
191
def post_container(
192
url,
193
token,
194
container,
195
headers,
196
http_conn=None,
197
response_dict=None,
198
service_token=None
199
):
200
"""
201
Update container metadata.
202
203
Parameters:
204
- url: str, storage URL
205
- token: str, auth token
206
- container: str, container name to update
207
- headers: dict, headers to set as container metadata
208
- http_conn: tuple, (parsed_url, HTTPConnection) or None for new connection
209
- response_dict: dict, optional dict to store response info
210
- service_token: str, service auth token
211
212
Raises:
213
ClientException: HTTP POST request failed
214
"""
215
216
def delete_container(
217
url,
218
token,
219
container,
220
http_conn=None,
221
response_dict=None,
222
service_token=None,
223
query_string=None,
224
headers=None
225
):
226
"""
227
Delete a container.
228
229
Parameters:
230
- url: str, storage URL
231
- token: str, auth token
232
- container: str, container name to delete
233
- http_conn: tuple, (parsed_url, HTTPConnection) or None for new connection
234
- response_dict: dict, optional dict to store response info
235
- service_token: str, service auth token
236
- query_string: str, query string to append to path
237
- headers: dict, additional headers to include
238
239
Raises:
240
ClientException: HTTP DELETE request failed
241
"""
242
```
243
244
### Object Operations
245
246
Direct HTTP operations for object management including upload, download, metadata, copying, and deletion.
247
248
```python { .api }
249
def get_object(
250
url,
251
token,
252
container,
253
name,
254
http_conn=None,
255
resp_chunk_size=None,
256
query_string=None,
257
response_dict=None,
258
headers=None,
259
service_token=None
260
):
261
"""
262
Get an object.
263
264
Parameters:
265
- url: str, storage URL
266
- token: str, auth token
267
- container: str, container name that the object is in
268
- name: str, object name to get
269
- http_conn: tuple, (parsed_url, HTTPConnection) or None for new connection
270
- resp_chunk_size: int, chunk size for reading response (enables streaming)
271
- query_string: str, query string to append to path
272
- response_dict: dict, optional dict to store response info
273
- headers: dict, additional headers to include (e.g., Range)
274
- service_token: str, service auth token
275
276
Returns:
277
tuple: (response_headers dict, object_content bytes or iterable)
278
279
Raises:
280
ClientException: HTTP GET request failed
281
"""
282
283
def head_object(
284
url,
285
token,
286
container,
287
name,
288
http_conn=None,
289
service_token=None,
290
headers=None,
291
query_string=None
292
):
293
"""
294
Get object info and metadata.
295
296
Parameters:
297
- url: str, storage URL
298
- token: str, auth token
299
- container: str, container name that the object is in
300
- name: str, object name to get info for
301
- http_conn: tuple, (parsed_url, HTTPConnection) or None for new connection
302
- service_token: str, service auth token
303
- headers: dict, additional headers to include
304
- query_string: str, query string to append to path
305
306
Returns:
307
dict: response headers with object metadata (all lowercase keys)
308
309
Raises:
310
ClientException: HTTP HEAD request failed
311
"""
312
313
def put_object(
314
url,
315
token=None,
316
container=None,
317
name=None,
318
contents=None,
319
content_length=None,
320
etag=None,
321
chunk_size=None,
322
content_type=None,
323
headers=None,
324
http_conn=None,
325
proxy=None,
326
query_string=None,
327
response_dict=None,
328
service_token=None
329
):
330
"""
331
Put an object.
332
333
Parameters:
334
- url: str, storage URL
335
- token: str, auth token (None to send no token)
336
- container: str, container name (None if part of URL)
337
- name: str, object name (None if part of URL)
338
- contents: str/bytes/file-like/iterable, object data (None for zero-byte PUT)
339
- content_length: int, content length (computed if None)
340
- etag: str, MD5 hash of contents (None to not send)
341
- chunk_size: int, chunk size for file-like objects (default 65536)
342
- content_type: str, content type header value
343
- headers: dict, additional headers to include
344
- http_conn: tuple, (parsed_url, HTTPConnection) or None for new connection
345
- proxy: str, proxy URL (format: 'http://127.0.0.1:8888')
346
- query_string: str, query string to append to path
347
- response_dict: dict, optional dict to store response info
348
- service_token: str, service auth token
349
350
Returns:
351
str: ETag of uploaded object
352
353
Raises:
354
ClientException: HTTP PUT request failed
355
"""
356
357
def post_object(
358
url,
359
token,
360
container,
361
name,
362
headers,
363
http_conn=None,
364
response_dict=None,
365
service_token=None
366
):
367
"""
368
Update object metadata.
369
370
Parameters:
371
- url: str, storage URL
372
- token: str, auth token
373
- container: str, container name that the object is in
374
- name: str, name of the object to update
375
- headers: dict, headers to set as object metadata
376
- http_conn: tuple, (parsed_url, HTTPConnection) or None for new connection
377
- response_dict: dict, optional dict to store response info
378
- service_token: str, service auth token
379
380
Raises:
381
ClientException: HTTP POST request failed
382
"""
383
384
def copy_object(
385
url,
386
token,
387
container,
388
name,
389
destination=None,
390
headers=None,
391
fresh_metadata=None,
392
http_conn=None,
393
response_dict=None,
394
service_token=None
395
):
396
"""
397
Copy object.
398
399
Parameters:
400
- url: str, storage URL
401
- token: str, auth token (None to send no token)
402
- container: str, container name that the source object is in
403
- name: str, source object name
404
- destination: str, destination in format /container/object (None uses source)
405
- headers: dict, additional headers to include
406
- fresh_metadata: bool, omit existing user metadata (None/False preserves)
407
- http_conn: tuple, (parsed_url, HTTPConnection) or None for new connection
408
- response_dict: dict, optional dict to store response info
409
- service_token: str, service auth token
410
411
Raises:
412
ClientException: HTTP COPY request failed
413
"""
414
415
def delete_object(
416
url,
417
token=None,
418
container=None,
419
name=None,
420
http_conn=None,
421
headers=None,
422
proxy=None,
423
query_string=None,
424
response_dict=None,
425
service_token=None
426
):
427
"""
428
Delete object.
429
430
Parameters:
431
- url: str, storage URL
432
- token: str, auth token (None to send no token)
433
- container: str, container name (None if part of URL)
434
- name: str, object name (None if part of URL)
435
- http_conn: tuple, (parsed_url, HTTPConnection) or None for new connection
436
- headers: dict, additional headers to include
437
- proxy: str, proxy URL (format: 'http://127.0.0.1:8888')
438
- query_string: str, query string to append to path
439
- response_dict: dict, optional dict to store response info
440
- service_token: str, service auth token
441
442
Raises:
443
ClientException: HTTP DELETE request failed
444
"""
445
```
446
447
### Connection and Capability Functions
448
449
Low-level connection management and cluster information retrieval.
450
451
```python { .api }
452
def http_connection(*args, **kwargs):
453
"""
454
Create HTTP connection for Swift requests.
455
456
Returns:
457
tuple: (parsed_url, HTTPConnection_object)
458
"""
459
460
def get_capabilities(http_conn):
461
"""
462
Get cluster capability information.
463
464
Parameters:
465
- http_conn: tuple, (parsed_url, HTTPConnection)
466
467
Returns:
468
dict: cluster capabilities and configuration
469
470
Raises:
471
ClientException: HTTP Capabilities GET failed
472
"""
473
```
474
475
## Usage Examples
476
477
### Basic Low-Level Usage
478
479
```python
480
from swiftclient import (
481
get_auth, get_account, put_container, put_object, get_object, delete_object
482
)
483
484
# Authenticate first
485
storage_url, token = get_auth(
486
'https://identity.example.com:5000/v3',
487
'username',
488
'password',
489
auth_version='3',
490
os_options={'project_name': 'project-name'}
491
)
492
493
# Account operations
494
account_headers = head_account(storage_url, token)
495
print(f"Account containers: {account_headers['x-account-container-count']}")
496
497
headers, containers = get_account(storage_url, token, limit=10)
498
for container in containers:
499
print(f"Container: {container['name']}")
500
501
# Container operations
502
put_container(storage_url, token, 'documents')
503
headers, objects = get_container(storage_url, token, 'documents')
504
505
# Object operations
506
etag = put_object(
507
storage_url,
508
token,
509
'documents',
510
'hello.txt',
511
'Hello, World!',
512
content_type='text/plain'
513
)
514
515
headers, content = get_object(storage_url, token, 'documents', 'hello.txt')
516
print(content.decode('utf-8'))
517
518
delete_object(storage_url, token, 'documents', 'hello.txt')
519
```
520
521
### Connection Reuse
522
523
```python
524
from swiftclient import http_connection, get_account, get_container
525
526
# Create persistent connection
527
storage_url, token = get_auth(...)
528
parsed_url, conn = http_connection(storage_url)
529
530
try:
531
# Reuse connection for multiple operations
532
headers, containers = get_account(
533
storage_url, token, http_conn=(parsed_url, conn)
534
)
535
536
for container in containers:
537
headers, objects = get_container(
538
storage_url, token, container['name'], http_conn=(parsed_url, conn)
539
)
540
print(f"Container {container['name']} has {len(objects)} objects")
541
542
finally:
543
conn.close()
544
```
545
546
### Streaming Large Objects
547
548
```python
549
import io
550
551
# Upload large object with streaming
552
large_data = io.BytesIO(b'x' * 50000000) # 50MB
553
etag = put_object(
554
storage_url,
555
token,
556
'documents',
557
'large-file.dat',
558
large_data,
559
content_length=50000000,
560
chunk_size=1048576 # 1MB chunks
561
)
562
563
# Download with streaming
564
headers, content = get_object(
565
storage_url,
566
token,
567
'documents',
568
'large-file.dat',
569
resp_chunk_size=1048576 # 1MB chunks
570
)
571
572
total_size = 0
573
for chunk in content:
574
total_size += len(chunk)
575
print(f"Downloaded {total_size} bytes", end='\r')
576
print(f"\nTotal: {total_size} bytes")
577
```
578
579
### Custom Headers and Metadata
580
581
```python
582
# Upload with custom headers
583
custom_headers = {
584
'X-Object-Meta-Author': 'John Doe',
585
'X-Object-Meta-Project': 'Documentation',
586
'Content-Disposition': 'attachment; filename="report.pdf"',
587
'Cache-Control': 'max-age=3600'
588
}
589
590
put_object(
591
storage_url,
592
token,
593
'documents',
594
'report.pdf',
595
pdf_content,
596
content_type='application/pdf',
597
headers=custom_headers
598
)
599
600
# Retrieve metadata
601
headers = head_object(storage_url, token, 'documents', 'report.pdf')
602
print(f"Author: {headers.get('x-object-meta-author')}")
603
print(f"Last modified: {headers.get('last-modified')}")
604
print(f"Content length: {headers.get('content-length')}")
605
606
# Update metadata only
607
post_object(
608
storage_url,
609
token,
610
'documents',
611
'report.pdf',
612
{'X-Object-Meta-Version': '2.0'}
613
)
614
```
615
616
### Range Requests
617
618
```python
619
# Download specific byte range
620
range_headers = {'Range': 'bytes=0-1023'} # First 1KB
621
headers, partial_content = get_object(
622
storage_url,
623
token,
624
'documents',
625
'large-file.dat',
626
headers=range_headers
627
)
628
629
print(f"Content range: {headers.get('content-range')}")
630
print(f"Partial content length: {len(partial_content)}")
631
```
632
633
### Error Handling
634
635
```python
636
from swiftclient import ClientException
637
638
try:
639
headers, content = get_object(storage_url, token, 'documents', 'nonexistent.txt')
640
except ClientException as e:
641
if e.http_status == 404:
642
print("Object not found")
643
elif e.http_status == 401:
644
print("Authentication failed")
645
else:
646
print(f"Request failed: {e.http_status} {e.http_reason}")
647
```