-
Notifications
You must be signed in to change notification settings - Fork 2
Description
I would like to summarize what additional things I found so far in the API system:
GENERIC MODES
The API does not CREATE Generic Modes, and no ID is returned when listing them.
In order to CREATE them you need to use web interface and retrieve their IDs manually.
The API also doesn't support UPDATE, so you need to update them via the web interface as well.
In order to CREATE and UPDATE Generic Modes automatically, I created WEB functions that are doing that using selenium web-driver.
LIST, RETRIEVE, and DESTROY operations work as expected through the API.
However, I also added WEB function for listing GM with their IDs since they are not returned in the table by default.
GENERIC MODE GROUPS
Exactly the same issues as explained above for the GM.
I would add also one addition thing regarding GMG and their creation.
Creating a NEW GMG fails if the INSTRUMENT_TYPE has already been used for the creation of another generic mode group.
This means I can only create a new generic mode group using a "new" or "unused" instrument type.
This was tested also manually trough configDB.
Attached is a screenshot capturing the bug.
MODE TYPES
There is no API function for Mode Types (http://127.0.0.1:7000/admin/hardware/modetype) and I think it would be nice to have this, since for everything else API exists.
Python code
I am sharing my python code including all API and WEB functions that I created and tested locally, and are working well with confingDB on my computer. Maybe someone will find it useful :)
P.S. When I have time to write and test WEB functions for Mode Types I will attached them as well.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Jan 2025
@author: nikola knezevic AOB
"""
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
import json
def list_components(BASE_URL, COMPONENT, filters=None):
"""
Retrieve and list all components with optional filters.
Args:
BASE_URL: Base URL of your ConfigDB.
COMPONENT: Possible ConfigDB component.
filters (dict, optional): Optional query parameters for filtering.
Returns:
list: List of components or error message.
"""
endpoint = f'{BASE_URL}/{COMPONENT}/'
all_components = []
while endpoint:
response = requests.get(endpoint, params=filters)
print(f"Status Code --> [{response.status_code} : {response.reason}]")
if response.status_code == 200:
json_response = response.json()
all_components.extend(json_response['results'])
endpoint = json_response.get('next')
print(f"Total {COMPONENT} retrieved: {len(all_components)}")
return all_components
def get_OE_id(BASE_URL, USERNAME, PASSWORD, oe):
# Set up Chrome options for headless mode
chrome_options = Options()
# Run Chrome in headless mode
chrome_options.add_argument("--headless")
# Prevents rendering issues in older systems
chrome_options.add_argument("--disable-gpu")
# Useful options for containerized environments like Docker
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
# Set up the WebDriver service
driver = webdriver.Chrome(options=chrome_options)
try:
# Open the login page
driver.get(f"{BASE_URL}/admin/login/?next=/admin/")
# Log in
username_field = driver.find_element(By.NAME, 'username')
password_field = driver.find_element(By.NAME, 'password')
username_field.send_keys(USERNAME)
password_field.send_keys(PASSWORD)
login_button = driver.find_element(By.XPATH, '//input[@type="submit"]')
login_button.click()
# Check if login was successful
WebDriverWait(driver, 10).until(EC.title_contains("Site administration"))
# Navigate to the form page and interact with it
driver.get(f"{BASE_URL}/admin/hardware/opticalelement/")
# Locate the rows in the table body
rows = driver.find_elements(By.CSS_SELECTOR, "table#result_list tbody tr")
# Initialize a list to store extracted data
data = []
# Loop through each row and extract required information
for row in rows:
name = row.find_element(By.CSS_SELECTOR, "th.field-name a").text
value = row.find_element(By.CSS_SELECTOR, "td.action-checkbox input").get_attribute("value")
code = row.find_element(By.CSS_SELECTOR, "td.field-code").text
data.append({"name": name, "code": code, "id": value})
oe_id = next((item['id'] for item in data if item['name'] == oe['name'] and item['code'] == oe['code']), None)
driver.quit()
return int(oe_id)
except Exception as e:
print(f"An error occurred: {e}")
driver.quit()
return None
def list_OE_ids(BASE_URL, USERNAME, PASSWORD):
# Set up Chrome options for headless mode
chrome_options = Options()
# Run Chrome in headless mode
chrome_options.add_argument("--headless")
# Prevents rendering issues in older systems
chrome_options.add_argument("--disable-gpu")
# Useful options for containerized environments like Docker
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
# Set up the WebDriver service
driver = webdriver.Chrome(options=chrome_options)
try:
# Open the login page
driver.get(f"{BASE_URL}/admin/login/?next=/admin/")
print("Accessed login page.")
# Log in
username_field = driver.find_element(By.NAME, 'username')
password_field = driver.find_element(By.NAME, 'password')
username_field.send_keys(USERNAME)
password_field.send_keys(PASSWORD)
login_button = driver.find_element(By.XPATH, '//input[@type="submit"]')
login_button.click()
# Check if login was successful
WebDriverWait(driver, 10).until(EC.title_contains("Site administration"))
print("Login successful: OK")
# Navigate to the form page and interact with it
driver.get(f"{BASE_URL}/admin/hardware/opticalelement/")
print("Accessed optical element form.")
# Locate the rows in the table body
rows = driver.find_elements(By.CSS_SELECTOR, "table#result_list tbody tr")
# Initialize a list to store extracted data
data = []
# Loop through each row and extract required information
for row in rows:
name = row.find_element(By.CSS_SELECTOR, "th.field-name a").text
value = row.find_element(By.CSS_SELECTOR, "td.action-checkbox input").get_attribute("value")
code = row.find_element(By.CSS_SELECTOR, "td.field-code").text
data.append({"name": name, "code": code, "id": value})
# Print the extracted data
print ('Optical elements and their IDs:')
for entry in data:
print(entry)
driver.quit()
return data
except Exception as e:
print(f"An error occurred: {e}")
driver.quit()
return data
def list_GM_ids(BASE_URL, USERNAME, PASSWORD):
# Set up Chrome options for headless mode
chrome_options = Options()
# Run Chrome in headless mode
chrome_options.add_argument("--headless")
# Prevents rendering issues in older systems
chrome_options.add_argument("--disable-gpu")
# Useful options for containerized environments like Docker
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
# Set up the WebDriver service
driver = webdriver.Chrome(options=chrome_options)
try:
# Open the login page
driver.get(f"{BASE_URL}/admin/login/?next=/admin/")
print("Accessed login page.")
# Log in
username_field = driver.find_element(By.NAME, 'username')
password_field = driver.find_element(By.NAME, 'password')
username_field.send_keys(USERNAME)
password_field.send_keys(PASSWORD)
login_button = driver.find_element(By.XPATH, '//input[@type="submit"]')
login_button.click()
# Check if login was successful
WebDriverWait(driver, 10).until(EC.title_contains("Site administration"))
print("Login successful: OK")
# Go to Generic Modes page
driver.get(f"{BASE_URL}/admin/hardware/genericmode/")
# Locate the rows in the table body
rows = driver.find_elements(By.XPATH, "//table[@id='result_list']/tbody/tr")
# Initialize a list to store extracted data
data = []
# Loop through each row and extract required information
for row in rows:
# Extract the name (from the <a> tag inside <th class="field-name">)
name_element = row.find_element(By.XPATH, ".//th[@class='field-name']/a")
name = name_element.text
# Extract the ID (from the <input> tag inside <td class="action-checkbox">)
id_element = row.find_element(By.XPATH, ".//td[@class='action-checkbox']/input")
value = id_element.get_attribute("value")
# Extract the code (from the <td class="field-code">)
code_element = row.find_element(By.XPATH, ".//td[@class='field-code']")
code = code_element.text
# Append the extracted data to the list
data.append({"name": name, "code": code, "id": value})
# Print the extracted data
print("Generic Mode elements and their IDs:")
for entry in data:
print(entry)
driver.quit()
return data
except Exception as e:
print(f"An error occurred: {e}")
driver.quit()
return data
def list_GMG_ids(BASE_URL, USERNAME, PASSWORD):
# Set up Chrome options for headless mode
chrome_options = Options()
# Run Chrome in headless mode
chrome_options.add_argument("--headless")
# Prevents rendering issues in older systems
chrome_options.add_argument("--disable-gpu")
# Useful options for containerized environments like Docker
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
# Set up the WebDriver service
driver = webdriver.Chrome(options=chrome_options)
try:
# Open the login page
driver.get(f"{BASE_URL}/admin/login/?next=/admin/")
print("Accessed login page.")
# Log in
username_field = driver.find_element(By.NAME, 'username')
password_field = driver.find_element(By.NAME, 'password')
username_field.send_keys(USERNAME)
password_field.send_keys(PASSWORD)
login_button = driver.find_element(By.XPATH, '//input[@type="submit"]')
login_button.click()
# Check if login was successful
WebDriverWait(driver, 10).until(EC.title_contains("Site administration"))
print("Login successful: OK")
# Go to Generic Modes page
driver.get(f"{BASE_URL}/admin/hardware/genericmodegroup/")
# Locate the rows in the table body
rows = driver.find_elements(By.XPATH, "//table[@id='result_list']/tbody/tr")
# Initialize a list to store extracted data
data = []
# Loop through each row and extract required information
for row in rows:
# Extract the instrument type (from the <a> tag inside <th class="field-instrument_type nowrap">)
instrument_type_element = row.find_element(By.XPATH, ".//th[@class='field-instrument_type nowrap']/a")
instrument_type = instrument_type_element.text
# Extract the type (from the <td class="field-type nowrap">)
type_element = row.find_element(By.XPATH, ".//td[@class='field-type nowrap']")
mode_type = type_element.text
# Extract the default value (from the <td class="field-default nowrap">)
default_element = row.find_element(By.XPATH, ".//td[@class='field-default nowrap']")
default = default_element.text
# Extract the generic mode group (from the <td class="field-__str__">)
generic_mode_group_element = row.find_element(By.XPATH, ".//td[@class='field-__str__']")
generic_mode_group = generic_mode_group_element.text
# Extract the ID (from the <input> tag inside <td class="action-checkbox">)
id_element = row.find_element(By.XPATH, ".//td[@class='action-checkbox']/input")
value = id_element.get_attribute("value")
# Append the extracted data to the list
data.append({
"instrument_type": instrument_type,
"type": mode_type,
"default": default,
"generic_mode_group": generic_mode_group,
"id": value
})
# Print the extracted data
print("Generic Mode Groups and their IDs:")
for entry in data:
print(entry)
driver.quit()
return data
except Exception as e:
print(f"An error occurred: {e}")
driver.quit()
return data
def create_component(BASE_URL, COMPONENT, AUTHORIZATION_TOKEN, component_new):
"""
Create a new component with the provided data.
Args:
BASE_URL: Base URL of your ConfigDB.
COMPONENT: Possible ConfigDB component.
AUTHORIZATION_TOKEN: Authorization token (super-user or local configDB token).
component_new (dict): The JSON payload containing the new component data.
Returns:
dict: Newly created component details or error message.
"""
endpoint = f'{BASE_URL}/{COMPONENT}/'
headers = {"Authorization": f"Token {AUTHORIZATION_TOKEN}"}
response = requests.post(endpoint, data=component_new, headers=headers)
print(f"Status Code --> [{response.status_code} : {response.reason}]")
if response.status_code == 201:
json_response = response.json()
if COMPONENT == 'opticalelements':
oe = {'name': component_new['name'], 'code': component_new['code']}
oe_id = get_OE_id(oe)
print (f"New {COMPONENT[:-1]} with 'id = {oe_id}' was successfully created.")
else:
print (f"New {COMPONENT[:-1]} with 'id = {json_response['id']}' was successfully created.")
return json_response
else:
print (f"Failed to create new {COMPONENT[:-1]}.")
return {}
def login_and_create_OEG(BASE_URL, USERNAME, PASSWORD, oeg_new):
# Set up Chrome options for headless mode
chrome_options = Options()
# Run Chrome in headless mode
chrome_options.add_argument("--headless")
# Prevents rendering issues in older systems
chrome_options.add_argument("--disable-gpu")
# Useful options for containerized environments like Docker
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
# Set up the WebDriver service
driver = webdriver.Chrome(options=chrome_options)
try:
# Open the login page
driver.get(f"{BASE_URL}/admin/login/?next=/admin/")
print("Accessed login page.")
# Log in
username_field = driver.find_element(By.NAME, 'username')
password_field = driver.find_element(By.NAME, 'password')
username_field.send_keys(USERNAME)
password_field.send_keys(PASSWORD)
login_button = driver.find_element(By.XPATH, '//input[@type="submit"]')
login_button.click()
# Check if login was successful
WebDriverWait(driver, 10).until(EC.title_contains("Site administration"))
print("Login successful: OK")
# Navigate to the form page and interact with it
driver.get(f"{BASE_URL}/admin/hardware/opticalelementgroup/add/")
print("Accessed optical element group form.")
# Fill in the fields
#------------------------------------------------------------------------------------------------------------------------
name_field = driver.find_element(By.NAME, 'name')
name_field.send_keys(oeg_new['name'])
#------------------------------------------------------------------------------------------------------------------------
type_field = driver.find_element(By.NAME, 'type')
type_field.send_keys(oeg_new['type'])
#------------------------------------------------------------------------------------------------------------------------
# Select multiple options
optical_elements_field = driver.find_element(By.ID, 'id_optical_elements')
my_list_of_optical_elements = [e['name'] for e in oeg_new['optical_elements']]
for option in optical_elements_field.find_elements(By.TAG_NAME, 'option'):
if option.text in my_list_of_optical_elements:
option.click()
#------------------------------------------------------------------------------------------------------------------------
all_optical_elements_options = [option.text for option in optical_elements_field.find_elements(By.TAG_NAME, 'option')]
non_existing_elements = []
for my_option in my_list_of_optical_elements:
if my_option not in all_optical_elements_options:
print ("Unable to add optical element with the name '" + my_option + "' because it doesn't exist in the configDB.")
non_existing_elements.append(my_option)
#------------------------------------------------------------------------------------------------------------------------
if non_existing_elements == my_list_of_optical_elements:
print ('No optical elements to add to the optical element group. Optical element group will not be created.')
driver.quit()
return None
#------------------------------------------------------------------------------------------------------------------------
overhead_field = driver.find_element(By.NAME, 'element_change_overhead')
# Clear the field first
overhead_field.clear()
# Send the value
overhead_field.send_keys(oeg_new['element_change_overhead'])
#------------------------------------------------------------------------------------------------------------------------
if 'default' in list(oeg_new.keys()):
default_elements_field = driver.find_element(By.ID, 'id_default')
my_default_element = oeg_new['default']['name']
my_list_of_optical_elements_new = [e for e in my_list_of_optical_elements if e not in non_existing_elements]
if my_default_element in my_list_of_optical_elements_new:
for option in default_elements_field.find_elements(By.TAG_NAME, 'option'):
if option.text == my_default_element:
option.click()
break
else:
print ("Unable to set default element with the name '" + my_default_element + "' because it doesn't "\
"exist among the added optical elements ['" + "', '".join(my_list_of_optical_elements_new) + "'] for this group.")
#------------------------------------------------------------------------------------------------------------------------
# Submit the form
save_button = driver.find_element(By.NAME, '_save')
save_button.click()
#------------------------------------------------------------------------------------------------------------------------
# Check if the group was added successfully
success_message = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'success')))
if success_message:
print("Optical element group added successfully: OK")
#------------------------------------------------------------------------------------------------------------------------
# Go to Optical Element Groups page and return ID of the newly created group
driver.get(f"{BASE_URL}/admin/hardware/opticalelementgroup/")
# Initialize lists to store the IDs
ids = []
# Find all rows in the table body
rows = driver.find_elements(By.XPATH, "//table[@id='result_list']/tbody/tr")
# Loop through each row and extract ID
for row in rows:
# Extract the ID (from the <a> tag inside <th class="field-id">)
id_element = row.find_element(By.XPATH, ".//th[@class='field-id']/a")
ids.append(int(id_element.text))
# Get group ID
sorted_ids = sorted(ids)
new_group_id = sorted_ids[-1]
print (f"New opticalelementgroup with 'id = {new_group_id}' was successfully created.")
driver.quit()
return new_group_id
except Exception as e:
print(f"An error occurred: {e}")
driver.quit()
return None
def login_and_create_GM(BASE_URL, USERNAME, PASSWORD, new_gm):
# Set up Chrome options for headless mode
chrome_options = Options()
# Run Chrome in headless mode
chrome_options.add_argument("--headless")
# Prevents rendering issues in older systems
chrome_options.add_argument("--disable-gpu")
# Useful options for containerized environments like Docker
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
# Set up the WebDriver service
driver = webdriver.Chrome(options=chrome_options)
try:
# Open the login page
driver.get(f"{BASE_URL}/admin/login/?next=/admin/")
print("Accessed login page.")
# Log in
username_field = driver.find_element(By.NAME, 'username')
password_field = driver.find_element(By.NAME, 'password')
username_field.send_keys(USERNAME)
password_field.send_keys(PASSWORD)
login_button = driver.find_element(By.XPATH, '//input[@type="submit"]')
login_button.click()
# Check if login was successful
WebDriverWait(driver, 10).until(EC.title_contains("Site administration"))
print("Login successful: OK")
# Navigate to the form page and interact with it
driver.get(f"{BASE_URL}/admin/hardware/genericmode/add/")
print("Accessed generic mode form.")
# Fill in the fields
#------------------------------------------------------------------------------------------------------------------------
name_field = driver.find_element(By.ID, 'id_name')
name_field.send_keys(new_gm['name'])
#------------------------------------------------------------------------------------------------------------------------
code_field = driver.find_element(By.ID, 'id_code')
code_field.send_keys(new_gm['code'])
#------------------------------------------------------------------------------------------------------------------------
overhead_field = driver.find_element(By.ID, 'id_overhead')
# Clear the field first
overhead_field.clear()
# Send the value
overhead_field.send_keys(new_gm['overhead'])
#------------------------------------------------------------------------------------------------------------------------
# Locate the checkbox element
checkbox = driver.find_element(By.ID, 'id_schedulable')
# Check if the checkbox is already in the desired state
checkbox_state = new_gm['schedulable']
if checkbox_state != checkbox.is_selected():
checkbox.click()
#------------------------------------------------------------------------------------------------------------------------
# Locate the validation schema element
validation_schema = driver.find_element(By.ID, "id_validation_schema")
# Convert the dictionary to a JSON string
json_string = json.dumps(new_gm['validation_schema'])
# Clear the existing content in the validation schema element
validation_schema.clear()
# Send the JSON string to the validation schema element
validation_schema.send_keys(json_string)
#------------------------------------------------------------------------------------------------------------------------
# Submit the form
save_button = driver.find_element(By.NAME, '_save')
save_button.click()
#------------------------------------------------------------------------------------------------------------------------
# Check if the element was added successfully
success_message = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'success')))
if success_message:
print("Generic mode element added successfully: OK")
#------------------------------------------------------------------------------------------------------------------------
# Go to Optical Element Groups page and return ID of the newly created group
driver.get(f"{BASE_URL}/admin/hardware/genericmode/")
# Initialize lists to store extracted IDs
ids = []
# Find all rows in the table body
rows = driver.find_elements(By.XPATH, "//table[@id='result_list']/tbody/tr")
# Loop through each row and extract ID
for row in rows:
# Extract the ID (from the <input> tag inside <td class="action-checkbox">)
id_element = row.find_element(By.XPATH, ".//td[@class='action-checkbox']/input")
ids.append(int(id_element.get_attribute("value")))
# Get generic mode ID
sorted_ids = sorted(ids)
new_gm_id = sorted_ids[-1]
print (f"New genericmode with 'id = {new_gm_id}' was successfully created.")
driver.quit()
return new_gm_id
except Exception as e:
print(f"An error occurred: {e}")
driver.quit()
return None
def login_and_create_GMG(BASE_URL, USERNAME, PASSWORD, new_gmg):
# Set up Chrome options for headless mode
chrome_options = Options()
# Run Chrome in headless mode
chrome_options.add_argument("--headless")
# Prevents rendering issues in older systems
chrome_options.add_argument("--disable-gpu")
# Useful options for containerized environments like Docker
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
# Set up the WebDriver service
driver = webdriver.Chrome(options=chrome_options)
try:
# Open the login page
driver.get(f"{BASE_URL}/admin/login/?next=/admin/")
print("Accessed login page.")
# Log in
username_field = driver.find_element(By.NAME, 'username')
password_field = driver.find_element(By.NAME, 'password')
username_field.send_keys(USERNAME)
password_field.send_keys(PASSWORD)
login_button = driver.find_element(By.XPATH, '//input[@type="submit"]')
login_button.click()
# Check if login was successful
WebDriverWait(driver, 10).until(EC.title_contains("Site administration"))
print("Login successful: OK")
# Navigate to the form page and interact with it
driver.get(f"{BASE_URL}/admin/hardware/genericmodegroup/add/")
print("Accessed generic mode group form.")
# Fill in the fields
#------------------------------------------------------------------------------------------------------------------------
instrument_type_field = driver.find_element(By.ID, 'id_instrument_type')
all_instrument_type_options = [option.text for option in instrument_type_field.find_elements(By.TAG_NAME, 'option')]
my_instrument_type = new_gmg['instrument_type']
for option in instrument_type_field.find_elements(By.TAG_NAME, 'option'):
if option.text == my_instrument_type:
option.click()
break
if my_instrument_type not in all_instrument_type_options:
print ("Unable to create generic mode group with the instrument type '" + my_instrument_type + "' because that "\
"instrument type doesn't exist among the existing instrument types ['" + "', '".join(all_instrument_type_options[1:]) + "']")
driver.quit()
return None
#------------------------------------------------------------------------------------------------------------------------
mode_type_field = driver.find_element(By.ID, 'id_type')
all_mode_type_options = [option.text for option in mode_type_field.find_elements(By.TAG_NAME, 'option')]
my_mode_type = new_gmg['type']
for option in mode_type_field.find_elements(By.TAG_NAME, 'option'):
if option.text == my_mode_type:
option.click()
break
if my_mode_type not in all_mode_type_options:
print ("Unable to create generic mode group with the mode type '" + my_instrument_type + "' because that "\
"mode type doesn't exist among the existing mode types ['" + "', '".join(all_mode_type_options[1:]) + "']")
driver.quit()
return None
#------------------------------------------------------------------------------------------------------------------------
modes_type_field = driver.find_element(By.ID, 'id_modes')
my_modes_list = [e['code'] + ': ' + e['name'] for e in new_gmg['modes']]
for option in modes_type_field.find_elements(By.TAG_NAME, 'option'):
if option.text in my_modes_list:
option.click()
all_modes_type = [option.text for option in modes_type_field.find_elements(By.TAG_NAME, 'option')]
non_existing_elements = []
for my_option in my_modes_list:
if my_option not in all_modes_type:
print ("Unable to add generic mode to the generic mode group because generic mode '" + my_option + "' doesn't exist "\
"among the existing generic modes ['" + "', '".join(all_modes_type) + "']")
non_existing_elements.append(my_option)
if non_existing_elements == my_modes_list:
print ('No generic modes to add to the generic mode group. Generic mode group will not be created.')
driver.quit()
return None
#------------------------------------------------------------------------------------------------------------------------
if new_gmg['default'] != {}:
default_field = driver.find_element(By.ID, 'id_default')
my_default = new_gmg['default']['code'] + ': ' + new_gmg['default']['name']
added_modes = [e for e in my_modes_list if e not in non_existing_elements]
if my_default in added_modes:
for option in default_field.find_elements(By.TAG_NAME, 'option'):
if option.text == my_default:
option.click()
break
else:
print ("Unable to set default generic mode for the generic mode group because that mode '" + my_default + "' "\
"doesn't exist among the added modes ['" + "', '".join(added_modes) + "'] for this group.")
#------------------------------------------------------------------------------------------------------------------------
# Submit the form
save_button = driver.find_element(By.NAME, '_save')
save_button.click()
#------------------------------------------------------------------------------------------------------------------------
# Check if the gorup was added successfully
success_message = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'success')))
if success_message:
print("Generic mode group added successfully: OK")
#------------------------------------------------------------------------------------------------------------------------
# Go to Generic Mode Groups page and return ID of the newly created group
driver.get(f"{BASE_URL}/admin/hardware/genericmodegroup/")
# Initialize lists to store extracted IDs
ids = []
# Find all rows in the table body
rows = driver.find_elements(By.XPATH, "//table[@id='result_list']/tbody/tr")
# Loop through each row and extract ID
for row in rows:
# Extract the ID (from the <input> tag inside <td class="action-checkbox">)
id_element = row.find_element(By.XPATH, ".//td[@class='action-checkbox']/input")
ids.append(int(id_element.get_attribute("value")))
# Get generic mode ID
sorted_ids = sorted(ids)
new_gmg_id = sorted_ids[-1]
print (f"New genericmodegroup with 'id = {new_gmg_id}' was successfully created.")
driver.quit()
return new_gmg_id
except Exception as e:
print(f"An error occurred: {e}")
driver.quit()
return None
def retrieve_component(BASE_URL, COMPONENT, component_id, filters=None):
"""
Retrieve details of a specific component.
Args:
BASE_URL: Base URL of your ConfigDB.
COMPONENT: Possible ConfigDB component.
component_id (int): ID of the component.
filters (dict, optional): Optional query parameters for filtering.
Returns:
dict: Component details or error message.
"""
endpoint = f'{BASE_URL}/{COMPONENT}/{component_id}/'
response = requests.get(endpoint, params=filters)
print(f"Status Code --> [{response.status_code} : {response.reason}]")
if response.status_code == 200:
json_response = response.json()
print (f"Specified {COMPONENT[:-1]} with 'id = {component_id}' was successfully retrieved.")
return json_response
else:
print (f"Failed to retrieve specifed {COMPONENT[:-1]} with 'id = {component_id}'.")
return {}
def update_component(BASE_URL, COMPONENT, AUTHORIZATION_TOKEN, component_id, component_update, filters=None):
"""
Updates a component using the provided API endpoint.
Args:
BASE_URL: Base URL of your ConfigDB.
COMPONENT: Possible ConfigDB component.
AUTHORIZATION_TOKEN: Authorization token (super-user or local configDB token).
component_id (int): The ID of the component to update.
component_update (dict): The JSON payload containing the updated fields.
filters (dict, optional): Optional query parameters for filtering.
Returns:
dict: Updated component details or error message.
"""
endpoint = f"{BASE_URL}/{COMPONENT}/{component_id}/"
headers = {"Authorization": f"Token {AUTHORIZATION_TOKEN}"}
response = requests.put(endpoint, params=filters, data=component_update, headers=headers)
print(f"Status Code --> [{response.status_code} : {response.reason}]")
if response.status_code == 200:
json_response = response.json()
print (f"Specified {COMPONENT[:-1]} with 'id = {component_id}' was successfully updated.")
return json_response
else:
print(f"Failed to update specifed {COMPONENT[:-1]} with 'id = {component_id}'.")
return {}
def login_and_update_OEG(BASE_URL, USERNAME, PASSWORD, oeg_id, update_oeg):
# Set up Chrome options for headless mode
chrome_options = Options()
# Run Chrome in headless mode
chrome_options.add_argument("--headless")
# Prevents rendering issues in older systems
chrome_options.add_argument("--disable-gpu")
# Useful options for containerized environments like Docker
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
# Set up the WebDriver service
driver = webdriver.Chrome(options=chrome_options)
try:
# Open the login page
driver.get(f"{BASE_URL}/admin/login/?next=/admin/")
print("Accessed login page.")
# Log in
username_field = driver.find_element(By.NAME, 'username')
password_field = driver.find_element(By.NAME, 'password')
username_field.send_keys(USERNAME)
password_field.send_keys(PASSWORD)
login_button = driver.find_element(By.XPATH, '//input[@type="submit"]')
login_button.click()
# Check if login was successful
WebDriverWait(driver, 10).until(EC.title_contains("Site administration"))
print("Login successful: OK")
# Navigate to the form page and interact with it
driver.get(f"{BASE_URL}/admin/hardware/opticalelementgroup/{oeg_id}/change/")
print(f"Accessed optical element group with 'id = {oeg_id}'")
# Fill in the fields
#------------------------------------------------------------------------------------------------------------------------
name_field = driver.find_element(By.NAME, 'name')
# Clear the field first
name_field.clear()
name_field.send_keys(update_oeg['name'])
#------------------------------------------------------------------------------------------------------------------------
type_field = driver.find_element(By.NAME, 'type')
# Clear the field first
type_field.clear()
type_field.send_keys(update_oeg['type'])
#------------------------------------------------------------------------------------------------------------------------
# Select multiple options
optical_elements_field = driver.find_element(By.ID, 'id_optical_elements')
# Use JavaScript to clear all selections
driver.execute_script(
"""
var select = arguments[0];
for (var i = 0; i < select.options.length; i++)
{
select.options[i].selected = false; // Deselect each option
}
""",
optical_elements_field
)
my_list_of_optical_elements = [e['name'] for e in update_oeg['optical_elements']]
for option in optical_elements_field.find_elements(By.TAG_NAME, 'option'):
if option.text in my_list_of_optical_elements:
option.click()
#------------------------------------------------------------------------------------------------------------------------
all_optical_elements_options = [option.text for option in optical_elements_field.find_elements(By.TAG_NAME, 'option')]
non_existing_elements = []
for my_option in my_list_of_optical_elements:
if my_option not in all_optical_elements_options:
print ("Unable to update optical element group with the optical element '" + my_option + "' because it doesn't exist in the configDB.")
non_existing_elements.append(my_option)
#------------------------------------------------------------------------------------------------------------------------
if non_existing_elements == my_list_of_optical_elements:
print ('No optical elements were updated in the optical element group.')
driver.quit()
return False
#------------------------------------------------------------------------------------------------------------------------
overhead_field = driver.find_element(By.NAME, 'element_change_overhead')
# Clear the field first
overhead_field.clear()
# Send the value
overhead_field.send_keys(update_oeg['element_change_overhead'])
#------------------------------------------------------------------------------------------------------------------------
# Submit the form
save_button = driver.find_element(By.NAME, '_save')
save_button.click()
# Navigate to the form page and interact with it
driver.get(f"{BASE_URL}/admin/hardware/opticalelementgroup/{oeg_id}/change/")
#------------------------------------------------------------------------------------------------------------------------
default_elements_field = driver.find_element(By.ID, 'id_default')
# Use JavaScript to clear all selections
driver.execute_script(
"""
var select = arguments[0];
for (var i = 0; i < select.options.length; i++)
{
select.options[i].selected = false; // Deselect each option
}
""",
default_elements_field
)
if 'default' in list(update_oeg.keys()):
my_default_element = update_oeg['default']['name']
my_list_of_optical_elements_new = [e for e in my_list_of_optical_elements if e not in non_existing_elements]
if my_default_element in my_list_of_optical_elements_new:
for option in default_elements_field.find_elements(By.TAG_NAME, 'option'):
if option.text == my_default_element:
option.click()
break
else:
print ("Unable to set default element with the name '" + my_default_element + "' because it doesn't "\
"exist among the added optical elements ['" + "', '".join(my_list_of_optical_elements_new) + "'] for this group.")
#------------------------------------------------------------------------------------------------------------------------
# Submit the form
save_button = driver.find_element(By.NAME, '_save')
save_button.click()
#------------------------------------------------------------------------------------------------------------------------
# Check if the group was updated successfully
success_message = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'success')))
if success_message:
print (f"Optical element group with 'id = {oeg_id}' was successfully updated.")
#------------------------------------------------------------------------------------------------------------------------
driver.quit()
return True
except Exception as e:
print(f"An error occurred: {e}")
driver.quit()
return False
def login_and_update_GM(BASE_URL, USERNAME, PASSWORD, gm_id, update_gm):
# Set up Chrome options for headless mode
chrome_options = Options()
# Run Chrome in headless mode
chrome_options.add_argument("--headless")
# Prevents rendering issues in older systems
chrome_options.add_argument("--disable-gpu")
# Useful options for containerized environments like Docker
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
# Set up the WebDriver service
driver = webdriver.Chrome(options=chrome_options)
try:
# Open the login page
driver.get(f"{BASE_URL}/admin/login/?next=/admin/")
print("Accessed login page.")
# Log in
username_field = driver.find_element(By.NAME, 'username')
password_field = driver.find_element(By.NAME, 'password')
username_field.send_keys(USERNAME)
password_field.send_keys(PASSWORD)
login_button = driver.find_element(By.XPATH, '//input[@type="submit"]')
login_button.click()
# Check if login was successful
WebDriverWait(driver, 10).until(EC.title_contains("Site administration"))
print("Login successful: OK")
# Navigate to the form page and interact with it
driver.get(f"{BASE_URL}/admin/hardware/genericmode/{gm_id}/change/")
print(f"Accessed generic mode element with 'id = {gm_id}'")
# Update fields
#------------------------------------------------------------------------------------------------------------------------
name_field = driver.find_element(By.ID, 'id_name')
# Clear the field first
name_field.clear()
name_field.send_keys(update_gm['name'])
#------------------------------------------------------------------------------------------------------------------------
code_field = driver.find_element(By.ID, 'id_code')
# Clear the field first
code_field.clear()
code_field.send_keys(update_gm['code'])
#------------------------------------------------------------------------------------------------------------------------
overhead_field = driver.find_element(By.ID, 'id_overhead')
# Clear the field first
overhead_field.clear()
# Send the value
overhead_field.send_keys(update_gm['overhead'])
#------------------------------------------------------------------------------------------------------------------------
# Locate the checkbox element
checkbox = driver.find_element(By.ID, 'id_schedulable')
# Check if the checkbox is already in the desired state
checkbox_state = update_gm['schedulable']
if checkbox_state != checkbox.is_selected():
checkbox.click()
#------------------------------------------------------------------------------------------------------------------------
# Locate the validation schema element
validation_schema = driver.find_element(By.ID, "id_validation_schema")
# Convert the dictionary to a JSON string
json_string = json.dumps(update_gm['validation_schema'])
# Clear the existing content in the validation schema element
validation_schema.clear()
# Send the JSON string to the validation schema element
validation_schema.send_keys(json_string)
#------------------------------------------------------------------------------------------------------------------------
# Submit the form
save_button = driver.find_element(By.NAME, '_save')
save_button.click()
#------------------------------------------------------------------------------------------------------------------------
# Check if the generic mode element was updated successfully
success_message = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'success')))
if success_message:
print (f"Generic mode element with 'id = {gm_id}' was successfully updated.")
#------------------------------------------------------------------------------------------------------------------------
driver.quit()
return True
except Exception as e:
print(f"An error occurred: {e}")
driver.quit()
return False
def login_and_update_GMG(BASE_URL, USERNAME, PASSWORD, gmg_id, update_gmg):
# Set up Chrome options for headless mode
chrome_options = Options()
# Run Chrome in headless mode
chrome_options.add_argument("--headless")
# Prevents rendering issues in older systems
chrome_options.add_argument("--disable-gpu")
# Useful options for containerized environments like Docker
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
# Set up the WebDriver service
driver = webdriver.Chrome(options=chrome_options)
try:
# Open the login page
driver.get(f"{BASE_URL}/admin/login/?next=/admin/")
print("Accessed login page.")
# Log in
username_field = driver.find_element(By.NAME, 'username')
password_field = driver.find_element(By.NAME, 'password')
username_field.send_keys(USERNAME)
password_field.send_keys(PASSWORD)
login_button = driver.find_element(By.XPATH, '//input[@type="submit"]')
login_button.click()
# Check if login was successful
WebDriverWait(driver, 10).until(EC.title_contains("Site administration"))
print("Login successful: OK")
# Navigate to the form page and interact with it
driver.get(f"{BASE_URL}/admin/hardware/genericmodegroup/{gmg_id}/change/")
print("Accessed generic mode group form.")
# Fill in the fields
#------------------------------------------------------------------------------------------------------------------------
instrument_type_field = driver.find_element(By.ID, 'id_instrument_type')
# Use JavaScript to clear all selections
driver.execute_script(
"""
var select = arguments[0];
for (var i = 0; i < select.options.length; i++)
{
select.options[i].selected = false; // Deselect each option
}
""",
instrument_type_field
)
all_instrument_type_options = [option.text for option in instrument_type_field.find_elements(By.TAG_NAME, 'option')]
my_instrument_type = update_gmg['instrument_type']
for option in instrument_type_field.find_elements(By.TAG_NAME, 'option'):
if option.text == my_instrument_type:
option.click()
break
if my_instrument_type not in all_instrument_type_options:
print ("Unable to update generic mode group with the instrument type '" + my_instrument_type + "' because that "\
"instrument type doesn't exist among the existing instrument types ['" + "', '".join(all_instrument_type_options[1:]) + "']")
driver.quit()
return False
#------------------------------------------------------------------------------------------------------------------------
mode_type_field = driver.find_element(By.ID, 'id_type')
# Use JavaScript to clear all selections
driver.execute_script(
"""
var select = arguments[0];
for (var i = 0; i < select.options.length; i++)
{
select.options[i].selected = false; // Deselect each option
}
""",
mode_type_field
)
all_mode_type_options = [option.text for option in mode_type_field.find_elements(By.TAG_NAME, 'option')]
my_mode_type = update_gmg['type']
for option in mode_type_field.find_elements(By.TAG_NAME, 'option'):
if option.text == my_mode_type:
option.click()
break
if my_mode_type not in all_mode_type_options:
print ("Unable to update generic mode group with the mode type '" + my_instrument_type + "' because that "\
"mode type doesn't exist among the existing mode types ['" + "', '".join(all_mode_type_options[1:]) + "']")
driver.quit()
return False
#------------------------------------------------------------------------------------------------------------------------
modes_type_field = driver.find_element(By.ID, 'id_modes')
# Use JavaScript to clear all selections
driver.execute_script(
"""
var select = arguments[0];
for (var i = 0; i < select.options.length; i++)
{
select.options[i].selected = false; // Deselect each option
}
""",
modes_type_field
)
my_modes_list = [e['code'] + ': ' + e['name'] for e in update_gmg['modes']]
for option in modes_type_field.find_elements(By.TAG_NAME, 'option'):
if option.text in my_modes_list:
option.click()
all_modes_type = [option.text for option in modes_type_field.find_elements(By.TAG_NAME, 'option')]
non_existing_elements = []
for my_option in my_modes_list:
if my_option not in all_modes_type:
print ("Unable to update generic mode group with generic mode '" + my_option + "' because that mode doesn't exist "\
"among the existing generic modes ['" + "', '".join(all_modes_type) + "']")
non_existing_elements.append(my_option)
if non_existing_elements == my_modes_list:
print ('No generic modes to update the generic mode group. Generic mode group will not be updated.')
driver.quit()
return False
#------------------------------------------------------------------------------------------------------------------------
# Submit the form
save_button = driver.find_element(By.NAME, '_save')
save_button.click()
# Navigate to the form page and interact with it
driver.get(f"{BASE_URL}/admin/hardware/genericmodegroup/{gmg_id}/change/")
#------------------------------------------------------------------------------------------------------------------------
if update_gmg['default'] != {}:
default_field = driver.find_element(By.ID, 'id_default')
# Use JavaScript to clear all selections
driver.execute_script(
"""
var select = arguments[0];
for (var i = 0; i < select.options.length; i++)
{
select.options[i].selected = false; // Deselect each option
}
""",
default_field
)
my_default = update_gmg['default']['code'] + ': ' + update_gmg['default']['name']
added_modes = [e for e in my_modes_list if e not in non_existing_elements]
if my_default in added_modes:
for option in default_field.find_elements(By.TAG_NAME, 'option'):
if option.text == my_default:
option.click()
break
else:
print ("Unable to update default generic mode for this generic mode group because that mode '" + my_default + "' "\
"doesn't exist among the updated modes ['" + "', '".join(added_modes) + "'] for this group.")
#------------------------------------------------------------------------------------------------------------------------
# Submit the form
save_button = driver.find_element(By.NAME, '_save')
save_button.click()
#------------------------------------------------------------------------------------------------------------------------
# Check if the gorup was added successfully
success_message = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'success')))
if success_message:
print (f"Generic mode group with 'id = {gmg_id}' was successfully updated.")
#------------------------------------------------------------------------------------------------------------------------
driver.quit()
return True
except Exception as e:
print(f"An error occurred: {e}")
driver.quit()
return False
def destroy_component(BASE_URL, COMPONENT, AUTHORIZATION_TOKEN, component_id, filters=None):
"""
Delete a specific component.
Args:
BASE_URL: Base URL of your ConfigDB.
COMPONENT: Possible ConfigDB component.
AUTHORIZATION_TOKEN: Authorization token (super-user or local configDB token).
component_id (int): ID of the component.
filters (dict, optional): Optional query parameters for filtering.
Returns:
prints out message about deleted component or error message.
"""
endpoint = f'{BASE_URL}/{COMPONENT}/{component_id}/'
headers = {"Authorization": f"Token {AUTHORIZATION_TOKEN}"}
response = requests.delete(endpoint, params=filters, headers=headers)
print(f"Status Code --> [{response.status_code} : {response.reason}]")
if response.status_code == 204:
print (f"Specified {COMPONENT[:-1]} with 'id = {component_id}' was successfully deleted.")
else:
print (f"Failed to delete specified {COMPONENT[:-1]} with 'id = {component_id}'.")
I hope this can be helpful.
Best regards,
Nikola
