Copilot commented on code in PR #320:
URL: https://github.com/apache/hugegraph-ai/pull/320#discussion_r3159119703
##########
hugegraph-python-client/src/tests/api/test_gremlin.py:
##########
@@ -26,21 +26,40 @@
class TestGremlin(unittest.TestCase):
client = None
gremlin = None
+ skip_gremlin_tests = False
@classmethod
def setUpClass(cls):
- cls.client = ClientUtils()
- cls.client.clear_graph_all_data()
- cls.gremlin = cls.client.gremlin
- cls.client.init_property_key()
- cls.client.init_vertex_label()
- cls.client.init_edge_label()
+ try:
+ cls.client = ClientUtils()
+ cls.gremlin = cls.client.gremlin
+ cls.client.clear_graph_all_data()
+ cls.client.init_property_key()
+ cls.client.init_vertex_label()
+ cls.client.init_edge_label()
+ # Test if gremlin endpoint is available by executing a simple query
+ cls.gremlin.exec("1 + 1")
+ except (NotFoundError, Exception) as e:
+ # Skip gremlin tests if the server is unavailable
+ # (connection timeout, 404, or other gremlin-specific errors)
+ error_str = str(e)
+ if any(
+ marker in error_str
+ for marker in ["404", "Not Found", "timed out", "Connection
refused", "Gremlin can't get results"]
+ ):
Review Comment:
The `except (NotFoundError, Exception)` clause is equivalent to `except
Exception` (so `NotFoundError` is redundant). Also, this block now
conditionally skips the entire test suite based on substring matching of the
exception message, which can accidentally skip on unrelated failures that
happen to contain one of these markers. Consider narrowing the exception
type(s) and using a more deterministic signal (HTTP status / explicit error
code) before skipping.
##########
hugegraph-python-client/src/tests/api/test_metric.py:
##########
@@ -83,13 +63,16 @@ def test_metrics_operations(self):
timers_metrics = self.metrics.get_timers_metrics()
self.assertIsInstance(timers_metrics, dict)
- server_version = tuple(self.client.client.cfg.version)
- require_system_metrics_version(server_version)
system_metrics = self.metrics.get_system_metrics()
self.assertIsInstance(system_metrics, dict)
statistics = self.metrics.get_statistics_metrics()
self.assertIsInstance(statistics, dict)
backend_metrics = self.metrics.get_backend_metrics()
- self.assertGreater(len(backend_metrics["hugegraph"]), 1)
+ # In HugeGraph 1.7.0+, the backend_metrics structure changed
+ # It's still a dict, but the "hugegraph" key may not exist in the same
format
+ self.assertIsInstance(backend_metrics, dict)
+ # Only assert on the "hugegraph" key if it exists (for backward
compatibility)
+ if "hugegraph" in backend_metrics:
+ self.assertGreater(len(backend_metrics["hugegraph"]), 1)
Review Comment:
This assertion became very permissive: `backend_metrics` can now be an empty
dict (or a dict missing all expected backend entries) and the test will still
pass. If the backend metrics payload changed in 1.7, consider asserting on a
more stable invariant (e.g., non-empty response, or presence of at least one
known top-level key) so the test still detects regressions.
##########
hugegraph-python-client/src/pyhugegraph/utils/huge_config.py:
##########
@@ -53,15 +53,31 @@ def __post_init__(self):
)
match = re.search(r"(\d+)\.(\d+)(?:\.(\d+))?(?:\.\d+)?", core)
Review Comment:
`re.search()` can return `None` if the server returns an unexpected `core`
version string, but the code immediately calls `match.group(...)`. That failure
is then treated as a generic parsing/network issue and falls back to "default
v1" behavior, which also bypasses the new <1.5.0 version guard. Consider
explicitly handling `match is None` (raise a clear error or at least log and
avoid proceeding as a supported version).
##########
hugegraph-python-client/src/pyhugegraph/api/gremlin.py:
##########
@@ -28,12 +28,16 @@ class GremlinManager(HugeParamsBase):
@router.http("POST", "/gremlin")
def exec(self, gremlin):
gremlin_data = GremlinData(gremlin)
+
+ # Version-specific gremlin request handling
if self._sess.cfg.gs_supported:
+ # For graphspace-supported versions (3.0+), use graphspace-scoped
aliases
gremlin_data.aliases = {
"graph":
f"{self._sess.cfg.graphspace}-{self._sess.cfg.graph_name}",
"g":
f"__g_{self._sess.cfg.graphspace}-{self._sess.cfg.graph_name}",
}
else:
+ # For HugeGraph 1.x (including 1.7.0), always include aliases so
`g` is bound
Review Comment:
The comment says graphspace support is for "3.0+", but the code path is
gated only by `cfg.gs_supported`. With the updated version detection enabling
`gs_supported` for 1.7 as well, this comment (and possibly the intended
branching) is now inconsistent. Please align the comment/logic so it’s clear
which server versions should use graphspace-scoped aliases vs graph-scoped
aliases.
##########
hugegraph-python-client/src/pyhugegraph/api/auth.py:
##########
@@ -22,13 +22,19 @@
from pyhugegraph.utils import huge_router as router
+# NOTE: Auth endpoints currently use absolute paths (/auth/...) which rely on a
+# temporary PathFilter compatibility layer in HugeGraph 1.7.0. This layer will
be
+# removed in future versions. When it is removed, these paths should be
converted
+# to relative paths (auth/...) with proper graphspace-scoped routing for
non-group
+# endpoints, similar to the Java Client's dual-path strategy.
+# See: apache/hugegraph-ai#322 (HugeGraph 1.7.0 auth API migration)
class AuthManager(HugeParamsBase):
- @router.http("GET", "auth/users")
+ @router.http("GET", "/auth/users")
def list_users(self, limit=None):
params = {"limit": limit} if limit is not None else {}
return self._invoke_request(params=params)
- @router.http("POST", "auth/users")
+ @router.http("POST", "/auth/users")
def create_user(self, user_name, user_password, user_phone=None,
user_email=None) -> dict | None:
Review Comment:
These auth routes were changed from relative paths (resolved under
`/graphs/{graph}/...` or `/graphspaces/{graphspace}/graphs/{graph}/...`) to
absolute paths (resolved at the server root). This is a breaking behavior
change for deployments/versions that only expose graph-scoped auth endpoints.
If the intention is to support both layouts, consider adding version-based
routing or a fallback strategy (try graph-scoped first, then root-scoped)
rather than permanently switching everything to absolute paths.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]