How do I make bottle work with google app engine? - python

This is the code,
import webapp2
from framework import bottle
from framework.bottle import route, template, request, error, debug
#route('/')
def root():
return 'hello world'
class MainHandler(webapp2.RequestHandler):
def get(self):
root()
app = webapp2.WSGIApplication([
('/', MainHandler)
], debug=True)
All the dependencies are there (framework, bottle, etc), however, when I deploy it using GAE, I just get an empty page!
Also I tried these and none of them worked, perhaps GAE changed its settings:
http://blog.rutwick.com/use-bottle-python-framework-with-google-app-engine
problems deploying bottle application with google app engine

You have not followed the advice in those links. Most obviously, you are simply calling root without actually returning its result back as the response. In Python, you need to explicitly use return to send a value back from a function, which you don't do in get.
You are also hopelessly confused with setting up the handlers. If you're using bottle, use it: there's no need to have webapp in the mix as well. Webapp is an alternative to bottle, not something that is baked into GAE. Your links show exactly how to do this.

Another solution that worked perfectly for me: https://github.com/GoogleCloudPlatform/appengine-bottle-skeleton

Be aware to use:
app.run(server='gae')
Otherwise bottle will try to access your system and GAE will fail

The Bottle class implements WSGI which works for GAE if you make it a global variable in your main script handler.
main.py
from bottle import default_app, route, run
#route('/')
def root():
return 'hello world'
app = default_app()
app.yaml
runtime: python39
handlers:
- url: .*
script: main.app
requirements.txt
bottle
And that's it!
I tested this on Google Cloud Shell with Bottle 0.12.19 and deploying to Google App Engine Standard.

Related

Unsure how to configure WSGI handler/Flask to enable cron job in Python/App Engine

I have the following code which works successfully when I deploy it on App Engine. Except I want to run it with a cron.
import pandas as pd
import requests
from flask import Flask
app = Flask(__name__)
#app.route('/')
def sfLibraries():
return 'Success'
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8080, debug=True)
cron.yaml
cron:
- description: "SF Loader"
url: /task/loader
schedule: every 1 hours
app.yaml
runtime: python38
handlers:
- url: /task/loader
script: auto
I know that if I change #app.route('/') to #app.route('/task/loader') that the cron will work successfully, yet I lose the capability to go to the site when I first deploy it and see success.
gcloud app browse
Did not detect your browser. Go to this link to view your app:
https://<<<my_synapse>>>.uc.r.appspot.com
https://<<<my_synapse>>>.uc.r.appspot.com:
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
How can I have it both ways -both able to go to the site via gcloud app browse and see success as well as run the cron successfully?
I mentioned WSGI Handler because I found this pertinent post but not sure how WSGI Handler might help or improve from what Flask is doing Setting up cron job in google app engine python
Create two different routes to accomplish what you need. The functions must have a different name in this case.
#app.route('/')
def sfLibraries():
return 'Success'
#app.route('/task/loader')
def sfLibrariesSecond():
return 'Success'
Assign different actions for each one.
They could also both do the exact same thing. If that was the case, then assign two routes to the same function.
#app.route('/')
#app.route('/task/loader')
def sfLibraries():
return 'Success'

Creating an API to execute a python script

I have a python script app.py in my local server (path=Users/soubhik.b/Desktop) that generates a report and mails it to certain receivers. Instead of scheduling this script on my localhost, i want to create an API which can be accessed by the receivers such that they would get the mail if they hit the API with say a certain id.
With the below code i can create an API to display a certain text. But, what do i modify to run the script through this?
Also if i want to place the script in a server instead of localhost, how do i configure the same?
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return ("hello world")
if __name__ == '__main__':
app.run(debug=True)
Python Version is 2.7
A good way to do this would be to put the script into a function, then import that function in your Flask API file and run it using that. For hosting on a web server you can use Python Anywhere if you are a beginner else heroku is also a good option.
If you are tying to achieve something using Python-Flask API than you can have a close look at this documentations and proceed further https://www.flaskapi.org/, http://flask.pocoo.org/docs/1.0/api/
Apart from these here are few basic examples and references you can refer for a quickstart :
1-https://programminghistorian.org/en/lessons/creating-apis-with-python-and-flask
2- https://flask-restful.readthedocs.io/en/latest/
3- https://realpython.com/flask-connexion-rest-api/
You could do something like this
from flask import Flask
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class ExecuteScript:
def printScript:
return "Hello World"
api.add_resource(ExecuteScript, '/printScript')
if __name__ == '__main__':
app.run(debug=True)

Combining 2 Flask apps using DispatcherMiddleware instance results in 404 for second app

Sorry for ambiguous question, I'm not sure how better I can put it. So let me do the explanation of my problem.
I've the Flask application libindic, which has 2 Flask application one is frontend and other is api. So I've wsgi.py as follows
from werkzeug.serving import run_simple
from werkzeug.wsgi import DispatcherMiddleware
from silpa import api, frontend
import os
conffile = os.path.join(os.path.dirname(__file__), "etc", "silpa.conf")
application = DispatcherMiddleware(frontend.create_app(conffile),
{'/api': api.create_app(conffile)})
if __name__ == "__main__":
run_simple('0.0.0.0', 5000, application,
use_reloader=True, use_debugger=True)
The front end access works properly but when I hit /api/JSONRPC I get 404 error returned. This rule is defined as follows in silpa/api/jsonrpc.py
bp = Blueprint('api_jsonrpc', __name__, url_prefix='/api')
#route(bp, '/JSONRPC', methods=['POST'])
def handle_jsonrpc_call():
...
And when I print value of application and application.app and application.mounts in python interpreter I see folllowing
>>> application.app
<Flask 'silpa.frontend'>
>>> application.mounts
{'/api': <Flask 'silpa.api'>}
I'm unable to figure out why /api/JSONRPC results in 404. I'm not sure how can I debug it. I did check the app.url_map for api application and I can see rule for /api/JSONRPC registered there.
If some one can tell me what I might be doing wrong it would be a great help.
OK after debugging and stepping through Flask code I figured out the reason for the problem. The following line actually caused the problem
bp = Blueprint('api_jsonrpc', __name__, url_prefix='/api')
url_prefix should not be present in code because I'm already mounting this app at /api. Adding a /api url_prefix will result in following url instead /api/api/JSONRPC. Removing the above line fixed the issue.
So if you are mouting your app at different mount point than / using DispatcherMiddleware you should not url_prefix in blueprint.

Cannot get API specs with Flask Blueprints and Swagger UI

So, following the examples for swagger ui usage with flask blueprints (https://github.com/rantav/flask-restful-swagger/blob/master/examples/blueprints.py), I have the following code:
app = Flask(__name__)
test_blueprint = Blueprint('tests', __name__)
test_api = swagger.docs(restful.Api(test_blueprint), apiVersion='0.1',
basePath='http://localhost:5000',
produces=["application/json", "text/html"],
api_spec_url='/api/spec')
# Operation TestOp defined here
test_api.add_resource(TestOp, '/')
if __name__ == "__main__":
app.register_blueprint(test_blueprint, url_prefix='/test')
app.run(debug=True)
However, when I try to access the api spec docs, the URL cannot be located.
I've tried...
localhost:5000/api/spec
localhost:5000/test_api/api/spec
localhost:5000/test_api
...all of which return a 404. I've also tried creating the app without blueprints, creating the docs with
swagger.docs(restful.Api(app)...)
instead. When there this is done and no blueprints are involved, I can reach the docs at
localhost:5000/api/spec
So, am I creating my application incorrectly with blueprints, or am I just not hitting the right URL to get access to the docs?
I know this thread is old, but I ran into this exact problem today, trying to use flask-restful-swagger with my (somewhat) modern flask + python3 app that uses blueprints. Same problem, no errors, just no spec available no matter what i tried.
I finally abandoned this package (as it seems like it hasn't been very active anyway), even though I like the markup better with this package.
I chose Flasgger, which seemed to be updated more recently. In 10 minutes I had it up and running. Code and short tutorial are here: https://github.com/rochacbruno/flasgger
It looks like you're just not hitting the right URL. Because your blueprint url_prefix is "/test", the Swagger spec url should be at:
localhost:5000/test/api/spec
something wrong in swagger.docs()
from flask_restful import Api
test_blueprint = Blueprint('tests', __name__)
test_api = swagger.docs(Api(test_blueprint)...)
app.register_blueprint(test_blueprint)
what'more
main_blueprint = Blueprint('api', __name__, url_prefix='/demo')

App Engine Python how to handle urls?

I just want to ask a simple question, as I don't imagine how to do it.
In the app.yaml, when I want to declare query string parameter, how do I do it?
For example, to make a multi language site, I create the url in this format:
mysite.com/english/aboutus
mysite.com/italiano/aboutus
and in app.yaml the script to handle them are
- url: /english/aboutus
script: index.py
- url: /italiano/aboutus
script: index.py
In which way can I determine the difference between these two urls, and how to handle them in index.py?
I know this is simple question, I could look around for references, but it might help for others in stackoverflow.com as well.
I remember doing something like this:
in app.yaml put
- url: /(.*)/(.*)/?
script: main.py
and in main.py
class MainHandler(webapp.RequestHandler):
def get(self, Urlpart1, Urlpart2):
def main():
application = webapp.WSGIApplication([('/(.*)/(.*)/', MainHandler),
('/(.*)/(.*)', MainHandler)],
debug=True)
where Urlparts are words between slashes
Instead you could use the webapp framework to handle the URL's.
For example, in index.py
application = webapp.WSGIApplication(
[('/english', EnglishHandler)],
[('/italiano', ItalianHandler)],
debug=True)
More information can be found here. http://code.google.com/appengine/docs/python/gettingstarted/usingwebapp.html
The SCRIPT_NAME environ entry contains the path under which your script was invoked. Haven't tested this in GAE specifically, but it's something WSGI inherited from CGI.
language= environ['SCRIPT_NAME'][1:].split('/', 1)[0]
if language not in ('english', 'italiano'):
language= 'english'
There're 39 human languages supported. Best way seems comply via lib/django/django/conf/locale/
Here's an app that translates all engines messages via parameter hl=[languageCode]
[code disposable]2

Categories

Resources