I have some JSON scripts that I plan on parsing on the site and then allowing the clients to edit them through my interface (to later be loaded and parsed once again for display). Problem is, Javascript doesn't have access to writing to the file system. I've already got a system for reading the JSON files using Javascript (and jQuery). Now, I've heard I can use CGI to save the data later. Can somebody give me some references and in depth explanations? I've read a bit about CGI in general but nothing specific.
Thanks for any help!
CGI is a way for servers to interface with scripts. Pretty much, you just set up the server to execute a file, and it will execute it with several environment variables set and POST data fed to its standard input. The script should output the headers for the page, followed by the content.
CGI scripts can be written in many different languages. Perl is well-known for CGI scripts; it has documentation on it here. Python has a cgi module to deal with CGI. Ruby has a CGI package as well.
Here's a quick CGI script written in Python that writes to a file. You'll probably want to modify it or use it as a reference rather than using it as-is:
#!/usr/bin/env python
import os
import os.path
import sys
import json
import cgi
# You'll probably want to remove or alter
# the following line for production.
import cgitb; cgitb.enable()
def bad_request():
print "Status: 400 Bad Request"
print "Content-Type: application/json"
print ""
json.dump({'success': False}, sys.stdout)
sys.exit(0)
assert 'REQUEST_METHOD' in os.environ
if os.environ['REQUEST_METHOD'] != 'POST':
bad_request()
form = cgi.FieldStorage()
if 'data' not in form:
bad_request()
filename = os.path.join(os.path.dirname(__file__), "some_file.json")
with open(filename, "wb") as f:
f.write(form['data'].value)
print "Content-Type: application/json"
print ""
json.dump({'success': True}, sys.stdout)
If you POST to it with a data parameter, it will save that data into some_file.json in the same directory as itself.
Related
So this particular programming conundrum I find myself in is quite a bit above my Ruby skills or any programming skills in general I guess.
Using an HTML (Post) form I am able to upload an image to my server side CGI script and from there I am able to take the data and then save it on my server. The bones of HTML required to do this, with all of the formatting fluff stripped away is essentially:
<form enctype="multipart/form-data" action="logoupload.pl" method="post">
<input name="imagefiletoupload" type="file">
<input id="newlogo" name="imglogo" value="Update Logo">
</form>
I really don’t understand how this works, other than the HTML form is able to select the file from the client end and then transfer it to my CGI/Perl file (logoupload.pl). On the server end I have some code in place that checks for errors, size etc… and then saves the file to the directory of my choosing.
This is all good, I can make this work.
Now what I want to try and do is within Ruby (given a path to an existing image file) send that image file to my same server side CGI script using some type of GET or POST call.
I have no idea how to do this.
My typical way I make calls to my server (or any other website address) is something like this:
some_url = "http://design.medeek.com/resources/somescript.pl?var1=#{#Var1}&var2=#{Var2}&var3=#{#Var3}"
require 'open-uri'
begin
open(some_url) { |io|
url_response = io.read
# Then parse the response with some code here or convert JSON to ruby array etc...
}
rescue StandardError => e
UI.messagebox ("Unable to connect to server, action aborted.")
end
How would I send an image via a URL call like this? Or is there a better way to do this?
So far I have no idea how to program this.
Try this:
require "net/http"
require "uri"
uri = URI.parse("https://your-backend-url")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri)
request.body = url_response
request["Content-Type"] = "multipart/form-data"
http.request(request)
Js:
fetch('app.py').then(res=>res.text()).then(data=>console.log(data));
Python:
print('helloworld')
console.log() shows print('helloworld') instead of helloworld
Am I not getting something here? I want the Python code to return "helloworld" to the browser's console, but instead it sends the sourcecode. Same with php(note that php --version in cmd sends PHP Warning:'vcruntime140.dll' 14.0 is not compat..). But python appears to have no issues on my pc.
Is my problem in my code? Or what is necessary for the app.py or app.php to run when I fetch it?
Hi, I'm a young programmer, have been trying to add scripts to my server to let client-side send data to server-side, in which server-side's job is to receive and write data into files to my server. Thanks
All that code is doing is fetching a local file (app.py) and then printing its contents to the browser console. This isn't how api's work. You can create an api endpoint in Flask (a Python library for writing apis) that will print helloworld to a separate (the server) console, or return it as data. Follow this guide to get you started (you may want to follow the installation instructions first - link on the page) https://flask.palletsprojects.com/en/1.1.x/quickstart/
Your fetch statement will look like this
fetch('/').then(res=>res.text()).then(data=>console.log(data));
your app.py will look as follows:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello, World!'
I am not familiar with php so afraid I can't give you pointers there.
You cannot run Python or PHP files on the client side, this has to be done on the backend. For Python you need to run a script (server) that listens for incoming requests, and on that send a response. The same applies to PHP, you can use web servers like Apache, Nginx, Lighttpd and more to run php.
Seems like you have a static server for files fetching, but again, you cannot request the file and expectate it to run.
First off, I am a total beginner when it comes to web tech, so this may be a relatively simple problem to solve. I am attempting to open a text file from a python script that is interacting with an XMLHTTPRequest and I am receiving the following error:
Traceback (most recent call last):
File "/home/ryan/VirtualDesktop/ComputerScience/4410_web_Technologies/projects/p3stuff/cgi-bin/p3.py", line 20, in <module>
msgs = open("msgs.txt")
FileNotFoundError: [Errno 2] No such file or directory: 'msgs.txt'
This is the python code:
#!/usr/bin/python3
import sys, cgi
import cgitb
cgitb.enable()
sys.stderr = sys.stdout
print("Access-Control-Allow-Origin: *")
print("Content-type: text/html\n\n")
msgs = open("msgs.txt")
print(msgs.read())
The "msgs.txt" file is definitely in the proper directory and it runs fine if I run the python script in my terminal (without interacting with the javascript):
ryan#ryan-XPS-15-9560:~/VirtualDesktop/ComputerScience/4410_web_Technologies/projects/p3stuff/cgi-bin$ ls
msgs.txt p3.py*
ryan#ryan-XPS-15-9560:~/VirtualDesktop/ComputerScience/4410_web_Technologies/projects/p3stuff/cgi-bin$ ./p3.py
Access-Control-Allow-Origin: *
Content-type: text/html
alice: hello
bob: whatever
ryan#ryan-XPS-15-9560:~/VirtualDesktop/ComputerScience/4410_web_Technologies/projects/p3stuff/cgi-bin$
It seems to me the javascript code that I am using to interact with the python script is working fine, as it goes smoothly if I just print the contents of msgs.txt straight from the python file (ie removing the last two lines of the python code and replacing them with print("alice: hello\nbob: whatever"). Just trying to access that file seems to be my main problem. It's like the python script can't even see it when I'm trying to open it from my webpage.
Any advice would be much appreciated. Thank you in advance!
Edit: Using the full filepath in the open call is not permitted (this is part of an assignment).
If you know that msgs.txt will be in the same directory as p3.py, you can query the directory portion of __file__.
Try this:
import os
def filename(x):
return os.path.join(os.path.dirname(os.path.realpath(__file__)), x)
with open(filename('msgs.txt')) as msgs:
print(msgs.read())
I'm working on automatically generating a local HTML file, and all the relevant data that I need is in a Python script. Without a web server in place, I'm not sure how to proceed, because otherwise I think an AJAX/json solution would be possible.
Basically in python I have a few list and dictionary objects that I need to use to create graphs using javascript and HTML. One solution I have (which really sucks) is to literally write HTML/JS from within Python using strings, and then save to a file.
What else could I do here? I'm pretty sure Javascript doesn't have file I/O capabilities.
Thanks.
You just need to get the data you have in your python code into a form readable by your javascript, right?
Why not just take the data structure, convert it to JSON, and then write a .js file that your .html file includes that is simply var data = { json: "object here" };
What do you thing about using some Templating system? It will fit your needs.
I know you've specifically mentioned "without a web-server", but unless you want to really go out of your way, and over-complicate this, and restrict flexibility for future use:-
Could you not use a very simple webserver such as: http://docs.python.org/library/simplehttpserver.html ? That way, should you need to expose the site, you've got the URL's already in place to set-up a proper webserver.
Maybe you could write to a cookie and then access that via JavaScript? Similar to this SO answer here?
You could use Python's JSON Encoder and Decoder library. This way you could encode your Python data into JSON format and include that in your HTML document. You would then use Javascript in the HTML file to work with the JSON encoded data.
http://docs.python.org/library/json.html
If this only needs to be for localhost, you could do something like the following.
To access, you would make a call to http://localhost:8080/foo; this can cause some issues due to Cross Site Injection Protection, however; these are readily solved by Googling around.
On the JS side, you would make an AJAX call like this (assuming jQuery)
$.ajax('http://localhost:8080/foo', function (data) {console.log(data)});
And then on the Python side you would have this file in the same directory as the html file you are seeking to use (index.html) on your computer, and execute it.
import BaseHTTPServer
import json
class WebRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
desiredDict = {'something':'sent to JS'}
if self.path == '/foo':
self.send_response(200)
self.send_header("Content-type", "application/json")
self.end_headers()
self.wfile.write(json.dumps(desiredDict))
else:
if self.path == '/index.html' or self.path == '/':
htmlFile = open('index.html', 'rb')
self.send_response(200)
self.send_header("Content-type", "text/html")
self.send_header("Access-Control-Allow-Origin","http://localhost:8080/")
self.end_headers()
self.wfile.write(htmlFile.read())
else:
self.send_error(404)
server = BaseHTTPServer.HTTPServer(('',8080), WebRequestHandler)
server.serve_forever()
I'm trying to make a file uploader page that will prompt the user for a file and will upload while displaying progress.
At the moment I've managed to make a simple HTML page that can calls my python script. The python script will then get the file and upload in 1000 byte chunks.
I have two main problem (mainly due to be completely new to this):
1) I can't get the file size to calculate percentage
2) I don't know how to communicate between the server side python and whatever is in the page to update the progress status;presumably javascript.
Am I going about everything the wrong way? Or is there a solution to my woes?
Here is my python code:
#!/usr/local/bin/python2.5
import cgi, os
import cgitb; cgitb.enable()
try:
import msvcrt
msvcrt.setmode (0, os.O_BINARY)
msvcrt.setmode (1, os.O_BINARY)
except ImportError:
pass
form = cgi.FieldStorage()
upload = form['file']
if upload.filename:
name = os.path.basename(upload.filename)
out = open('/home/oetzi/webapps/py/' + name, 'wb', 1000)
message = "The file '" + name + "' was uploaded successfully"
while True:
packet = upload.file.read(1000)
if not packet:
break
out.write(packet)
out.close()
else:
message = "Derp... could you try that again please?"
print """\
Content-Type: text/html\n
<html><body>
<p>%s</p>
</body></html>
""" % (message,)
This is more complex than it seems, given how file uploading works in the HTTP protocol. Most web servers will give control to the CGI script only when the uploaded file has been completely transferred, so there's no way to give feedback in the meanwhile.
There are some Python libraries that attempt to tackle this issue, though. For example: gp.fileupload (works with WSGI, not CGI).
The trick is to provide a way to query the upload progress via AJAX while still transferring the uploaded file. This is of no use if the web server (for example, Apache or nginx) is not configured to support the upload progress feature because you will probably see a 0% to 100% jump in the progress bar.
I suggest you try Plupload, which works on the client-side and is much simpler.