I'm trying to test cherrypy framework by using example from their site:
import cherrypy
class HelloWorld(object):
def index(self):
return "Hello World!"
index.exposed = True
cherrypy.quickstart(HelloWorld())
When I run it I get this response in the console:
[05/Dec/2011:00:15:11] ENGINE Listening for SIGHUP.
[05/Dec/2011:00:15:11] ENGINE Listening for SIGTERM.
[05/Dec/2011:00:15:11] ENGINE Listening for SIGUSR1.
[05/Dec/2011:00:15:11] ENGINE Bus STARTING
CherryPy Checker:
The Application mounted at '' has an empty config.
[05/Dec/2011:00:15:11] ENGINE Started monitor thread '_TimeoutMonitor'.
[05/Dec/2011:00:15:11] ENGINE Started monitor thread 'Autoreloader'.
[05/Dec/2011:00:15:12] ENGINE Serving on 127.0.0.1:8080
[05/Dec/2011:00:15:12] ENGINE Bus STARTED
When running browser locally and pointing to localhost:8080 it works. How can I configure the application so that it responds to a domain name say: www.example.com? I want the Hello World to be tested in my production server having the domain name, so that it can be accessed by anyone over the world from any location or any computer?
You'll use the static ip for the production server...
config = {
'global' : {
'server.socket_host' : 'XXX.XXX.XXX.XXX',
'server.socket_port' : 80,
}
}
cherrypy.quickstart(HelloWorld(), '/', config)
Then have a dns entry for your domain, www.example.com, pointed to the static ip.
Hope this helps!
Related
Situation:
I deploy my flask server in the AWS EC2 ubuntu and running. And react.js running on my local machine try to test is remote server setup correctly and works, contains Restful API and WebSocket.
Question:
Everything works fine on the local machine which python and react both running on the local machine. When l make flask running on the AWS, the Restful API works fine, but WebSocket is not working, there is no connect refused error, switch protocol is 101 and in the inspector network section is 200 status. Just remote server cannot receiving data. I am not sure what was happended at this time and how to fix that, anyone has the same experience?
this one is my client
const endPoint = "http://3.237.172.105:5000/friends";
const socket = io.connect(endPoint);
const addFriends=(friend)=>{
socket.emit("Addedfriend",{username:name , friendName:friendName});
}
this one is my flask start file: call python3 app.py to run
from logging import debug
from flask import Flask
from flask_socketio import SocketIO
from flask_cors import CORS
from Controller.logReg import logReg
from Controller.profile import profile
from Controller.ticket import ticket
from Controller.personal import personal
import logging
#log = logging.getLogger('werkzeug')
#log.setLevel(logging.ERROR)
app = Flask(__name__)
socketio = SocketIO(app, cors_allowed_origins="*")
app.register_blueprint(logReg)
app.register_blueprint(profile)
app.register_blueprint(ticket)
app.register_blueprint(personal)
print("socket started ... ...")
CORS(app)
if __name__ == '__main__':
print("socket opened")
socketio.run(app, host='0.0.0.0', port=5000)
this is my socket file: print data is not print anything and I am not sure why
#socketio.on('Addedfriend', namespace='/friends')
def add_friend(data, t):
print("this is from addFriend" + str(data))
# print("friend SID: "+str(request.sid))
user = data['username']
friend = data['friendName']
user_friends = FriendsDB.find_one({"username": user})['friends']
if friend in user_friends:
emit("Addedfriend", {"result": "already added", "friendPhoto":"", "friendStatus": False})
return
if FriendsDB.find_one({"username": friend}) is None:
emit("Addedfriend", {"result": "Not Exist", "friendPhoto": "", "friendStatus": False})
return
this is the network screenshot
this is AWS IP address
this is AWS inbound rule
I have developed a small web app on my Windows PC and tested it locally.
Then I wanted to transfer it to an AWS Ubuntu 18 instance.
For the sake of brevity, the app processes a form from a webpage and redirects a user to the page with the result. The contents of the app do not really matter, since the error occurs before you can interact with it.
I have not encountered any issues running it locally (i.e. the same code as below, w/out cherrypy.config.update).
import cherrypy
import os
filepath = os.getcwd()
class MyApp(object):
#cherrypy.expose
def index(self):
with open('./index.html', 'r') as f:
text = f.read()
return text
#cherrypy.expose
def process_filled_form(self, field1, field2):
out = filed1+field2
return(out)
if __name__ == '__main__':
config = {"/folder": {"tools.staticdir.on": True,
"tools.staticdir.dir": os.path.join(filepath, "folder")}}
cherrypy.config.update({'server.socket_host': 'XXX.XXX.XXX.XXX',
'server.socket_port': 9028,})
cherrypy.quickstart(MyApp(), '/', config)
But when I try to make the app public on an AWS instance, I get the following error:
[06/Mar/2021:06:25:12] ENGINE Listening for SIGTERM.
[06/Mar/2021:06:25:12] ENGINE Listening for SIGHUP.
[06/Mar/2021:06:25:12] ENGINE Listening for SIGUSR1.
[06/Mar/2021:06:25:12] ENGINE Bus STARTING
[06/Mar/2021:06:25:12] ENGINE Started monitor thread 'Autoreloader'.
[06/Mar/2021:06:25:12] ENGINE Error in HTTP server: shutting down
Traceback (most recent call last):
File "/home/user/.conda/envs/user_app/lib/python3.9/site-packages/cherrypy/process/servers.py", line 225, in _start_http_thread
self.httpserver.start()
File "/home/user/.conda/envs/user_app/lib/python3.9/site-packages/cheroot/server.py", line 1836, in start
self.prepare()
File "/home/user/.conda/envs/user_app/lib/python3.9/site-packages/cheroot/server.py", line 1791, in prepare
raise socket.error(msg)
OSError: No socket could be created -- (('XXX.XXX.XXX.XXX', 9028): [Errno 99] Cannot assign requested address)
[06/Mar/2021:06:25:12] ENGINE Bus STOPPING
[06/Mar/2021:06:25:12] ENGINE HTTP Server cherrypy._cpwsgi_server.CPWSGIServer(('XXX.XXX.XXX.XXX', 9028)) already shut down
[06/Mar/2021:06:25:12] ENGINE Stopped thread 'Autoreloader'.
[06/Mar/2021:06:25:12] ENGINE Bus STOPPED
[06/Mar/2021:06:25:12] ENGINE Bus EXITING
[06/Mar/2021:06:25:12] ENGINE Bus EXITED
Changing the socket does not affect anything. The app produces no errors when launched locally on AWS.
I am totally new to anything web-related, so the problem might be smt very obvious. Perhaps, I am missing something in the config, or `quickstart` may not be the right option to launch the app.
Please help
Most likely you are binding to a wrong address.
In you config.update call, modify the socket_host value to 0.0.0.0:
cherrypy.config.update({'server.socket_host': '0.0.0.0',
'server.socket_port': 9028,})
That should allow your app to listen for requests on all the network addresses that are available in your host.
I can't preview this appliation using AWS Cloud9 (c9) python flask:
from flask import Flask
import os
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
host = 'localhost' # '0.0.0.0' #"127.0.0.1" # I tried all of these ip's
if __name__ == '__main__':
app.debug = True
port = int(os.environ.get("PORT", 8080)) # I also tried port was 5000
app.run(host=host, port=port)
# This is the error I got 52.15.73.96 The connection has timed out
#The server at 52.15.73.96 is taking too long to respond.
This is similar to AWS cloud9 timeout when running flask application
Here is the answer: You have to get past the AWS firewall.
You have to
Go into EC2 (from the list of all AWS services)
Click security groups
Click your Cloud9 instance
Click Inbound
Click Edit
Click Add Rule
Add this rule:
For Type, choose Custom TCP Rule. - All Traffic also worked.
For Port Range, type 8080, 8081, or 8082. - If you did 'All Traffic' this will default to all ports.
For Source, choose Anywhere, which looks like 0.0.0.0/0
Here is a screen shot link: https://imgur.com/a/zhQbA
AWS does have this, buried, in their C9 documentation.
https://docs.aws.amazon.com/cloud9/latest/user-guide/app-preview.html#app-preview-share-security-group
In Share a Running Application over the Internet, Step 2: Set Up the Security Group for the Instance
You need to run your server in 0.0.0.0 using port 8080 (or other available C9 ports).
Change your app.run() command to something like this:
app.run(host='0.0.0.0', port=8080, debug=True)
If 8080 doesn’t work, try with 80.
flask run --host=127.0.0.1 --port=8080
I am running my application with Windows Azure on a Virtual Machine with ubuntu 14.04 lts. I am running my Django application through WSGI on Apache.
Previously i ran django locally with the command "python manage.py runserver", and every thing worked fine when my website connected to my sockets.py file from website.html.
I am running Django through Apache on public ip port 80
I am running the sockets.py separately in a terminal through Putty
I am reading the error through the Google Chrome console
Suddenly this error occurs: Failed to execute 'send' on 'WebSocket': Still in CONNECTING state. whenever i try to connect to the socket.
After a while my page response with: failed: Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT
website.html js:
ws = new WebSocket("ws://10.77.22.74:1339/ws");
function load_all() {
target = "load_all"
ws.send(target)
}
ws.onmessage = function(evt) {
console.log(evt.data)
}
The ip is my internal ip on my virtual machine.
sockets.py:
import tornado.httpserver
import tornado.websocket
import tornado.ioloop
import tornado.web
class WSHandler(tornado.websocket.WebSocketHandler):
def check_origin(self, origin):
return True
def open(self):
print 'new connection'
def on_message(self, message):
self.write_message(message)
def on_close(self):
print 'connection closed'
application = tornado.web.Application([
(r'/ws', WSHandler),
])
if __name__ == "__main__":
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(1339)
tornado.ioloop.IOLoop.instance().start()
I have tried to change the http_server.listen(1339) to http_server.listen(1339, adress='10.77.22.74') (sockets.py)
I have tried using my public ip and opening a port through tcp (endpoints) and adjusting the scripts after that (sockets.py & website.html)
I have tried running with the localhost & 127.0.0.1 (sockets.py & website.html)
I have tried with ws & wss
I still get the error for some reason, do i need to give Apache (www-data) some permissions to connect to the sockets.py?
Which IP should i use, both on socket.py and website.htm?
Solved
Turn out Tornado is listening to all IP:s if you not specify the adress in the socket server. I opened a port on the public IP and used that IP for my javascript socket connection.
I have a flask app that I want to deploy using CherryPy's built in server. I chose CherryPy so that the app can be deployed without having to reverse proxy (ie. nginx in front).
I'm having trouble getting CherryPy to listen for requests on just a single hostname.
Say I'm serving 2 sites: test1.com and test2.com (and have them set in my hosts file to point back to localhost).
My /etc/hosts file:
127.0.0.1 test1.com test2.com
CherryPy is serving test1.com, test2.com doesn't have anything serving it.
My cherrypy file is as follows:
import cherrypy
from my_test_flask_app import app
if __name__ == '__main__':
cherrypy.tree.graft(app, "/")
cherrypy.server.unsubscribe()
server = cherrypy._cpserver.Server()
server.socket_host = "test1.com"
server.socket_port = 8030
server.thread_pool = 30
server.subscribe()
cherrypy.engine.start()
cherrypy.engine.block()
Set up this way, I go to test1.com:8030 on my browser and it works as expected.
But when I go to test2.com:8030, the same app is served. I expected it not to serve anything, since CherryPy isn't set up to listen for test2.com.
To me, it seems that CherryPy is just listening for everything on the given port (8030), and treating the socket_host part as if its 0.0.0.0
Am I missing something here? I've looked through lots of docs and tutorials, but all things suggest that this code snippet should be working as I expected.
Thanks
Here's how you can setup what you want...
root = Root()
RootApp = cherrypy.Application(root)
Domain2App = cherrypy.Application(root)
SecureApp = cherrypy.Application(Secure())
vhost = cherrypy._cpwsgi.VirtualHost(RootApp,
domains={'www.domain2.example': Domain2App,
'www.domain2.example:443': SecureApp,
})
cherrypy.tree.graft(vhost)
https://cherrypy.readthedocs.org/en/3.3.0/refman/_cpwsgi.html#classes
Hope this helps!
You misunderstand the socket listen address - they are IP addresses only, not on DNS names. Set this way, CherryPy listens to the localhost (127.0.0.1) only - try using your Ethernet/Wlan local address and you should get connection refused.
Also, you can wrap your application with a WSGI middleware that checks the Host header for the proper domain, or use CherryPy virtual host facility to check the host header.