Connect to dev server in Flask for unittest - flask

I am trying to write unittests for my Flask API endpoints. I want the test cases to connect to the dev server which is running on a different port 5555.
Here is what I am doing in setUp() to make a test_client.
import flask_app
flask_app.app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+mysqldb://root:#localhost/mvp_test_db'
flask_app.app.config['TESTING'] = True
flask_app.app.config['SERVER_NAME'] = '192.168.2.2' //the IP of the dev server
flask_app.app.config['SERVER_PORT'] = 5555
self.app_client = flask_app.app.test_client()
Then when I make a request using app_client like -
r = self.app_client.post('/API/v1/dummy_api', data = {'user_id' : 1})
I get a 404 when I print r and the request never comes to the dev server (no logs printed). I am not able to inspect the URL to which the connection is being attempted above. Any ideas?

It (app.test_client) does not send requests through network interfaces. All requests are simulated. These are processed inside werkzeug routing system. To process "/API/v1/dummy_api" url you need register a view for. If it is registered, connect it in the import section. Application settings and test settings almost always have almost equal settings.

Related

Flask-SocketIO access session from background task

I have a Flask app for http and web socket (Flask-SocketIO) communication between client and server using gevent. I also use server side session with Flask-Session extension for the app. I run a background task using SocketIO.start_background_task. And from this task, I need to access session information which will be used to emit message using socketio. I get error when accessing session from the task "RuntimeError: Working outside of request context." This typically means that you attempted to use functionality that needed an active HTTP request.
Socket IO instance is created as below-
socket_io = SocketIO(app, async_mode='gevent', manage_session=False)
Is there any issue with this usage. How this issue could be addressed?
Thanks
This is not related to Flask-SocketIO, but to Flask. The background task that you started does not have request and application contexts, so it does not have access to the session (it doesn't even know who the client is).
Flask provides the copy_current_request_context decorator duplicate the request/app contexts from the request handler into a background task.
The example from the Flask documentation uses gevent.spawn() to start the task, but this would be the same for a task started with start_background_task().
import gevent
from flask import copy_current_request_context
#app.route('/')
def index():
#copy_current_request_context
def do_some_work():
# do some work here, it can access flask.request or
# flask.session like you would otherwise in the view function.
...
gevent.spawn(do_some_work)
return 'Regular response'

Using Bokeh Server in Google Cloud AI Notebook

I am attempting to build and test some bokeh components in the Google Cloud AI notebook environment. I have been using this cloud instance for several months with little to no issues but I cannot seem to get the tutorial, https://docs.bokeh.org/en/latest/docs/user_guide/notebook.html, working. Has anyone successfully worked with a bokeh server in this environment?
The tutorial does not seem to work for my use case. Several JavaScript errors are returned when following and adapting this method.
handler = FunctionHandler(modify_doc)
app = Application(handler)
show(modify_doc, notebook_url=remote_jupyter_proxy_url)
def remote_jupyter_proxy_url(port):
"""
Callable to configure Bokeh's show method when a proxy must be
configured.
If port is None we're asking about the URL
for the origin header.
"""
base_url = URL OF AI NOTEBOOK
host = urllib.parse.urlparse(base_url).netloc
# If port is None we're asking for the URL origin
# so return the public hostname.
if port is None:
return host
service_url_path = NOT A JUPYTER HUB SO UNCLEAR WHAT SHOULD BE HERE
proxy_url_path = 'proxy/%d' % port
user_url = urllib.parse.urljoin(base_url, service_url_path)
full_url = urllib.parse.urljoin(user_url, proxy_url_path)
print(full_url)
return full_url
When patching together the previous code, I receive the following message when inspecting the notebook:
panellayout.js:213 Mixed Content: The page at 'URL' was loaded over HTTPS, but requested an insecure script 'URL'. This request has been blocked; the content must be served over HTTPS.

Deploying a Flask Web Application: Access from Remote Server

I am building a small web app with Flask so that someone else can use my script from their device (in network) without installing the attendant modules. I can get the app to run on my localhost but am having trouble getting it to be available to other devices in network.
I'm using Flask's in-built platform so I am using app.run(host="0.0.0.0"). I've tried enabling/disabling the debug parameter. I've tried adding the port parameter as 5000, although it already seems to be running on that port. I've had the other person go to http://my_ip_address:5000 as well as http://0.0.0.0:5000 (not sure which one they should be using).
Below is a segment of my code, with the actual app classes and methods not included:
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route('/')
def command_outputs():
return render_template("info.html")
#app.route('/result',methods = ['POST', 'GET'])
def result():
if request.method == 'POST':
result = request.form
f=request.files["File"]
f.save(f.filename)
f.stream.seek(0)
finder=OutputFinder(result["Device"], f, result["Username"], result["Password"])
finder.findOutput()
lines=finder.result.split("\n")
return "<br/>".join(lines)
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=False)
When I run the script (I am using PyCharm) and enter http://0.0.0.0:5000 into the browser, I get an "Unknown Host" error. When I enter the localhost or my device's IP address, I get a 404 not found error, and 127.0.0.1 - - [26/Jun/2019 15:03:42] "GET / HTTP/1.1" 404 appears in the terminal.
When the other person opens it with http://0.0.0.0:5000, they get the same error I do. When they run it using my IP address, they get a "site cannot be reached" page.
I'm pretty sure I'm just putting the wrong stuff into the URL. Also, the error messages are inconsistent sometimes. I will run the exact same script and get differing error messages, but the ones mentioned above are the most common.
EDIT: It is working on my own computer when I use my IP address in the url, but it is not working on the other person's computer using my IP address.

Use test database database for views testing

I am writing tests for my django application views and i am a beginner at this. I know that before running tests a new database is generated which only contains data that is being created at the time of running of tests but in my view's tests i am making API calls by url on my server which is using my default database not the test database in following way.
def test_decline_activity_valid_permission(self):
url = 'http://myapp:8002/api/v1/profile/' + self.profileUUID + '/document/' + \
self.docUUID + '/decline/'
response = requests.post(
url,
data=json.dumps(self.payload_valid_permission),
headers=self.headers,
)
self.assertEquals(response.status_code, status.HTTP_201_CREATED)
i want to know that if we can use test database for our testing our views or not. And what is difference between using request and using Client?
You could try using Django's LiveServerTestCase. That works like TransactionTestCase but will start up a server on localhost pointing at the test database. It gets started/stopped at the beginning/end of each test.
You could then configure the URL in your test to point at that local server. Django provides self.live_server_url for accessing the URL of the server.
As mentioned in the comments, Django's test client allows you to test views without making real HTTP requests. Whereas the requests library that you're using in your test, will send and receive real HTTP request and responses.

Continuous CONNECT/GET requests to web server on port 9485

I've tried using both CherryPy 3.5 and Tornado 4 to host my Flask WSGI application. Regardless of the WSGI server, every 2s my browser tries to make a CONNECT/GET request to myserver:9485.
Chrome's network view looks like this:
Firefox's network view looks like this:
Finally, IE's network view doesn't show anything, but I do see this in the console:
Everything about the site works fine, but it kills me knowing this is happening in the background. How do I stop the madness?
Oddly enough, I don't see these messages when I run the code shown below on my development machine.
Additional details:
Python 2.7.6, Flask 0.10.1, Angular 1.2.19
CherryPy code:
static_handler = tools.staticdir.handler(section='/', dir=app.static_folder)
d = wsgiserver.WSGIPathInfoDispatcher({'/': app, '/static': static_handler})
server = wsgiserver.CherryPyWSGIServer(('127.0.0.1', 9000), d)
server.start()
Probably unrelated, but I am using an EventSource polyfill on one of my pages (I see these messages regardless if I hit that page or not).