I am running this simple command in my terminal:
python -m http.server 8080
But when I try to access localhost:8080, nothing came out. Why does this happen? Can someone help me?
Thanks in advance.
When I tried another python code provided by the Udacity course:
#!/usr/bin/env python3
#
# A buggy web service in need of a database.
from flask import Flask, request, redirect, url_for
from forumdb import get_posts, add_post
app = Flask(__name__)
# HTML template for the forum page
HTML_WRAP = '''\
<!DOCTYPE html>
<html>
<head>
<title>DB Forum</title>
<style>
h1, form { text-align: center; }
textarea { width: 400px; height: 100px; }
div.post { border: 1px solid #999;
padding: 10px 10px;
margin: 10px 20%%; }
hr.postbound { width: 50%%; }
em.date { color: #999 }
</style>
</head>
<body>
<h1>DB Forum</h1>
<form method=post>
<div><textarea id="content" name="content"></textarea></div>
<div><button id="go" type="submit">Post message</button></div>
</form>
<!-- post content will go here -->
%s
</body>
</html>
'''
# HTML template for an individual comment
POST = '''\
<div class=post><em class=date>%s</em><br>%s</div>
'''
#app.route('/', methods=['GET'])
def main():
'''Main page of the forum.'''
posts = "".join(POST % (date, text) for text, date in get_posts())
html = HTML_WRAP % posts
return html
#app.route('/', methods=['POST'])
def post():
'''New post submission.'''
message = request.form['content']
add_post(message)
return redirect(url_for('main'))
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)
when I tried this for the first time, it worked just fine. But then I closed the terminal. The second time I try to run this python file, I couldn't connect to localhost:8000 anymore.
the same problem keeps coming back.
Sometimes it works fine and I see the page I want. Why is that?
Question:
Do I run the webserver from my virtualMachine or from my macos system?
Firstly, create a python file (server.py) in your project file.
Copy the code below into server.py
import http.server
import socketserver
PORT = 8080
Handler = http.server.SimpleHTTPRequestHandler
httpd = socketserver.TCPServer(("",PORT), Handler)
print("Server at PORT : ",PORT)
httpd.serve_forever()
After that, run the following code command=>
python server.py
Maybe nothing comes out because it's an empty server? You have no HTML content.
You can do this
mkdir /tmp/www
echo 'It works' > /tmp/www/index.html
python -m http.server 8080 --directory /tmp/www
And in a new terminal
curl -v http://localhost:8080
You should see something
Related
I am making a info screen for a few 3D printers, I have a rest API where I get the data from. The data should be updated continuously and it will be name and time. I however want to just start getting the current name displaying on the HTML site.
I have a working Python program that loops and updating the current name and that output needs to go to a specific field, in this case (HTML file field INPUT NAME 1) I will have multiple printers so needs to be easy to direct the data to the HTML tags... Have been trying flask but I do not know if that is the best for this?
python program:
import sched, time
from time import time, sleep
import flask
from flask import Flask, redirect, url_for, render_template, request, flash
import requests
app=Flask(__name__,template_folder='templates')
#printer-S3-nr1
response_ums3_1 = requests.get("http://192.168.50.203/api/v1/print_job/name")
response_ums5_1 = requests.get("http://192.168.50.201/api/v1/print_job/name")
#app.route("/")
def profile():
while (True):
sleep(10 - time()%10)
#ULTIMAKER S3 NR 1
if response_ums3_1.status_code == 404:
return render_template("server.html", s3name1 = "No Prints Running")
if response_ums3_1.status_code == 200:
return render_template("server.html", s3name1 = response_ums3_1.text.strip('"'))
#ULTIMAKER S3 NR 1
#ULTIMAKER S5 NR 1
if response_ums5_1.status_code == 404:
return render_template("server.html", s5name1 = "No Prints Running")
if response_ums5_1.status_code == 200:
return render_template("server.html", s5name1 = response_ums5_1.text.strip('"'))
#ULTIMAKER S5 NR 1
if __name__ == "__main__":
app.run(debug=True)
```
<!DOCTYPE html>
<html>
<head>
<style>
#customers {
font-family: Arial, Helvetica, sans-serif;
border-collapse: collapse;
width: 100%;
}
#customers td,
#customers th {
border: 1px solid #ddd;
padding: 8px;
}
#customers tr:nth-child(even) {
background-color: #f2f2f2;
}
#customers tr:hover {
background-color: #ddd;
}
#customers th {
padding-top: 12px;
padding-bottom: 12px;
text-align: left;
background-color: #1b77f7;
color: white;
}
</style>
</head>
<H1 align="center"> Printer Status </H1>
<body>
<table id="customers">
<tr>
<th>Skrivare</th>
<th>Färdig</th>
<th>Namn</th>
<th>Video</th>
</tr>
<tr>
<td>Ultimaker-S5-nr1</td>
<td>INPUT TIME</td>
<td>{{s5name1}}</td>
<td><img src="http://192.168.50.201:8080/?action=stream" alt="Ultimaker-S5-nr1" style="width:202.5px;height:151.85px;" </td>
</tr>
<tr>
<td>Ultimaker S3 nr1</td>
<td>INPUT TIME</td>
<td>{{s3name1}}</td>
<td><img src="http://192.168.50.203:8080/?action=stream" alt="Ultimaker S3 nr1" style="width:202.5px;height:151.85px;" </td>
</tr>
<tr>
</table>
</body>
</html>
```
In Flask, if you want to send data back from server to the front end, then you have to use the return command. Right now, all you're doing is sending output (your print command) to your console. When you return values from your server to the front end, you'll have to use Jinja Template to display the values e.g.
#server code
if response.status_code == 202:
return render_template("index.htm", INPUT_NAME_1 = response.text)
#html page e.g index.htm
....
<td>{{INPUT_NAME_1}}</td>
...
So from the above code (#server code), you're sending a variable called INPUT_NAME_1 back to an html page called index.htm and on that page you get the value of the variable by using the Jinja syntax of double curly brackets i.e. {{}}
Flask is a web framework. It allows you to build web-based applications which use Python. Another framework is Django. If your target is a web application, then you can use any of them.
Note: Right now, your code doesn't include anything to make it web-based. You haven't even imported the Flask libraries to your python code and that brings me to my next point.
Your question shows you're still missing some basics and continuing down this path will lead to more frustration for you. I would advise that you first understand the basics of Flask e.g. read materials that introduce you to Flask. A quick Googling returned the following - https://pymbook.readthedocs.io/en/latest/flask.html,
https://flask.palletsprojects.com/en/2.0.x/
Once you get the basics of Flask, you should then figure out if you want your web application to reside on your local machine or you want to host it on the web. For web hosting, there are cheap (or free) hosts like python anywhere, heroku, Google App Engine. If you decide to go the route of Google App Engine, check out our website where we have a GUI for it
I am creating a REST service using Bottle and MongoDB. The problem is I am getting a 500 error code when trying to insert a document.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
<head>
<title>Error: 500 Internal Server Error</title>
<style type="text/css">
html {background-color: #eee; font-family: sans;}
body {background-color: #fff; border: 1px solid #ddd;
padding: 15px; margin: 15px;}
pre {background-color: #eee; border: 1px solid #ddd; padding: 5px;}
</style>
</head>
<body>
<h1>Error: 500 Internal Server Error</h1>
<p>Sorry, the requested URL <tt>'http://localhost:8080/create'</tt>
caused an error:</p>
<pre>Unhandled exception</pre>
</body>
</html>
cURL
curl -H "Content-Type: application/json" -X POST -d '{"id" : "10011-2017-TEST","certificate_number" : 9278833,"business_name" : "ACME TEST INC.","date" : "Feb 20 2017","result" : "No Violation Issued","sector" : "Test Retail Dealer - 101"}' http://localhost:8080/create
The thing is though, I am able to successfully insert a document even though I get the 500 error code. Why am I getting the 500 error code? I have been trying to implement exception handling for both MongoDB and Bottle. Not sure if that is why I am getting the code. If not, how can I properly implement exception handling? I have read up on abort but I have had trouble with that. Also, when I comment out return result , I get a 200 response code, but I want to return the id of the document inserted. Thanks
Source Code:
#!/usr/bin/python
# -*- coding: utf-8 -*-
from bson import json_util
import json
import bottle
from bottle import route, run, request, abort, post, error
import pymongo
from pymongo import MongoClient
import datetime as datetime
connection = MongoClient('localhost', 27017)
db = connection['city']
collection = db['inspections']
#route('/create', method='POST')
def insert_document():
try:
data = request.json
result = collection.insert_one(data).inserted_id
except Exception, e:
print ('EXCEPTION: ', e)
return result
if __name__ == '__main__':
run(host='localhost', port=8080)
Change
return result
to
return str(result)
or simply remove the line altogether.
I am very new to leaflet, and I'm trying to workout how to return the lat and lng from a onMapClick event in leaflet to the flask server app, to allow me to use the coordinates t perform a spatial search on my database. The event currently only shows the lat long in a pop-up on the web app.
I've had a search around, but I guess my knowledge is so basic I don't know what functions I'm searching for.
My web map
<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.0.3/dist/leaflet.css" /> <!-- Leaflet CSS file (style sheets)>-->
<script src="https://unpkg.com/leaflet#1.0.3/dist/leaflet.js"></script> <!--leaflet java script file>-->
</head>
<body>
<div id="map1" style="width: 800px; height: 600px;"></div>
<script>
var mymap = L.map('map1').setView([51.5, -0.09], 10);
<!--add map to display>-->
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
maxZoom: 18,
id: 'mapbox.streets',
accessToken: '*****************'
}).addTo(mymap);
<!--add popups as a layer>-->
var popup = L.popup();
<!--logs the action and gives lat long of where click occured >-->
function onMapClick(e) {
.setLatLng(e.latlng)
.setContent("You clicked the map at " + e.latlng.toString())
.openOn(mymap);
}
mymap.on('click', onMapClick);
</script>
</body>
</html>
and the server app
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/demo')
def webMap():
return render_template('demo.html')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8090)
EDIT
I have attempted using an ajax call but getting a 405 error
$.ajax('demo/data/', {
type: 'GET',
data: {
lat: e.latlng.lat,
lng: e.latlng.lng
}
});
};
Flask app
#app.route('/demo/data/')
def demoData():
return request.form['lng'], request.form['lat']
A 405 error is a method not allowed error.
You should use a POST request sending information when using the REST-api, as discussed here.
You're going to want to change your app.route to,
#app.route('/demo/data/' methods=["POST"])
To allow a post method
This question already has an answer here:
Flask: A RESTful API and SocketIO Server
(1 answer)
Closed 7 years ago.
This seems like a very simple problem but it's got me confused nonetheless, I have a Flask application that serves up a webpage and communicates with that page via Socket.io. The Flask application looks like this:
app = Flask(__name__)
socketio = SocketIO(app)
#socketio.on_error()
def error_handler(e):
print e
#this fires
#socketio.on("connect")
def connect():
print "connected"
#this does not
#socketio.on('test')
def test_handler(message):
print "TEST WORKS"
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0')
socketio.run(app)
My page itself is very simple:
<!doctype html>
<html>
<head>
<title>Flask Socket.IO test</title>
<style>
body { font: 13px Helvetica, Arial; }
</style>
<script src="socket.io-1.4.3.js"></script>
<script src="jquery-2.2.0.min.js"></script>
<script>
var socket = io("192.168.42.1:5000");
socket.on('connect', function() {
console.log(" connected ");
});
$(document).ready( function() {
$( '.startBtn' ).click(function() {
console.log("ok");
socket.emit('test', {data:"start!"});
});
});
</script>
</head>
<body>
<div class="startBtn">
<h1>START</h1>
</div>
</body>
</html>
I see on both sides that they connect (i.e. the connect event is triggered on both sides) but nothing that I send from the page to the server is received. I'm guessing somehow I have things misconfigured but the connection being established makes me think otherwise.
So the problem seems to be in how I was setting up the Flask application and socketio. Changing it to this:
app = Flask(__name__)
socketio = SocketIO(app, async_mode='eventlet')
#app.route('/')
def index():
return render_template('index.html')
#socketio.on('test')
def josh_test(message):
print "test"
if __name__ == '__main__':
socketio.run(app, debug=True)
it now all works fantastically with no changes to the HTML file. My previous version had:
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0')
socketio.run(app)
and that was what was causing the problems.
I am trying to write a web service that performs some data processing. The requests contain a data vector as a binary file, and meta-data and processing parameters as form data. An example using python with requests:
import numpy as np
import requests
url = 'http://localhost:8080/pp'
payload = {'param_a': 4, 'param_b': -2.1}
file = {'binary_data': ('file_name.bin', bytes(np.random.randn(1000))}
r = requests.post(url, data=payload, files=file)
Now on the service side, I have:
import bottle
import numpy as np
#bottle.post('/pp')
def pp():
file_path = '/home/generic_user/howhaveyou.bin'
return_file_path = '/home/generic_user/finethanks.bin'
bin_file = bottle.request.files.get('binary_data')
bin_file.save(file_path, overwrite=True)
param_a = float(bottle.request.forms.get('param_a')
param_b = float(bottle.request.forms.get('param_b')
data_vector = np.fromfile(file_path)
processed_data_vector = (data_vector-param_a)*param_b
processed_data_mean = np.mean(processed_data_vector)
processed_data_samples = len(processed_data_vector)
return_metrics = {'mean': processed_data_mean,
'n_of_samples': processed_data_samples}
with open(return_file_path, 'wb') as return_file:
return_file.write(bytes(processed_data_vector))
return return_metrics, bottle.static_file(return_file_path, '/')
which doesn't quite work. Either of the returns work on their own, but together I get the following response:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
<head>
<title>Error: 500 Internal Server Error</title>
<style type="text/css">
html {background-color: #eee; font-family: sans;}
body {background-color: #fff; border: 1px solid #ddd;
padding: 15px; margin: 15px;}
pre {background-color: #eee; border: 1px solid #ddd; padding: 5px;}
</style>
</head>
<body>
<h1>Error: 500 Internal Server Error</h1>
<p>Sorry, the requested URL <tt>'http://localhost:8080/pp'</tt>
caused an error:</p>
<pre>Unsupported response type: <class 'dict'></pre>
</body>
</html>
I have a complete lack of experience with Web Services, so I don't even know if I'm on the right track at all. The point is I wish to return some binary data, along with a few (preferably named) metrics of said data. Is it possible to do this using bottle only? Is there a best practice (with respect to web services, python or both) that I should follow when it comes to this kind of thing?
Note that the client will not be written in python, that is just my test case.
Thanks for any guidance!
The problem with the server-side code is that you cannot return a dictionary (return_metrics) and the contents of a file (return_file_path) with the same response. A solution is to encode the file contents in a string and include it in the returned dict (return_metrics). Then, the client will need to decode the content string to access the data.