Uploading Badges To Google Cloud Badgeyay

Badgeyay is an open source project developed by FOSSASIA community. This project mainly aims for generating badges for technical conferences and events.The project is divided into two parts mainly. Backend is developed in flask and frontend is developed in emberjs. The problem is after the badge generation, the flask server is storing and serving those files. In practise this is not a good convention to do so. This should be handled by secondary hosting server program like gunicorn or nginx. Better approach would be to consume the firebase storage and admin sdk for storing the badges on google cloud. This will also offload storage needs from the flask server and also give a public link over the network to access. Procedure Get the file path of the temporary badge generated on the flask server. Currently badges are saved in the directory of the image file uploaded and final badge generated is written in all-badges.pdf` badgePath = os.getcwd() + '/static/temporary/' + badgeFolder badgePath + '/all-badges.pdf'   Create the blob path for the storage. Blob can be understood as the final reference to the location where the contents are saved onto the server. This can be a nested directory structure or simply a filename in root directory. 'badges/' + badge_created.id + '.pdf'   In our case it is the id of the badge that is generated in the badges directory. Function for uploading the file generated in temporary storage to google cloud storage. def fileUploader(file_path, blob_path):   bucket = storage.bucket()   fileUploaderBlob = bucket.blob(blob_path)   try:       with open(file_path, 'rb') as file_:           fileUploaderBlob.upload_from_file(file_)   except Exception as e:       print(e)   fileUploaderBlob.make_public()   return fileUploaderBlob.public_url   It creates a bucket using the firebase admin SDK and then open the file from the file path. After opening the file from the path it writes the data to the cloud storage. After the data is written, the blob is made public and the public access link to the blob is fetched, which then later returned and saved in the local database. Topics Involved Firebase admin sdk for storage Google cloud storage sdk Resources Firebase admin sdk documentation - Link Google Cloud Storage SDK Python - Link Blob Management - Link  

Continue ReadingUploading Badges To Google Cloud Badgeyay

Exporting CSV data through API

A Badge generator like Badgeyay must be able to generate, store and export the user data as and when needed. This blog post is about adding the exporting functionality to badgeyay backend.. Why do we need such an API? Exporting data is required for a user. A user may want to know the details he/she has uploaded to the system or server. In our case we are dealing with the fact of exporting the CSV data from backend of Badgeyay. Adding the functionality to backend Let us see how we implemented this functionality into the backend of the project. Step 1 : Adding the necessary imports We first need to import the required dependencies for the route to work import os import base64 import uuid from flask import request, Blueprint, jsonify from flask import current_app as app from api.models.file import File from api.schemas.file import ExportFileSchema from api.utils.errors import ErrorResponse from api.schemas.errors import FileNotFound Step 2 : Adding a route This step involves adding a separate route that provides us with the exported data from backend. @router.route('/csv/data', methods=['GET']) def export_data(): input_data = request.args file = File().query.filter_by(filename=input_data.get('filename')).first() if file is None: return ErrorResponse(FileNotFound(input_data.get('filename')).message, 422, {'Content-Type': 'application/json'}).respond() export_obj = { 'filename': file.filename, 'filetype': file.filetype, 'id': str(uuid.uuid4()), 'file_data': None} with open(os.path.join(app.config.get('BASE_DIR'), 'static', 'uploads', 'csv', export_obj['filename']), "r") as f: export_obj['file_data'] = f.read() export_obj['file_data'] = base64.b64encode(export_obj['file_data'].encode()) return jsonify(ExportFileSchema().dump(export_obj).data) Step 2 : Adding a relevant Schema After creating a route we need to add a relevant schema that will help us to deliver the badges generated by the user to the Ember JS frontend so that it can be consumed as JSON API objects and shown to the user. class ExportFileSchema(Schema): class Meta: type_ = 'export-data' kwargs = {'id': '<id>'} id = fields.Str(required=True, dump_only=True) filename = fields.Str(required=True, dump_only=True) filetype = fields.Str(required=True, dump_only=True) file_data = fields.Str(required=True, dump_only=True) This is the ExportFileSchema that produces the output results of the GET request on the route. This helps us get the data onto the frontend. Further Improvements We are working on making badgeyay more comprehensive yet simple. This API endpoint needs to get registered onto the frontend. This can be a further improvement to the project and can be iterated over the next days. Resources The Pull Request for the same : https://github.com/fossasia/badgeyay/pull/1138 The Issue for the same : https://github.com/fossasia/badgeyay/issues/1137 Read about adding routes Blueprint : http://flask.pocoo.org/docs/1.0/blueprints/ Read about Schemas : https://github.com/marshmallow-code/marshmallow-jsonapi

Continue ReadingExporting CSV data through API

Dated queries in Badgeyay admin

Badgeyay is not just an anonymous badge generator that creates badges according to your needs, but it now has an admin section that allows the admin of the website to control and look over the statistics of the website. Why do we need such an API? For an admin, one of the most common functionality is to gather the details of the users or the files being served onto or over the server. Not just that, but the admin must also be aware about the traffic or files on the server in a particular duration of time. So we need an API that can coordinate all the stuff that requires dated queries from the backend database. Adding the functionality to backend Let us see how we implemented this functionality into the backend of the project. Step 1 : Adding a route This step involves adding a separate route that provides us with the output of the dated badges queries from backend. @router.route('/get_badges_dated', methods=['POST']) def get_badges_dated(): schema = DatedBadgeSchema() input_data = request.get_json() data, err = schema.load(input_data) if err: return jsonify(err) dated_badges = Badges.query.filter(Badges.created_at <= data.get('end_date')).filter(Badges.created_at >= data.get('start_date')) return jsonify(AllBadges(many=True).dump(dated_badges).data) This route allows us to get badges produced by any user during a certain duration as a JSON API data object. This object is fed to the frontend to render the badges as cards. Step 2 : Adding a relevant Schema After creating a route we need to add a relevant schema that will help us to deliver the badges generated by the user to the Ember JS frontend so that it can be consumed as JSON API objects and shown to the user. class DatedBadgeSchema(Schema): class Meta: type_ = 'dated-badges' kwargs = {'id': '<id>'} id = fields.Str(required=True, dump_only=True) start_date = fields.Date(required=True) end_date = fields.Date(required=True) class AllBadges(Schema): class Meta: type_ = 'all-badges' self_view = 'admin.get_all_badges' kwargs = {'id': '<id>'} id = fields.Str(required=True, dump_only=True) image = fields.Str(required=True) csv = fields.Str(required=True) badge_id = fields.Str(required=True) text_color = fields.Str(required=True) badge_size = fields.Str(required=True) created_at = fields.Date(required=True) user_id = fields.Relationship( self_url='/api/upload/get_file', self_url_kwargs={'file_id': '<id>'}, related_url='/user/register', related_url_kwargs={'id': '<id>'}, include_resource_linkage=True, type_='User' ) This is the DatedBadge schema that produces the output results of the POST request on the route. And there is the AllBadges schema that produces the output results of the POST request on the route. Further Improvements We are working on adding multiple routes and adding modifications to database models and schemas so that the functionality of Badgeyay can be extended to a large extent. This will help us in making this badge generator even better. Resources The Pull Request for the same : https://github.com/fossasia/badgeyay/pull/1040 The Issue for the same : https://github.com/fossasia/badgeyay/issues/1039 Read about adding routes Blueprint : http://flask.pocoo.org/docs/1.0/blueprints/ Read about Schemas : https://github.com/marshmallow-code/marshmallow-jsonapi  

Continue ReadingDated queries in Badgeyay admin

Get My Badges from Badgeyay API

Badgeyay is no longer a simple badge generator. It has more cool features than before. Badgeyay now supports a feature that shows your badges. It is called ‘my-badges’ component. To get this component work, we need to design a backend API to deliver the badges produced by a particular user. Why do we need such an API? The main aim of Badgeyay has changed from being a standard and simple badge generator to a complete suite that solves your badge generation and management problem. So to tackle the problem of managing the produced badges per user, we need to define a separate route and schema that delivers the generated badges. Adding the functionality to backend Let us see how we implemented this functionality into the backend of the project. Step 1 : Adding a route This step involves adding a separate route that provides with the generated output of the badges linked with the user account. @router.route('/get_badges', methods=['GET']) def get_badges(): input_data = request.args user = User.getUser(user_id=input_data.get('uid')) badges = Badges().query.filter_by(creator=user) return jsonify(UserBadges(many=True).dump(badges).data) This route allows us to get badges produced by the user as a JSON API data object. This object is fed to the frontend to render the badges as cards. Step 2 : Adding a relevant Schema After creating a route we need to add a relevant schema that will help us to deliver the badges generated by the user to the Ember JS frontend so that it can be consumed as JSON API objects and shown to the user. class UserBadges(Schema): class Meta: type_ = 'user-badges' self_view = 'generateBadges.get_badges' kwargs = {'id': '<id>'} id = fields.Str(required=True, dump_only=True) image = fields.Str(required=True) csv = fields.Str(required=True) badge_id = fields.Str(required=True) text_color = fields.Str(required=True) badge_size = fields.Str(required=True) user_id = fields.Relationship( self_url='/api/upload/get_file', self_url_kwargs={'file_id': '<id>'}, related_url='/user/register', related_url_kwargs={'id': '<id>'}, include_resource_linkage=True, type_='User' ) This is the ‘UserBadge’ schema that produces the output results of the GET request on the route. Finally, once this is done we can fire up a GET request on our deployment to receive results. The command that you need to run is given below. $ ~ curl -X GET http://localhost:5000/api/get_badges?uid={user_id} Further Improvements We are working on adding multiple routes and adding modifications to database models and schemas so that the functionality of Badgeyay can be extended to a large extent. This will help us in making this badge generator even better. Resources The Pull Request for the same : https://github.com/fossasia/badgeyay/pull/949 The Issue for the same : https://github.com/fossasia/badgeyay/issues/948 Read about adding routes Blueprint : http://flask.pocoo.org/docs/1.0/blueprints/ Read about Schemas : https://github.com/marshmallow-code/marshmallow-jsonapi  

Continue ReadingGet My Badges from Badgeyay API

Custom Colored Images with Badgeyay

Backend functionality of any Badge generator is to generate badges as per the requirements of the user. Currently Badgeyay is capable of generating badges by the following way: Adding or Selecting a Pre-defined Image from the given set Uploading a new image and then using it as a background Well, badgeyay has been missing a functionality of generating Custom Colored images. What is meant by Custom Colored Badges? Currently, there are a set of 7 different kind of pre-defined images to choose from. But let’s say that a user want to choose from the images but doesn’t like any of the color. Therefore we provide the user with an additional option of applying custom background-color for their badges. This allows Badgeyay to deliver a more versatile amount of badges than ever before. Adding the functionality to backend Lets see how this functionality has been implemented in the backend of the project. Step 1 :  Adding a background-color route to backend Before generating badges, we need to know that what is the color that the user wants on the badge. Therefore we created a route that gathers the color and saves the user-defined.svg into that particular color. @router.route('/background_color', methods=['POST']) def background_color(): try: data = request.get_json()['data']['attributes'] bg_color = data['bg_color'] except Exception: return ErrorResponse(PayloadNotFound().message, 422, {'Content-Type': 'application/json'}).respond() svg2png = SVG2PNG() bg_color = '#' + str(bg_color) user_defined_path = svg2png.do_svg2png(1, bg_color) with open(user_defined_path, "rb") as image_file: image_data = base64.b64encode(image_file.read()) os.remove(user_defined_path) try: imageName = saveToImage(imageFile=image_data.decode('utf-8'), extension=".png") except Exception: return ErrorResponse(ImageNotFound().message, 422, {'Content-Type': 'application/json'}).respond() uid = data['uid'] fetch_user = User.getUser(user_id=uid) if fetch_user is None: return ErrorResponse(UserNotFound(uid).message, 422, {'Content-Type': 'application/json'}).respond() file_upload = File(filename=imageName, filetype='image', uploader=fetch_user) file_upload.save_to_db() return jsonify(ColorImageSchema().dump(file_upload).data) Step 2: Adding Schema for background-color to backend To get and save values from and to database, we need to have some layer of abstraction and so we use schemas created using marshmallow_jsonapi class ColorImageSchema(Schema): class Meta: type_ = 'bg-color' self_view = 'fileUploader.background_color' kwargs = {'id': '<id>'} id = fields.Str(required=True, dump_only=True) filename = fields.Str(required=True) filetype = fields.Str(required=True) user_id = fields.Relationship( self_url='/api/upload/background_color', self_url_kwargs={'file_id': '<id>'}, related_url='/user/register', related_url_kwargs={'id': '<id>'}, include_resource_linkage=True, type_='User' ) Now we have our schema and route done, So we can move forward with the logic of making badges. Step 3 : Converting the SVG to PNG and adding custom color Now we have the user-defined color for the badge background, but we still need a way to apply it to the badges. It is done using the following code below. def do_svg2png(self, opacity, fill): """ Module to convert svg to png :param `opacity` - Opacity for the output :param `fill` -  Background fill for the output """ filename = os.path.join(self.APP_ROOT, 'svg', 'user_defined.svg') tree = parse(open(filename, 'r')) element = tree.getroot() # changing style using XPath. path = element.xpath('//*[@id="rect4504"]')[0] style_detail = path.get("style") style_detail = style_detail.split(";") style_detail[0] = "opacity:" + str(opacity) style_detail[1] = "fill:" + str(fill) style_detail = ';'.join(style_detail) path.set("style", style_detail) # changing text using XPath. path = element.xpath('//*[@id="tspan932"]')[0] # Saving in the original XML tree etree.ElementTree(element).write(filename, pretty_print=True) print("done") png_name = os.path.join(self.APP_ROOT, 'static', 'uploads', 'image', str(uuid.uuid4())) + ".png" svg2png(url=filename, write_to=png_name) return png_name Finally…

Continue ReadingCustom Colored Images with Badgeyay

Implementing Leak Canary in PSLab Android App

This post discusses the issue of memory leaks and how to handle them efficiently and what are the tools available which help developers in managing the memory leaks. After working on PR #824 opened under PSLab - Android repository I have got a greater idea about how to manage the memory efficiently and what are the tools that should be used to ease the work. What are memory leaks and how it affects the quality of app? In simple words, memory leaks happen when you hold on to an item for long after its purpose have been served. It is as simple as that. But let us dive in further to understand more about this topic. Programming languages like C and C++ need memory management done by user whereas in higher level languages like Java, Python, etc. low-level memory management and garbage collection is done automatically by the system. But it is due to programming faults that memory leaks happen and so care needs to be taken with higher level languages too in handling memory efficiently. In Android or say in any OS (operating system), every item has to be destroyed or say deleted or freed from the memory after its purpose is served. But if the reference of this object is passed on to any other object which has a greater time of importance than this, then it will try to hold this object for long and so the garbage collector won’t be able to collect it and so there will be memory leaks in the code. This is how memory leaks occurs inside an app. Now, the issue of memory leaks is utmost important among developers as due to it, the app becomes slow, laggy, eats up a lot of memory and the app crashes after some time of use which creates a very bad user experience. As the user keeps on using the app, the heap memory also keeps on increasing and due to memory leaks, this heap can’t be freed by the garbage collector. Thus, all these issues contribute to making the threads or processes running inside the app slower and it can result in a lag of time from microseconds to milliseconds too!! How can you detect these memory leaks? This blog is mostly for Android developers and so I will use the environment of Android Studio for reference. For controlling memory leaks, Android Studio has a very powerful tool named Monitors. There are individual monitors not only for memory usage but for CPU, GPU, and network usage as well. An example of it is shown in figure 1 below. Figure 1. Monitor in Android Studio Now how to observe the graphs that are produced by Monitors to see if there are any memory leaks? The first alarming case is when the memory usage graph constantly increases and doesn’t come down as time passes and even not decreases when you put the app in the background. The tools which are used to undo memory leaks…

Continue ReadingImplementing Leak Canary in PSLab Android App

Ember Data Integration In Badgeyay Frontend

Badgeyay is an open source utility to develop badges for events and tech conferences. Badgeyay project is divided into two components. Frontend part is designed with ember and backend part is designed with Flask and database as PostgreSQL and Firebase as PaaS. After refactoring the backend API for generation of badges, now it is time to consume the API in frontend by ember, and the way to consume the api in ember front--end is with the use of in built ember-data library. Ember data behaves in a way similar to server side ORM’s (Object Relational Mappers). It is a very versatile library and can be equipped with variety of backend services. It can be used with REST as well as sockets and other transfer protocols for communication. For better understanding the working of ember data, let’s see how to use the same to consume the File Upload endpoint in the backend. Procedure Enabling CORS on server, to allow cross-domain requests to the API. from flask_cors import CORS CORS(app, resources={r"*": {"origins": "*"}}) Creating Adapter for the model in frontend. In our case it is csv-file. In the adapter we need to specify the host and the path, because our backend api is not running on the same port. import DS from 'ember-data'; const { RESTAdapter } = DS; export default RESTAdapter.extend({ host : 'http://localhost:5000', pathForType : () => { return 'api/upload/file'; } }); After creating the adapter we need to create the record in the controller of the respective component. The record is like an object of a class, which when pushed to store will make a network request to backend (POST) and fetch the response from the backend. Backend response will provide the id to save in store import Controller from '@ember/controller'; import { inject as service } from '@ember/service'; export default Controller.extend({ routing : service('-routing'), actions : { mutateCSV(csvData) { let csv_ = this.get('store').createRecord('csv-file', { csvFile : csvData, extension : 'csv' }); csv_.save(); }, mutateText(txtData) { console.log(txtData); } } }); Model for the csv-file import DS from 'ember-data'; const { Model, attr } = DS; export default Model.extend({ csvFile : attr('string'), extension : attr('string') }); Next is to create serializers for the model. Serializers gets triggered at two moments, first when the data is sent to the server and second when data is received from the server. Each time an independent function gets executed. As the naming conventions of the functions pretty much explains their role, but for the sake of clarification serialize function gets executed when we send request to the server and normalizeResponse gets executed when we are getting response from the server. import DS from 'ember-data'; const { JSONAPISerializer } = DS; export default JSONAPISerializer.extend({ serialize(snapshot, options) { let json = this._super(...arguments); json.csvFile = { 'csvFile' : json.data.attributes['csv-file'], 'extension' : json.data.attributes.extension }; delete json.data; return json; }, normalizeResponse(store, primaryModelClass, payload, id, requestType) { return payload; } }); After receiving the response a promise is returned by the push method to save the record in the store…

Continue ReadingEmber Data Integration In Badgeyay Frontend

Implementing Sign up Feature through Email in Badgeyay

Badgeyay project is divided into two parts i.e front-end of Ember JS and back-end with REST-API programmed in Python. We already have logging In features implemented with the help of Firebase Authentication. A User can login in the Badgeyay with the help of Google, Facebook and Twitter credentials through a single click. Now, the challenging part is to implement the sign up with Email feature in Frontend and Backend to enable the user to signup and Login with the help of Email and Password In this blog, I will be discussing how I set up Sign up feature in Badgeyay frontend to send the data in backend besides having Oauth logging features in Badgeyay integrated with Firebase in my Pull Request. The sign up form is already implemented and I have already mentioned in my previous blog. So we need to send the form data to backend to register user so that user can login using the registered credentials. We need an Adapter, Signup action, controller , Signup Data model  and a serializer for doing this task. Let’s get started and understand the terminologies before implementing the feature. What is Ember Data ? It is a data management library for Ember Framework which help to deal with persistent application data. We will generate Ember data model using Ember CLI in which we will define the data structure we will be requiring to provide to our application for User Signup. Step 1 : Generate ember data model for signup. $ ember g model user-signup   Step 2: Define the user-signup data model. import DS from 'ember-data'; const { Model, attr } = DS; export default Model.extend({ username : attr('string'), email : attr('string'), password : attr('string') });   What are Actions ? We already have the signup form implemented in frontend. Now we need to provide a action to the form when the user enters the data in form. If we add the {{action}} helper to any HTML DOM element, when a user clicks the element, the named event will be sent to the template's corresponding component or controller. <button class="ui orange submit button" {{ action 'signUp' }}>Sign Up</button>   We need to add signUp action in sign-up component and controller. // Signup Controller import Controller from '@ember/controller'; import { inject as service } from '@ember/service'; export default Controller.extend({ routing : service('-routing'), actions : { signUp(email, username, password) { const _this = this; let user_ = this.get('store').createRecord('user-signup', { email, username, password }); user_.save() .then(record => { _this.transitionToRoute('/'); }) .catch(err => { console.log(err); }); } } }); // Sign up Component import Component from '@ember/component'; export default Component.extend({ init() { this._super(...arguments); }, email : '', password : '', isLoading : false, actions: { signUp(event) { event.preventDefault(); let email = ''; let password = ''; let username = ''; email = this.get('email'); password = this.get('password'); username = this.get('username'); this.get('signUp')(email, username, password); } }, });   What is an Adapter ? An adapter determines how the data is persisted to a backend data store. We…

Continue ReadingImplementing Sign up Feature through Email in Badgeyay

Database Listener for User Centric Events

Badgeyay is an open-source utility developed by FOSSASIA to generate badges for conferences and events. The project is separated into two components to ease maintainability. First is the frontend part which is in ember and second part is backend which is in Flask. The choice of database to support backend is PostgreSQL. Now comes the problem, whenever a user is registered in the database, he should receive  a verification mail, that he is successfully registered on the platform. For this case we have to listen to the database events on User model. This issue has greater extendibility than only sending greeting or verification mail to the user. We can extend this to trigger services that are dependent on user registration, like subscribing the user to some set of services based on the plan he opted while registration and many more. These type of issues cannot be handled by normal relationship with tables and other entities, there has to be logic in place to support such functionalities. So the challenges for tackling the problem are as follows: Listen to the insert_action in User model Extracting the details necessary for the logic Execute particular logic Procedure Attaching insert_action listener to the User model. This function will get triggered whenever an entity is saved in the User model. <!-- HTML generated using hilite.me -->@db.event.listens_for(User, "after_insert") def logic(mapper, connection, target): { ...... } When the function gets triggered, extract the details of the saved user that is necessary for the logic. As currently we are sending greeting mail to the user,we only need the email of the user. Target is the actual saved user passed as argument to the listening function from the library. <!-- HTML generated using hilite.me -->msg = {} msg['subject'] = "Welcome to Badgeyay" msg['receipent'] = target.email msg['body'] = "It's good to have you onboard with Badgeyay. Welcome to " \ "FOSSASIA Family." sendMail(msg) Now the details are passed to sendMail() function for sending mail which uses flask-mail library to send mail to the recipient. def sendMail(message): if message and message.receipent: try: msg = Message( subject=message.subject, sender=app.config['MAIL_USERNAME'], Response(200).generateMessage( recipients=[message.receipent], body=message.body) Mail(app).send(msg) except Exception as e: return jsonify( Response(500).exceptWithMessage( str(e), 'Unable to send the mail')) return jsonify( Response(200).generateMessage( 'Mail Sent')) else: return jsonify( Response(403).generateMessage( 'No data received')) 'No data received')) This will send mail to the user who has been registered to the application. Similarly we can use separate logics according to the need of the application.   The Pull Request for the above functionality is at this Link Topics Involved Working on the issue involve following topics: Configuring mail service to allow insecure apps access. Sending mail from the flask-mail to end user Attaching listener to listen for database change Extraction of data from saved object in database sqlalchemy. Resources Sending Mails Programmatically -  Link Flask Mail Documentation - Link Listening to database events - Link Enabling access to GMAIL to send mails to recipient - Link

Continue ReadingDatabase Listener for User Centric Events

Badgeyay: Integrating EmberJS Frontend with Flask Backend

Badgeyay is a simple badge generator with a simple web UI that generates a printable badge in PDFs. The project had gone through different cycles starting from a Flask server to a CLI application then a python library and now API Interface for generation of badges. According to latest changes in the project structure, now the frontend and backend are independent components developed in Ember JS and Flask respectively. Now there is a need to connect the frontend to the backend, which means the user should see the response on the same page without refresh, if the badge generated successfully. AJAX would fit right into the spot. Asynchronous Javascript and XML also known as AJAX, will enable us to perform asynchronous operation on the page without refreshing the page. We can make an API call to the Server running in backend or deployed on heroku, but the server is not suitable for doing CORS(Cross-Origin Resource Sharing), ability to share the resources on server with the client having different domain names, but as the server and the frontend are not hosted on the same host  so there is a need to enable the server to accept CORS request calls. Now the challenges were: Enabling Flask Server to accept CORS requests. AJAX query for sending request to the Flask server. Procedure Giving the form an id and creating an AJAX request to the Flask server (may be localhost or deployed on heroku). <form id="form1" action="" method="post" enctype="multipart/form-data" onsubmit="return validate()">   When the generate button is clicked, an AJAX request is made to the server to generate badges and at the same time prevent the page from refreshing. In the AJAX request we set the CORS header to allow the domain.   <script type="text/javascript"> $(document).ready(function () { $('#form1').submit(function (event) { event.preventDefault(); $.ajaxSetup({ headers: {"Access-Control-Allow-Origin": "*"} }); $.ajax({ url: "http://badgeyay-api.herokuapp.com/api/v1.0/generate_badges", data: $(this).serialize(), type: 'POST', success: function (data) {...}, error: function (error) {...} }) }); }) </script>   Import the library and enable the API endpoint to accept CORS requests. from flask_cors import CORS cors = CORS(app, resources={r"/api/*": {"origins": "*"}})   Add Logic for appending the download link by extracting the download link from the response and replacing the static text in the template with the download link, also changing the download variable to the filename, by stripping the base url from the download link. if (data["response"][0]["type"] === "success") { $('#success').css('visibility', 'visible'); let link = data["response"][0]["download_link"]; link = link.replace("backend/app/", "http://badgeyay-api.herokuapp.com/"); $('#badge-link').attr("href", link); link = link.replace("static/badges/", ""); $('#badge-link').attr("download", link); }   Output the success on the page. <div id="success" style="visibility: hidden;"> <div class="flash-success">Your badges have been created successfully.</div> <div class="text-center"> <a id="badge-link" href="http://badgeyay-api.herokuapp.com/static/badges/{{msg}}-badges.pdf" class="btn btn-success" download="{{msg}}-badges.pdf">Download as PDF</a> </div> </div>   Frontend and Backend now are connected to each other.The Server now accepts CORS requests and response is generated after the user requests from Frontend.   The Pull Request with the above changes is on this Link Topics Involved Working on this issue (Link)  involves following topics : Enabling Flask Server for CORS Request Headers AJAX…

Continue ReadingBadgeyay: Integrating EmberJS Frontend with Flask Backend