Quick intro to the modules: app.py - runs basic flask app, which imports file to MySQL database using SQLAlchemy. storage.py - has a connection to BackBlaze, which picks up a file from static folder and sends it for storage, storage link gets generated from BackBlaze.
I'm trying to amend the code so, once I upload the file to flask via app.py, file link is saved in MySQL and actual file is sent to BackBlaze. Can you please assist to link two modules?
app.py
from io import BytesIO
from flask_migrate import Migrate
from flask import Flask, render_template, request, send_file
from flask_sqlalchemy import SQLAlchemy
from storage import backblazeload
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:password@localhost/fof'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)
migrate = Migrate(app, db)
class Trades(db.Model):
id = db.Column(db.Integer, primary_key=True)
filename = db.Column(db.String(50))
data = db.Column(db.LargeBinary)
link = db.Column(db.String(200))
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
file = request.files['file']
upload = Trades(filename=file.filename, data=file.read())
db.session.add(upload)
db.session.commit()
# Generate the BackBlaze link and save it to the database
link = backblazeload(file)
upload.link = link
db.session.commit()
return f'Uploaded: {file.filename}'
return render_template('index.html')
@app.route('/download/<upload_id>')
def download(upload_id):
upload = Trades.query.filter_by(id=upload_id).first()
return send_file(upload.data, attachment_filename=upload.filename, as_attachment=True)
if __name__ == '__main__':
app.run(debug=True)
storage.py
import os
from dotenv import load_dotenv
from b2sdk.v2 import InMemoryAccountInfo, B2Api
from io import BytesIO
def backblazeload(file):
load_dotenv()
info = InMemoryAccountInfo() # store credentials, tokens and cache in memory
b2_api = B2Api(info)
application_key_id = "app_id"
application_key = "app_key"
b2_api.authorize_account("production", application_key_id, application_key)
bucket = b2_api.get_bucket_by_name("pickabucketname")
file_data = BytesIO(file.read())
b2_file_name = file.filename
file_info = {'how': 'good-file'}
uploaded_file_info = bucket.upload_bytes(
file_data,
file_name=b2_file_name,
file_infos=file_info
)
uploaded_file_id = uploaded_file_info['fileId']
print(b2_api.get_download_url_for_fileid(uploaded_file_id))
I'm getting below error now:
TypeError: object of type '_io.BytesIO' has no len()
Two issues in
storage.pyare:BytesIOtobucket.upload_bytes(), when it just wants the bytesFileVersionobject returned bybucket.upload_bytes()as if it were a dict, causing the'FileVersion' object is not subscriptableerror.This should work for you: