improves documentation, tabbing and error handling in APIHandler class

Claude Code helped with autocompletion, the rest is my work
This commit is contained in:
2026-05-08 23:29:54 +02:00
parent 1ef944288e
commit 0102bb282e

View File

@@ -4,7 +4,18 @@ import elabapi_python as elabapi
class APIHandler:
"""
Class to standardize the format of the headers of our http requests.
Class which handles all interactions with the eLabFTW API.
It provides methods to retrieve data from the API and download attachments.
It relies minimally on the elabapi-python library, which is used only for downloading attachments
(since the API doesn't support downloading attachments AFAIK).
Args:
api_key: A valid API key for the eLabFTW instance where the data is stored, with permissions to access the relevant entries.
eLabFTW's API keys are well documented here: https://doc.elabftw.net/docs/usage/api/.
If you don't have an API key and are uncapable of creating one, contact your eLabFTW administrator.
Or RTFM and create one yourself, it's not that hard.
ELABFTW_API_URL: Complete URL of the eLabFTW instance's root for the API endpoints.
In full caps because it won't (shouldn't) be changed much.
"""
# TO-DO: remove static url.
@@ -20,40 +31,54 @@ class APIHandler:
def get_entry_from_elabid(self, elabid, entryType="items"):
"""
Method which returns a resource's raw data (as dictionary) from its elabid and entry type.
Returns raw data (as dictionary) from its elabid and entry type.
Entry type can be either "experiments" or "items".
args:
elabid: elabftw internal id of the selected resource.
entryType: Resource type. Anything other than "experiments" or "items" WILL raise an error.
"""
# TO-DO: validation and error handling on entryType value.
if entryType not in ["experiments", "items"]:
raise Exception(
"You can only download attachments from experiments or items."
)
header = self.header
response = requests.get(
headers=header, url=f"{self.elaburl}/{entryType}/{elabid}", verify=True
)
if response.status_code // 100 in [1, 2, 3]:
entry_data = response.json()
return entry_data
elif response.status_code // 100 == 4:
# Response is 5xx = server error:
if response.status_code // 100 == 5:
raise ConnectionError(
f"There's a problem on the server. Status code: {response.status_code}."
)
# Response is 4xx = client error:
if response.status_code // 100 == 4:
match response.status_code:
case 401 | 403:
# Forbidden or unauthorized:
raise ConnectionError(
f"Invalid API key, authentication method or elabid. Check if an item with ID = {elabid} actually exists."
)
case 404:
# Lapalissian:
raise ConnectionError(
f"404: Not Found. This means there's no resource with this elabid (wrong elabid?) on your eLabFTW (wrong endpoint?)."
)
case 400:
# I genuinely have no idea:
raise ConnectionError(
f"400: Bad Request. This means the API endpoint you tried to reach is invalid. Did you tamper with the source code? If not, contact the developer."
)
case _:
# For some fucking reason, this is the only error I actually get from the API...
raise ConnectionError(
f"HTTP request failed with status code: {response.status_code} (NOTE: 4xx means user's fault)."
)
else:
raise ConnectionError(
f"There's a problem on the server. Status code: {response.status_code}."
)
entry_data = response.json()
return entry_data
def download_attachments_data(self, elabid, entryType="experiments"):
"""
@@ -123,4 +148,3 @@ class APIHandler:
with open(os.path.join(dump_dir, f"exp{elabid}-{file}"), "wb") as f:
f.write(raw_data)
return