Flask ein Bild mit dynamischen Namen als Teil des Dateinamen anzeigen

Django, Flask, Bottle, WSGI, CGI…
Agascha88
User
Beiträge: 23
Registriert: Sonntag 6. März 2022, 21:04

Hallo zusammen,

ich versuche einmal mein Problem so deutlich wie möglich zu erklären.
Ich betreibe mehrere Clients, die zyklisch u.a. ein Statusbild an den Flask-Server senden. Im Flask-Server findet die Konfiguration dieser Clients statt. Jeder Client besitzt seine eigene Configseite im Server.
Während der Ersteinrichtung eines Clients wird eine eindeutige config_id für den Client vergeben. Der Client setzt vor dem Senden des Bildes den Namen aus der config_id und _matrix.png zusammen.
Zum Beispiel: 123456789_matrix.png

Jetzt möchte ich gerne auf der entsprechenden Configseite auch das richtige Bild sehen.

Teil der config-Eingabe ist:
<label>Öffentliche ID</label>
{{ form.public_id() }}

Im Beispiel wurde im Feld Öffentliche ID: 123456789 eingegeben und gespeichert.

Also dachte ich, dass ich es so in der Art lösen könnte:
<img src="{{ url_for('static', filename=public_id + '_matrix.png') }}"/>

Aber leider ohne Erfolg :(

Hoffentlich hat einer von euch einen Tipp für mich

Viele Grüße
Agascha
Benutzeravatar
__blackjack__
User
Beiträge: 10537
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Agascha88: Was heisst denn „ohne Erfolg“? Wo genau hakt es? Welche Fehlermeldungen werden ausgegeben? Kannst Du das Bild abrufen wenn Du die entsprechende URL manuell eingibst?

Und bei statischen Namen hast Du natürlich das Problem, dass der Webbrowser die Bilder cachen wird. Da müsste man also noch irgendwas an der URL machen, beispielsweise eine Query-Teil anhängen, der von der aktuellen Zeit abhängt, oder zumindest von der Zeit zu der das Bild zuletzt aktualisiert wurde.
“»So computers are tools of the devil?« thought Newt. He had no problem believing it. Computers had to be the tools of *somebody*, and all he knew for certain was that it definitely wasn't him.” — Neil Gaiman & Terry Pratchett, Good Omens
Sirius3
User
Beiträge: 16127
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum schreibst Du einmal `form.public_id()` und einmal nur `public_id`?
Agascha88
User
Beiträge: 23
Registriert: Sonntag 6. März 2022, 21:04

Danke schon ein mal wegen der Antworten.

Also, wenn ich <img src="{{ url_for('static', filename='123456789_matrix.png') }}"/> fest eingebe, wird mir das Bild angezeigt.
Es gibt auch keine Veränderung, wenn ich 'form.public_id()' oder 'public_id' benutze. Jedes Mal kein Bild.
Den cache habe ich abgestellt und das Bild wird auch aktualisiert angezeigt. Nur leider nicht zur entsprechenden Config, da ich die ID nicht zuordnen kann.

Danke für eure Bemühungen
Sirius3
User
Beiträge: 16127
Registriert: Sonntag 21. Oktober 2012, 17:20

Welche URL wird denn generiert und wie weicht die von Deiner Erwartung ab?
Agascha88
User
Beiträge: 23
Registriert: Sonntag 6. März 2022, 21:04

Antwort vom Server:
http://192.168.178.98:8008/conf/0

Internal Server Error
The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
Sirius3
User
Beiträge: 16127
Registriert: Sonntag 21. Oktober 2012, 17:20

Es wird also nicht nur nicht das Bild angezeigt, sondern es gibt einen anderen Fehler. Jetzt wäre es natürlich hilfreich, zu wissen, was denn Flask als Traceback anzeigt.
Agascha88
User
Beiträge: 23
Registriert: Sonntag 6. März 2022, 21:04

Einmal das Log mit config_id:

192.168.178.71 - - [22/Jun/2022:18:35:26 +0200] "GET /static/123456789ABC_matrix.png HTTP/1.1" 304 0 "http://192.168.178.98:8008/conf/0" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.124 Safari/537.36 Edg/102.0.1245.44"
192.168.178.71 - - [22/Jun/2022:18:35:38 +0200] "GET /static/css/main.css HTTP/1.1" 304 0 "http://192.168.178.98:8008/conf/0" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.124 Safari/537.36 Edg/102.0.1245.44"
192.168.178.71 - - [22/Jun/2022:18:49:46 +0200] "GET /dashboard HTTP/1.1" 200 944 "http://192.168.178.98:8008/conf/0" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.124 Safari/537.36 Edg/102.0.1245.44"
192.168.178.71 - - [22/Jun/2022:18:49:46 +0200] "GET /static/css/main.css HTTP/1.1" 304 0 "http://192.168.178.98:8008/dashboard" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.124 Safari/537.36 Edg/102.0.1245.44"
[2022-06-22 18:49:49,645] ERROR in app: Exception on /conf/0 [GET]
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/usr/lib/python3/dist-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/lib/python3/dist-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python3/dist-packages/flask/_compat.py", line 35, in reraise
raise value
File "/usr/lib/python3/dist-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/lib/python3/dist-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/usr/local/lib/python3.7/dist-packages/flask_login/utils.py", line 272, in decorated_view
return func(*args, **kwargs)
File "/home/pi/konfigurationsanwendung_6/main.py", line 190, in conf
return flask.render_template('conf.html', form=form, apikeydata={"end": userconfig._api_key_end, "gen": userconfig._api_key_gentime} if userconfig._api_key_hash else {})
File "/usr/lib/python3/dist-packages/flask/templating.py", line 135, in render_template
context, ctx.app)
File "/usr/lib/python3/dist-packages/flask/templating.py", line 117, in _render
rv = template.render(context)
File "/usr/lib/python3/dist-packages/jinja2/asyncsupport.py", line 76, in render
return original_render(self, *args, **kwargs)
File "/usr/lib/python3/dist-packages/jinja2/environment.py", line 1008, in render
return self.environment.handle_exception(exc_info, True)
File "/usr/lib/python3/dist-packages/jinja2/environment.py", line 780, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python3/dist-packages/jinja2/_compat.py", line 37, in reraise
raise value.with_traceback(tb)
File "/home/pi/konfigurationsanwendung_6/templates/conf.html", line 1, in top-level template code
{% extends "loggedin.html" %}
File "/home/pi/konfigurationsanwendung_6/templates/loggedin.html", line 1, in top-level template code
{% extends "layout.html" %}
File "/home/pi/konfigurationsanwendung_6/templates/layout.html", line 32, in top-level template code
{% block main %}
File "/home/pi/konfigurationsanwendung_6/templates/conf.html", line 7, in block "main"
<img src="{{ url_for('static', filename=config_id + '_matrix.png') }}"/>
jinja2.exceptions.UndefinedError: 'config_id' is undefined
192.168.178.71 - - [22/Jun/2022:18:49:49 +0200] "GET /conf/0 HTTP/1.1" 500 291 "http://192.168.178.98:8008/dashboard" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.124 Safari/537.36 Edg/102.0.1245.44"
Agascha88
User
Beiträge: 23
Registriert: Sonntag 6. März 2022, 21:04

Und einmal mit form.config_id():

192.168.178.71 - - [22/Jun/2022:18:55:10 +0200] "GET /static/css/main.css HTTP/1.1" 304 0 "http://192.168.178.98:8008/dashboard" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.124 Safari/537.36 Edg/102.0.1245.44"
[2022-06-22 18:55:12,246] ERROR in app: Exception on /conf/0 [GET]
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/usr/lib/python3/dist-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/lib/python3/dist-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python3/dist-packages/flask/_compat.py", line 35, in reraise
raise value
File "/usr/lib/python3/dist-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/lib/python3/dist-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/usr/local/lib/python3.7/dist-packages/flask_login/utils.py", line 272, in decorated_view
return func(*args, **kwargs)
File "/home/pi/konfigurationsanwendung_6/main.py", line 190, in conf
return flask.render_template('conf.html', form=form, apikeydata={"end": userconfig._api_key_end, "gen": userconfig._api_key_gentime} if userconfig._api_key_hash else {})
File "/usr/lib/python3/dist-packages/flask/templating.py", line 135, in render_template
context, ctx.app)
File "/usr/lib/python3/dist-packages/flask/templating.py", line 117, in _render
rv = template.render(context)
File "/usr/lib/python3/dist-packages/jinja2/asyncsupport.py", line 76, in render
return original_render(self, *args, **kwargs)
File "/usr/lib/python3/dist-packages/jinja2/environment.py", line 1008, in render
return self.environment.handle_exception(exc_info, True)
File "/usr/lib/python3/dist-packages/jinja2/environment.py", line 780, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python3/dist-packages/jinja2/_compat.py", line 37, in reraise
raise value.with_traceback(tb)
File "/home/pi/konfigurationsanwendung_6/templates/conf.html", line 1, in top-level template code
{% extends "loggedin.html" %}
File "/home/pi/konfigurationsanwendung_6/templates/loggedin.html", line 1, in top-level template code
{% extends "layout.html" %}
File "/home/pi/konfigurationsanwendung_6/templates/layout.html", line 32, in top-level template code
{% block main %}
File "/home/pi/konfigurationsanwendung_6/templates/conf.html", line 7, in block "main"
<img src="{{ url_for('static', filename=form.config_id() + '_matrix.png') }}"/>
jinja2.exceptions.UndefinedError: 'main.ConfForm object' has no attribute 'config_id'
192.168.178.71 - - [22/Jun/2022:18:55:12 +0200] "GET /conf/0 HTTP/1.1" 500 291 "http://192.168.178.98:8008/dashboard" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.124 Safari/537.36 Edg/102.0.1245.44"
Agascha88
User
Beiträge: 23
Registriert: Sonntag 6. März 2022, 21:04

sorry, jetzt hatte ich mich auch noch verschrieben gehabt...
statt public_id habe ich fälschlicherweise config_id geschrieben gehabt....

Darum auch die falschen Logs
Agascha88
User
Beiträge: 23
Registriert: Sonntag 6. März 2022, 21:04

Der Link mit <img src="{{ url_for('static', filename=form.public_id + '_matrix.png') }}"/>

gibt folgende URL zurück:

<img src="/static/%3Cinput%20id%3D%22public_id%22%20name%3D%22public_id%22%20type%3D%22text%22%20value%3D%22123456789%22%3E_matrix.png">

Hier ist 'static' die public_id = '123456789' und '_matrix.png' drin enthalten.

Aber leider auch ganz viele Prozentzeichen und uninteressante Zahlen...
Benutzeravatar
__blackjack__
User
Beiträge: 10537
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Agascha88: Die ganzen ”uninteressanten Zahlen” sollte man mal dekodieren:

Code: Alles auswählen

In [35]: s="/static/%3Cinput%20id%3D%22public_id%22%20name%3D%22public_id%22%20t
    ...: ype%3D%22text%22%20value%3D%22123456789%22%3E_matrix.png"              

In [36]: import urllib.parse                                                    

In [37]: urllib.parse.unquote(s)                                                
Out[37]: '/static/<input id="public_id" name="public_id" type="text" value="123456789">_matrix.png'
`form.public_id` ist halt nicht die ID sondern ein Feld vom Eingabeform. Das hat da so nichts zu suchen. Das Objekt scheint die Addition zu überschreiben, oder Du hast nicht den passenden Code gezeigt.

Du musst halt an den Wert von dem Feld heran. Ich vermute den gibt es als Attribut von dem Feld.
“»So computers are tools of the devil?« thought Newt. He had no problem believing it. Computers had to be the tools of *somebody*, and all he knew for certain was that it definitely wasn't him.” — Neil Gaiman & Terry Pratchett, Good Omens
Benutzeravatar
noisefloor
User
Beiträge: 3343
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: Görgeshausen
Kontaktdaten:

Hallo,

wenn du nur den Wert der public_id willst musst du den auch auslesen. Scheinbar übergibst du ja das komplett Form-Field und nicht nur den Wert. Zeig' doch mal den Code, wo `form` her kommt.

Gruß, noisefloor
Agascha88
User
Beiträge: 23
Registriert: Sonntag 6. März 2022, 21:04

Denke auch, dass ich auf dem Holzweg bin...

Das ist das config.html, wo ich im oberen Bereich das Bild einfügen möchte.
form.public_id befindet sich etwas weiter unten.



{% extends "loggedin.html" %}

{% block main %}


<h3>Konfiguration: {{ form.configname.data or '' }}</h3>
<img src="{{ url_for('static', filename=form.public_id() + '_matrix.png') }}"/>
<form action="" method="post" name="conf">
<fieldset>
<legend>Daten</legend>
{% for field in form if not field.name in ("public_id", "configname", "submit", "delete", "delete_api_key", "create_api_key") %}
{% if field.type not in ('CSRFTokenField') %}
<br/>
{{ field.label() }}
{% endif %}
{{ field() }}
{% if field.description %}
<span class="fielddesc">{{ field.description }}</span>
{% endif %}
{% endfor %}
<br/>
</fieldset>

<fieldset>
<legend>Einstellungen</legend>
<label>Name</label>
{{ form.configname() }}
<br/>
<label>&ouml;ffentliche ID</label>
{{ form.public_id() }}
<span class="fielddesc">falls leer: Zugriff nur &uuml;ber API-Key</span>
<br/>
<br/>
<label>API-Key</label>
{% if apikeydata %}
&hellip;{{ apikeydata.end }}, generiert {{ apikeydata.gen }}
<br/>
{{ form.delete_api_key.label() }}{{ form.delete_api_key() }}
{% else %}
<em>nicht gesetzt</em>
<br/>
{{ form.create_api_key.label() }}{{ form.create_api_key() }}
{% endif %}
</fieldset>

<fieldset>
<legend>Aktionen</legend>
{{ form.submit() }}
{{ form.delete(onclick="return confirm('Sind Sie sich sicher?')") }}
</fieldset>
</form>
{% endblock %}
Benutzeravatar
__blackjack__
User
Beiträge: 10537
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Agascha88: Ah, und da sind sie dann doch die Klammern. Hätte mich auch ein bisschen gewundert wenn Formfeld-Objekt ``+`` Zeichenkette einfach so funktioniert hätte.
“»So computers are tools of the devil?« thought Newt. He had no problem believing it. Computers had to be the tools of *somebody*, and all he knew for certain was that it definitely wasn't him.” — Neil Gaiman & Terry Pratchett, Good Omens
Agascha88
User
Beiträge: 23
Registriert: Sonntag 6. März 2022, 21:04

Danke schön, ihr habt sehr geholfen

Es funktioniert jetzt. Ich habe 'form.public_id.data' benutzt...

Manchmal hilft es halt darüber zu sprechen, um einen Weg zu finden

Schönen Abend
Agascha88
User
Beiträge: 23
Registriert: Sonntag 6. März 2022, 21:04

Hallo zusammen,

ich hoffe, ich nerve nicht zu viel mit meinen Fragen. Es ist auch eher jammern auf hohem Niveau.

Mit dem Aufruf: <img src="{{ url_for('static', filename=form.public_id.data + '_matrix.png') }}"/>
bekomme ich jetzt das zugehörige Statusbild angezeigt. Schön wäre es jetzt noch das Bilddatum/-Zeit neben dem Bild anzuzeigen.
Dann wäre es eindeutiger, ob es sich um ein historisches Statusbild handelt.

Kann man irgendwie das Bilddatum/-Zeit mit anzeigen?

Schönen Abend
Viele Grüße Agascha
Benutzeravatar
noisefloor
User
Beiträge: 3343
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: Görgeshausen
Kontaktdaten:

Hallo,

Gegenfrage: wo willst du denn Bilddatum und -zeit herholen? Ist das in der DB? Den Metadaten des Bildes?

Gruß, noisefloor
Agascha88
User
Beiträge: 23
Registriert: Sonntag 6. März 2022, 21:04

Hallo noisefloor,

idealerweise aus den Metadaten des Bildes.

Gruß
Agascha
Benutzeravatar
noisefloor
User
Beiträge: 3343
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: Görgeshausen
Kontaktdaten:

Hallo,

dann die Metadaten auslesen - dazu gibt es ja Tools auch für Python - und dann halt die Daten an das Template mit übergeben und anzeigen lassen.

Gruß, noisefloor
Antworten