Generating Badges from Badgeyay API

Badgeyay is a badge generator and its main functionality is generating badges. Since the beginning of GSoC 2018 period, Badgeyay is under refactoring and remodeling process. We have introduced many APIs to make sure that Badgeyay works. Now, the badge generator has an endpoint to generate badges for your events/meetups How to create badges? Creating badges using the newly formed API is simpler than before. All you need to do is pass some basic details of the image you want, the data you want, the size and the color of font etc to the API and woosh! Within a blink of your eye the badges are generated. Backend requires some data fields to generate badges { "csv" : "a731h-jk12n-bbau2-saj2-nxg31.csv", "image" : "p2ja7-gna398-c23ba-naj31a.png", "text-color" : "#ffffff" } “csv” is the filename of the csv that the user uploads and get back as a result, “image” is the image name that user gets after a successful upload to the respective APIs, “text-color” is the color of the text that the user wants on the badges. Output of the API { "output" :  "path-to-the-pdf-of-the-badge-generated", . . } What is happening behind the scene? Once the user sends the data to the API, the required route is triggered and the data is checked,If the data is not present an error response is sent back to the user so as to inform them about the misplacement or improper format of data. import os from flask import Blueprint, jsonify, request from flask import current_app as app # from api.helpers.verifyToken import loginRequired from api.utils.response import Response from api.utils.svg_to_png import SVG2PNG from api.utils.merge_badges import MergeBadges router = Blueprint('generateBadges', __name__) @router.route('/generate_badges', methods=['POST']) def generateBadges(): try: data = request.get_json() except Exception as e: return jsonify( Response(401).exceptWithMessage(str(e),'Could not find any JSON')) if not data.get('csv'): return jsonify( Response(401).generateMessage('No CSV filename found')) if not data.get('image'): return jsonify(Response(401).generateMessage('No Image filename found')) csv_name = data.get('csv') image_name = data.get('image') text_color = data.get('text-color') or '#ffffff' svg2png = SVG2PNG() svg2png.do_text_fill('static/badges/8BadgesOnA3.svg', text_color) merge_badges = MergeBadges(image_name, csv_name) merge_badges.merge_pdfs() output = os.path.join(app.config.get('BASE_DIR'), 'static', 'temporary', image_name) return jsonify( Response(200).generateMessage(str(output)))   After the data is received, we send it to MergeBadges which internally calls the GenerateBadges class which creates the badges. Brief explanation of the Badge Generation Process: - Gather data from the user- Fill the SVG for badges with the text color - Load the image from uploads directory - Generate badges for every individual - Create PDFs for individual Badges - Merge those PDFs to provide an all-badges pdf to the user   And this is how we generated badges for the user using the Badgeyay Backend API. How is this effective? We are making sure that the user chooses the image and csv that he/she has uploaded only, In this way we maintain a proper workflow, we also manage these badges into the database and hence using the filenames helps a lot.It does not involve sending huge files and a lot of data like we had in the previous API. Earlier, we used to send the image and the csv…

Continue ReadingGenerating Badges from Badgeyay API

File and Image Upload API in Badgeyay

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…

Continue ReadingFile and Image Upload API in Badgeyay