├── README.md ├── app.py └── templates ├── delete.html ├── index.html └── upload.html /README.md: -------------------------------------------------------------------------------- 1 | # flask-with-ibm-cloud-object-storage 2 | 3 | Working with IBM Cloud Storage 4 | 5 | Step 1 : install Python SDK for Cloud Object Storage 6 | 7 | ``` 8 | pip install ibm-cos-sdk 9 | ``` 10 | 11 | Read Document - https://cloud.ibm.com/docs/cloud-object-storage?topic=cloud-object-storage-python 12 | 13 | Step 2 : Clone or download this flask repo 14 | 15 | ``` 16 | git clone git@github.com:kshyam/flask-with-ibm-cloud-object-storage.git 17 | ``` 18 | 19 | Download Zip - https://github.com/kshyam/flask-with-ibm-cloud-object-storage/archive/refs/heads/main.zip 20 | 21 | Stpe 3 : Run flask app in debug mode 22 | 23 | ``` 24 | flask --debug run 25 | ``` 26 | 27 | OR 28 | 29 | ``` 30 | export FLASK_ENV=development 31 | flask run 32 | 33 | ``` 34 | 35 | Open the application 36 | 37 | ``` 38 | http://127.0.0.1:5000/ 39 | 40 | 41 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask,redirect,url_for,render_template,request 2 | import ibm_boto3 3 | from ibm_botocore.client import Config, ClientError 4 | 5 | COS_ENDPOINT="https://s3.jp-tok.cloud-object-storage.appdomain.cloud" 6 | COS_API_KEY_ID=" " 7 | COS_INSTANCE_CRN="" 8 | 9 | 10 | 11 | # Create resource https://s3.ap.cloud-object-storage.appdomain.cloud 12 | cos = ibm_boto3.resource("s3", 13 | ibm_api_key_id=COS_API_KEY_ID, 14 | ibm_service_instance_id=COS_INSTANCE_CRN, 15 | config=Config(signature_version="oauth"), 16 | endpoint_url=COS_ENDPOINT 17 | ) 18 | 19 | app=Flask(__name__) 20 | 21 | 22 | 23 | def get_item(bucket_name, item_name): 24 | print("Retrieving item from bucket: {0}, key: {1}".format(bucket_name, item_name)) 25 | try: 26 | file = cos.Object(bucket_name, item_name).get() 27 | 28 | print("File Contents: {0}".format(file["Body"].read())) 29 | except ClientError as be: 30 | print("CLIENT ERROR: {0}\n".format(be)) 31 | except Exception as e: 32 | print("Unable to retrieve file contents: {0}".format(e)) 33 | 34 | 35 | def get_bucket_contents(bucket_name): 36 | print("Retrieving bucket contents from: {0}".format(bucket_name)) 37 | try: 38 | files = cos.Bucket(bucket_name).objects.all() 39 | files_names = [] 40 | for file in files: 41 | files_names.append(file.key) 42 | print("Item: {0} ({1} bytes).".format(file.key, file.size)) 43 | return files_names 44 | except ClientError as be: 45 | print("CLIENT ERROR: {0}\n".format(be)) 46 | except Exception as e: 47 | print("Unable to retrieve bucket contents: {0}".format(e)) 48 | 49 | 50 | def delete_item(bucket_name, object_name): 51 | try: 52 | cos.delete_object(Bucket=bucket_name, Key=object_name) 53 | print("Item: {0} deleted!\n".format(object_name)) 54 | except ClientError as be: 55 | print("CLIENT ERROR: {0}\n".format(be)) 56 | except Exception as e: 57 | print("Unable to delete object: {0}".format(e)) 58 | 59 | 60 | 61 | def multi_part_upload(bucket_name, item_name, file_path): 62 | try: 63 | print("Starting file transfer for {0} to bucket: {1}\n".format(item_name, bucket_name)) 64 | # set 5 MB chunks 65 | part_size = 1024 * 1024 * 5 66 | 67 | # set threadhold to 15 MB 68 | file_threshold = 1024 * 1024 * 15 69 | 70 | # set the transfer threshold and chunk size 71 | transfer_config = ibm_boto3.s3.transfer.TransferConfig( 72 | multipart_threshold=file_threshold, 73 | multipart_chunksize=part_size 74 | ) 75 | 76 | # the upload_fileobj method will automatically execute a multi-part upload 77 | # in 5 MB chunks for all files over 15 MB 78 | with open(file_path, "rb") as file_data: 79 | cos.Object(bucket_name, item_name).upload_fileobj( 80 | Fileobj=file_data, 81 | Config=transfer_config 82 | ) 83 | 84 | print("Transfer for {0} Complete!\n".format(item_name)) 85 | except ClientError as be: 86 | print("CLIENT ERROR: {0}\n".format(be)) 87 | except Exception as e: 88 | print("Unable to complete multi-part upload: {0}".format(e)) 89 | 90 | 91 | @app.route('/') 92 | def index(): 93 | files = get_bucket_contents('flaskapp123') 94 | return render_template('index.html', files = files) 95 | 96 | @app.route('/deletefile', methods = ['GET', 'POST']) 97 | def deletefile(): 98 | if request.method == 'POST': 99 | bucket=request.form['bucket'] 100 | name_file=request.form['filename'] 101 | 102 | delete_item(bucket,name_file) 103 | return 'file deleted successfully' 104 | 105 | if request.method == 'GET': 106 | return render_template('delete.html') 107 | 108 | 109 | @app.route('/uploader', methods = ['GET', 'POST']) 110 | def upload(): 111 | if request.method == 'POST': 112 | bucket=request.form['bucket'] 113 | name_file=request.form['filename'] 114 | f = request.files['file'] 115 | multi_part_upload(bucket,name_file,f.filename) 116 | return 'file uploaded successfully GO to Home' 117 | 118 | 119 | if request.method == 'GET': 120 | return render_template('upload.html') 121 | 122 | if __name__=='__main__': 123 | app.run(host='0.0.0.0',port=8080,debug=True) 124 | 125 | 126 | -------------------------------------------------------------------------------- /templates/delete.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | HOME 5 | Upload 6 | Delete 7 |

8 | 9 |

IBM Object Storage

10 | 11 |
12 | 13 | 14 |
15 |
16 | 17 |
18 |
19 | 20 |
21 | 22 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | HOME 2 | Upload 3 | Delete 4 |

5 |

IBM Object Storage

6 | 7 | 8 | 9 | 10 | 11 | {% for row in files %} 12 |
13 |

Filename : {{row}}

14 | 15 |
16 | {% endfor %} 17 | 18 | -------------------------------------------------------------------------------- /templates/upload.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HOME 6 | Upload 7 | Delete 8 |

9 | 10 |

IBM Upload File

11 | 12 |
14 | 15 |
16 |
17 | 18 |
19 |
20 | 21 |
22 |
23 | 24 |
25 | 26 | --------------------------------------------------------------------------------