Badgeyay has seen many changes in the recent past during its refactoring. It started off with backend and we have now transition to remodeling backend as well.
The backend transition is working perfectly. We have established sufficient APIs so far to get it working.
Some of the most important APIs that we created are
- Image Upload API
- File Upload API
Why do we need APIs?
We need APIs so that the frontend written in Ember JS can coordinate with the backend written in Python Flask with the database being PostgreSQL.
Creating the APIs
Creating these APIs is easy and straightforward. The following APIs are written in Python Flask with a backend database support of PostgreSQL.
Image Upload API
The image upload API considers that the frontend is sending the Image as a base64 encoded string and the backend is supposed to accept this string and convert this string into an image and save it onto the server.
We proceed by creating a file named fileUploader.py and code the following API.
First of all, we need to declare the imports
from flask import Blueprint, request, jsonify from api.utils.response import Response from api.helpers.verifyToken import loginRequired from api.helpers.uploads import saveToImage, saveToCSV
Now, let’s create a route for image upload.
router = Blueprint('fileUploader', __name__) @router.route('/image', methods=['POST']) @loginRequired def uploadImage(): try: image = request.json['data'] except Exception as e: return jsonify( Response(400).exceptWithMessage( str(e), 'No Image is specified')) extension = request.json['extension'] try: imageName = saveToImage(imageFile=image, extension=extension) except Exception as e: return jsonify( Response(400).exceptWithMessage( str(e), 'Image could not be uploaded')) return jsonify( Response(200).generateMessage({ 'message': 'Image Uploaded Successfully', 'unique_id': imageName}))
We are using the saveToImage function to actually save the image to the backend server.
The function definition of saveToImage function is given below.
def generateFileName(): return str(uuid.uuid4())def saveToImage(imageFile=None, extension='.png'): imageName = generateFileName() + extension imageDirectory = os.path.join(app.config.get('BASE_DIR'), 'static', 'uploads', 'image')if not os.path.isdir(imageDirectory): os.makedirs(imageDirectory)imagePath = os.path.join(imageDirectory, imageName) image = open(imagePath, "wb") image.write(imageFile.decode('base64')) image.close() return imageName
Similarly, we are using file upload route to upload files to backend server.
The route for uploading files along with its helper function saveToCSV is given below.
def saveToCSV(csvFile=None, extension='.csv'): csvName = generateFileName() + extension csvDirectory = os.path.join(app.config.get('BASE_DIR'), 'static', 'uploads', 'csv')if not os.path.isdir(csvDirectory): os.makedirs(csvDirectory)csvPath = os.path.join(csvDirectory, csvName) csvFile.save(csvPath)return csvName
@router.route('/file', methods=['POST']) @loginRequired def fileUpload(): if 'file' not in request.files: return jsonify( Response(401).generateMessage( 'No file is specified'))file = request.files['file'] try: csvName = saveToCSV(csvFile=file, extension='.csv') except Exception as e: return jsonify( Response(400).exceptWithMessage( str(e), 'CSV File could not be uploaded'))return jsonify( Response(200).generateMessage({ 'message': 'CSV Uploaded successfully', 'unique_id': csvName}))
What happens to the uploaded files?
The uploaded files gets saved into their respective directories, i.e. static/uploads/csv for CSV files and static/uploads/images for Image uploads.
The developer can view them from their respective folders. The static folder has been added to .gitignore so that it does not gets uploaded to github repository.
Everything has been taken care of with immense accuracy and proper error handling.
Further Improvements
Further improvements in Badgeyay includes adding separate database models, work on adding a beautiful frontend and to add proper routes for completing the backend.
Resources
- Badgeyay Repository : https://github.com/fossasia/badgeyay
- Pull Request for the same : https://github.com/fossasia/badgeyay/pull/697
- Issue for the same : https://github.com/fossasia/badgeyay/issues/696
- Pull Request for the same : https://github.com/fossasia/badgeyay/pull/716
- Issue for the same : https://github.com/fossasia/badgeyay/issues/701
- Flask File Uploads Guide : flask.pocoo.org/docs/0.12/patterns/fileuploads/
- A really great website for learning flask : https://www.tutorialspoint.com/flask/flask_file_uploading.htm
- Read about Flask JWT : https://pythonhosted.org/Flask-JWT