Skip to content

Commit

Permalink
#136: Refactor get entity by ID helper function and associated infra…
Browse files Browse the repository at this point in the history
…structure

- This change is mostly about moving code into their own functions, but also making the id_condition more generic so it can be used throughout the helper functions. A design decision needs to be made about how to best structure the code creating conditions
- Added docstrings throughout, documenting the accepted parameters and their types
  • Loading branch information
MRichards99 committed Jul 16, 2020
1 parent 9bfefcf commit f747bae
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 16 deletions.
2 changes: 1 addition & 1 deletion common/python_icat_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def count_with_filters(self, session_id, table, filters):
@requires_session_id
@queries_records
def get_with_id(self, session_id, table, id):
return get_entity_by_id(self.client, table, id)
return get_entity_by_id(self.client, table.__name__, id)

@requires_session_id
@queries_records
Expand Down
67 changes: 52 additions & 15 deletions common/python_icat_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def refresh_client_session(client):
client.refresh()


def construct_icat_query(client, entity_name, conditions=None):
def construct_icat_query(client, entity_name, conditions=None, aggregate=None):
"""
Create a Query object within Python ICAT
Expand All @@ -75,9 +75,12 @@ def construct_icat_query(client, entity_name, conditions=None):
:type entity_name: TODO
:param conditions: TODO
:type conditions: TODO
:param aggregate: Name of the aggregate function to apply. Operations such as counting the
number of records. See `icat.query.setAggregate for valid values.
:type aggregate: :class:`str`
:return: Query object from Python ICAT
"""
return Query(client, entity_name, conditions=conditions)
return Query(client, entity_name, conditions=conditions, aggregate=aggregate)


def execute_icat_query(client, query):
Expand All @@ -88,7 +91,8 @@ def execute_icat_query(client, query):
:type client: :class:`icat.client.Client`
:param query: ICAT Query object to execute within Python ICAT
:type query: :class:`icat.query.Query`
:return: Data (of type list) from the executed query in a format that can be converted straight to JSON
:return: Data (of type list) from the executed query in a format that can be converted
straight to JSON
"""
query_result = client.search(query)

Expand All @@ -105,31 +109,64 @@ def execute_icat_query(client, query):
return data


def get_entity_by_id(client, table, id):
def get_python_icat_entity_name(client, database_table_name):
"""
From the database table name, this function returns the correctly cased entity name relating
to the table name
Due to the case sensitivity of Python ICAT, the table name must be compared with each of the
valid entity names within Python ICAT to get the correctly cased entity name. This is done by
putting everything to lowercase and comparing from there
:param client: ICAT client containing an authenticated user
:type client: :class:`icat.client.Client`
:param database_table_name: Table name (from icatdb) to be interacted with
:type database_table_name: :class:`str`
:return: Entity name (of type string) in the correct casing ready to be passed into Python ICAT
"""

lowercase_table_name = database_table_name.lower()
entity_names = client.getEntityNames()
python_icat_entity_name = None
for entity_name in entity_names:
lowercase_name = entity_name.lower()

if lowercase_name == lowercase_table_name:
python_icat_entity_name = entity_name

# Raise a 400 if a valid entity cannot be found
if python_icat_entity_name is None:
raise BadRequestError(f"Bad request made, cannot find {database_table_name} entity within Python ICAT")

return python_icat_entity_name


def get_entity_by_id(client, table_name, id):
"""
Gets a record of a given ID of the specified entity
:param client: ICAT client containing an authenticated user
:type client: :class:`icat.client.Client`
:param table: Table to extract which entity to use
:type table: TODO
:param table_name: Table name to extract which entity to use
:type table_name: TODO
:param id: ID number of the entity to retrieve
:type id: :class:`int`
:return: The record of the specified ID from the given entity
"""

# Set query condition for the selected ID
# TODO - Could this be moved out of this function for more generic conditions that'll be implemented later on?
id_condition = {'id': f'= {id}'}
id_condition = {}
operator = '='
id_condition[attribute_name] = f"{operator} '{id}'"

selected_entity_name = get_python_icat_entity_name(client, table_name)

id_query = construct_icat_query(client, selected_entity_name, id_condition)
entity_by_id_data = execute_icat_query(client, id_query)

return entity_by_id_data

# Due to the case sensitivity of Python ICAT, the table name must be compared with each of the
# valid entity names within Python ICAT to get the correctly cased entity name. This is done by
# putting everything to lowercase and comparing from there
lowercase_table_name = table.__name__.lower()
entity_names = client.getEntityNames()
selected_entity = None
for entity_name in entity_names:
lowercase_name = entity_name.lower()

def update_entity_by_id(client, table_name, id, new_data):
"""
Expand Down

0 comments on commit f747bae

Please sign in to comment.