1
0
Fork 0

Enhancement: API Error Logging

Introduced common function to check API responses for errors and log the payload (if any)
This commit is contained in:
Salvoxia 2024-09-28 12:16:41 +02:00
parent e4c1f80364
commit c1393160ae

View file

@ -303,7 +303,7 @@ def fetchServerVersion() -> dict:
# Any other errors mean communication error with API # Any other errors mean communication error with API
else: else:
logging.error("Communication with Immich API failed! Make sure the passed API URL is correct!") logging.error("Communication with Immich API failed! Make sure the passed API URL is correct!")
r.raise_for_status() checkApiResponse(r)
return version return version
@ -368,7 +368,7 @@ def fetchAssetsWithOptions(searchOptions: dict) -> list:
page += 1 page += 1
body['page'] = page body['page'] = page
r = requests.post(root_url+'search/metadata', json=body, **requests_kwargs) r = requests.post(root_url+'search/metadata', json=body, **requests_kwargs)
assert r.status_code == 200 checkApiResponse(r)
responseJson = r.json() responseJson = r.json()
assetsReceived = responseJson['assets']['items'] assetsReceived = responseJson['assets']['items']
logging.debug("Received %s assets with chunk %s", len(assetsReceived), page) logging.debug("Received %s assets with chunk %s", len(assetsReceived), page)
@ -382,7 +382,7 @@ def fetchAlbums():
apiEndpoint = 'albums' apiEndpoint = 'albums'
r = requests.get(root_url+apiEndpoint, **requests_kwargs) r = requests.get(root_url+apiEndpoint, **requests_kwargs)
r.raise_for_status() checkApiResponse(r)
return r.json() return r.json()
def fetchAlbumAssets(albumId: str): def fetchAlbumAssets(albumId: str):
@ -399,7 +399,7 @@ def fetchAlbumAssets(albumId: str):
apiEndpoint = f'albums/{albumId}' apiEndpoint = f'albums/{albumId}'
r = requests.get(root_url+apiEndpoint, **requests_kwargs) r = requests.get(root_url+apiEndpoint, **requests_kwargs)
r.raise_for_status() checkApiResponse(r)
return r.json()["assets"] return r.json()["assets"]
def deleteAlbum(album: dict): def deleteAlbum(album: dict):
@ -423,11 +423,12 @@ def deleteAlbum(album: dict):
logging.debug("Album ID = %s, Album Name = %s", album['id'], album['albumName']) logging.debug("Album ID = %s, Album Name = %s", album['id'], album['albumName'])
r = requests.delete(root_url+apiEndpoint+'/'+album['id'], **requests_kwargs) r = requests.delete(root_url+apiEndpoint+'/'+album['id'], **requests_kwargs)
if r.status_code not in [200, 201]: try:
checkApiResponse(r)
return True
except:
logging.error("Error deleting album %s: %s", album['albumName'], r.reason) logging.error("Error deleting album %s: %s", album['albumName'], r.reason)
return False return False
return True
def createAlbum(albumName: str, albumOrder: str) -> str: def createAlbum(albumName: str, albumOrder: str) -> str:
""" """
@ -457,7 +458,7 @@ def createAlbum(albumName: str, albumOrder: str) -> str:
'description': albumName 'description': albumName
} }
r = requests.post(root_url+apiEndpoint, json=data, **requests_kwargs) r = requests.post(root_url+apiEndpoint, json=data, **requests_kwargs)
assert r.status_code in [200, 201] checkApiResponse(r)
albumId = r.json()['id'] albumId = r.json()['id']
@ -466,7 +467,7 @@ def createAlbum(albumName: str, albumOrder: str) -> str:
'order': albumOrder 'order': albumOrder
} }
r = requests.patch(root_url+apiEndpoint+f'/{albumId}', json=data, **requests_kwargs) r = requests.patch(root_url+apiEndpoint+f'/{albumId}', json=data, **requests_kwargs)
assert r.status_code in [200, 201] checkApiResponse(r)
return albumId return albumId
@ -542,12 +543,7 @@ def addAssetsToAlbum(albumId: str, assets: list[str]) -> list[str]:
for assets_chunk in assets_chunked: for assets_chunk in assets_chunked:
data = {'ids':assets_chunk} data = {'ids':assets_chunk}
r = requests.put(root_url+apiEndpoint+f'/{albumId}/assets', json=data, **requests_kwargs) r = requests.put(root_url+apiEndpoint+f'/{albumId}/assets', json=data, **requests_kwargs)
if r.status_code not in [200, 201]: checkApiResponse(r)
print(album)
print(r.json())
print(data)
continue
assert r.status_code in [200, 201]
response = r.json() response = r.json()
cpt = 0 cpt = 0
@ -569,7 +565,7 @@ def fetchUsers():
apiEndpoint = 'users' apiEndpoint = 'users'
r = requests.get(root_url+apiEndpoint, **requests_kwargs) r = requests.get(root_url+apiEndpoint, **requests_kwargs)
assert r.status_code in [200, 201] checkApiResponse(r)
return r.json() return r.json()
def shareAlbumWithUserAndRole(album_id: str, share_user_ids: list[str], share_role: str): def shareAlbumWithUserAndRole(album_id: str, share_user_ids: list[str], share_role: str):
@ -608,7 +604,7 @@ def shareAlbumWithUserAndRole(album_id: str, share_user_ids: list[str], share_ro
'albumUsers': album_users 'albumUsers': album_users
} }
r = requests.put(root_url+apiEndpoint, json=data, **requests_kwargs) r = requests.put(root_url+apiEndpoint, json=data, **requests_kwargs)
assert r.status_code in [200, 201] checkApiResponse(r)
def fetchLibraries(): def fetchLibraries():
"""Queries and returns all libraries""" """Queries and returns all libraries"""
@ -616,10 +612,7 @@ def fetchLibraries():
apiEndpoint = 'libraries' apiEndpoint = 'libraries'
r = requests.get(root_url+apiEndpoint, **requests_kwargs) r = requests.get(root_url+apiEndpoint, **requests_kwargs)
if r.status_code == 403: checkApiResponse(r)
logging.fatal("--sync-mode 2 requires an Admin User API key!")
else:
assert r.status_code in [200, 201]
return r.json() return r.json()
def triggerOfflineAssetRemoval(libraryId: str): def triggerOfflineAssetRemoval(libraryId: str):
@ -641,7 +634,7 @@ def triggerOfflineAssetRemoval(libraryId: str):
if r.status_code == 403: if r.status_code == 403:
logging.fatal("--sync-mode 2 requires an Admin User API key!") logging.fatal("--sync-mode 2 requires an Admin User API key!")
else: else:
assert r.status_code == 204 checkApiResponse(r)
def setAlbumThumbnail(albumId: str, assetId: str): def setAlbumThumbnail(albumId: str, assetId: str):
""" """
@ -663,7 +656,7 @@ def setAlbumThumbnail(albumId: str, assetId: str):
data = {"albumThumbnailAssetId": assetId} data = {"albumThumbnailAssetId": assetId}
r = requests.patch(root_url+apiEndpoint, json=data, **requests_kwargs) r = requests.patch(root_url+apiEndpoint, json=data, **requests_kwargs)
r.raise_for_status() checkApiResponse(r)
def setAssetsArchived(assetIds: list[str], isArchived: bool): def setAssetsArchived(assetIds: list[str], isArchived: bool):
""" """
@ -688,9 +681,32 @@ def setAssetsArchived(assetIds: list[str], isArchived: bool):
} }
r = requests.put(root_url+apiEndpoint, json=data, **requests_kwargs) r = requests.put(root_url+apiEndpoint, json=data, **requests_kwargs)
if r.status_code != 204: checkApiResponse(r)
logging.error("Error setting assets archived: %s", r.json())
r.raise_for_status() def checkApiResponse(response: requests.Response):
"""
Checks the HTTP return code for the privided response and
logs any errors before raising an HTTPException
Parameters
----------
respsone : requests.Response
A list of asset IDs to archive
isArchived : bool
Flag indicating whether to archive or unarchive the passed assets
Raises
----------
HTTPException if the API call fails
"""
try:
response.raise_for_status()
except:
if response.json():
logging.error("Error in API call: %s", response.json())
else:
logging.error("API respsonse did not contain a payload")
response.raise_for_status()
if insecure: if insecure: