2012-07-31 13 views
9

Estoy tratando de averiguar cómo crear una conexión local entre un servidor Python y un cliente Javascript utilizando el formato JSON para recuperar los datos. Particularmente, necesito hacer algunas consultas en el lado del cliente HTML, enviar estas consultas al servidor en formato JSON y ejecutarlas en el lado del servidor Python para buscar datos en una base de datos SQLite. Y después de obtener los resultados de la base de datos, envíe esos resultados nuevamente al cliente en formato JSON también.Cómo conectar Javascript a Python para compartir datos con el formato JSON en ambos sentidos?

Por ahora, sólo se puede ejecutar la consulta en Python y el código en JSON como esto:

import sqlite3 as dbapi 
import json 

connection = dbapi.connect("C:/folder/database.db") 
mycursor = connection.cursor() 
mycursor.execute("select * from people") 
results = [] 
for information in mycursor.fetchall(): 
     results += information 

onFormat = json.dumps(results) 
print(onFormat) 

Sé que este código hace algo por igual (de hecho se ejecuta), ya que llama a un servicio de un servidor que devuelve los datos en formato JSON (pero el servidor en este ejemplo no es Python):

<html> 
    <head> 
     <style>img{ height: 100px; float: left; }</style> 
     <script src="http://code.jquery.com/jquery-latest.js"></script> 
    </head> 
    <body> 
     <div id="images"></div> 
    <script> 
     $.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?", 
     { 
     tags: "mount rainier", 
     tagmode: "any", 
     format: "json" 
     }, 
     function(data) { 
     $.each(data.items, function(i,item){ 
      $("<img/>").attr("src", item.media.m).appendTo("#images"); 
      if (i == 3) return false; 
     }); 
     });</script> 

    </body> 
</html> 

lo que necesito es saber cómo debería funcionar (localmente) el programa de pitón a haber una ejecución disponible en web servicio y cómo debería ser el Javascript para recuperar los datos del servidor python.

Lo busqué en Internet en todas partes, pero no encontré esta respuesta en ninguna parte porque las únicas respuestas que dan son sobre cómo codificar JSON dentro de Python o dentro de Javascript pero sin conectar ambos. Espero que alguien pueda ayudarme en esto !!!

+1

Puede que le interese [el marco Pico] (https://github.com/fergalwalsh/pico) (sí, soy colaborador, pero eso no lo hace) Menos bueno). Funciona realmente bien. –

+0

Probablemente deberías aceptar una respuesta. – Marcin

Respuesta

3

he encontrado por fin una manera más fácil que el frasco. Es un marco de Python llamado Bottle. Solo necesita descargar la biblioteca del sitio web oficial y colocar todos sus archivos en su directorio de trabajo para importar la biblioteca. También puede instalarlo utilizando el programa setup python incluido para evitar llevarlo con el código fuente en todas partes.Entonces, para hacer su servicio de servidor Web puede codificar así:

from bottle import hook, response, route, run, static_file, request 
import json 
import socket 
import sqlite3 

#These lines are needed for avoiding the "Access-Control-Allow-Origin" errors 
@hook('after_request') 
def enable_cors(): 
    response.headers['Access-Control-Allow-Origin'] = '*' 

#Note that the text on the route decorator is the name of the resource 
# and the name of the function which answers the request could have any name 
@route('/examplePage') 
def exPage(): 
    return "<h1>This is an example of web page</h1><hr/><h2>Hope you enjoy it!</h2>" 

#If you want to return a JSON you can use a common dict of Python, 
# the conversion to JSON is automatically done by the framework 
@route('/sampleJSON', method='GET') 
def mySample(): 
    return { "first": "This is the first", "second": "the second one here", "third": "and finally the third one!" } 

#If you have to send parameters, the right sintax is as calling the resoure 
# with a kind of path, with the parameters separed with slash (/) and they 
# MUST to be written inside the lesser/greater than signs (<parameter_name>) 
@route('/dataQuery/<name>/<age>') 
def myQuery(name,age): 
    connection= sqlite3.connect("C:/folder/data.db") 
    mycursor = connection.cursor() 
    mycursor.execute("select * from client where name = ? and age= ?",(name, age)) 
    results = mycursor.fetchall() 
    theQuery = [] 
    for tuple in results: 
     theQuery.append({"name":tuple[0],"age":tuple[1]}) 
    return json.dumps(theQuery) 

#If you want to send images in jpg format you can use this below 
@route('/images/<filename:re:.*\.jpg>') 
def send_image(filename): 
    return static_file(filename, root="C:/folder/images", mimetype="image/jpg") 

#To send a favicon to a webpage use this below 
@route('/favicon.ico') 
def favicon(): 
    return static_file('windowIcon.ico', root="C:/folder/images", mimetype="image/ico") 

#And the MOST important line to set this program as a web service provider is this 
run(host=socket.gethostname(), port=8000) 

Por último, se puede llamar al servicio web resto de su aplicación Bottlepy en un cliente Javascript de esta manera:

var addr = "192.168.1.100" 
var port = "8000" 

function makeQuery(name, age){ 
    jQuery.get("http://"+addr+":"+port+"/dataQuery/"+ name+ "/" + age, function(result){ 
     myRes = jQuery.parseJSON(result); 
     toStore= "<table border='2' bordercolor='#397056'><tr><td><strong>name</strong></td><td><strong>age</strong></td></tr>"; 
     $.each(myRes, function(i, element){ 
      toStore= toStore+ "<tr><td>"+element.name+"</td><td>" + element.age+ "</td></td></tr>"; 
     }) 
     toStore= toStore+ "</table>" 
     $('#theDataDiv').text(''); 
     $('<br/>').appendTo('#theDataDiv'); 
     $(toStore).appendTo('#theDataDiv'); 
     $('<br/>').appendTo('#theDataDiv'); 
    }) 
} 

Espero que pueda ser útil para otra persona

+3

¿Y qué hace que la botella sea más fácil que el matraz? – Marcin

7

Su pregunta equivale a "cómo puedo hacer de este python un servicio web".

Probablemente las formas más ligeras de hacerlo sean web.py y flask. Échales un vistazo.

Si esto se agranda, considere django con tastypie - esa es una forma sencilla de hacer una API basada en json.

Actualización: Aparentemente, también hay un marco RPC Python-javascript llamado Pico, al que Felix Kling contribuye. La introducción dice:

Literalmente añadir una línea de código (pico de importación) a su módulo de Python para convertirlo en un servicio web que es accesible a través del Javascript (y Python) libararies cliente Pico.

9

Aquí hay un "hola mundo" ejemplo de a flask web-application que puede servir HTML estático y archivos javascript, base de datos de búsqueda con el parámetro de una petición Javascript, y los resultados volver a javascript como JSON:

import sqlite3 
from flask import Flask, jsonify, g, redirect, request, url_for 

app = Flask(__name__) 

@app.before_request 
def before_request(): 
    g.db = sqlite3.connect('database.db') 

@app.teardown_request 
def teardown_request(exception): 
    if hasattr(g, 'db'): 
     g.db.close() 

@app.route('/') 
def index(): 
    return redirect(url_for('static', filename='page.html')) 

@app.route('/json-data/') 
def json_data(): 
    # get number of items from the javascript request 
    nitems = request.args.get('nitems', 2) 
    # query database 
    cursor = g.db.execute('select * from items limit ?', (nitems,)) 
    # return json 
    return jsonify(dict(('item%d' % i, item) 
         for i, item in enumerate(cursor.fetchall(), start=1))) 

if __name__ == '__main__': 
    app.run(debug=True, host='localhost', port=5001) # http://localhost:5001/ 
else: 
    application = app # for a WSGI server e.g., 
    # twistd -n web --wsgi=hello_world.application --port tcp:5001:interface=localhost 

La base de datos el código de instalación es de Using SQLite 3 with Flask.

static/page.html y static/json-jquery.js archivos son de Ajax/jQuery.getJSON Simple Example, donde el código JavaScript se modifica ligeramente para pasar una URL diferente y nitems parámetro:

$(document).ready(function(){ 
    $('#getdata-button').live('click', function(){ 
     $.getJSON('/json-data', {'nitems': 3}, function(data) { 
      $('#showdata').html("<p>item1="+data.item1+" item2="+data.item2+" item3="+data.item3+"</p>"); 
     }); 
    }); 
}); 
+0

Perdón por abrir temas antiguos. Solo tengo una pregunta. ¿No hay implicaciones de seguridad con solo tomar los argumentos y alimentarlos directamente en la base de datos? No estoy siendo crítico; solo curiosidades Estoy tratando de entender cómo funciona JSON. ¿Alguien no puede invocar esta API por lo que es susceptible de ataques de inyección sql? –

+1

@FlorinStingaciu: es una consulta parametrizada. El motor se escapa de todos los argumentos. – jfs

Cuestiones relacionadas