diff --git a/src/APIHandler.py b/src/APIHandler.py index 1f3bfa5..ebd1fc8 100644 --- a/src/APIHandler.py +++ b/src/APIHandler.py @@ -23,11 +23,11 @@ class APIHandler: # TO-DO: remove static url. def __init__(self, api_key="", ELABFTW_API_URL=None): """Init method, api_key suggested but not required (empty by default).""" - if not ELABFTW_API_URL: - load_dotenv() - ELABFTW_API_URL = os.getenv("ELABFTW_API_URL") or input( - "Enter a valid eLabFTW API URL (ends with '/api/v2)': " - ) + # if not ELABFTW_API_URL: + # load_dotenv() + # ELABFTW_API_URL = os.getenv("ELABFTW_API_URL") or input( + # "Enter a valid eLabFTW API URL (ends with '/api/v2)': " + # ) self.api_key = api_key self.auth = {"Authorization": api_key} self.content = {"Content-Type": "application/json"} diff --git a/src/classes.py b/src/classes.py index ef5f83c..6288c63 100644 --- a/src/classes.py +++ b/src/classes.py @@ -134,7 +134,7 @@ class Layer: self.start_time = layer_data.get("created_at") or None self.description = layer_data.get("body") or None - def get_instruments(self, api_key): + def get_instruments(self, api_key, ELABFTW_API_URL): """ Retruns a dictionary of all the instruments used to create the layer. The format of the dictionary is: @@ -144,18 +144,20 @@ class Layer: "rheed_system": str } - Arg: api_key: str: 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. + Args: + api_key: str: 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: str: URL for the API root endpoint of the eLabFTW instance. Ends with '/api/v2' - no trailing slash. """ - raw_lasersys_data = APIHandler(api_key).get_entry_from_elabid( + raw_lasersys_data = APIHandler(api_key, ELABFTW_API_URL).get_entry_from_elabid( self.laser_system_elabid, entryType="items" ) - raw_chamber_data = APIHandler(api_key).get_entry_from_elabid( + raw_chamber_data = APIHandler(api_key, ELABFTW_API_URL).get_entry_from_elabid( self.chamber_elabid, entryType="items" ) - raw_rheedsys_data = APIHandler(api_key).get_entry_from_elabid( + raw_rheedsys_data = APIHandler(api_key, ELABFTW_API_URL).get_entry_from_elabid( self.rheed_system_elabid, entryType="items" ) instruments_used = { @@ -248,6 +250,7 @@ class Entrypoint: * linked_experiments_elabid: list: List of eLabFTW internal id's of the experiments linked to the entrypoint. """ try: + self.name = sample_data["title"] self.extra = sample_data["metadata_decoded"]["extra_fields"] self.linked_items = sample_data["items_links"] # dict self.batch_elabid = self.extra["Substrate batch"]["value"] # elabid @@ -262,11 +265,6 @@ class Entrypoint: raise KeyError( f'The provided dictionary lacks a "{k}" key. Check the sample entry on eLabFTW and make sure you used the correct Resource template.' ) - # Non-required attributes: - self.name = ( - sample_data.get("title") or None - ) # error prevention is more important than preventing empty fields here - # although I don't think it's even possible to fuck up this bad... class Material: @@ -310,7 +308,7 @@ class Material: f'The provided dictionary lacks a "{k}" key. Check the target/substrate entry on eLabFTW and make sure you used the correct Resource template.' ) - def get_compound_data(self, apikey): + def get_compound_data(self, apikey, ELABFTW_API_URL): """ Returns a dictionary with the relevant data on the compound of which the material is made. The format of the dictionary is: @@ -320,12 +318,14 @@ class Material: "cas_number": str } - Arg: api_key: str: 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. + Args: + api_key: str: 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: str: URL for the API root endpoint of the eLabFTW instance. Ends with '/api/v2' - no trailing slash. """ - raw_compound_data = APIHandler(apikey).get_entry_from_elabid( + raw_compound_data = APIHandler(apikey, ELABFTW_API_URL).get_entry_from_elabid( self.compound_elabid, entryType="items" ) name = raw_compound_data["title"] @@ -339,8 +339,20 @@ class Material: } return compound_data - def get_compound_formula(self, apikey): - formula = self.get_compound_data(apikey).get("chemical_formula") + def get_compound_formula(self, apikey, ELABFTW_API_URL): + """ + Returns a string with the chemical formula of the compound. + + Args: + api_key: str: 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: str: URL for the API root endpoint of the eLabFTW instance. Ends with '/api/v2' - no trailing slash. + """ + formula = self.get_compound_data(apikey, ELABFTW_API_URL).get( + "chemical_formula" + ) return formula @@ -454,7 +466,8 @@ if __name__ == "__main__": # print(f"Example header:\n\t{head.header}\n") # print("Warning: you're not supposed to be running this as the main program.") api_key = getpass("Paste API key here [no echo]: ") - handler = APIHandler(api_key=api_key) + ELABFTW_API_URL = input("Enter a valid eLabFTW API URL (ends with '/api/v2)': ") + handler = APIHandler(api_key, ELABFTW_API_URL) exp58 = handler.get_entry_from_elabid(elabid=58, entryType="experiments") layer58 = Layer(exp58) print(layer58.list_attachments()) diff --git a/src/main.py b/src/main.py index fe404c2..e447a6b 100755 --- a/src/main.py +++ b/src/main.py @@ -20,7 +20,7 @@ def call_entrypoint_from_elabid(elabid): Arg: elabid: int eLabFTW internal id of the selected resource. """ try: - sample_data = APIHandler(api_key).get_entry_from_elabid( + sample_data = APIHandler(api_key, ELABFTW_API_URL).get_entry_from_elabid( elabid, entryType="items" ) if not sample_data.get("category_title") == "Sample": @@ -44,7 +44,7 @@ def call_material_from_elabid(elabid): arg: elabid: int eLabFTW internal id of the selected resource. """ try: - material_data = APIHandler(api_key).get_entry_from_elabid( + material_data = APIHandler(api_key, ELABFTW_API_URL).get_entry_from_elabid( elabid, entryType="items" ) material_category = material_data.get("category_title") @@ -75,7 +75,7 @@ def call_layers_from_list(elabid_list): list_of_layers = [] for elabid in elabid_list: try: - layer_data = APIHandler(api_key).get_entry_from_elabid( + layer_data = APIHandler(api_key, ELABFTW_API_URL).get_entry_from_elabid( elabid, entryType="experiments" ) if not layer_data.get("category_title") == "PLD Deposition": @@ -106,7 +106,7 @@ def call_proposal_from_elabid(elabid): Arg: elabid: int eLabFTW internal id of the selected resource. """ try: - proposal_data = APIHandler(api_key).get_entry_from_elabid( + proposal_data = APIHandler(api_key, ELABFTW_API_URL).get_entry_from_elabid( elabid, entryType="items" ) proposal_category = proposal_data.get("category_title") @@ -186,7 +186,7 @@ def deduplicate_instruments_from_layers(layers): rheeds = [] elegant_dict = {} for lyr in layers: - instruments = lyr.get_instruments(api_key) + instruments = lyr.get_instruments(api_key, ELABFTW_API_URL) lasers.append(instruments["laser_system"]) chambers.append(instruments["deposition_chamber"]) rheeds.append(instruments["rheed_system"]) @@ -356,7 +356,9 @@ def make_nexus_schema_dictionary(substrate_object, layers): "sample": { "substrate": { "name": substrate_object.name, - "chemical_formula": substrate_object.get_compound_formula(api_key), + "chemical_formula": substrate_object.get_compound_formula( + api_key, ELABFTW_API_URL + ), "orientation": substrate_object.orientation, "miscut_angle": { "value": substrate_object.miscut_angle, @@ -384,7 +386,9 @@ def make_nexus_schema_dictionary(substrate_object, layers): target_object = chain_layer_to_target(layer) target_dict = { "name": target_object.name, - "chemical_formula": target_object.get_compound_formula(api_key), + "chemical_formula": target_object.get_compound_formula( + api_key, ELABFTW_API_URL + ), "description": target_object.description, "shape": target_object.shape, "dimensions": target_object.dimensions, @@ -772,7 +776,7 @@ def build_nexus_file(pld_fabrication, output_path="output/nffa-di_unnamed.h5"): n = layer_dict["layer_number"] rheed_data_file = layer_dict["data"][0] # first in the tuple rheed_image_file = layer_dict["data"][1] # second in the tuple - handler = APIHandler(api_key) + handler = APIHandler(api_key, ELABFTW_API_URL) # TO-DO: maybe make a dedicated function??? data_path = None @@ -877,7 +881,10 @@ if __name__ == "__main__": or input("Enter elabid of your starting sample [default = 1111]: ") or 1111 ) - handler = APIHandler(api_key) + ELABFTW_API_URL = os.getenv("ELABFTW_API_URL") or input( + "Enter a valid eLabFTW API URL (ends with '/api/v2)': " + ) + handler = APIHandler(api_key, ELABFTW_API_URL) data = handler.get_entry_from_elabid(elabid) sample = Entrypoint(data) sample_name = sample.name.strip().replace(