Need help accessing a virtual server using Flask - python

So for our last coding projects we've set up a web API that runs on local host. But now he has set up a virtual server for us to use along with usernames and passwords to use as well as which ports we are alllowed to use. I have my current code here. On the last line it used to be localhost and the port was 8080 but I changed it to reflect the new server we were given. However, it doesn't work and I couldn't seem to find a solution online. I also have the IP address and it didn't work either. I wasn't sure how to add my username and password to the mix as well as I am sure it is needed to access the server.
from flask_cors import CORS
import os
from flask import Flask, jsonify, make_response, Blueprint
from flask_swagger_ui import get_swaggerui_blueprint
from routes import request_api
import ssl
context = ssl.SSLContext()
context.load_cert_chain('certificate.pem', 'key.pem')
APP = Flask(__name__)
SWAGGER_URL = '/swagger'
API_URL = '/static/swagger.json'
SWAGGERUI_BLUEPRINT = get_swaggerui_blueprint(
SWAGGER_URL,
API_URL,
config={
'app_name': "Kales Flask Project"
}
)
APP.register_blueprint(SWAGGERUI_BLUEPRINT, url_prefix=SWAGGER_URL)
APP.register_blueprint(request_api.get_blueprint())
#APP.errorhandler(400)
def handle_400_error(_error):
return make_response(jsonify({'error': 'Misunderstood'}), 400)
#APP.errorhandler(404)
def handle_404_error(_error):
return make_response(jsonify({'error': 'Not found'}), 404)
#APP.errorhandler(401)
def handle_401_error(_error):
return make_response(jsonify({'error': 'Invalid Key Provided'}), 401)
if __name__ == '__main__':
CORS = CORS(APP)
APP.run(host='easel4.cs.utsarr.net', port=int(os.environ.get('PORT', 12145)), ssl_context=context)
Here is the output when I attempt to run this code
C:\Users\kingk\PycharmProjects\AdvanceSoft>python webapi.py
* Serving Flask app "webapi" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
Traceback (most recent call last):
File "webapi.py", line 44, in <module>
APP.run(host='10.100.201.3', port=12145, ssl_context=context)
File "C:\Users\kingk\PycharmProjects\AdvanceSoft\yes\lib\site-packages\flask\app.py", line 943, in run
run_simple(host, port, self, **options)
File "C:\Users\kingk\PycharmProjects\AdvanceSoft\yes\lib\site-packages\werkzeug\serving.py", line 1009, in run_simple
inner()
File "C:\Users\kingk\PycharmProjects\AdvanceSoft\yes\lib\site-packages\werkzeug\serving.py", line 962, in inner
fd=fd,
File "C:\Users\kingk\PycharmProjects\AdvanceSoft\yes\lib\site-packages\werkzeug\serving.py", line 805, in make_server
host, port, app, request_handler, passthrough_errors, ssl_context, fd=fd
File "C:\Users\kingk\PycharmProjects\AdvanceSoft\yes\lib\site-packages\werkzeug\serving.py", line 698, in __init__
HTTPServer.__init__(self, server_address, handler)
File "C:\Users\kingk\AppData\Local\Programs\Python\Python37\lib\socketserver.py", line 452, in __init__
self.server_bind()
File "C:\Users\kingk\AppData\Local\Programs\Python\Python37\lib\http\server.py", line 137, in server_bind
socketserver.TCPServer.server_bind(self)
File "C:\Users\kingk\AppData\Local\Programs\Python\Python37\lib\socketserver.py", line 466, in server_bind
self.socket.bind(self.server_address)
OSError: [WinError 10049] The requested address is not valid in its context

I assume the host='easel4.cs.utsarr.net' is the problem. The Flask documentation of the run method of the Application object recommends:
host – the hostname to listen on. Set this to '0.0.0.0' to have the server available externally as well. Defaults to '127.0.0.1' or the host in the SERVER_NAME config variable if present.

Related

"Permission denied" while using flask

I am trying to make a messenger bot using Wit.ai. For that I need a webhook. I am using ngrok, and this is just a test file but I am getting this error.
This is the error I am getting.
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
Traceback (most recent call last):
File "app.py", line 56, in <module>
app.run(debug = True, port = 80)
File "/home/parth/.local/lib/python3.6/site-packages/flask/app.py", line 990, in run
run_simple(host, port, self, **options)
File "/usr/local/lib/python3.6/dist-packages/werkzeug/serving.py", line 988, in run_simple
s.bind(server_address)
PermissionError: [Errno 13] Permission denied
This is the code
import os, sys
from flask import Flask, request
app = Flask(__name__)
#app.route('/', methods=['GET'])
def verify():
# Webhook verification
if request.args.get("hub.mode") == "subscribe" and request.args.get("hub.challenge"):
if not request.args.get("hub.verify_token") == "hello":
return "Verification token mismatch", 403
return request.args["hub.challenge"], 200
return "Hello world", 200
if __name__ == "__main__":
app.run(debug = True, port = 80)
Thanks!
You're getting that error because you're using a Privileged Port.
The TCP/IP port numbers below 1024 are special in that normal users
are not allowed to run servers on them.
...
When you run a server as a test from a non-priviliged account, you
will normally test it on other ports, such as 2784, 5000, 8001 or
8080.
Change your port to 5000, for example, and that will fix your problem.

Python Flask Server MQTT can't interact with socket.io

Server:
Ubuntu 18.04.3 LTS
python3.6
I want show device's message on web, my structure like:
Device--(MQTT)-->Server--(socket.io)-->Web
First, I publish message by mqtt to Server, and Server successed subscribed to get message .
Second, I use socket.io to send message to Web, but problem is here, if Server send message by socket.io after mqtt.on_message, the web's socket.io will be stuck, until refresh web.
My Flask Server a part of code:
from flask import Flask, request, render_template, flash, redirect, url_for
from flask_mqtt import Mqtt
from flask_socketio import SocketIO
from flask_bootstrap import Bootstrap
from flask_login import UserMixin, LoginManager, login_required, current_user, login_user, login_required, logout_user
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from forms import RegisterForm, LoginForm, AddForm, ChangePasswordForm
import pymysql
from config import Config
from sqlalchemy.ext.declarative import declarative_base
import json
import plotly as py
from datetime import datetime
import eventlet
eventlet.monkey_patch()
# MQTT
app = Flask(__name__)
bcrypt = Bcrypt(app)
app.config['SECRET'] = ''
app.config['TEMPLATES_AUTO_RELOAD'] = True
app.config['MQTT_BROKER_URL'] = ''
app.config['MQTT_BROKER_PORT'] =
app.config['MQTT_USERNAME'] = ''
app.config['MQTT_PASSWORD'] = ''
app.config['MQTT_KEEPALIVE'] = 5
app.config['MQTT_TLS_ENABLED'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = ''
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
mqtt = Mqtt(app)
socketio = SocketIO(app, cors_allowed_origins='*')
if __name__ == '__main__':
socketio.run(app, keyfile='privkey.pem', certfile='fullchain.pem', host='0.0.0.0', port=5002, use_reloader=True, debug=True)
Flask Server MQTT and socket.io part of code:
#mqtt.on_connect()
def handle_connect(client, userdata, flags, rc):
mqtt.subscribe('test')
#mqtt.on_message()
def handle_mqtt_message(client, userdata, message):
topic = message.topic,
raw_payload = message.payload.decode()
if(topic[0] == "test"):
socketio.emit('web', "received")
Web Client javascript code:
socket.on('web', function(data) {
console.log(data);
})
If just use socket.io to send message to web didn't use mqtt it's work fine. I don't know why they can't interact together. Then I find something on flask-mqtt offical file about "MQTT Interact with SocketIO", example code the difference from me is "import eventlet". So i guess is abotu threading problem? But when i also import it will show error, the error is:
Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/eventlet/hubs/hub.py", line 461, in fire_timers
timer()
File "/usr/local/lib/python3.6/dist-packages/eventlet/hubs/timer.py", line 59, in __call__
cb(*args, **kw)
File "/usr/local/lib/python3.6/dist-packages/eventlet/greenthread.py", line 221, in main
result = function(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/eventlet/wsgi.py", line 818, in process_request
proto.__init__(conn_state, self)
File "/usr/local/lib/python3.6/dist-packages/eventlet/wsgi.py", line 357, in __init__
self.handle()
File "/usr/local/lib/python3.6/dist-packages/eventlet/wsgi.py", line 390, in handle
self.handle_one_request()
File "/usr/local/lib/python3.6/dist-packages/eventlet/wsgi.py", line 419, in handle_one_request
self.raw_requestline = self._read_request_line()
File "/usr/local/lib/python3.6/dist-packages/eventlet/wsgi.py", line 402, in _read_request_line
return self.rfile.readline(self.server.url_length_limit)
File "/usr/lib/python3.6/socket.py", line 586, in readinto
return self._sock.recv_into(b)
File "/usr/local/lib/python3.6/dist-packages/eventlet/green/ssl.py", line 241, in recv_into
return self._base_recv(nbytes, flags, into=True, buffer_=buffer)
File "/usr/local/lib/python3.6/dist-packages/eventlet/green/ssl.py", line 256, in _base_recv
read = self.read(nbytes, buffer_)
File "/usr/local/lib/python3.6/dist-packages/eventlet/green/ssl.py", line 176, in read
super(GreenSSLSocket, self).read, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/eventlet/green/ssl.py", line 146, in _call_trampolining
return func(*a, **kw)
File "/usr/lib/python3.6/ssl.py", line 874, in read
return self._sslobj.read(len, buffer)
File "/usr/lib/python3.6/ssl.py", line 631, in read
v = self._sslobj.read(len, buffer)
ssl.SSLWantReadError: The operation did not complete (read) (_ssl.c:2309)
I searched about this error, some result say this is eventlet's Bug on python3, Is any solution for this error?

How to solve the address issue if I restart an external service inside python with flask?

I am using flask to build a python web service, for example, I set the flask port as 8080 like this:
#app.route('/data', methods=['POST'])
def data_construct():
os.system('sh restart.sh')
if __name__ == '__main__':
app.debug = True
app.run(host='0.0.0.0', port=8080)
and the restart.sh is used for restarting an external service, but after I send a HTTP POST request to /data, the restart is successfully completed, but after a while, I get an error:
Traceback (most recent call last):
File "hello.py", line 87, in <module>
app.run(host='0.0.0.0', port=8080)
File "/home/work/.jumbo/lib/python2.7/site-packages/flask/app.py", line 739, in run
run_simple(host, port, self, **options)
File "/home/work/.jumbo/lib/python2.7/site-packages/werkzeug/serving.py", line 613, in run_simple
test_socket.bind((hostname, port))
File "/home/work/.jumbo/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 98] Address already in use
the 'restart.sh' is like this (storage is a C++-complied program):
killall storage
nohup ./storage &
and I find the external service is starting using the port 8080 which it is not supposed to do (its original port is still in use), how to solve this problem?

API started, db killed, db started, peewee.InterfaceError connection already closed

Starting app.py, then killing the database and hitting /api/foo gives me:
peewee.OperationalError: could not connect to server: Connection refused
Bringing the database back up gives me and hitting /api/foo gives me:
peewee.OperationalError: terminating connection due to administrator
command\nSSL connection has been closed unexpectedly\n
And hitting /api/foo again gives me:
peewee.InterfaceError: connection already closed
Test case
test_case/__init__.py
#!/usr/bin/env python
from os import environ
from bottle import Bottle, request, response
from playhouse.db_url import connect
bottle_api = Bottle()
db = connect(environ['RDBMS_URI'])
from test_case.foo.models import Foo
db.connect() # Not needed, but do want to throw errors ASAP
db.create_tables([Foo], safe=True) # Create tables (if they don't exist)
from test_case.foo.routes import foo_api
bottle_api.merge(foo_api)
bottle_api.catchall = False
#bottle_api.hook('before_request')
def _connect_db():
print 'Connecting to db'
db.connect()
#bottle_api.hook('after_request')
def _close_db():
print 'Closing db'
if not db.is_closed():
db.close()
def error_catcher(environment, start_response):
try:
return bottle_api.wsgi(environment, start_response)
except Exception as e:
environment['PATH_INFO'] = '/api/error'
environment['api_error'] = e
return bottle_api.wsgi(environment, start_response)
#bottle_api.route('/api/error')
def global_error():
response.status = 500
return {'error': (lambda res: res[res.find("'") + 1:res.rfind("'")])(
str(request.environ['api_error'].__class__)),
'error_message': request.environ['api_error'].message}
test_case/__main__.py
from __init__ import bottle_api
# Or `from __init__ import bottle_api`; `from bottle import run`;
# Then `run(error_catcher, port=5555)`
bottle_api.run(port=5555)
test_case/foo/__init__.py
test_case/foo/models.py
from peewee import Model, CharField
from test_case import db
class Foo(Model):
id = CharField(primary_key=True)
class Meta(object):
database = db
test_case/foo/routes.py
from bottle import Bottle
from playhouse.shortcuts import model_to_dict
from test_case.foo.models import Foo
foo_api = Bottle()
#foo_api.get('/api/foo')
def retrieve_foos():
return {'foos': tuple(model_to_dict(foo) for foo in Foo.select())}
Github gist for easy cloning.
Update:
I believe the problem lies in how you've structured your imports and the way python loads and caches modules in sys.path.
I think that one of your modules is being imported and loaded twice and different parts of the codebase use different instances of the module.
Thus, the views in foo.routes, are using one instance of the database object, while the connection hooks are using another.
Instead of from __init__, what about trying from test_case import bottle_api? That is the one import statement that jumps out at me as a possible culprit.
I added the following to your code so I could run it from the command-line:
if __name__ == '__main__':
api.run()
Then I made a request to /api/foo and saw some fake data. I stopped the Postgresql server and got this error:
Traceback (most recent call last):
File "/usr/lib64/python2.7/wsgiref/handlers.py", line 85, in run
self.result = application(self.environ, self.start_response)
File "/home/charles/tmp/scrap/bottlez/lib/python2.7/site-packages/bottle.py", line 979, in __call__
return self.wsgi(environ, start_response)
File "/home/charles/tmp/scrap/bottlez/lib/python2.7/site-packages/bottle.py", line 954, in wsgi
out = self._cast(self._handle(environ))
File "/home/charles/tmp/scrap/bottlez/lib/python2.7/site-packages/bottle.py", line 857, in _handle
self.trigger_hook('before_request')
File "/home/charles/tmp/scrap/bottlez/lib/python2.7/site-packages/bottle.py", line 640, in trigger_hook
return [hook(*args, **kwargs) for hook in self._hooks[__name][:]]
File "bt.py", line 31, in _connect_db
db.connect()
File "/home/charles/tmp/scrap/bottlez/src/peewee/peewee.py", line 2967, in connect
self.initialize_connection(self.__local.conn)
File "/home/charles/tmp/scrap/bottlez/src/peewee/peewee.py", line 2885, in __exit__
reraise(new_type, new_type(*exc_value.args), traceback)
File "/home/charles/tmp/scrap/bottlez/src/peewee/peewee.py", line 2965, in connect
**self.connect_kwargs)
File "/home/charles/tmp/scrap/bottlez/src/peewee/peewee.py", line 3279, in _connect
conn = psycopg2.connect(database=database, **kwargs)
File "/home/charles/tmp/scrap/bottlez/lib/python2.7/site-packages/psycopg2/__init__.py", line 164, in connect
conn = _connect(dsn, connection_factory=connection_factory, async=async)
OperationalError: could not connect to server: Connection refused
Is the server running on host "localhost" (::1) and accepting
TCP/IP connections on port 5432?
could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
When I restarted the server and made a subsequent request I got a normal response with my test data.
So, in short, I'm not sure what I may be missing but the code seems to be working correctly to me.
Postgresql 9.4, psycopg2 2.6, python 2.7.9, peewee 2.6.0

flask run from server 1 using host from server 2

I have a two servers. Is it possible to run the flask from e.g (192.168.1.1) using host = "192.168.1.2"
i got errors
Traceback (most recent call last):
File "app.py", line 38, in <module>
debug=True
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 772, in run
run_simple(host, port, self, **options)
File "/usr/local/lib/python2.7/site-packages/werkzeug/serving.py", line 706, in run_simple
test_socket.bind((hostname, port))
File "/usr/local/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 99] Cannot assign requested address
here is my code. from .e.g 192.168.1.1
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
#app.route('/index')
def index():
return render_template('index.html')
#app.route('/_add_numbers')
def add_numbers():
a = request.args.get('a', 0, type=int)
b = request.args.get('b', 0, type=int)
return jsonify(result=a + b)
if __name__ == '__main__':
app.run(
host="192.168.1.2",
port=int("80"),
debug=True
)
This seems to be a misunderstanding on how networking works... You cannot use the IP address of another server as your own, for the same reason you cannot invite people to your neighbor's house and expect them to end up at your door.
If you want to handle web requests on both servers, you are going to need load balancing. Or, a reverse proxy that proxies requests from one server to the other.

Categories