Flask, matplotlib, HTML Form, als png zurück geben

Django, Flask, Bottle, WSGI, CGI…
Antworten
telegraph
User
Beiträge: 31
Registriert: Mittwoch 6. November 2013, 10:59

Hallo kann mir jemand Sagen mit welcher Methode ich die werte der FORM auf abgreifen kann um auf einer Seite den Plot in ein bild zu Posten ??? ohne der Auswahl eines wertes funktioniert es mit <img src="{{url_for('build_plot')}}" alt="Loading plot0" />

Daten_fürden_Plot sind als "Form Data" vorhanden aber ich kann die nicht einlesen? Man kann sie im Post Headers auslesen im Firefox und Chrome?


HTML seite mit einer form zum aus wählen der Daten
[codebox=html5 file=Unbenannt.html]
<form action="{{url_for('values')}}" method="POST" id="select">
<select name="Daten_fürden_Plot" size="14">
<option value="Wirkenergie_kWh">Wirkengie</option>
<option value="Strommittelwert_L1">L1</option>
<option value="Strommittelwert_L2">L2</option>
<option value="Strommittelwert_L3">L3</option>
<option value="Schaltkreis_1_Wirkenergie_kWh">Wirkenergie 1</option>
<option value="Schaltkreis_1_Strommittelwert_A">Strommittelwert 1</option>
<option value="Schaltkreis_2_Wirkenergie_kWh">Wirkenergie 2</option>
<option value="Schaltkreis_2_Strommittelwert_A">Strommittelwert 2</option>
<option value="Schaltkreis_3_Wirkenergie_kWh">Wirkenergie 3</option>
<option value="Schaltkreis_3_Strommittelwert_A">Strommittelwert 3</option>
<option value="Schaltkreis_4_Wirkenergie_kWh">Wirkenergie 4</option>
<option value="Schaltkreis_4_Strommittelwert_A">Strommittelwert 4</option>

</select>
<input type="submit">
[/code]

Code: Alles auswählen

@app.route('/xxxxxxxx', methods=['POST', 'GET'])
def values()

html seite mit der erstellung des Bildes
[codebox=html5 file=Unbenannt.html]
<img src="{{url_for('build_plot')}}" alt="Loading plot0" />
[/code]

Zeile 4 funktioniert nicht

Code: Alles auswählen

@app.route('/plot.png', methods=['POST', 'GET'])
def build_plot():
    #values_of_interest = request.form??????
    #zu plot png directvalues_of_interest = request.form['Daten_fürden_Plot']
    conn = sqlite3.connect('/XXXXXX')
    c = conn.cursor()
    c.execute('SELECT {0}, Ortszeitstempel FROM egx300'.format(values_of_interest))
    dates = []
    values = []
    for row in c.fetchall():
        dates.append(row[1])
        values.append(row[0])
    fig = Figure()
    ax = fig.add_subplot(111)
    ax.plot(dates, values)
    img = io.BytesIO()
    canvas = FigureCanvasAgg(fig)
    canvas.print_figure(img, format='png')
    response = make_response(img.getvalue())
    response.headers['Content-Type'] = 'image/png'
    return response

Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@telegraph: per GET-Parameter <img src="/plot.png?a=b" />

Ach übrigens, niemals Parameter in Tabellen- oder Feldnamen hineinkodieren, sondern sauber als eigene Tabelle mit eigenen Feldern abstrahieren. Wenn man dann noch unkontrolliert Werte von Webseiten übernimmt, hat man ein riesiges Sicherheitsproblem.
telegraph
User
Beiträge: 31
Registriert: Mittwoch 6. November 2013, 10:59

@Sirius3 die Sicherheitsaspektes hab ich verstanden und werde die noch aus bessern. in ner liste und nem try catch abfragen. Aber wie komme ich an die Query String Parameter ?
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

was funktioniert denn an Zeile 4 nicht? Das ist schon der richtige Weg, um an POST-Parameter zukommen.
Welchen Wert hat `directvalues_of_interest`, wenn du es per print() ausgeben lässt.

Gruß, noisefloor
telegraph
User
Beiträge: 31
Registriert: Mittwoch 6. November 2013, 10:59

nichts er sagt einfach Bad Request "GET /plot.png HTTP/1.1" 400 -
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

dann ist IMHO an deinem Request was falsch - du schickst doch eigentlich einen POST-Request.

Gruß, noisefloor
telegraph
User
Beiträge: 31
Registriert: Mittwoch 6. November 2013, 10:59

build_plot wird nicht aufgerufen

verwende ich die code unter der ValueSeite, leitet er mich auf die plot.png seite

Code: Alles auswählen

<img src="{{url_for('build_plot')}}" alt="Loading plot0"  />
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@telegraph: Du mußt die Parameter, wie in meiner Antwort schon geschrieben, an die plot-URL anhängen, sonst kriegt sie ja build_plot gar nicht mit.
telegraph
User
Beiträge: 31
Registriert: Mittwoch 6. November 2013, 10:59

Hallo;

ich pack es nicht, er gibt die werte mit

Code: Alles auswählen

{{request.form.get('Daten_fürden_Plot')}} 
aus, aber wie bekomme ich Die in die Funktion build_plot()


<img src="/plot.png?{{values_of_interest=request.form.get('Daten_fürden_Plot')}}" />
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

Code: Alles auswählen

<img src="{{url_for('build_plot')}}?values_of_interest={{request.form.get('Daten_fürden_Plot')|urlencode}}" alt="Loading plot0"  />
telegraph
User
Beiträge: 31
Registriert: Mittwoch 6. November 2013, 10:59

die Angefragte Adresse ist http://127.0.0.1:5000/plot.png/?values_ ... nergie_kWh aber es gibt ein 500 Server Error zurück?
telegraph
User
Beiträge: 31
Registriert: Mittwoch 6. November 2013, 10:59

Code: Alles auswählen

@app.route('/values/', methods=['POST', 'GET'])
def values():
    if 'username' in session:


        values_of_interest = request.form.get('Daten_fürden_Plot')

        print(values_of_interest) # hier werden die Daten richtig ausgegeben 



        return render_template('values.html', username=session['username'])
    else:
        return redirect(url_for('login'))


@app.route('/plot.png/', methods=['POST', 'GET'])
def build_plot():
    #values_of_interest = request.form['Daten_fürden_Plot']

    values_of_interest = request.form.get('Daten_fürden_Plot')


    conn = sqlite3.connect('C:\\Users\\teleg\\OneDrive\\Desktop\\Easy_projekt\\CSV_to_SQLite\\DB_egx300.db')
    c = conn.cursor()
    c.execute('SELECT {0}, Ortszeitstempel FROM egx300'.format(values_of_interest))
    dates = []
    values = []
    for row in c.fetchall():
        dates.append(row[1])
        values.append(row[0])
    fig = Figure()
    ax = fig.add_subplot(111)
    ax.plot(dates, values)
    img = io.BytesIO()
    canvas = FigureCanvasAgg(fig)
    canvas.print_figure(img, format='png')
    response = make_response(img.getvalue())
    response.headers['Content-Type'] = 'image/png'
    return response

values.html
[codebox=html5 file=Unbenannt.html]
{% extends "base.html" %}

{% block title %} values {% endblock %}

{% block content %}

<p><h1>Hallo, {{username}} - <a href="{{url_for('logout')}}">Logout</a> </h1></p>

<h1>{{request.form.get('Daten_fürden_Plot')}}</h1> #hier werden die Daten richtig ausgeben

<img src="{{url_for('build_plot')}}" alt="Loading plot0" />


<img src="{{url_for('build_plot')}}?values_of_interest={{request.form.get('Daten_fürden_Plot')}}" alt="Loading plot0" />


<img src="{{url_for('build_plot1')}}" alt="plot1" />





<br>


{% endblock %}
[/code]

welcome.html
[codebox=html5 file=Unbenannt.html]




{% block content %}

<p><h1>Hallo, {{username}} - <a href="{{url_for('logout')}}">Logout</a> </h1></p>

<p><h2><a href="{{url_for('values')}}">Show you plot</a></h2></p>


<form action="{{url_for('values')}}" method="POST" id="select" >
<select name="Daten_fürden_Plot" size="14" >
<option value="Wirkenergie_kWh">Wirkengie</option>
<option value="Strommittelwert_L1">L1</option>
<option value="Strommittelwert_L2">L2</option>
<option value="Strommittelwert_L3">L3</option>
<option value="Schaltkreis_1_Wirkenergie_kWh">Wirkenergie 1</option>
<option value="Schaltkreis_1_Strommittelwert_A">Strommittelwert 1</option>
<option value="Schaltkreis_2_Wirkenergie_kWh">Wirkenergie 2</option>
<option value="Schaltkreis_2_Strommittelwert_A">Strommittelwert 2</option>
<option value="Schaltkreis_3_Wirkenergie_kWh">Wirkenergie 3</option>
<option value="Schaltkreis_3_Strommittelwert_A">Strommittelwert 3</option>
<option value="Schaltkreis_4_Wirkenergie_kWh">Wirkenergie 4</option>
<option value="Schaltkreis_4_Strommittelwert_A">Strommittelwert 4</option>

</select>
<input type="submit">

</form>
[/code]
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@telegraph: die grundlegenden Methoden von HTML-Seiten sollte man schon kennen, wenn man HTML-Seiten erstellt. Was soll jetzt der `/` bei plot.png? Kennst Du irgendein Bildformat das mit `/` endet?
Du übergibst im /plot.png-Request den Parameter value_of_interest, willst dann aber wieder über `Daten_fürden_Plot` zugreifen? Das kann nicht funktionieren. Du formatierst immer noch ungeprüft Benutzereingaben in einen SQL-Ausdruck.
Um Dich zu zitieren:
telegraph hat geschrieben:die Sicherheitsaspektes hab ich verstanden und werde die noch aus bessern
Das hat Du also bisher noch ignoriert. Solche Sicherheitsscheunentore muß man sofort schließen.

Und das `urlencode` von mir ist nicht nur Folklore, sondern die nächste riesige Sicherheitslücke, die Du in Dein System reißt: Cross-Site-Injection.
Antworten