Listen on given path using python - python-3.x

I am new to python basically i work in Infra.
To test one of AWS service i have written below python code which listen "/ping" GET method and "/invocations" POST method.
from flask import Flask, Response
app = Flask(__name__)
#app.route("/ping",methods=["GET"])
def ping():
return Response(response="ping endpoint", status=200)
#app.route("/invocations",methods=["POST"])
def predict():
return Response(response="invocation endpoint here", status=200)
if __name__ == "__main__":
print("Traninig started")
app.run(host="localhost", port=8080)
This code works fine but Flask give warning like "Dont use in production".
So i was looking to do the same in Django but not able to find appropriate ways to achieve this.Not sure what i am trying to do is even doable but i hope i made it clear what i am trying to do.

Use Gunicorn server for your flask projects in production

Related

Am I using application dispatching in Flask correctly?

I am fairly new to Flask applications, but well versed in Python. I have recently begun making web applications instead of regular application and I'm trying to gather some of them on a single server. Enter "Application Dispatching".
I was hoping to be able to develop an app locally and then deploy it on the server using dispatching. This means that locally I will have a script that launches the Flask app (wsgi.py), which imports stuff in the application. Now, once I add it to the dispatcher, I import the new application. This means that before the wsgi.py was a script and now it is a module - all hell breaks loose.
dispatcher.py:
from flask import Flask
from werkzeug.middleware.dispatcher import DispatcherMiddleware
from werkzeug.exceptions import NotFound
from app1 import app as app1
from app2 import app as app2
from app3 import app as app3
from app4 import app as app4
app = Flask(__name__)
app.wsgi_app = DispatcherMiddleware(NotFound(), {
"/app1": app1,
'/app2': app2,
'/app3': app3,
'/app4': app4,
})
if __name__ == "__main__":
app.run()
app1\__init__.py: (works like this, but merely a proof of concept / simple app)
from flask import Flask
app = Flask(__name__)
#app.route("/")
def index_one():
return "Hi im 1"
if __name__ == "__main__":
app.run()
Both of these work - the dispatcher and the app1 can be run independently. Now, let's say I need to import a module to make app1 more functional:
from flask import Flask
import db
...
Since the dispatcher is in a parent directory, in order for it to work I need to do something like this:
from . import db
# or
from app1 import db
Now the application doesn't work independently anymore. I would like to avoid either having to refactor the application every time it needs to be deployed or adding a lot of boilerplate code like this:
if __name__ == "__main__":
import db
else:
from . import db
In any case this doesn't work when configuring the app with app.config.from_object("config.Config") as it can't be forced to be relative import (?) and otherwise can't find it without explicitly telling it which module it resides in.
From the tutorial, I got the sense that I could isolate the applications from each other:
Application dispatching is the process of combining multiple Flask
applications on the WSGI level. You can combine not only Flask
applications but any WSGI application. This would allow you to run a
Django and a Flask application in the same interpreter side by side if
you want. The usefulness of this depends on how the applications work
internally.
The fundamental difference from Large Applications as Packages is that
in this case you are running the same or different Flask applications
that are entirely isolated from each other. They run different
configurations and are dispatched on the WSGI level.
What am I doing wrong and can I get it working like I describe, by being able to launch the applications isolated or on the dispatcher, without changing my code or adding a bunch of unrelated boilerplate code to make it work?
I figured it out myself and indeed was using application dispatcher wrong. It will always integrate the different applications into one server instance.
Instead, I found out that using nginx could be used to forward to different server instances, thus completely separating the applications in each virtual environment.

Gcloud not found in flask api

I am using the following python method in GCP. This methods is in test.py
#functools.lru_cache()
def get_project():
return subprocess.check_output("gcloud config list --format 'value(core.project)'", shell=True).decode(
"utf-8").strip()
When I run test.py solely on tpu, it works and when I use this method in flask API then I get error
'gcloud not found'.
However, the same method works solely and under flask API in GCP VM.
I am not able to figure out what could be the possible cause of this.
This is not exactly an answer to your question, but you might be interested in knowing about the metadata server.
From this answer we can more or less deduce that the metadata server also works with TPUs. Note that I'm not 100% sure on this though.
Try the following code to see if you can get the project id with it.
import requests
def get_project():
# https://cloud.google.com/compute/docs/metadata/default-metadata-values#project_metadata
response = requests.get(
"http://metadata.google.internal/computeMetadata/v1/project/project-id",
headers={"Metadata-Flavor": "Google"}
)
return response.text

Accessing file via URL

I deployed a python flask app on Heroku and it works fine. I have also uploaded a well-known folder that contains an apple-app-site association file, but when I try to access the file via URL, it returns 404. Basically, I'm testing universal links, so I wanted the apple-app-site association to be accessible. When I checked the status in the branch.io aasa validator, it returns server error, please find attached the screenshot Screenshot
What I'm doing wrong?
main.py
from flask import Flask
app = Flask(__name__, static_url_path='/well-known')
#app.route('/')
def index():
return "<h1>Welcome to Universal Link - iOS<h1>"
wsgi.py
from app.main import app
if __name__ == "__main__":
app.run()

Google Cloud Functions Python3: Wrapping HTTP trigger functions with endpoints

I am exploring Google Cloud Functions in Python to write HTTP triggered functions. I have a main.py with all my triggered functions structured like in this post, but would like to be able to wrap in some endpoints. On nodejs, one could do so like in this post using Express, and on Python, very similarly using Flask.
I have attempted to dabble by wrapping my Cloud Functions using Flask, but Google will bring me to Google's authentication page. My code as follows:
from flask import Flask, jsonify, request
# Initialize Flask application
application = Flask(__name__)
#application.route('/some/endpoint/path', methods=['GET'])
def predict():
inputs = request.args.get('inputs')
//Some logic...
response_object = {}
response_object['statusCode'] = 200
response_object['results'] = results
return jsonify(response_object)
Is there a way to wrap the python cloud functions in such a way to acheive something like this?
https://us-central1-my-project.cloudfunctions.net/some
https://us-central1-my-project.cloudfunctions.net/some/endpoint
https://us-central1-my-project.cloudfunctions.net/some/endpoint/path
I believe you are getting the authentication Google screen because you are trying to access the base url for Cloud Functions on your project.
With HTTP Cloud Functions the trigger url is usually https://[REGION]-[PROJECT_ID].cloudfunctions.net/[FUNCTION_NAME], so any routes would need to follow another slash after the function name.
That being said, I found this post where the solution provided manage to set routes within the same main.py file to access the endpoints from a single Cloud Function. I had to adapt some things, but in the end it worked for me.
The following is the source code I tested at my end:
import flask
import werkzeug.datastructures
app = flask.Flask(__name__)
#app.route('/')
def root():
return 'Hello World!'
#app.route('/hi')
def hi():
return 'Hi there'
#app.route('/hi/<username>')
def hi_user(username):
return 'Hi there, {}'.format(username)
#app.route('/hi/<username>/congrats', methods=['POST'])
def hi_user_congrat(username):
achievement = flask.request.form['achievement']
return 'Hi there {}, congrats on {}!'.format(username, achievement)
def main(request):
with app.app_context():
headers = werkzeug.datastructures.Headers()
for key, value in request.headers.items():
headers.add(key, value)
with app.test_request_context(method=request.method, base_url=request.base_url, path=request.path, query_string=request.query_string, headers=headers, data=request.form):
try:
rv = app.preprocess_request()
if rv is None:
rv = app.dispatch_request()
except Exception as e:
rv = app.handle_user_exception(e)
response = app.make_response(rv)
return app.process_response(response)
This defined the following routes within a single Cloud Function:
https://[REGION]-[PROJECT_ID].cloudfunctions.net/[FUNCTION_NAME]
https://[REGION]-[PROJECT_ID].cloudfunctions.net/[FUNCTION_NAME]/hi
https://[REGION]-[PROJECT_ID].cloudfunctions.net/[FUNCTION_NAME]/hi/<username>
https://[REGION]-[PROJECT_ID].cloudfunctions.net/[FUNCTION_NAME]/hi/<username>/congrats
And the following was the command used to deploy this function:
gcloud functions deploy flask_function --entry-point main --runtime python37 --trigger-http --allow-unauthenticated
Cloud Functions is designed to be used as a single endpoint. You might consider using Cloud Run instead, as it's more suited towards applications with multiple routes, and has many of the same benefits as Cloud Functions.
If you're dead set on using Cloud Functions, something like the answer at Injecting a Flask Request into another Flask App should work, but it's not ideal.

Implementing code coverage and unit testing on existing Python/Flask app

Having trouble getting this implementation down.
What I need: Code coverage results on my existing flask application, preferably using unit tests compatible with pytest.
What I am seeing:
I am seeing coverage only for lines that are executed on the startup of my app. When I use pytest or postman to send requests to my server, coverage metrics do not change. That is, I can start the server, stop it, and get the same results as starting it, sending requests, and stopping it.
I have investigated using pytest, pytest-cov, and coverage.py.
I implemented the sitecustomize.py coverage plugin workaround in site_packages to support subprocess coverage, to no effect.
I am running the coverage server like this:
coverage run --source . app.py -m
Then in a new terminal, I am running pytest like this:
pytest
Then I ctrl+c the server, run
coverage report -m
to view my output.
My app.py has contents like this:
from flask import Flask, request, render_template, make_response
from flask_cors import CORS
from flask_restplus import Resource, Api, reqparse
app = Flask(__name__)
CORS(app)
api = Api(app)
if ENV == 'dev':
app.debug = True
else:
app.debug = False
ns_namespace = api.namespace('namespace', description='namespace')
#ns_namespace.route("/")
class Namespace(Resource):
def get(self):
pass
if __name__ == '__main__':
app.debug = True
app.run(host='0.0.0.0')
Ideally, I want to run one command to start the app.py server, execute pytest, and record the actual code coverage. Has someone run into something like this?
Found out the issue.
Turns out, the app.debug=True was the culprit here. app.debug spawns a separate process, or something like that, which we lose insight into coverage.

Resources