> ## Documentation Index
> Fetch the complete documentation index at: https://docs.squarecloud.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Listeners

> Erfahre, wie du mit dem Square Cloud Python SDK Listener in deiner Anwendung einsetzt.

Manchmal ist es sehr nützlich, Listener für Anfragen zu haben, mit denen du Funktionen umsetzen kannst, die immer dann aufgerufen werden müssen, wenn in deiner Anwendung "etwas" passiert.

Zu diesem Zweck wurden zwei Arten von Listenern hinzugefügt.

## Capture Listener

Stell dir zum Beispiel vor, dass mein Code jedes Mal, wenn eine Anfrage an die Route '/logs' gestellt wird, eine Aufgabe ausführt, die prüft, ob sich die neuen Logs von den alten unterscheiden. Sehen wir uns an, wie das umgesetzt werden kann:

```python theme={null}
import squarecloud as square
from squarecloud import Endpoint

@app.capture(endpoint=Endpoint.logs())
async def on_logs_request(before, after):
    if after != before:
        print(f'New logs!!! {after}')

async def main():
    client = square.Client('your api key')
    app = await client.app('application_id')

    await app.logs()  # True
    await app.logs()  # False
```

Wie oben zu sehen, wird eine Funktion, auf die der Decorator app.capture angewendet wird, jedes Mal aufgerufen, wenn eine Anfrage an den im Decorator angegebenen Endpoint gestellt wird. Die akzeptierten Endpoints sind `APP_STATUS`, `LOGS` oder `BACKUP`. Diese Funktion sollte zwei Parameter annehmen:

* `before` (repräsentiert den Zustand vor der Anfrage)
* `after` (repräsentiert den Zustand nach der Anfrage)

Der von `before` und `after` zurückgegebene Datentyp hängt davon ab, auf welchen Endpoint der Listener "hört". Handelt es sich um die Route **APP\_STATUS**, erhält er `StatusData`, **LOGS** erhält `LogsData` und **BACKUP** erhält `BackupData`.

Wie du im Beispiel oben vielleicht bemerkt hast, gibt beim ersten Vergleich der Logs `after != before` True zurück. Das passiert genau deshalb, weil after gleich `LogsData(logs='')` ist, da intern noch nichts im Cache gespeichert wurde.

<Accordion title="Zusätzliche Informationen zu diesem Decorator">
  * Wenn du discord.py oder einen Fork davon verwendest (was du wahrscheinlich tust), weißt du,
    dass Events durch den Namen
    der Funktionen unterschieden werden, die der Decorator umschließt, aber hier ist das anders. Um zu wissen,
    auf welche
    API-Route der Decorator "hören" muss, verwenden wir den Parameter `endpopint`, der
    eine `Endpoint`-Klasse erhält, sodass der Name der Funktion, die der Decorator
    umschließt, dir überlassen bleibt.
  * Die Funktion, die der Decorator umschließt, kann tatsächlich alles sein, was
    aufrufbar ist. Das umfasst reguläre Funktionen, Coroutinen und sogar
    Klassen (`__init__` wird aufgerufen).
  * Wenn der Endpoint kein \[Endpoint.app\_status()], \[Endpoint.logs()] oder \[Endpoint.backup()] ist,
    wird nur ein `response`-Parameter (vom Typ `squarecloud.http.Response`)
    zurückgegeben.
</Accordion>

<Tip>
  Du kannst den Parameter `avoid_listener=True` verwenden, damit der Listener der Anwendung nicht aufgerufen wird.
</Tip>

## Request Listener

Die "Request Listener" machen im Grunde dasselbe. Aber hier verwendest du den \[Client], und der Rückgabewert aller Endpoints sind `squarecloud.http.Response`-Objekte.

```python theme={null}
import squarecloud as square
from squarecloud import Endpoint

@client.on_request(endpoint=Endpoint.logs())
async def on_logs_request(response):
    print(1, response)

async def main():
    client = square.Client('your api key')
    await client.get_logs(app_id='application_id')  # 1, Response(success)
```

## Zusätzliche Argumente übergeben

Du kannst an einige Methoden ein Schlüsselwortargument namens `extra` übergeben, das dann an deinen Listener weitergereicht wird

```python theme={null}
import squarecloud as square
from squarecloud import Endpoint

@client.on_request(Endpoint.status())
async def get_extra_param(before, after, extra: dict[str, str]):
    print(extra)

async def main():
    client = square.Client('your api key')
    await client.app_status('application_id', extra={'name': 'robertinho'})
```

<Tip>Du kannst in Listenern einige nützliche Funktionen nutzen, indem du pydantic in deinem Projekt einsetzt, wirf einen Blick auf [pydantic verwenden](./using_pydantic)</Tip>
