Printing any value to web server with Flask - python

My question is very simple, when you run this code :
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
You will see Hello World! on 127.0.0.1:5000
But I' m trying to change like this, I took "Internal Server Error".
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
a= 5+10
return a
if __name__ == '__main__':
app.run()
Code Source: http://flask.pocoo.org/docs/quickstart/#a-minimal-application

Your hello_world method should return a str or file-like object, but in this case you're returning an int. Just cast:
#app.route('/')
def hello_world():
a = 5 + 10
return str(a)

If you are still learning Flask, it would be a good idea to enable debug mode.
app.debug = True
app.run()
Or pass it as a parameter to run:
app.run(debug=True)
This way, you'll see more than just a 500 error.

Related

Python flask: return values multiple times

I ran my code on Jupyter Notebook and I wanted to return different values on the web while running the function. However, it only returned one value. I also tried yield, but it had an error on the web.
from werkzeug.wrappers import Request, Response
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
list = [0,0,0]
for i in range(10):
list.append(i)
return str(list)
if __name__ == "__main__":
from werkzeug.serving import run_simple
run_simple('localhost', 9000, app)
Output:
[0,0,0,0]
Expected Output:
[0,0,0,0]
then change to:
[0,0,0,0,1]
then go on until it stops at:
[0,0,0,0,1,2,3,4,5,6,7,8,9]
Your indent is a little off on the return of the list. This is returning it on the first loop. Corrected Code is below:
from werkzeug.wrappers import Request, Response
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
list = [0,0,0]
for i in range(10):
list.append(i)
return str(list)
if __name__ == "__main__":
from werkzeug.serving import run_simple
run_simple('localhost', 9000, app)

How to call microservice-2 from microservice-1 using python?

How to call my microservice-2 from microservice-1. So our result looks like this:-
Result :- {“message”: “vivek”} --> {“message”: “keviv”, “random”: 3.89}
command to access microservice-1:-
curl http://127.0.0.1:5000/reverse_random/vivek
microservice-1
from flask import Flask, jsonify
app = Flask(__name__)
#app.route('/reverse_reandom/<string:string>', methods=['GET'])
def reverse(string):
string = string[::-1]
return jsonify({'message': string })
if __name__ == '__main__':
app.run(debug = True)
microservice-2
import random
from flask import Flask, jsonify
app = Flask(__name__)
#app.route('/', methods=['GET'])
def myRandom():
r1 = random.uniform(0, 10)
return jsonify({'message': r1 })
if __name__ == '__main__':
app.run(debug=True)
you'll need to issue a GET request to service 2 in order to get the random number, I suggest to use requests for this, like
r = requests.get('url-for-service-2:port/')
data = r.json()
random_num = data['message']
keep in mind to check the data object for message key, or using .get() or equivalent
Run microservice-2 on a different port. Send request using Python standard or 3rd party library from microservice-1
to microservice-2 upon request to microservice-1.
Below is the example of using Python3 standard library only:
m1.py:
from flask import Flask, jsonify
import urllib
import json
app = Flask(__name__)
#app.route('/reverse_random/<string:string>', methods=['GET'])
def reverse(string):
content = urllib.request.urlopen('http://127.0.0.1:5001').read().decode('utf-8')
print('response from m2: ', content)
string = string[::-1]
return jsonify({'message': string, 'random' : json.loads(content)['message']})
if __name__ == '__main__':
app.run(debug = True)
m2.py:
import random
from flask import Flask, jsonify
app = Flask(__name__)
#app.route('/', methods=['GET'])
def myRandom():
r1 = random.uniform(0, 10)
return jsonify({'message': r1 })
if __name__ == '__main__':
app.run(debug=True, port=5001) # running m2 on a different port than default 5000
Run the m1: python3 m1.py
Run the m2 in a different shell: python3 m2.py
Send request to m1: curl http://127.0.0.1:5000/reverse_random/vivek
The result is:
{
"message": "keviv",
"random": 4.138115905045612
}
Observe the log of m1 and of m2 to make sure m2 was invoked.
To connect between services you can use background tasks such as celery and ramq or use nsq and nats

random number generator using python

I am creating a microservice using Flask, that needs to give me a random number.
Unfortunately I am getting this error:
AttributeError: 'function' object has no attribute 'uniform'
import random
from flask import Flask
app: Flask = Flask(__name__)
#app.route('/', methods=['GET'])
def random():
r1 = random.uniform(0, 10)
return r1
if __name__ == '__main__':
app.run(debug=True)
new to microservice and python.
It is because you redefined random. You can either change the function name or give alias to imported random library.
Method 1:
Change the function name you defined.
import random
from flask import Flask
app: Flask = Flask(__name__)
#app.route('/', methods=['GET'])
def myRandom(): //Changed here
r1 = random.uniform(0, 10)
return r1
if __name__ == '__main__':
app.run(debug=True)
Method 2
Import random using alias.
import random as r //Changed here
from flask import Flask
app: Flask = Flask(__name__)
#app.route('/', methods=['GET'])
def random():
r1 = r.uniform(0, 10)
return r1
if __name__ == '__main__':
app.run(debug=True)

Python Mock Testing to mock session

I am learning how to test functions in Python using Mock. I am trying to write a test for a simple function,
#social.route('/friends', methods=['GET', 'POST'])
def friends():
test_val = session.get('uid')
if test_val is None:
return redirect(url_for('social.index'))
else:
return render_template("/home.html")
However, I am stuck at how to try and mock session.get('uid') value. So far, this has been my attempt,
#patch('session', return_value='')
#patch('flask.templating._render', return_value='')
def test_mocked_render(self, mocked, mock_session):
print "mocked", repr(self.app.get('/social/friends').data)
print "was _render called?", mocked.called
This attempt may be completely wrong and this is definitely the wrong way as I am still not able to mock session. However, can someone please guide me in the right way through this? Thanks.
Starting with Flask 0.8 we provide a so called “session transaction” which simulates the appropriate calls to open a session in the context of the test client and to modify it.
Let's give a simple example: app.py
from flask import Flask, session
app = Flask(__name__)
app.secret_key = 'very secret'
#app.route('/friends', methods=['GET', 'POST'])
def friends():
test_val = session.get('uid')
if test_val is None:
return 'uid not in session'
else:
return 'uid in session'
if __name__ == '__main__':
app.run(debug=True)
The test file: test_app.py
import unittest
from app import app
class TestSession(unittest.TestCase):
def test_mocked_session(self):
with app.test_client() as c:
with c.session_transaction() as sess:
sess['uid'] = 'Bar'
# once this is reached the session was stored
rv = c.get('/friends')
assert rv.data == 'uid in session'
if __name__ == '__main__':
unittest.main()
run the tests via python test_app.py.
Documentation: Accessing and Modifying Sessions

Working with a global singleton in Flask (WSGI), do I have to worry about race conditions? [duplicate]

This question already has answers here:
Are global variables thread-safe in Flask? How do I share data between requests?
(4 answers)
Closed 13 days ago.
The hello world demo for Flask is:
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
What if I modified this like so:
from flask import Flask
app = Flask(__name__)
a = 1
b = 2
c = 3
#app.route("/")
def hello():
a += 1
b += a
c += b
return "Hello World!"
if __name__ == "__main__":
app.run()
I understand WSGI application might have multiple threads. The hello function could be running on multiple threads at the same time, and then we'd have a race condition. Is this correct? If the above code is not thread safe, what can I do to make it thread safe?
Avoiding globals is a possible solution, but can you always avoid globals? What if I want something like a python object cache?
You could try the Local class from werkzeug.
Here's some info about it: Context Locals
Example:
from flask import Flask
from werkzeug.local import Local
app = Flask(__name__)
loc = Local()
loc.a = 1
loc.b = 2
loc.c = 3
#app.route("/")
def hello():
loc.a += 1
loc.b += loc.a
loc.c += loc.b
return "Hello World!"
if __name__ == "__main__":
app.run()
You might take a look at the g object that you can import directly from flask, keeps an object globally for that request. If you're using an event driven WSGI server (tornado, gevent, etc) you shouldn't have any issues.

Categories

Resources