Skip to content

Commit 8c317d2

Browse files
committed
MAINT: Removed dependency on direct mongo plugin
1 parent cde5159 commit 8c317d2

5 files changed

Lines changed: 161 additions & 10 deletions

File tree

dserver_dependency_graph_plugin/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
from dservercore import AuthenticationError, ExtensionABC
3434
from dservercore.sql_models import DatasetSchema
3535
from dservercore.utils import _preprocess_privileges
36-
from dserver_direct_mongo_plugin.utils import _dict_to_mongo_query
36+
from .utils import _dict_to_mongo_query
3737

3838
from .schemas import DependencyKeysSchema
3939

@@ -246,7 +246,8 @@ def dependency_graph_by_user_and_uuid(username, uuid, dependency_keys=Config.DEP
246246
mongo_aggregation = query_dependency_graph(pre_query=pre_query,
247247
post_query=post_query,
248248
dependency_keys=dependency_keys,
249-
mongo_dependency_view=dependency_view)
249+
mongo_dependency_view=dependency_view,
250+
mongo_collection=current_app.config['MONGO_COLLECTION'])
250251
logger.debug("Constructed mongo aggregation: {}".format(mongo_aggregation))
251252
cx = DependencyGraphExtension.db[current_app.config['MONGO_COLLECTION']].aggregate(mongo_aggregation)
252253

dserver_dependency_graph_plugin/graph.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
"""Aggregation pipelines for graph operations."""
22

3-
from dserver_dependency_graph_plugin.config import Config as dependency_graph_plugin_config
4-
from dserver_direct_mongo_plugin.config import Config as direct_mongo_plugin_config
3+
from .config import Config
54

65
# a regular expression to filter valid v4 UUIDs
76
UUID_v4_REGEX = '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[4][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}'
87

98

109
# most of those 'functions' are pretty static and just wrapped in function
1110
# definitions for convenience.
12-
def unwind_dependencies(dependency_keys=dependency_graph_plugin_config.DEPENDENCY_KEYS):
11+
def unwind_dependencies(dependency_keys=Config.DEPENDENCY_KEYS):
1312
"""Create parallel aggregation pipelines for unwinding all configured dependency keys."""
1413

1514
parallel_aggregations = []
@@ -41,7 +40,7 @@ def unwind_dependencies(dependency_keys=dependency_graph_plugin_config.DEPENDENC
4140
return parallel_aggregations
4241

4342

44-
def merge_dependencies(dependency_keys=dependency_graph_plugin_config.DEPENDENCY_KEYS):
43+
def merge_dependencies(dependency_keys=Config.DEPENDENCY_KEYS):
4544
"""Aggregate (directed) dependency graph edges.
4645
4746
All configured dependency keys are merged in a key-agnostic 'dependencies'
@@ -117,7 +116,7 @@ def group_inverse_dependencies():
117116
return aggregation
118117

119118

120-
def build_undirected_adjecency_lists(dependency_keys=dependency_graph_plugin_config.DEPENDENCY_KEYS):
119+
def build_undirected_adjecency_lists(dependency_keys=Config.DEPENDENCY_KEYS):
121120
"""Aggregate undirected adjacency lists."""
122121
aggregation = [
123122
*merge_dependencies(dependency_keys),
@@ -200,8 +199,8 @@ def build_undirected_adjecency_lists(dependency_keys=dependency_graph_plugin_con
200199
# behavior would be to yield all redundant dataset entries for a uuid.
201200
def query_dependency_graph(mongo_dependency_view,
202201
pre_query, post_query=None,
203-
dependency_keys=dependency_graph_plugin_config.DEPENDENCY_KEYS,
204-
mongo_collection=direct_mongo_plugin_config.MONGO_COLLECTION):
202+
dependency_keys=Config.DEPENDENCY_KEYS,
203+
mongo_collection=None):
205204
"""Aggregation pipeline for querying dependency view on datasets collection.
206205
207206
:param pre_query: selects all documents for whicht to query the dependency graph.
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
"""Utility functions for MongoDB query construction.
2+
3+
These functions were originally part of dserver-direct-mongo-plugin but are
4+
copied here to decouple the dependency-graph-plugin from that package.
5+
"""
6+
7+
import logging
8+
9+
logger = logging.getLogger(__name__)
10+
11+
12+
VALID_MONGO_QUERY_KEYS = (
13+
"free_text",
14+
"creator_usernames",
15+
"base_uris",
16+
"uuids",
17+
"tags",
18+
)
19+
20+
MONGO_QUERY_LIST_KEYS = (
21+
"creator_usernames",
22+
"base_uris",
23+
"uuids",
24+
"tags",
25+
)
26+
27+
28+
def _dict_to_mongo(query_dict):
29+
"""Convert a query dictionary to a MongoDB query.
30+
31+
:param query_dict: Dictionary with query parameters
32+
:returns: MongoDB query dictionary
33+
"""
34+
def _sanitise(query_dict):
35+
for key in list(query_dict.keys()):
36+
if key not in VALID_MONGO_QUERY_KEYS:
37+
del query_dict[key]
38+
for lk in MONGO_QUERY_LIST_KEYS:
39+
if lk in query_dict:
40+
if len(query_dict[lk]) == 0:
41+
del query_dict[lk]
42+
43+
def _deal_with_possible_or_statment(a_list, key):
44+
if len(a_list) == 1:
45+
return {key: a_list[0]}
46+
else:
47+
return {"$or": [{key: v} for v in a_list]}
48+
49+
def _deal_with_possible_and_statement(a_list, key):
50+
if len(a_list) == 1:
51+
return {key: a_list[0]}
52+
else:
53+
return {key: {"$all": a_list}}
54+
55+
_sanitise(query_dict)
56+
57+
sub_queries = []
58+
if "free_text" in query_dict:
59+
sub_queries.append({"$text": {"$search": query_dict["free_text"]}})
60+
if "creator_usernames" in query_dict:
61+
sub_queries.append(
62+
_deal_with_possible_or_statment(
63+
query_dict["creator_usernames"], "creator_username"
64+
)
65+
)
66+
if "base_uris" in query_dict:
67+
sub_queries.append(
68+
_deal_with_possible_or_statment(query_dict["base_uris"], "base_uri")
69+
)
70+
if "uuids" in query_dict:
71+
sub_queries.append(_deal_with_possible_or_statment(query_dict["uuids"], "uuid"))
72+
if "tags" in query_dict:
73+
sub_queries.append(
74+
_deal_with_possible_and_statement(query_dict["tags"], "tags")
75+
)
76+
77+
if len(sub_queries) == 0:
78+
return {}
79+
elif len(sub_queries) == 1:
80+
return sub_queries[0]
81+
else:
82+
return {"$and": [q for q in sub_queries]}
83+
84+
85+
def _dict_to_mongo_query(query_dict):
86+
"""Construct mongo query, allowing embedding of a raw mongo query.
87+
88+
Converts a query dictionary to a MongoDB query format. If the query_dict
89+
contains a 'query' key with a dict value, that raw MongoDB query is
90+
merged with the constructed query.
91+
92+
:param query_dict: Dictionary with query parameters. May contain:
93+
- free_text: Text search string
94+
- creator_usernames: List of creator usernames
95+
- base_uris: List of base URIs
96+
- uuids: List of UUIDs
97+
- tags: List of tags
98+
- query: Raw MongoDB query dict (optional)
99+
:returns: MongoDB query dictionary
100+
"""
101+
if "query" in query_dict and isinstance(query_dict["query"], dict):
102+
raw_mongo = query_dict["query"]
103+
del query_dict["query"]
104+
else:
105+
raw_mongo = {}
106+
107+
mongo_query = _dict_to_mongo(query_dict)
108+
109+
if len(raw_mongo) > 0 and len(mongo_query) == 0:
110+
mongo_query = raw_mongo
111+
elif len(raw_mongo) > 0 and len(mongo_query) == 1 and "$and" in mongo_query:
112+
mongo_query["$and"].append(raw_mongo)
113+
elif len(raw_mongo) > 0:
114+
mongo_query = {"$and": [mongo_query, raw_mongo]}
115+
116+
logger.debug("Constructed mongo query: {}".format(mongo_query))
117+
return mongo_query
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# file generated by setuptools-scm
2+
# don't change, don't track in version control
3+
4+
__all__ = [
5+
"__version__",
6+
"__version_tuple__",
7+
"version",
8+
"version_tuple",
9+
"__commit_id__",
10+
"commit_id",
11+
]
12+
13+
TYPE_CHECKING = False
14+
if TYPE_CHECKING:
15+
from typing import Tuple
16+
from typing import Union
17+
18+
VERSION_TUPLE = Tuple[Union[int, str], ...]
19+
COMMIT_ID = Union[str, None]
20+
else:
21+
VERSION_TUPLE = object
22+
COMMIT_ID = object
23+
24+
version: str
25+
__version__: str
26+
__version_tuple__: VERSION_TUPLE
27+
version_tuple: VERSION_TUPLE
28+
commit_id: COMMIT_ID
29+
__commit_id__: COMMIT_ID
30+
31+
__version__ = version = '0.4.3.dev1'
32+
__version_tuple__ = version_tuple = (0, 4, 3, 'dev1')
33+
34+
__commit_id__ = commit_id = 'gcde515931'

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ dynamic = ["version"]
1414
dependencies = [
1515
"dtoolcore>=3.18.0",
1616
"dservercore>=0.20.0",
17-
"dserver-direct-mongo-plugin",
17+
"pymongo",
1818
]
1919

2020
[project.optional-dependencies]

0 commit comments

Comments
 (0)