Serving dynamic webpages using aws? - python

I'm new to AWS in general, and would like to learn how to deploy a dynamic website with AWS. I'm coming from a self-hosted perspective (digitalocean + flask app), so I'm confused on what exactly the process would be for AWS.
With self-hosting solution, the process is something like:
User makes a request to my server (nginx)
nginx then directs the request to my flask app
flask app handles the specific route (ie, GET /users)
flask does db operations, then builds an html page using jinja2 with the results from the db operation
returns html to user and user's browser renders the page.
With AWS, I understand the following:
User makes a request to Amazon's API Gateway (ie, GET /users)
API Gateway can call a AWS Lambda function
AWS Lambda function does db functions or whatever, returns some data
API Gateway returns the result as JSON (assuming I set the content-type to JSON)
The confusing part is how do I generate the webpage for the user, not just return the JSON data? I see two options:
1) Somehow get AWS Lambda to use Jinja2 module, and use it to build the HTML pages after querying the db for data. API Gateway will just return the finished HTML text. Downside is this will no longer be a pure api, and so I lose flexibility.
2) Deploy Flask app onto Amazon Beanstalk. Flask handles application code, like session handling, routes, HTML template generation, and makes calls to Amazon's API Gateway to get any necessary data for the page.
I think (2) is the 'correct' way to do things; I get the benefit of scaling the flask app with Beanstalk, and I get the flexibility of calling an API with the API Gateway.
Am I missing anything? Did I misunderstand something in (2) for serving webpages? Is there another way to host a dynamic website without using a web framework like Flask through AWS, that I don't know about?

The recommended way to host a server with lambda and without EC2 is:
Host your front static files on S3 (html, css, js).
Configure your S3 bucket to be a static web server
Configure your lambdas for dynamic treatments and open it to the outside with API-gateway
your JS call the lambda through API-gateway, so don't forget to activate CORS (on the S3 bucket AND on API-gateway).
configure route53 to link it with your bucket (your route53 config must have the same name as your bucket) so you can use your own DNS name, not the generic S3-webserver url

You definitely have to weigh the pros and cons of serving the dynamic website via API GW and Lambda.
Pros:
Likely cheaper at low volume
Don't have to worry about scaling
Lambda Functions are easier to manage than even beanstalk.
Cons:
There will be some latency overhead
In some ways less flexible, although Python is well supported and you should be able to import the jinja2 module.
Both of your proposed solutions would work well, it kind of depends on how you view the pros and cons.

Related

How to serve csv files in my s3 bucket to a python app deployed on heroku

I have a python app (specifically a dash plotly dashboard) that I have deployed on Heroku. I have static files (csv/maps in the form of html etc.) that are input files for my app. However I am unable to get my python script to read these files when the heroku app starts.
I have already done the initial authentication piece of allowing heroku to access my aws bucket and set permissions.
Ok the steps are like this. This has to be a serverless application. Upon clicking the submit button on your website, an api should be called. Get/Post depending on your need.
(1)
An API will invoke a Lambda function that will take the csv file and store in s3.
Create a rest api using apigateway, connect with lamdba then store in s3.
You can use boto3 library if you pick python for lambda.
(2) Another way, if you don't need to manipulate the data on backend. You can create an API that takes a file (less than 6mb) and stores directly to s3 bucket.
If you are familiar with terraform this might help.
Best wishes.

How to connect a Flask Back-end app to Flask Front-end app?

I've developed a Python Flask Back-end app which allows me to do some HTTP requests on a Jsonfile (a sort of database) such as GET (to see a list of items) or POST (to create a new item in the Json database). Until now, I used Postman to test my app and all worked well. However, I'd like to develop a Python Flask Front-end app in order to create a graphical interface (in a web browser with jinja templates) to do the same requests. The problem is, I don't know how to begin my new app, I've googled all my questions but found no answer...
How can we "link" front-end and back-end apps in order to get the information from the web brower, make the requests via the back-end and then send the response with the front-end?
Using RESTful API.
A infrastructure solution could be (a classic one):
Your app server listening on 5000. It uses the REST architectural.
Your frontend server listening on 80/443. It makes requests to your app server to get the data and fill your html template with this data. The requests can be made with a library like requests. The requests library is one of the simpliest but you can choose another one to make HTTP requests.
Workflow:
Client <-HTTP requests-> Frontend <-HTTP requests made with requests->
App Server <--> Database
Advantage:
One of the advantage of this architecture: you can easily duplicate your servers or having multiple app servers responsible of different tasks. They can be running on the same machine or separated machines.
Serving static files:
If you are talking about serving static files for the frontend, then you should use an existing Webserver like Nginx (html/css/js files).

Can python/flask websites be hosted on firebase?

I have a website that uses python/flask, and I know that firebase hosting is only for static websites, but I need to be able to use firebase cloud functions in my app, and that requires firebase hosting (please correct me if I am wrong). As node js is server side, but you can use it with firebase hosting, I was hopeful that there might be a way to use python too. Otherwise, if there is a way to use cloud functions without firebase hosting, you can tell me about that too.
You don't need Firebase Hosting for using Firebase Functions, and as you mentioned Firebase Hosting is for static pages.
Firebase Functions are hosted on firebase (independent from Firebase Hosting for static pages), and currently don't support python.
For HTTP trigger Firebase Functions you simply make HTTP requests to your function's url, from any backend or from frontend itself.
Firebase DB/Storage and other trigger functions work in the same way, but don't explicitly call then they are triggered on specific events in DB/Storage etc. that you specify when defining functions.

Using aws chalice to build a single page application?

Has anyone here ever worked with chalice? Its an aws tool for creating api's. I want to use it to create a single page application, but Im not sure how to actually serve html from it. I've seen videos where its explored, but I can't figure out how they actually built the thing. Anyone have any advice on where to go, how to start this?
You wouldn't serve HTML from Chalice directly. It is explicitly designed to work in concert with AWS Lambda and API Gateway to serve dynamic, API-centric content. For the static parts of an SPA, you would use a web server (nginx or Apache) or S3 (with or without CloudFront).
Assuming you are interested in a purely "serverless" application model, I suggest looking into using the API Gateway "Proxy" resource type, forwarding to static resources on S3.
Worth noting that it's probably possible to serve HTML from Chalice, but from an architecture perspective, that's not the intent of the framework and you'd be swimming upstream to get all the capabilities and benefits from tools purpose-built for serving static traffic (full HTTP semantics w/ caching, conditional gets, etc)
Add Response from Chalice and the use it to set the response headers and you're g2g.
from chalice import Chalice, Response
return Response(template, status_code=200, headers={"Content-Type": "text/html", "Access-Control-Allow-Origin": "*"})
I read about it here;
https://medium.com/#tim_33529/creating-a-serverless-blog-with-chalice-bdc39b835f75

Heroku router logging format

I've recently deployed a Flask app on Heroku. It provides an API on top of an existing API and requires a confidential API key for the original service from the user. The app is really just a few forms, the values of which are passed with ajax to a specific URL on the server. Nothing fancy. I take steps to not store confidential information in the app and want no traces of it anywhere within the app.
Looking at the logs from heroku logs --source heroku, the heroku router process stores all HTTP requests for the app, including those requests that include the confidential information.
Is there a way to specify the log format for the heroku process so as to not store the URL served?
As other commenters mentioned, it is a bad practice to put confidential info in a URL. These could get cached or logged by a number of systems (e.g. routers, proxy servers, caches) on the roundtrip to the server. There are a couple ways to solve this:
Put them in a the Authorization header. This is probably the most common way authentication is handled for REST-based APIs.
Put them in the POST body. This works to get it out of the URL, but is a little weird semantically to say that your are POSTing the credentials to some resource (if this a REST API), unless it is a login call.

Categories

Resources