├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── example.py └── requirements.txt /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 4 | > Please provide us with the following information: 5 | > --------------------------------------------------------------- 6 | 7 | ### This issue is for a: (mark with an `x`) 8 | ``` 9 | - [ ] bug report -> please search issues before submitting 10 | - [ ] feature request 11 | - [ ] documentation issue or request 12 | - [ ] regression (a behavior that used to work and stopped in a new release) 13 | ``` 14 | 15 | ### Minimal steps to reproduce 16 | > 17 | 18 | ### Any log messages given by the failure 19 | > 20 | 21 | ### Expected/desired behavior 22 | > 23 | 24 | ### OS and Version? 25 | > Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?) 26 | 27 | ### Versions 28 | > 29 | 30 | ### Mention any other details that might be useful 31 | 32 | > --------------------------------------------------------------- 33 | > Thanks! We'll be in touch soon. 34 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Purpose 2 | 3 | * ... 4 | 5 | ## Does this introduce a breaking change? 6 | 7 | ``` 8 | [ ] Yes 9 | [ ] No 10 | ``` 11 | 12 | ## Pull Request Type 13 | What kind of change does this Pull Request introduce? 14 | 15 | 16 | ``` 17 | [ ] Bugfix 18 | [ ] Feature 19 | [ ] Code style update (formatting, local variables) 20 | [ ] Refactoring (no functional changes, no api changes) 21 | [ ] Documentation content changes 22 | [ ] Other... Please describe: 23 | ``` 24 | 25 | ## How to Test 26 | * Get the code 27 | 28 | ``` 29 | git clone [repo-address] 30 | cd [repo-name] 31 | git checkout [branch-name] 32 | npm install 33 | ``` 34 | 35 | * Test the code 36 | 37 | ``` 38 | ``` 39 | 40 | ## What to Check 41 | Verify that the following are valid 42 | * ... 43 | 44 | ## Other Information 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # SageMath parsed files 80 | *.sage.py 81 | 82 | # dotenv 83 | .env 84 | 85 | # virtualenv 86 | .venv 87 | venv/ 88 | ENV/ 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | .spyproject 93 | 94 | # Rope project settings 95 | .ropeproject 96 | 97 | # mkdocs documentation 98 | /site 99 | 100 | # mypy 101 | .mypy_cache/ 102 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [project-title] Changelog 2 | 3 | 4 | # x.y.z (yyyy-mm-dd) 5 | 6 | *Features* 7 | * ... 8 | 9 | *Bug Fixes* 10 | * ... 11 | 12 | *Breaking Changes* 13 | * ... 14 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to [project-title] 2 | 3 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 4 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 5 | the rights to use your contribution. For details, visit https://cla.microsoft.com. 6 | 7 | When you submit a pull request, a CLA-bot will automatically determine whether you need to provide 8 | a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions 9 | provided by the bot. You will only need to do this once across all repos using our CLA. 10 | 11 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 12 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 13 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 14 | 15 | - [Code of Conduct](#coc) 16 | - [Issues and Bugs](#issue) 17 | - [Feature Requests](#feature) 18 | - [Submission Guidelines](#submit) 19 | 20 | ## Code of Conduct 21 | Help us keep this project open and inclusive. Please read and follow our [Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 22 | 23 | ## Found an Issue? 24 | If you find a bug in the source code or a mistake in the documentation, you can help us by 25 | [submitting an issue](#submit-issue) to the GitHub Repository. Even better, you can 26 | [submit a Pull Request](#submit-pr) with a fix. 27 | 28 | ## Want a Feature? 29 | You can *request* a new feature by [submitting an issue](#submit-issue) to the GitHub 30 | Repository. If you would like to *implement* a new feature, please submit an issue with 31 | a proposal for your work first, to be sure that we can use it. 32 | 33 | * **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr). 34 | 35 | ## Submission Guidelines 36 | 37 | ### Submitting an Issue 38 | Before you submit an issue, search the archive, maybe your question was already answered. 39 | 40 | If your issue appears to be a bug, and hasn't been reported, open a new issue. 41 | Help us to maximize the effort we can spend fixing issues and adding new 42 | features, by not reporting duplicate issues. Providing the following information will increase the 43 | chances of your issue being dealt with quickly: 44 | 45 | * **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps 46 | * **Version** - what version is affected (e.g. 0.1.2) 47 | * **Motivation for or Use Case** - explain what are you trying to do and why the current behavior is a bug for you 48 | * **Browsers and Operating System** - is this a problem with all browsers? 49 | * **Reproduce the Error** - provide a live example or a unambiguous set of steps 50 | * **Related Issues** - has a similar issue been reported before? 51 | * **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be 52 | causing the problem (line of code or commit) 53 | 54 | You can file new issues by providing the above information at the corresponding repository's issues link: https://github.com/[organization-name]/[repository-name]/issues/new]. 55 | 56 | ### Submitting a Pull Request (PR) 57 | Before you submit your Pull Request (PR) consider the following guidelines: 58 | 59 | * Search the repository (https://github.com/[organization-name]/[repository-name]/pulls) for an open or closed PR 60 | that relates to your submission. You don't want to duplicate effort. 61 | 62 | * Make your changes in a new git fork: 63 | 64 | * Commit your changes using a descriptive commit message 65 | * Push your fork to GitHub: 66 | * In GitHub, create a pull request 67 | * If we suggest changes then: 68 | * Make the required updates. 69 | * Rebase your fork and force push to your GitHub repository (this will update your Pull Request): 70 | 71 | ```shell 72 | git rebase master -i 73 | git push -f 74 | ``` 75 | 76 | That's it! Thank you for your contribution! 77 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_type: sample 3 | languages: 4 | - python 5 | products: 6 | - azure 7 | - azure-storage 8 | description: "How to upload and download blobs from Azure Blob Storage with Python." 9 | urlFragment: upload-download-blobs-python 10 | --- 11 | 12 | # How to upload and download blobs from Azure Blob Storage with Python 13 | 14 | ## This sample shows how to do the following operations of Storage Blobs with Storage SDK 15 | - Create a Storage Account using the Azure Portal. 16 | - Create a container. 17 | - Upload a file to block blob. 18 | - List blobs. 19 | - Download a blob to file. 20 | - Delete a blob. 21 | - Delete the container. 22 | 23 | ## Prerequisites 24 | 25 | If you don't have an Azure subscription, create a [free account] before you begin. 26 | 27 | ### Create a Storage Account using the Azure Portal 28 | 29 | Step 1 : Create a new general-purpose Storage Account to use for this tutorial. 30 | 31 | * Go to the [Azure Portal] and log in using your Azure account. 32 | * Select **New** > **Storage** > **Storage account**. 33 | * Select your Subscription. 34 | * For `Resource group`, create a new one and give it a unique name. 35 | * Enter a name for your storage Account. 36 | * Select the `Location` to use for your Storage Account. 37 | * Set `Account kind` to **StorageV2(general purpose v2)**. 38 | * Set `Performance` to **Standard**. 39 | * Set `Replication` to **Locally-redundant storage (LRS)**. 40 | * Set `Secure transfer required` to **Disabled**. 41 | * Check **Review + create** and click **Create** to create your Storage Account. 42 | 43 | Step 2 : Copy and save Connection string. 44 | 45 | After your Storage Account is created. Click on it to open it. 46 | Select **Settings** > **Access keys** > **Key1/key**, copy the associated **Connection string** to the clipboard, then paste it into a text editor for later use. 47 | 48 | ### Put the connection string in an environment variable 49 | 50 | This solution requires a connection string be stored in an environment variable securely on the machine running the sample. Follow one of the examples below depending on your operating system to create the environment variable. If using Windows close your open IDE or shell and restart it to be able to read the environment variable. 51 | 52 | Linux 53 | 54 | ```bash 55 | export AZURE_STORAGE_CONNECTIONSTRING="" 56 | ``` 57 | 58 | Windows 59 | 60 | ```cmd 61 | setx AZURE_STORAGE_CONNECTIONSTRING "" 62 | ``` 63 | 64 | ### Set up 65 | 66 | First, clone the repository on your machine: 67 | 68 | ```bash 69 | git clone https://github.com/Azure-Samples/azure-sdk-for-python-storage-blob-upload-download.git 70 | ``` 71 | 72 | Then, install the dependencies: 73 | 74 | ```bash 75 | pip install -r requirements.txt 76 | ``` 77 | 78 | Finally, execute the following command to run this sample: 79 | ```bash 80 | python example.py 81 | ``` 82 | 83 | ### Use latest Storage SDK 84 | 85 | The storage SDK package version here is **2.x.x**, if you are using the [latest](https://pypi.org/project/azure-storage-blob/) version of the storage SDK package, please reference to the following examples: 86 | 87 | * [blob_samples_hello_world.py](https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/storage/azure-storage-blob/samples/blob_samples_hello_world.py) - Examples for common Storage Blob tasks: 88 | * Create a container 89 | * Create a block, page, or append blob 90 | * Upload a file to blob 91 | * Download a blob 92 | * Delete a blob 93 | * Delete the container 94 | * [blob_samples_enumerate_blobs.py](https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/storage/azure-storage-blob/samples/blob_samples_enumerate_blobs.py)- Examples to enumerate blobs 95 | * List blobs. 96 | 97 | ## Contributing 98 | 99 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 100 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 101 | the rights to use your contribution. For details, visit https://cla.microsoft.com. 102 | 103 | When you submit a pull request, a CLA-bot will automatically determine whether you need to provide 104 | a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions 105 | provided by the bot. You will only need to do this once across all repos using our CLA. 106 | 107 | This project has adopted the [Microsoft Open Source Code of Conduct]. 108 | For more information see the [Code of Conduct FAQ] or 109 | contact [opencode@microsoft.com] with any additional questions or comments. 110 | 111 | 112 | [Microsoft.Azure.Storage]: https://pypi.org/project/azure-storage/ 113 | [Microsoft.Azure.Storage.Blob]: https://pypi.org/project/azure-storage-blob/12.0.0/ 114 | [Azure Portal]: https://portal.azure.com 115 | [free account]: https://azure.microsoft.com/free/?WT.mc_id=A261C142F 116 | [Microsoft Open Source Code of Conduct]: https://opensource.microsoft.com/codeofconduct/ 117 | [Code of Conduct FAQ]: https://opensource.microsoft.com/codeofconduct/faq/ 118 | [opencode@microsoft.com]: mailto:opencode@microsoft.com 119 | -------------------------------------------------------------------------------- /example.py: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------------- 2 | # MIT License 3 | # 4 | # Copyright(c) Microsoft Corporation. All rights reserved. 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # ---------------------------------------------------------------------------------- 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | 24 | 25 | 26 | import os 27 | import uuid 28 | import sys 29 | from azure.storage.blob import BlockBlobService, PublicAccess 30 | 31 | # --------------------------------------------------------------------------------------------------------- 32 | # Method that creates a test file in the 'Sample' folder. 33 | # This sample application creates a test file, uploads the test file to the Blob storage, 34 | # lists the blobs in the container, and downloads the file with a new name. 35 | # --------------------------------------------------------------------------------------------------------- 36 | # Documentation References: 37 | # Associated Article - https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-python 38 | # What is a Storage Account - http://azure.microsoft.com/en-us/documentation/articles/storage-whatis-account/ 39 | # Getting Started with Blobs-https://docs.microsoft.com/en-us/azure/storage/blobs/storage-python-how-to-use-blob-storage 40 | # Blob Service Concepts - http://msdn.microsoft.com/en-us/library/dd179376.aspx 41 | # Blob Service REST API - http://msdn.microsoft.com/en-us/library/dd135733.aspx 42 | # ---------------------------------------------------------------------------------------------------------- 43 | 44 | 45 | def run_sample(): 46 | try: 47 | # Create the BlockBlobService that is used to call the Blob service for the storage account 48 | blob_service_client = BlockBlobService( 49 | account_name='accountname', account_key='accountkey') 50 | 51 | # Create a container called 'quickstartblobs'. 52 | container_name = 'quickstartblobs' 53 | blob_service_client.create_container(container_name) 54 | 55 | # Set the permission so the blobs are public. 56 | blob_service_client.set_container_acl( 57 | container_name, public_access=PublicAccess.Container) 58 | 59 | # Create Sample folder if it not exists, and create a file in folder Sample to test the upload and download. 60 | local_path = os.path.expanduser("~/Sample") 61 | if not os.path.exists(local_path): 62 | os.makedirs(os.path.expanduser("~/Sample")) 63 | local_file_name = "QuickStart_" + str(uuid.uuid4()) + ".txt" 64 | full_path_to_file = os.path.join(local_path, local_file_name) 65 | 66 | # Write text to the file. 67 | file = open(full_path_to_file, 'w') 68 | file.write("Hello, World!") 69 | file.close() 70 | 71 | print("Temp file = " + full_path_to_file) 72 | print("\nUploading to Blob storage as blob" + local_file_name) 73 | 74 | # Upload the created file, use local_file_name for the blob name 75 | blob_service_client.create_blob_from_path( 76 | container_name, local_file_name, full_path_to_file) 77 | 78 | # List the blobs in the container 79 | print("\nList blobs in the container") 80 | generator = blob_service_client.list_blobs(container_name) 81 | for blob in generator: 82 | print("\t Blob name: " + blob.name) 83 | 84 | # Download the blob(s). 85 | # Add '_DOWNLOADED' as prefix to '.txt' so you can see both files in Documents. 86 | full_path_to_file2 = os.path.join(local_path, str.replace( 87 | local_file_name ,'.txt', '_DOWNLOADED.txt')) 88 | print("\nDownloading blob to " + full_path_to_file2) 89 | blob_service_client.get_blob_to_path( 90 | container_name, local_file_name, full_path_to_file2) 91 | 92 | sys.stdout.write("Sample finished running. When you hit , the sample will be deleted and the sample " 93 | "application will exit.") 94 | sys.stdout.flush() 95 | input() 96 | 97 | # Clean up resources. This includes the container and the temp files 98 | blob_service_client.delete_container(container_name) 99 | os.remove(full_path_to_file) 100 | os.remove(full_path_to_file2) 101 | except Exception as e: 102 | print(e) 103 | 104 | 105 | # Main method. 106 | if __name__ == '__main__': 107 | run_sample() -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | azure-storage-blob==2.1.0 --------------------------------------------------------------------------------