# Developer-Guide für File-Manager

Diese Anleitung richtet sich an Entwickler und soll aufzeigen wie mit den NNH-APIs für File-Manager gearbeitet werden
kann. Dieser Anleitung sind mehrere Python-Skripts mit Beispielen beigelegt, um die Abläufe der APIs zu präsentieren.
Dazu ist auch die OpenAPI-Spezifikation von REOD enthalten, die daraus generierten Clients und Skripte für die
Authentifizierung. Für die Shell-Snippets in dieser Anleitung wird angenommen, das Bash in Version 5 verwendet wird.

## Übersicht

Die Beispiele kommen alle in Form von Python-Skripten mit dem Präfix `example_`. Die zwei Python-Module
`authorization_code_client` und `client_credentials_client` dienen dabei sowohl als Beispiel für den
Authorization-Code-Flow bzw. den Client-Credentials-Flow als auch als Bibliothek.

## Vorbereitung

Die Beispiele wurden für Python 3.12 geschrieben. Wir empfehlen eine virtuelle Umgebung einzurichten:

```shell
python3.12 -m venv --prompt nnh-dev-guide .venv
source .venv/bin/activate
pip install -r requirements.txt
```

### Einrichtung der Applikation

Über https://portal.nnh-holding.ch können neue Applikationen eingerichtet werden. Für die Verwendung der File-Managers
muss das REOD-Produkt ausgewählt werden. Für REOD ist ein Abonnement erforderlich, also muss es zusätzlich im Profil
abonniert werden. Für die Authorization-Code-Flow-Authetifizierung muss http://localhost:8000/callback als Callback in
der App hinterlegt werden.

### Freigabe

Beim File-Manager handelt es sich um ein API-Produkt, welches zwingend mit einem Benutzerkonto verwendet werden muss.
Dazu muss die Applikation nach der Erstellung durch NNH freigegeben und mit einem Systemaccount oder einem Identity
Provider verbunden werden.

### Umgebungsvariablen

Über das Portal kann Client-Key und -Secret abgerufen werden. Für den Authorization-Code-Flow wird nur der Key benötigt.
Die Beispiele erwarten diese Angaben in Form der Umgebungsvariablen `CLIENT_ID` und `CLIENT_SECRET`. Zusätzlich wird die
`BASE_URL` benötigt. Diese Angaben sollten in eine `.env`-Datei eingetragen werden, als Vorbild kann `.env.template`
verwendet werden:

```dotenv
export BASE_URL='https://api.nnh-holding.ch'
export CLIENT_ID=
export CLIENT_SECRET=
```

Die Datei sollte nicht verschickt und auch nicht in ein Versionskontrollsystem eingepflegt werden! Die Einstellungen
werden in allen Beispielen mittels `load_env()` geladen.

### Authentifizierung

Alle Beispiele sind für den Authorization Code Flow geschrieben, bei denen sich ein Benutzer via seinem Identity
Provider
authentifiziert. Als Alternative steht aber auch der Client-Credential-Flow zur Verfügung, bei denen sich ein System
über das Client Secret als Systembenutzer authentifiziert. Um statt dem Authorization-Code-Flow der
Client-Credential-Flow zu verwenden, muss die Authentifizierung wie folgt geändert werden:

```python
from client_credentials_client import client_credentials_flow

auth_response = client_credentials_flow()
```

Der Rest des Beispiels bleibt gleich.

### OpenAPI-Clients

Dieses Paket enthält generierte Clients damit die Beispiele direkt ausgeführt werden können. Sie wurden mit folgenden
Befehlen erstellt:

```shell
openapi-python-client generate --path reod-all.yaml --overwrite --output-path reod
openapi-python-client generate --path openapi-energyclass-v1.yaml --overwrite --output-path energyclass
```

## Beispiele

### Authentifizierung

Der für die Authentifizierung nach Authorization Code oder Client Credentials nötige Code kann in den Dateien
`authorization_code_client.py` und `client_credentials_client.py` eingesehen werden. Die kurzen Beispiele
[example_get_token_authorization_code.py](example_get_token_authorization_code.py) bzw.
[example_get_token_client_credentials.py](example_get_token_client_credentials.py)` führen die jeweilige
Authenifizierung durch und geben das resultierende Access Token aus.

### File-Manager

#### Erstellen eines Benutzerkontext

Ein Benutzer kann beliebige Benutzerkontexte anlegen und diese mit anderen Benutzern teilen oder weitergeben. Dateien,
welche in File Manager hochgeladen werden, sind immer an einen Benutzerkontext gekoppelt, auf diese Weise können sie
auch mit anderen Benutzern geteilt werden.

Das Skript [example_list_context.py](./example_create_context.py) erstellt einen neuen Benutzerkontext.

#### Abrufen der Benutzerkontexte / Paging

Ein Benutzer kann beliebige Benutzerkontexte anlegen und diese mit anderen Benutzern teilen oder weitergeben. Dateien,
welche in File Manager hochgeladen werden, sind immer an einen Benutzerkontext gekoppelt, auf diese Weise können sie
auch mit anderen Benutzern geteilt werden.

Das Skript [example_list_context.py](./example_list_context.py) listet alle Benutzerkontexte auf. Es ist zudem ein
Beispiel wie Paging verwendet wird - dabei wird das Token für die nächste Seite jeweils mitgegeben, die Länge der
Seiten wird beim ersten Aufruf definiert.

#### Datei-Upload

Um deine Datei hochzuladen muss zuerst eine Anfrage gestellt werden, in welcher der Name der Datei,
der Benutzer-Kontext und MIME-Type angegeben wird. Aus der Antwort zu dieser Anfrage kann dann die
Upload-URL und die zu verwendenden Header entnommen werden.

Das Skript [example_upload_file.py](./example_upload_file.py) lädt die User-Guide.md-Datei in den
Benutzerkontext, welcher im ersten Beispiel erstellt wurde.

#### Dateien auflisten

Das Skript [example_list_files.py](./example_list_files.py) ruft alle Dateien ab die in den Benutzerkontext aus dem
ersten Beispiel hochgeladen wurde.

### Energieklassen

Dieses API wird ausschliesslich über eine Client-Credenitals-Authentifizierung verwendet.

#### Abruf der Daten eines Gebäudes

Das Skript [example_get_energyclass.py](example_get_energyclass.py) ruft die Energieklasse eines Gebäudes ab.

