Skip to content

Commit

Permalink
Replace getSubTopics() with getTopics() with wildcard support
Browse files Browse the repository at this point in the history
  • Loading branch information
mfisherlevine committed Oct 10, 2023
1 parent 273ad40 commit d009768
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 21 deletions.
39 changes: 27 additions & 12 deletions python/lsst/summit/utils/efdUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import datetime
import logging
import pandas as pd
import re

from .utils import getSite

Expand All @@ -46,7 +47,7 @@
'getDayObsStartTime',
'getDayObsEndTime',
'getDayObsForTime',
'getSubTopics',
'getTopics',
]


Expand Down Expand Up @@ -530,26 +531,40 @@ def getDayObsForTime(time):
return int((time + offset).utc.isot[:10].replace('-', ''))


def getSubTopics(client, topic):
"""Get all the sub topics within a given topic.
def getTopics(client, toFind, caseSensitive=False):
"""Return all the strings in topics which match the topic query string.
Note that the topic need not be a complete one, for example, rather than
doing `getSubTopics(client, 'lsst.sal.ATMCS')` to get all the topics for
the AuxTel Mount Control System, you can do `getSubTopics(client,
'lsst.sal.AT')` to get all which relate to the AuxTel in general.
Supports wildcards, which are denoted as `*``, as per shell globs.
Example:
>>> # assume topics are ['apple', 'banana', 'grape']
>>> getTopics(, 'a*p*')
['apple', 'grape']
Parameters
----------
client : `lsst_efd_client.efd_helper.EfdClient`
The EFD client to use.
topic : `str`
The topic to query.
toFind : `str`
The query string, with optional wildcards denoted as *.
caseSensitive : `bool`, optional
If ``True``, the query is case sensitive. Defaults to ``False``.
Returns
-------
subTopics : `list` of `str`
The sub topics.
matches : `list` of `str`
The list of matching topics.
"""
loop = asyncio.get_event_loop()
topics = loop.run_until_complete(client.get_topics())
return sorted([t for t in topics if t.startswith(topic)])

# Replace wildcard with regex equivalent
pattern = toFind.replace('*', '.*')
flags = re.IGNORECASE if not caseSensitive else 0

matches = []
for topic in topics:
if re.match(pattern, topic, flags):
matches.append(topic)

return matches
File renamed without changes.
28 changes: 19 additions & 9 deletions tests/test_efdUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
getDayObsStartTime,
getDayObsEndTime,
getDayObsForTime,
getSubTopics,
getTopics,
)

from utils import getVcr
Expand Down Expand Up @@ -118,14 +118,24 @@ def test_getDayObsAsTimes(self):
self.assertEqual(dayEnd.jd, dayStart.jd + 1)

@vcr.use_cassette()
def test_getSubTopics(self):
subTopics = getSubTopics(self.client, 'lsst.sal.MTMount')
self.assertIsInstance(subTopics, list)
self.assertGreater(len(subTopics), 0)

subTopics = getSubTopics(self.client, 'fake.topics.does.not.exist')
self.assertIsInstance(subTopics, list)
self.assertEqual(len(subTopics), 0)
def test_getTopics(self):
topics = getTopics(self.client, 'lsst.sal.MTMount*')
self.assertIsInstance(topics, list)
self.assertGreater(len(topics), 0)

topics = getTopics(self.client, '*fake.topics.does.not.exist*')
self.assertIsInstance(topics, list)
self.assertEqual(len(topics), 0)

# check we can find the mount with a preceding wildcard
topics = getTopics(self.client, '*mTmoUnt*')
self.assertIsInstance(topics, list)
self.assertGreater(len(topics), 0)

# check it fails if we don't allow case insensitivity
topics = getTopics(self.client, '*mTmoUnt*', caseSensitive=True)
self.assertIsInstance(topics, list)
self.assertEqual(len(topics), 0)

@vcr.use_cassette()
def test_getEfdData(self):
Expand Down

0 comments on commit d009768

Please sign in to comment.