storage-blob.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. #----------------------------------------------------------------------------------
  2. # Microsoft Developer & Platform Evangelism
  3. #
  4. # Copyright (c) Microsoft Corporation. All rights reserved.
  5. #
  6. # THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
  7. # EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
  8. # OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
  9. #----------------------------------------------------------------------------------
  10. # The example companies, organizations, products, domain names,
  11. # e-mail addresses, logos, people, places, and events depicted
  12. # herein are fictitious. No association with any real company,
  13. # organization, product, domain name, email address, logo, person,
  14. # places, or events is intended or should be inferred.
  15. #----------------------------------------------------------------------------------
  16. import os
  17. import config
  18. from random_data import RandomData
  19. import base64
  20. import datetime
  21. import time
  22. from azure.storage import CloudStorageAccount, AccessPolicy
  23. from azure.storage.blob import BlockBlobService, PageBlobService, AppendBlobService
  24. from azure.storage.models import CorsRule, Logging, Metrics, RetentionPolicy, ResourceTypes, AccountPermissions
  25. from azure.storage.blob.models import BlobBlock, ContainerPermissions, ContentSettings
  26. #
  27. # Azure Storage Blob Sample - Demonstrate how to use the Blob Storage service.
  28. # Blob storage stores unstructured data such as text, binary data, documents or media files.
  29. # Blobs can be accessed from anywhere in the world via HTTP or HTTPS.
  30. #
  31. # Documentation References:
  32. # - What is a Storage Account - http://azure.microsoft.com/en-us/documentation/articles/storage-whatis-account/
  33. # - Getting Started with Blobs - https://azure.microsoft.com/en-us/documentation/articles/storage-python-how-to-use-blob-storage/
  34. # - Blob Service Concepts - http://msdn.microsoft.com/en-us/library/dd179376.aspx
  35. # - Blob Service REST API - http://msdn.microsoft.com/en-us/library/dd135733.aspx
  36. # - Blob Service Python API - http://azure.github.io/azure-storage-python/ref/azure.storage.blob.html
  37. # - Storage Emulator - http://azure.microsoft.com/en-us/documentation/articles/storage-use-emulator/
  38. #
  39. class BlobAdvancedSamples():
  40. def __init__(self):
  41. self.random_data = RandomData()
  42. # Runs all samples for Azure Storage Blob service.
  43. # Input Arguments:
  44. # account - CloudStorageAccount to use for running the samples
  45. def run_all_samples(self, account):
  46. print('\n\nAzure Storage Blob advanced sample - Starting.')
  47. try:
  48. print('\n\n* Container operations *\n')
  49. self.list_containers(account)
  50. print('\n\n* Set CORS *\n')
  51. self.set_cors_rules(account)
  52. print('\n\n* Container lease *\n')
  53. self.lease_container(account)
  54. print('\n\n* Copy blob *\n')
  55. self.copy_blob(account)
  56. print('\n\n* Page blob operations *\n')
  57. self.page_blob_operations(account)
  58. print('\n\n* Block blob operations *\n')
  59. self.block_blob_operations(account)
  60. print('\n\n* Properties and Metadata operations *\n')
  61. self.properties_and_metadata_operations(account)
  62. print('\n\n* Container ACL operations *\n')
  63. self.container_acl_operations(account)
  64. print('\n\n* Blob lease *\n')
  65. self.lease_blob(account)
  66. if (config.IS_EMULATED):
  67. print('\nShared Access Signature is not supported in emulator');
  68. else:
  69. print('\n\n* Container with SAS operations *\n')
  70. self.container_operations_with_sas(account)
  71. print('\n\n* SAS with access policy *\n')
  72. self.sas_with_container_access_policy(account)
  73. print('\n\n* Set blob service logging and metrics properties *\n')
  74. self.set_service_properties(account)
  75. except Exception as e:
  76. if (config.IS_EMULATED):
  77. print('Error occurred in the sample. If you are using the emulator, please make sure the emulator is running.', e)
  78. else:
  79. print('Error occurred in the sample. Please make sure the account name and key are correct.', e)
  80. finally:
  81. print('\nAzure Storage Blob advanced sample - Completed.\n')
  82. # Copy a source blob to a destination blob
  83. def copy_blob(self, account):
  84. file_upload = "HelloWorld.png"
  85. container_name = 'blockblobcontainer' + self.random_data.get_random_name(6)
  86. # Create a Block Blob Service object
  87. blockblob_service = account.create_block_blob_service()
  88. try:
  89. # Create a new container
  90. print('1. Create a container with name - ' + container_name)
  91. blockblob_service.create_container(container_name)
  92. # Upload file as a block blob
  93. print('2. Upload BlockBlob')
  94. #Get full path on drive to file_to_upload by joining the fully qualified directory name and file name on the local drive
  95. full_path_to_file = os.path.join(os.path.dirname(__file__), file_upload)
  96. blockblob_service.create_blob_from_path(container_name, file_upload, full_path_to_file)
  97. target_blob = "target.png"
  98. blob_source_url = blockblob_service.make_blob_url(container_name, file_upload)
  99. print('3. Copy blob')
  100. blockblob_service.copy_blob(container_name, target_blob, blob_source_url)
  101. print('4. Get target blob')
  102. target_blob_properties = blockblob_service.get_blob_properties(container_name, target_blob)
  103. print('5. Get copy properties')
  104. copy_properties = target_blob_properties.properties.copy
  105. print('Copy properties status: ' + copy_properties.status)
  106. if(copy_properties.status == "pending"):
  107. print('6. Abort copy')
  108. blockblob_service.abort_copy_blob(container_name, blob_name, copy_properties.id)
  109. finally:
  110. # Delete the container
  111. print("7. Delete Container")
  112. if blockblob_service.exists(container_name):
  113. blockblob_service.delete_container(container_name)
  114. def sas_with_container_access_policy(self, account):
  115. container_name = 'demosasblobcontainer' + self.random_data.get_random_name(6)
  116. blockblob_service = account.create_block_blob_service()
  117. try:
  118. print('1. Create a container with name - ' + container_name)
  119. blockblob_service.create_container(container_name)
  120. print('2. Create blob "blo1" with text')
  121. blockblob_service.create_blob_from_text(container_name, 'blob1', b'hello world')
  122. print('3. Set access policy for container')
  123. # Set access policy on container
  124. access_policy = AccessPolicy(permission=ContainerPermissions.READ,
  125. expiry=datetime.datetime.utcnow() + datetime.timedelta(hours=1))
  126. identifiers = {'id': access_policy}
  127. acl = blockblob_service.set_container_acl(container_name, identifiers)
  128. # Wait 30 seconds for acl to propagate
  129. print('Wait 30 seconds for acl to propagate')
  130. time.sleep(30)
  131. print('4. Get sas for access policy in container')
  132. # Indicates to use the access policy set on the container
  133. sas = blockblob_service.generate_container_shared_access_signature(
  134. container_name,
  135. id='id'
  136. )
  137. print('5. Create blob service with sas')
  138. # Create a service and use the SAS
  139. shared_blockblob_service = BlockBlobService(
  140. account_name=account.account_name,
  141. sas_token=sas,
  142. )
  143. print('6. Read blob content with sas')
  144. blob = shared_blockblob_service.get_blob_to_text(container_name, 'blob1')
  145. content = blob.content # hello world
  146. finally:
  147. print('7. Delete container')
  148. blockblob_service.delete_container(container_name)
  149. print("SAS with access policy sample completed")
  150. def container_operations_with_sas(self, account):
  151. container_name = 'demosasblobcontainer' + self.random_data.get_random_name(6)
  152. # Create a Block Blob Service object
  153. blockblob_service = account.create_block_blob_service()
  154. # Create a Shared Access Signature for the account
  155. print('1.Get account sas')
  156. account_sas = blockblob_service.generate_account_shared_access_signature(
  157. ResourceTypes.CONTAINER + ResourceTypes.OBJECT,
  158. AccountPermissions.READ + AccountPermissions.WRITE + AccountPermissions.DELETE + AccountPermissions.LIST + AccountPermissions.CREATE,
  159. datetime.datetime.utcnow() + datetime.timedelta(hours=1))
  160. shared_account = CloudStorageAccount(account_name=account.account_name, sas_token=account_sas)
  161. shared_account_block_service = shared_account.create_block_blob_service()
  162. try:
  163. print('2. Create container with account sas. Container name - ' + container_name)
  164. shared_account_block_service.create_container(container_name)
  165. # For the purposes of the demo, get a Container SAS
  166. # In a real-world application, the above Account SAS can be used
  167. print('3. Get container sas')
  168. container_sas = blockblob_service.generate_container_shared_access_signature(
  169. container_name,
  170. ContainerPermissions.READ + ContainerPermissions.WRITE + ContainerPermissions.DELETE + ContainerPermissions.LIST,
  171. datetime.datetime.utcnow() + datetime.timedelta(hours=1))
  172. shared_container_account = CloudStorageAccount(account_name=account.account_name, sas_token=container_sas)
  173. shared_container_block_service = shared_container_account.create_block_blob_service()
  174. print('4. Create blob with container sas')
  175. shared_container_block_service.create_blob_from_text(container_name, 'myblob', 'blob data')
  176. print('5. List blobs with container sas')
  177. blobs = shared_container_block_service.list_blobs(container_name)
  178. for blob in blobs:
  179. print('blob ' + blob.name)
  180. print('6. Delete blob with container sas')
  181. shared_container_block_service.delete_blob(container_name, 'myblob')
  182. finally:
  183. print('7. Delete container')
  184. blockblob_service.delete_container(container_name)
  185. print("Containers Sas sample completed")
  186. def list_containers(self, account):
  187. container_prefix = 'blockblobcontainers' + self.random_data.get_random_name(6)
  188. # Create a Block Blob Service object
  189. blockblob_service = account.create_block_blob_service()
  190. try:
  191. # Create containers
  192. for i in range(5):
  193. container_name = container_prefix + str(i)
  194. print('1. Create a container with name - ' + container_name)
  195. blockblob_service.create_container(container_name)
  196. # List all the blobs in the container
  197. print('2. List containers with prefix ' + container_prefix)
  198. containers = blockblob_service.list_containers(container_prefix)
  199. for container in containers:
  200. print('\tContainer Name: ' + container.name)
  201. finally:
  202. # Delete the containers
  203. print("3. Delete Containers")
  204. for i in range(5):
  205. container_name = container_prefix + str(i)
  206. if blockblob_service.exists(container_name):
  207. blockblob_service.delete_container(container_name)
  208. print("Containers sample completed")
  209. def container_acl_operations(self, account):
  210. container_name = 'aclblockblobcontainer' + self.random_data.get_random_name(6)
  211. # Create a Block Blob Service object
  212. blockblob_service = account.create_block_blob_service()
  213. try:
  214. print('1. Create a container with name - ' + container_name)
  215. blockblob_service.create_container(container_name)
  216. print('2. Set access policy for container')
  217. access_policy = AccessPolicy(permission=ContainerPermissions.READ,
  218. expiry=datetime.datetime.utcnow() + datetime.timedelta(hours=1))
  219. identifiers = {'id': access_policy}
  220. blockblob_service.set_container_acl(container_name, identifiers)
  221. print('3. Get access policy from container')
  222. acl = blockblob_service.get_container_acl(container_name)
  223. print('4. Clear access policy in container')
  224. # Clear
  225. blockblob_service.set_container_acl(container_name)
  226. finally:
  227. print('5. Delete container')
  228. blockblob_service.delete_container(container_name)
  229. print("Container ACL operations sample completed")
  230. def properties_and_metadata_operations(self, account):
  231. file_blob_name = "HelloWorld.png"
  232. text_blob_name = "Text"
  233. # Create a Block Blob Service object
  234. blockblob_service = account.create_block_blob_service()
  235. container_name = 'blockblobbasicscontainer' + self.random_data.get_random_name(6)
  236. try:
  237. # Create a new container
  238. print('1. Create a container with name and custom metadata - ' + container_name)
  239. blockblob_service.create_container(container_name, {'sample':'azure-storage'})
  240. # Upload file as a block blob
  241. print('2. Uploading BlockBlob from file with properties and custom metadata')
  242. #Get full path on drive to file_to_upload by joining the fully qualified directory name and file name on the local drive
  243. full_path_to_file = os.path.join(os.path.dirname(__file__), file_blob_name)
  244. blockblob_service.create_blob_from_path(container_name, file_blob_name, full_path_to_file,
  245. content_settings=ContentSettings(content_type='application/png'),
  246. metadata={'category':'azure-samples'})
  247. blockblob_service.create_blob_from_text(container_name, text_blob_name, 'Data',
  248. content_settings=ContentSettings(content_encoding ='UTF-8', content_language='en'),
  249. metadata={'origin':'usa', 'title': 'azure-samples'})
  250. # Get all the container properties
  251. print('3. Get Container metadata')
  252. container = blockblob_service.get_container_properties(container_name)
  253. print(' Metadata:')
  254. for key in container.metadata:
  255. print(' ' + key + ':' + container.metadata[key])
  256. # Get all the blob properties
  257. print('4. Get Blob properties')
  258. blob = blockblob_service.get_blob_properties(container_name, file_blob_name)
  259. print(' Metadata:')
  260. for key in blob.metadata:
  261. print(' ' + key + ':' + blob.metadata[key])
  262. print(' Properties:')
  263. print(' Content-Type:' + blob.properties.content_settings.content_type)
  264. finally:
  265. # Delete the container
  266. print("5. Delete Container")
  267. if blockblob_service.exists(container_name):
  268. blockblob_service.delete_container(container_name)
  269. # Set CORS
  270. def set_cors_rules(self, account):
  271. # Create a Block Blob Service object
  272. blockblob_service = account.create_block_blob_service()
  273. cors_rule = CorsRule(
  274. allowed_origins=['*'],
  275. allowed_methods=['POST', 'GET'],
  276. allowed_headers=['*'],
  277. exposed_headers=['*'],
  278. max_age_in_seconds=3600)
  279. print('1. Get Cors Rules')
  280. original_cors_rules = blockblob_service.get_blob_service_properties().cors;
  281. try:
  282. print('2. Overwrite Cors Rules')
  283. blockblob_service.set_blob_service_properties(cors=[cors_rule])
  284. finally:
  285. print('3. Revert Cors Rules back the original ones')
  286. #reverting cors rules back to the original ones
  287. blockblob_service.set_blob_service_properties(cors=original_cors_rules)
  288. print("CORS sample completed")
  289. # Lease Container
  290. def lease_container(self, account):
  291. # Create a Block Blob Service object
  292. blockblob_service = account.create_block_blob_service()
  293. try:
  294. container_name = 'blockblobcontainer' + self.random_data.get_random_name(6)
  295. print('1. Create a container with name - ' + container_name)
  296. blockblob_service.create_container(container_name)
  297. print('2. Acquire lease on container')
  298. lease_id = blockblob_service.acquire_container_lease(container_name, lease_duration=15)
  299. print("3. Deleted container without lease")
  300. try:
  301. blockblob_service.delete_container(container_name)
  302. except:
  303. print('Got expected exception. Cannot delete container, lease not specified')
  304. finally:
  305. print("4. Delete container with lease")
  306. blockblob_service.delete_container(container_name, lease_id=lease_id)
  307. print("Lease container sample completed")
  308. # Lease Blob
  309. def lease_blob(self, account):
  310. blob_name = "exclusive"
  311. # Create an block blob service object
  312. blockblob_service = account.create_block_blob_service()
  313. container_name = 'blobcontainer' + self.random_data.get_random_name(6)
  314. try:
  315. # Create a new container
  316. print('1. Create a container with name - ' + container_name)
  317. blockblob_service.create_container(container_name)
  318. # Create a block blob
  319. print('2. Create Block Blob')
  320. blob = self.random_data.get_random_bytes(255)
  321. blockblob_service.create_blob_from_bytes(container_name, blob_name, blob)
  322. print('3. Acquire lease on blob')
  323. lease_id = blockblob_service.acquire_blob_lease(container_name, blob_name, lease_duration=15)
  324. # Write to a block blob
  325. print('4. Try to write to Block Blob without lease')
  326. block_id = self.random_data.get_random_name(32)
  327. block = self.random_data.get_random_bytes(255)
  328. try:
  329. blockblob_service.put_block(container_name, blob_name, block, block_id)
  330. except:
  331. print('Got expected exception. Cannot write blob, lease not specified')
  332. print('5. Write to Block Blob with lease')
  333. blockblob_service.put_block(container_name, blob_name, block, block_id, lease_id=lease_id)
  334. print("6. Deleted blob without lease")
  335. try:
  336. blockblob_service.delete_blob(container_name, blob_name)
  337. except:
  338. print('Got expected exception. Cannot delete blob, lease not specified')
  339. print("7. Delete blob with lease")
  340. blockblob_service.delete_blob(container_name, blob_name, lease_id=lease_id)
  341. finally:
  342. print("8. Delete container")
  343. if blockblob_service.exists(container_name):
  344. blockblob_service.delete_container(container_name)
  345. print("Lease blob sample completed")
  346. #Page Blob Operations
  347. def page_blob_operations(self, account):
  348. file_to_upload = "HelloWorld.png"
  349. page_size = 1024;
  350. # Create an page blob service object
  351. pageblob_service = account.create_page_blob_service()
  352. container_name = 'pageblobcontainer' + self.random_data.get_random_name(6)
  353. try:
  354. # Create a new container
  355. print('1. Create a container with name - ' + container_name)
  356. pageblob_service.create_container(container_name)
  357. # Create a new page blob to upload the file
  358. print('2. Create a page blob')
  359. pageblob_service.create_blob(container_name, file_to_upload, page_size * 1024)
  360. # Read the file
  361. print('3. Upload pages to page blob')
  362. index = 0
  363. with open(file_to_upload, "rb") as file:
  364. file_bytes = file.read(page_size)
  365. while len(file_bytes) > 0:
  366. if len(file_bytes) < page_size:
  367. file_bytes = bytes(file_bytes + bytearray(page_size - len(file_bytes)))
  368. pageblob_service.update_page(container_name, file_to_upload, file_bytes, index * page_size, index * page_size + page_size - 1)
  369. file_bytes = file.read(page_size)
  370. index = index + 1
  371. pages = pageblob_service.get_page_ranges(container_name, file_to_upload)
  372. print('4. Enumerate pages in page blob')
  373. for page in pages:
  374. print('Page ' + str(page.start) + ' - ' + str(page.end))
  375. finally:
  376. print('5. Delete container')
  377. if pageblob_service.exists(container_name):
  378. pageblob_service.delete_container(container_name)
  379. #Block Blob Operations
  380. def block_blob_operations(self, account):
  381. file_to_upload = "HelloWorld.png"
  382. block_size = 1024
  383. # Create an page blob service object
  384. blockblob_service = account.create_block_blob_service()
  385. container_name = 'blockblobcontainer' + self.random_data.get_random_name(6)
  386. try:
  387. # Create a new container
  388. print('1. Create a container with name - ' + container_name)
  389. blockblob_service.create_container(container_name)
  390. blocks = []
  391. # Read the file
  392. print('2. Upload file to block blob')
  393. with open(file_to_upload, "rb") as file:
  394. file_bytes = file.read(block_size)
  395. while len(file_bytes) > 0:
  396. block_id = self.random_data.get_random_name(32)
  397. blockblob_service.put_block(container_name, file_to_upload, file_bytes, block_id)
  398. blocks.append(BlobBlock(id=block_id))
  399. file_bytes = file.read(block_size)
  400. blockblob_service.put_block_list(container_name, file_to_upload, blocks)
  401. print('3. Get the block list')
  402. blockslist = blockblob_service.get_block_list(container_name, file_to_upload, None, 'all')
  403. blocks = blockslist.committed_blocks
  404. print('4. Enumerate blocks in block blob')
  405. for block in blocks:
  406. print('Block ' + block.id)
  407. finally:
  408. print('5. Delete container')
  409. if blockblob_service.exists(container_name):
  410. blockblob_service.delete_container(container_name)
  411. # Manage properties of the Blob service, including logging and metrics settings, and the default service version.
  412. def set_service_properties(self, account):
  413. # Create an page blob service object
  414. blockblob_service = account.create_block_blob_service()
  415. print('1. Get Blob service properties')
  416. props = blockblob_service.get_blob_service_properties();
  417. retention = RetentionPolicy(enabled=True, days=5)
  418. logging = Logging(delete=True, read=False, write=True, retention_policy=retention)
  419. hour_metrics = Metrics(enabled=True, include_apis=True, retention_policy=retention)
  420. minute_metrics = Metrics(enabled=False)
  421. try:
  422. print('2. Ovewrite Blob service properties')
  423. blockblob_service.set_blob_service_properties(logging=logging, hour_metrics=hour_metrics, minute_metrics=minute_metrics, target_version='2015-04-05')
  424. finally:
  425. print('3. Revert Blob service properties back to the original ones')
  426. blockblob_service.set_blob_service_properties(logging=props.logging, hour_metrics=props.hour_metrics, minute_metrics=props.minute_metrics, target_version='2015-04-05')
  427. print('4. Set Blob service properties completed')