Projekt-Cache
Die Project Cache API verwaltet das projektbezogene Laden im Arbeitsspeicher für API-Operationen. Zu verstehen, wann Projekte geladen werden müssen, ist entscheidend für eine effiziente API-Nutzung.
Grundkonzepte
Einheitliche Cache-Architektur
API und UI teilen denselben In-Memory-Cache. Wenn Sie ein Projekt über die API laden, ist es derselbe Cache, den die UI verwendet. Das bedeutet:
- Gemeinsamer Zustand: API-Operationen sehen dieselben Daten wie UI-Nutzer
- Gemeinsame Ergebnisse: Ausführungsergebnisse sind sowohl API als auch UI sichtbar
- Keine Divergenz: API und UI können keine unterschiedlichen Ansichten eines Projekts haben
Betriebskategorien
API-Operationen fallen in drei Kategorien mit unterschiedlichen Caching-Anforderungen:
| Kategorie | Beschreibung | Projektladen erforderlich? | Beispiele |
|---|---|---|---|
| Direkte DB | Nur-Lese-Operationen | Nein | GET-Endpunkte, Mandanten-/Nutzerverwaltung |
| Auto-Load | Änderungsoperationen | Nein (wird automatisch geladen) | POST/PUT/DELETE an Investigations, Notebooks, Blocks |
| Benötigt Laden | Ausführungsoperationen | Ja | Notebook ausführen, Ausführungsergebnisse abrufen |
Auto-Load-Muster (vereinfachter Workflow)
Für die meisten CRUD-Operationen müssen Sie das Projekt nicht explizit laden. Die API lädt das Projekt bei Bedarf automatisch:
# ALTER Workflow (nicht mehr für CRUD benötigt):
# manager.load_project(project_id) # Nicht erforderlich!
# NEUER Workflow - Operation direkt aufrufen:
response = requests.put(
f"{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/notebook/{notebook_id}",
json={"Name": "Aktualisierter Name"},
headers=headers
)
# Projekt wird bei Bedarf automatisch geladen
Wann ein explizites Laden ERFORDERLICH ist
Das explizite Laden eines Projekts ist weiterhin bei Ausführungsoperationen erforderlich:
POST /execution/notebook/{notebookId}- Notebook ausführenGET /execution/notebook/{notebookId}/results- Ausführungsergebnisse abrufenGET /execution/status/{notebookId}- Ausführungsstatus prüfen
Projekt in den Cache laden
GET /api/{tenantId}/project/{projectId}/load
Lädt ein Projekt in den gemeinsamen Cache. Verwenden Sie dies vor der Ausführung von Notebooks.
Pfadparameter
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
tenantId |
GUID | Ja | Mandantenkennung |
projectId |
GUID | Ja | Projektkennung |
Antwort (200 OK)
{
"projectId": "87654321-4321-4321-4321-210987654321",
"projectName": "Purchase Order Analysis",
"tenantName": "acme-corp",
"investigationCount": 5,
"notebookCount": 12,
"datasetCount": 3,
"loadedFromCache": false,
"message": "Project loaded from database"
}
Antwortfelder
| Feld | Typ | Beschreibung |
|---|---|---|
projectId |
GUID | Projektkennung |
projectName |
string | Name des Projekts |
tenantName |
string | Name des Mandanten |
investigationCount |
integer | Anzahl der Investigations |
notebookCount |
integer | Anzahl der Notebooks |
datasetCount |
integer | Anzahl der Datensätze |
loadedFromCache |
boolean | Wahr, wenn bereits im Cache; falsch bei DB-Ladung |
message |
string | Menschlich lesbare Statusmeldung |
Cache-Verhalten
| Szenario | Antwort | Performance |
|---|---|---|
| Erster Aufruf (Cache Miss) | loadedFromCache: false |
~1000ms (Datenbankabfrage) |
| Folgende Aufrufe (Cache Hit) | loadedFromCache: true |
~75ms (13x schneller) |
| Nach 30 Min Inaktivität | Cache läuft ab | Nächster Aufruf lädt neu |
Cache-Eigenschaften
- Dauer: 30 Minuten nach letztem Zugriff
- Auto-Refresh: Jeder API-Aufruf für das Projekt setzt den 30-Minuten-Timer zurück
- Gemeinsam genutzt: Gleiches Cache von UI und API verwendet
- Speicherverwaltung: Automatische Bereinigung bei 90 % Speicherauslastung
Projekt aus dem Cache entladen
DELETE /api/{tenantId}/project/{projectId}/unload
Entfernt ein Projekt aus dem Cache und gibt Speicher frei.
Pfadparameter
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
tenantId |
GUID | Ja | Mandantenkennung |
projectId |
GUID | Ja | Projektkennung |
Antwort (200 OK)
{
"projectId": "87654321-4321-4321-4321-210987654321",
"wasInCache": true,
"message": "Project unloaded from cache successfully"
}
Workflow-Beispiele
Workflow A: CRUD-Operationen (Auto-Load)
Für das Erstellen, Aktualisieren oder Löschen von Investigations, Notebooks oder Blocks:
import requests
headers = {"Authorization": f"Bearer {API_KEY}"}
# Operation direkt aufrufen - Laden nicht erforderlich!
response = requests.post(
f"{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/investigation",
json={"name": "Neue Investigation", "description": "Über API erstellt"},
headers=headers
)
# Projekt wird bei Bedarf automatisch geladen
Workflow B: Notebook-Ausführung (Benötigt Laden)
Für die Ausführung von Notebooks und das Abrufen der Ergebnisse:
import requests
import time
headers = {"Authorization": f"Bearer {API_KEY}"}
# Schritt 1: Projekt laden (für Ausführung ERFORDERLICH)
response = requests.get(
f"{BASE_URL}/api/{TENANT_ID}/project/{PROJECT_ID}/load",
headers=headers
)
print(f"Projekt geladen: {response.json()['projectName']}")
# Schritt 2: Notebook ausführen
response = requests.post(
f"{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/execution/notebook/{NOTEBOOK_ID}",
headers=headers
)
print(f"Ausführung in Warteschlange: {response.json()['status']}")
# Schritt 3: Auf Abschluss warten
while True:
response = requests.get(
f"{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/execution/status/{NOTEBOOK_ID}",
headers=headers
)
status = response.json()
print(f"Status: {status['status']} ({status['progress']}%)")
if status['status'] == 'Completed':
break
time.sleep(2)
# Schritt 4: Ergebnisse abrufen
response = requests.get(
f"{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/execution/notebook/{NOTEBOOK_ID}/results",
headers=headers
)
results = response.json()
# Schritt 5: Projekt entladen (optionale Aufräumaktion)
requests.delete(
f"{BASE_URL}/api/{TENANT_ID}/project/{PROJECT_ID}/unload",
headers=headers
)
Implementierungsbeispiele
cURL
# Projekt in den Cache laden
curl -X GET "https://your-mindzie-instance.com/api/12345678-1234-1234-1234-123456789012/project/87654321-4321-4321-4321-210987654321/load" \
-H "Authorization: Bearer YOUR_API_KEY"
# Projekt aus dem Cache entladen
curl -X DELETE "https://your-mindzie-instance.com/api/12345678-1234-1234-1234-123456789012/project/87654321-4321-4321-4321-210987654321/unload" \
-H "Authorization: Bearer YOUR_API_KEY"
Python
import requests
TENANT_ID = '12345678-1234-1234-1234-123456789012'
BASE_URL = 'https://your-mindzie-instance.com'
class ProjectCacheManager:
def __init__(self, token):
self.headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
self.loaded_projects = set()
def load_project(self, project_id):
"""Lädt ein Projekt in den Cache (erforderlich für Ausführungsoperationen)."""
url = f'{BASE_URL}/api/{TENANT_ID}/project/{project_id}/load'
response = requests.get(url, headers=self.headers)
response.raise_for_status()
result = response.json()
self.loaded_projects.add(project_id)
status = "aus dem Cache" if result['loadedFromCache'] else "aus der Datenbank"
print(f"Projekt '{result['projectName']}' geladen {status}")
return result
def unload_project(self, project_id):
"""Entlädt ein Projekt aus dem Cache."""
url = f'{BASE_URL}/api/{TENANT_ID}/project/{project_id}/unload'
response = requests.delete(url, headers=self.headers)
response.raise_for_status()
self.loaded_projects.discard(project_id)
return response.json()
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
for project_id in list(self.loaded_projects):
self.unload_project(project_id)
# Verwendung mit Kontext-Manager
with ProjectCacheManager('your-api-key') as cache:
result = cache.load_project('87654321-4321-4321-4321-210987654321')
# Notebooks hier ausführen...
# Projekte werden beim Verlassen automatisch entladen
JavaScript/Node.js
const TENANT_ID = '12345678-1234-1234-1234-123456789012';
const BASE_URL = 'https://your-mindzie-instance.com';
class ProjectCacheManager {
constructor(token) {
this.headers = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};
this.loadedProjects = new Set();
}
async loadProject(projectId) {
const url = `${BASE_URL}/api/${TENANT_ID}/project/${projectId}/load`;
const response = await fetch(url, { headers: this.headers });
if (!response.ok) throw new Error(`Fehlgeschlagen: ${response.status}`);
const result = await response.json();
this.loadedProjects.add(projectId);
console.log(`Geladen: ${result.projectName} (aus Cache: ${result.loadedFromCache})`);
return result;
}
async unloadProject(projectId) {
const url = `${BASE_URL}/api/${TENANT_ID}/project/${projectId}/unload`;
const response = await fetch(url, {
method: 'DELETE',
headers: this.headers
});
this.loadedProjects.delete(projectId);
return response.json();
}
async unloadAll() {
await Promise.all(
Array.from(this.loadedProjects).map(id => this.unloadProject(id))
);
}
}
// Nutzung
const cache = new ProjectCacheManager('your-api-key');
try {
await cache.loadProject('87654321-4321-4321-4321-210987654321');
// Notebooks hier ausführen...
} finally {
await cache.unloadAll();
}
Best Practices
- CRUD-Operationen: Laden Sie nicht explizit – lassen Sie Auto-Load das übernehmen
- Ausführungsoperationen: Laden Sie immer zuerst das Projekt
- Langlaufende Clients: Entladen Sie Projekte nach der Nutzung, um Speicher freizugeben
- Kontext-Manager: Verwenden Sie
with-Anweisungen (Python) oder try/finally für Aufräumaktionen - Speicherbewusstsein: Der Cache bereinigt automatisch bei 90 % Speicherauslastung, aber explizites Entladen ist besser
- Gemeinsamer Cache: Denken Sie daran, dass UI-Nutzer denselben Projektzustand sehen wie Ihre API-Operationen