Seite 1 von 1

Couchdb python - Upload Attachment mit put_attachment

Verfasst: Dienstag 5. März 2024, 14:03
von sophe_9
Hallo,

ich versuche an ein bereits existierendes Document ein Bild bzw. Plot als png anzuhängen. Es wird auch angehängt, aber es erscheint folgender Fehler: " Die Grafik kann nicht angezeigt werden, weil sie Fehler enthält".
Ich vermute die Codierung ist fehlerhaft, da auch die Länge in dem Dokument ebenfalls nicht korrekt ist.

Wenn ich das Bild direkt über Futon anhänge sieht der Anhang folgendermaßen aus:

"_attachments": {
"Scan.png": {
"content_type": "image/png",
"revpos": 35,
"digest": "md5-t20y23eHOJOMDAwCcrTjOw==",
"length": 199281,
"stub": true
}
}

Über Python ist "length": 8

Wie kann ich das korrigieren?

Code: Alles auswählen

import couchdb 
couch = couchdb.Server('http://a73657.berlin.de:5984')
db = couch['vl'] # existing

json_file = "test_file"

doc = db.get(json_file) 


db.put_attachment(doc, 'Scan.png', 'Scan.png', content_type="image/png;base64")

Re: Couchdb python - Upload Attachment mit put_attachment

Verfasst: Dienstag 5. März 2024, 14:53
von __deets__
Also ohne da jetzt tiefer eingestiegen zu sein: wo uebergibst du denn die Bilddaten, und wer kodiert die base64? Ich sehe zweimal den Dateinamen, der dann auch noch zufaellig 8 Zeichen lang ist. Einer davon muss doch garantiert die Bilddaten sein. Wahlweise raw, oder als base64-enkodierte Daten.

Re: Couchdb python - Upload Attachment mit put_attachment

Verfasst: Dienstag 5. März 2024, 15:58
von sophe_9
Danke für die Antwort,
ich habe bei den Beschreibungen " put_attachment(doc, content, filename=None, content_type=None)" gefunden, mit einer Textdatei hat es wunderbar funktioniert. Nur pdfs oder images sind ein Problem.

Wahrscheinlich ist mein Ansatz falsch, wahrscheinlich muss ich den Plot laden, codieren und dann anhängen??

Hier das Beispiel, dass funktioniert:

Code: Alles auswählen

from matplotlib import pyplot as plt
import couchdb 
couch = couchdb.Server('http://a73434.berlin.ptb.de:5984')
db = couch['vl_db'] # existing

json_file = "cal_test"

doc = db.get(json_file) 


with open('test.txt','r') as fp:
    datatxt = fp.read()
    print(datatxt)
    
db.put_attachment(doc, datatxt, "datatxt.txt" , content_type="text/plain")
Hier ist mein Plot - Beispiel, dass nicht funktioniert:

Code: Alles auswählen

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import couchdb 
couch = couchdb.Server('http://a73434.berlin.ptb.de:5984')
db = couch['vl_db'] # existing
json_file = "cal_test"
doc = db.get(json_file) 


img = mpimg.imread('Scan.png')
imgplot = plt.imshow(img)
plt.show()


db.put_attachment(doc, img, "scan_plot.png" , content_type="image/png")

Jetzt erhalte ich diesen Fehler:

TypeError: Object of type ndarray is not JSON serializable

Re: Couchdb python - Upload Attachment mit put_attachment

Verfasst: Dienstag 5. März 2024, 16:09
von __deets__
Also ich weiss nicht, was du bei der Textdatei gemacht hast. Aber content ist der Inhalt, nicht der Name der Datei, die den Inhalt enthaelt. So wuerde ich das jedenfalls sehen. Und die Hypothese wird ja auch von der Dateilaenge "8" gestuetzt, die ja nun genau die Laenge des Namens, nicht des Inhaltes, ist.

Und statt numpy solltest du das PNG einfach als Bytes einlesen, und uebergeben, oder eben noch base64 enkodieren.

Code: Alles auswählen

content = pathlib.Path("pfad-zum-png").read_bytes()  # ggf noch durch base64 jagen.
Diese ganzen relativen Pfade (cal_test, scan_plot.png) werden dir auch irgendwann mal auf die Fuesse fallen, sowas sollte als Argumente uebergeben oder relativ zum Skript mit __file__ aufgeloest werden.

Re: Couchdb python - Upload Attachment mit put_attachment

Verfasst: Dienstag 5. März 2024, 16:48
von sophe_9
So ganz habe ich es noch nicht verstanden.
content ist der Inhalt, den ich anhängen möchte. In meinem Fall "img".

Es funktioniert leider noch nicht.

Code: Alles auswählen

with open("Scan.png", "rb") as img_file:
    img = base64.b64encode(img_file.read())
img = img.decode('utf-8')

db.put_attachment(doc, img, "scan_plot.png" , content_type="image/png")


Re: Couchdb python - Upload Attachment mit put_attachment

Verfasst: Dienstag 5. März 2024, 16:49
von __deets__
Was heisst "funktioniert nicht"? Und warum hast du hier das base64 im content_type entfernt, aber enkodierst damit?

Re: Couchdb python - Upload Attachment mit put_attachment

Verfasst: Dienstag 5. März 2024, 16:56
von sophe_9
Auch damit habe ich keinen Erfolg.

Code: Alles auswählen

db.put_attachment(doc, img, "scan_plot.png", content_type="image/png;base64")

Re: Couchdb python - Upload Attachment mit put_attachment

Verfasst: Dienstag 5. März 2024, 16:59
von sparrow
@sophe9: was heißt denn kein Erfolg?
Fehlermeldung? Hinweise? Woran machst du fest, dass es nicht geht?

Warum enkodierst du den Inhalt der Datei, nur um sie abschließend wieder zu dekorieren?

Re: Couchdb python - Upload Attachment mit put_attachment

Verfasst: Dienstag 5. März 2024, 17:18
von __deets__
@sparrow: das wird sein um aus Bytes einen String zu machen. Schadet denke ich eher nicht.

Re: Couchdb python - Upload Attachment mit put_attachment

Verfasst: Dienstag 5. März 2024, 17:20
von sophe_9
Beim Öffnen des Attachments in der CouchDB erhalte ich folgende Fehlermeldung:

" Die Grafik kann nicht angezeigt werden, weil sie Fehler enthält".

Laut Beschreibung von dem Paket "couch-python", sollte es mit "put_attachment(doc, content, filename=None, content_type=None)" funktionieren.


Ich sehe folgendes in der Datenbank: Beide Attachments beziehen sich auf das gleiche Bild.

image1 per Futon, das ist supi -- scan, leider nicht

Code: Alles auswählen

"_attachments": {
    "image1.png": {
      "content_type": "image/png",
      "revpos": 26,
      "digest": "md5-lZl1QyGtwhkLdWtltIo2og==",
      "length": 62890,
      "stub": true
    },
    "scan.png": {
      "content_type": "image/png",
      "revpos": 22,
      "digest": "md5-RU3QV7mPpcr9VjQ2C02B6A==",
      "length": 83976,
      "stub": true
    }
    
    

Re: Couchdb python - Upload Attachment mit put_attachment

Verfasst: Dienstag 5. März 2024, 17:36
von __deets__
Dann wuerde ich mal sagen musst du die base64-enkodierung sein lassen, denn offensichtlich ist das Bild genau die 33% groesser, die man bei einem base64-enkodierten Sack Bytes erwarten wuerde.

Also das Ding loeschen, und in deinem Code oben base64 sowohl als Aufruf als auch als encoding weg.

Re: Couchdb python - Upload Attachment mit put_attachment

Verfasst: Dienstag 5. März 2024, 17:41
von sophe_9

Code: Alles auswählen

img = mpimg.imread('Scan.png')

db.put_attachment(doc, img, "scan.png" , content_type="image/png")
Dann erhalte ich folgenden Fehler:

File ~\AppData\Local\Programs\Python\Python312\Lib\json\encoder.py:180 in default
raise TypeError(f'Object of type {o.__class__.__name__} '

TypeError: Object of type ndarray is not JSON serializable

Re: Couchdb python - Upload Attachment mit put_attachment

Verfasst: Dienstag 5. März 2024, 17:45
von __deets__
Ich wiederhole mich: du sollst nicht numpy benutzen, um dein Bild einzulesen. Gibt es einen Grund, warum den den Code, den ich dir in Beitrag #4 gezeigt habe, nicht verwendest?

Nachtrag: laut https://couchdb-python.readthedocs.io/e ... attachment kannst du sogar einfach nur einen geoeffneten File uebergeben, das wuerde ich machen.

Re: Couchdb python - Upload Attachment mit put_attachment

Verfasst: Mittwoch 6. März 2024, 08:36
von sophe_9
Vielen Dank.

das war die Lösung!

Jetzt habe ich es verstanden, eine base64 Enkodierung ist nicht mehr nötig.

:lol: :lol: :lol: