Enhancement: API Error Logging
Introduced common function to check API responses for errors and log the payload (if any)
This commit is contained in:
parent
e4c1f80364
commit
c1393160ae
1 changed files with 43 additions and 27 deletions
|
@ -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:
|
||||||
|
|
Loading…
Reference in a new issue