summaryrefslogtreecommitdiffstats
path: root/awxkit/awxkit/api/pages/page.py
diff options
context:
space:
mode:
authorJeff Bradberry <jeff.bradberry@gmail.com>2024-04-22 20:49:47 +0200
committerJeff Bradberry <jeff.bradberry@gmail.com>2024-04-24 23:04:40 +0200
commitfb237e3834d7404eac322c1058de65da7bd2dc9a (patch)
treebbad6a985982c8c5be34d19eb802d4d741da393e /awxkit/awxkit/api/pages/page.py
parentAdd help message for expiration tokens (#15076) (#15077) (diff)
downloadawx-fb237e3834d7404eac322c1058de65da7bd2dc9a.tar.xz
awx-fb237e3834d7404eac322c1058de65da7bd2dc9a.zip
Stop pre-caching every resource in the system upon import
If we don't have something in the cache when we call get_by_natural_key, do an actual filtered query for it and cache the results. We'll get more overall API calls this way, but they'll be smaller and will happen while we are importing, not upfront.
Diffstat (limited to '')
-rw-r--r--awxkit/awxkit/api/pages/page.py36
1 files changed, 31 insertions, 5 deletions
diff --git a/awxkit/awxkit/api/pages/page.py b/awxkit/awxkit/api/pages/page.py
index 4c26fd5314..d6c60d78bd 100644
--- a/awxkit/awxkit/api/pages/page.py
+++ b/awxkit/awxkit/api/pages/page.py
@@ -11,6 +11,7 @@ from awxkit.utils import PseudoNamespace, is_relative_endpoint, are_same_endpoin
from awxkit.api import utils
from awxkit.api.client import Connection
from awxkit.api.registry import URLRegistry
+from awxkit.api.resources import resources
from awxkit.config import config
import awxkit.exceptions as exc
@@ -493,10 +494,11 @@ class TentativePage(str):
class PageCache(object):
- def __init__(self):
+ def __init__(self, connection=None):
self.options = {}
self.pages_by_url = {}
self.pages_by_natural_key = {}
+ self.connection = connection or Connection(config.base_url, not config.assume_untrusted)
def get_options(self, page):
url = page.endpoint if isinstance(page, Page) else str(page)
@@ -550,7 +552,31 @@ class PageCache(object):
return self.set_page(page)
def get_by_natural_key(self, natural_key):
- endpoint = self.pages_by_natural_key.get(utils.freeze(natural_key))
- log.debug("get_by_natural_key: %s, endpoint: %s", repr(natural_key), endpoint)
- if endpoint:
- return self.get_page(endpoint)
+ page = self.pages_by_natural_key.get(utils.freeze(natural_key))
+ if page is None:
+ # We need some way to get ahold of the top-level resource
+ # list endpoint from the natural_key type. The resources
+ # object more or less has that for each of the detail
+ # views. Just chop off the /<id>/ bit.
+ endpoint = getattr(resources, natural_key['type'], None)
+ if endpoint is None:
+ return
+ endpoint = ''.join([endpoint.rsplit('/', 2)[0], '/'])
+ page_type = get_registered_page(endpoint)
+
+ kwargs = {}
+ for k, v in natural_key.items():
+ if isinstance(v, str) and k != 'type':
+ kwargs[k] = v
+
+ # Do a filtered query against the list endpoint, usually
+ # with the name of the object but sometimes more.
+ list_page = page_type(self.connection, endpoint=endpoint).get(all_pages=True, **kwargs)
+ if 'results' in list_page:
+ for p in list_page.results:
+ self.set_page(p)
+ page = self.pages_by_natural_key.get(utils.freeze(natural_key))
+
+ log.debug("get_by_natural_key: %s, endpoint: %s", repr(natural_key), page)
+ if page:
+ return self.get_page(page)