= digest()
:description: Gibt den kryptografischen Digest (Hash) eines ECM-Dokumentobjekts zurück (std.GetDocumentDigest). Wird für Integritätsprüfungen und Duplikaterkennung verwendet.
:keywords: digest, GetDocumentDigest, Hash, Integritätsprüfung, Duplikaterkennung, Dokument
:page-tags: api, dms

Gibt den Digest eines Dokumentobjekts über `std.GetDocumentDigest` zurück.

Standardmäßig (`calculate=False`) wird der in der Datenbank gespeicherte Digest
zurückgegeben. Bei `calculate=True` berechnet der Server einen frischen Digest
aus den tatsächlichen Dokumentdateien und gibt sowohl den gespeicherten als auch
den berechneten Digest zurück, was eine Integritätsprüfung ermöglicht.

== Signatur

[tabs]
====
Sync::
+
[source,python]
----
ecm.dms.digest(
    model: ECMDocumentModel | int,
    object_type_id: int | None = None,
    *,
    calculate: bool = False,
) -> ECMDocumentDigest
----

Async::
+
[source,python]
----
await ecm.dms.digest(
    model: ECMDocumentModel | int,
    object_type_id: int | None = None,
    *,
    calculate: bool = False,
) -> ECMDocumentDigest
----
====

== Parameter

[cols="1,1,1,3"]
|===
|Parameter |Typ |Standard |Beschreibung

|`model`
|`ECMDocumentModel \| int`
|—
|Entweder eine `ECMDocumentModel`-Instanz (deren `id` wird verwendet) oder eine numerische Dokument-Objekt-ID.

|`object_type_id`
|`int \| None`
|`None`
|Die numerische Objekttyp-ID. Wenn `None`, wird der Typ automatisch über `get_object_type_by_id()` ermittelt. Durch Angabe wird ein zusätzlicher Server-Roundtrip vermieden.

|`calculate`
|`bool`
|`False`
|Bei `True` berechnet der Server den Digest aus den tatsächlichen Dokumentdateien und gibt zusätzlich `local_digest` zurück. Bei `False` wird nur der gespeicherte Datenbankdigest zurückgegeben.
|===

== Rückgabewert

Eine `ECMDocumentDigest`-Instanz.

=== Felder von ECMDocumentDigest

[cols="1,1,3"]
|===
|Feld |Typ |Beschreibung

|`table_digest`
|`str`
|Der in der Datenbank gespeicherte Digest-Wert. Immer vorhanden.

|`local_digest`
|`str \| None`
|Der frisch berechnete Digest aus den tatsächlichen Dateien. Nur gesetzt bei `calculate=True`, sonst `None`.
|===

== Ausnahmen

[cols="1,3"]
|===
|Ausnahme |Bedingung

|`ValueError`
|`model` ist eine `ECMDocumentModel`-Instanz mit `id` gleich `None`.

|`ECMNotFoundException`
|`object_type_id` ist `None` und kein Objekt mit der angegebenen ID existiert auf dem Server.
|===

== Beispiele

=== Gespeicherten Digest lesen

[tabs]
====
Sync::
+
[source,python]
----
doc = ecm.dms.select(RechnungsDokument).where(RechnungsDokument.Titel == "Rechnung").execute()[0]
result = ecm.dms.digest(doc)
print(result.table_digest)
----

Async::
+
[source,python]
----
doc = (await ecm.dms.select(RechnungsDokument).where(RechnungsDokument.Titel == "Rechnung").execute())[0]
result = await ecm.dms.digest(doc)
print(result.table_digest)
----
====

=== Integrität prüfen: gespeicherten mit berechnetem Digest vergleichen

[tabs]
====
Sync::
+
[source,python]
----
result = ecm.dms.digest(doc, calculate=True)
if result.table_digest == result.local_digest:
    print("Integrität OK")
else:
    print(f"Abweichung! gespeichert={result.table_digest} berechnet={result.local_digest}")
----

Async::
+
[source,python]
----
result = await ecm.dms.digest(doc, calculate=True)
if result.table_digest == result.local_digest:
    print("Integrität OK")
else:
    print(f"Abweichung! gespeichert={result.table_digest} berechnet={result.local_digest}")
----
====

=== Mit numerischer Objekt-ID verwenden

[tabs]
====
Sync::
+
[source,python]
----
# object_type_id angeben, um einen zusätzlichen Server-Roundtrip zu vermeiden
result = ecm.dms.digest(12345, object_type_id=327685)
print(result.table_digest)
----

Async::
+
[source,python]
----
result = await ecm.dms.digest(12345, object_type_id=327685)
print(result.table_digest)
----
====

== Siehe auch

* xref:api/dms/files.adoc[files()] — Dateien eines Dokuments herunterladen
* xref:api/dms/get_object_type_by_id.adoc[get_object_type_by_id()] — Typ-ID eines Objekts ermitteln
