Skip to content

Commit ebf68db

Browse files
Refactor and improve code formatting in client modules
1 parent 3a763f8 commit ebf68db

7 files changed

Lines changed: 35 additions & 92 deletions

File tree

src/nexus_client/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,18 @@
4747
# LangGraph exports (optional - requires langgraph optional dependencies)
4848
try:
4949
from nexus_client.langgraph import get_nexus_tools, list_skills
50+
5051
_HAS_LANGGRAPH = True
5152
except ImportError:
5253
# LangGraph dependencies not installed
5354
_HAS_LANGGRAPH = False
55+
5456
# Don't export these if dependencies aren't available
5557
def _langgraph_not_available():
5658
raise ImportError(
57-
"LangGraph integration requires optional dependencies. "
58-
"Install with: pip install nexus-fs-python[langgraph]"
59+
"LangGraph integration requires optional dependencies. Install with: pip install nexus-fs-python[langgraph]"
5960
)
61+
6062
get_nexus_tools = _langgraph_not_available # type: ignore
6163
list_skills = _langgraph_not_available # type: ignore
6264

src/nexus_client/async_client.py

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,7 @@ async def _fetch_auth_info(self) -> None:
194194
else:
195195
self._agent_id = None
196196
logger.info(
197-
f"Authenticated as {subject_type}:{auth_info.get('subject_id')} "
198-
f"(tenant: {self._tenant_id})"
197+
f"Authenticated as {subject_type}:{auth_info.get('subject_id')} (tenant: {self._tenant_id})"
199198
)
200199
else:
201200
logger.debug("Not authenticated (anonymous access)")
@@ -208,9 +207,7 @@ async def _fetch_auth_info(self) -> None:
208207
@retry(
209208
stop=stop_after_attempt(3),
210209
wait=wait_exponential(multiplier=1, min=1, max=10),
211-
retry=retry_if_exception_type(
212-
(httpx.ConnectError, httpx.TimeoutException, RemoteConnectionError)
213-
),
210+
retry=retry_if_exception_type((httpx.ConnectError, httpx.TimeoutException, RemoteConnectionError)),
214211
reraise=True,
215212
)
216213
async def _call_rpc(
@@ -285,9 +282,7 @@ async def _call_rpc(
285282

286283
# Check HTTP status
287284
if response.status_code != 200:
288-
logger.error(
289-
f"API call failed: {method} - HTTP {response.status_code} ({elapsed:.3f}s)"
290-
)
285+
logger.error(f"API call failed: {method} - HTTP {response.status_code} ({elapsed:.3f}s)")
291286
raise RemoteFilesystemError(
292287
f"Request failed: {response.text}",
293288
status_code=response.status_code,
@@ -307,9 +302,7 @@ async def _call_rpc(
307302

308303
# Check for RPC error
309304
if rpc_response.error:
310-
logger.error(
311-
f"API call RPC error: {method} - {rpc_response.error.get('message')} ({elapsed:.3f}s)"
312-
)
305+
logger.error(f"API call RPC error: {method} - {rpc_response.error.get('message')} ({elapsed:.3f}s)")
313306
self._handle_rpc_error(rpc_response.error)
314307

315308
# Log detailed timing for grep operations
@@ -366,9 +359,7 @@ def _handle_rpc_error(self, error: dict[str, Any]) -> None:
366359
raise FileExistsError(message)
367360
elif code == RPCErrorCode.INVALID_PATH.value:
368361
raise InvalidPathError(message)
369-
elif (
370-
code == RPCErrorCode.ACCESS_DENIED.value or code == RPCErrorCode.PERMISSION_ERROR.value
371-
):
362+
elif code == RPCErrorCode.ACCESS_DENIED.value or code == RPCErrorCode.PERMISSION_ERROR.value:
372363
raise NexusPermissionError(message)
373364
elif code == RPCErrorCode.VALIDATION_ERROR.value:
374365
raise ValidationError(message)
@@ -658,9 +649,7 @@ async def mkdir(
658649
Returns:
659650
Directory metadata dict
660651
"""
661-
result = await self._call_rpc(
662-
"mkdir", {"path": path, "parents": parents, "exist_ok": exist_ok}
663-
)
652+
result = await self._call_rpc("mkdir", {"path": path, "parents": parents, "exist_ok": exist_ok})
664653
return result # type: ignore[no-any-return]
665654

666655
async def glob(
@@ -1071,9 +1060,7 @@ async def diff_versions(
10711060
Returns:
10721061
Diff result (dict for metadata, str for content)
10731062
"""
1074-
result = await self._call_rpc(
1075-
"diff_versions", {"path": path, "v1": v1, "v2": v2, "mode": mode}
1076-
)
1063+
result = await self._call_rpc("diff_versions", {"path": path, "v1": v1, "v2": v2, "mode": mode})
10771064
return result # type: ignore[no-any-return]
10781065

10791066
# ============================================================
@@ -2676,9 +2663,7 @@ async def get_trajectory_feedback(
26762663
Returns:
26772664
List of feedback dicts
26782665
"""
2679-
result = await self.remote_fs._call_rpc(
2680-
"ace_get_trajectory_feedback", {"trajectory_id": trajectory_id}
2681-
)
2666+
result = await self.remote_fs._call_rpc("ace_get_trajectory_feedback", {"trajectory_id": trajectory_id})
26822667
return result # type: ignore[no-any-return]
26832668

26842669
async def get_effective_score(

src/nexus_client/client.py

Lines changed: 14 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -695,9 +695,7 @@ def _fetch_auth_info(self) -> None:
695695
from the server's /api/auth/whoami endpoint.
696696
"""
697697
try:
698-
response = self.session.get(
699-
urljoin(self.server_url, "/api/auth/whoami"), timeout=self.connect_timeout
700-
)
698+
response = self.session.get(urljoin(self.server_url, "/api/auth/whoami"), timeout=self.connect_timeout)
701699

702700
if response.status_code == 200:
703701
auth_info = response.json()
@@ -711,8 +709,7 @@ def _fetch_auth_info(self) -> None:
711709
else:
712710
self.agent_id = None
713711
logger.info(
714-
f"Authenticated as {subject_type}:{auth_info.get('subject_id')} "
715-
f"(tenant: {self.tenant_id})"
712+
f"Authenticated as {subject_type}:{auth_info.get('subject_id')} (tenant: {self.tenant_id})"
716713
)
717714
else:
718715
logger.debug("Not authenticated (anonymous access)")
@@ -725,14 +722,10 @@ def _fetch_auth_info(self) -> None:
725722
@retry(
726723
stop=stop_after_attempt(3),
727724
wait=wait_exponential(multiplier=1, min=1, max=10),
728-
retry=retry_if_exception_type(
729-
(httpx.ConnectError, httpx.TimeoutException, RemoteConnectionError)
730-
),
725+
retry=retry_if_exception_type((httpx.ConnectError, httpx.TimeoutException, RemoteConnectionError)),
731726
reraise=True,
732727
)
733-
def _call_rpc(
734-
self, method: str, params: dict[str, Any] | None = None, read_timeout: float | None = None
735-
) -> Any:
728+
def _call_rpc(self, method: str, params: dict[str, Any] | None = None, read_timeout: float | None = None) -> Any:
736729
"""Make RPC call to server with automatic retry logic.
737730
738731
This method automatically retries on transient failures (connection errors,
@@ -807,9 +800,7 @@ def _call_rpc(
807800

808801
# Check HTTP status
809802
if response.status_code != 200:
810-
logger.error(
811-
f"API call failed: {method} - HTTP {response.status_code} ({elapsed:.3f}s)"
812-
)
803+
logger.error(f"API call failed: {method} - HTTP {response.status_code} ({elapsed:.3f}s)")
813804
raise RemoteFilesystemError(
814805
f"Request failed: {response.text}",
815806
status_code=response.status_code,
@@ -829,9 +820,7 @@ def _call_rpc(
829820

830821
# Check for RPC error
831822
if rpc_response.error:
832-
logger.error(
833-
f"API call RPC error: {method} - {rpc_response.error.get('message')} ({elapsed:.3f}s)"
834-
)
823+
logger.error(f"API call RPC error: {method} - {rpc_response.error.get('message')} ({elapsed:.3f}s)")
835824
self._handle_rpc_error(rpc_response.error)
836825

837826
# Log detailed timing breakdown for grep operations
@@ -896,9 +885,7 @@ def _handle_rpc_error(self, error: dict[str, Any]) -> None:
896885
raise FileExistsError(message)
897886
elif code == RPCErrorCode.INVALID_PATH.value:
898887
raise InvalidPathError(message)
899-
elif (
900-
code == RPCErrorCode.ACCESS_DENIED.value or code == RPCErrorCode.PERMISSION_ERROR.value
901-
):
888+
elif code == RPCErrorCode.ACCESS_DENIED.value or code == RPCErrorCode.PERMISSION_ERROR.value:
902889
raise NexusPermissionError(message)
903890
elif code == RPCErrorCode.VALIDATION_ERROR.value:
904891
raise ValidationError(message)
@@ -1438,9 +1425,7 @@ async def semantic_search(
14381425
)
14391426
return result # type: ignore[no-any-return]
14401427

1441-
async def semantic_search_index(
1442-
self, path: str = "/", recursive: bool = True
1443-
) -> dict[str, int]:
1428+
async def semantic_search_index(self, path: str = "/", recursive: bool = True) -> dict[str, int]:
14441429
"""Index documents for semantic search.
14451430
14461431
Args:
@@ -1538,9 +1523,7 @@ def rollback(self, path: str, version: int, context: Any = None) -> None: # noq
15381523
# context is unused in remote client (handled server-side)
15391524
self._call_rpc("rollback", {"path": path, "version": version})
15401525

1541-
def diff_versions(
1542-
self, path: str, v1: int, v2: int, mode: str = "metadata"
1543-
) -> dict[str, Any] | str:
1526+
def diff_versions(self, path: str, v1: int, v2: int, mode: str = "metadata") -> dict[str, Any] | str:
15441527
"""Compare two versions of a file."""
15451528
result = self._call_rpc("diff_versions", {"path": path, "v1": v1, "v2": v2, "mode": mode})
15461529
return result # type: ignore[no-any-return]
@@ -1904,8 +1887,7 @@ def get_acl(self, path: str) -> builtins.list[dict[str, str | bool | None]]:
19041887
- rebac_expand(): Find all subjects with a permission
19051888
"""
19061889
raise NotImplementedError(
1907-
"get_acl() is no longer supported. Use ReBAC instead:\n"
1908-
f" nx.rebac_list_tuples(object=('file', '{path}'))"
1890+
f"get_acl() is no longer supported. Use ReBAC instead:\n nx.rebac_list_tuples(object=('file', '{path}'))"
19091891
)
19101892

19111893
# ============================================================
@@ -2638,9 +2620,7 @@ def revoke_consent(self, from_subject: tuple[str, str], to_subject: tuple[str, s
26382620
... to_subject=("user", "bob")
26392621
... )
26402622
"""
2641-
result = self._call_rpc(
2642-
"revoke_consent", {"from_subject": from_subject, "to_subject": to_subject}
2643-
)
2623+
result = self._call_rpc("revoke_consent", {"from_subject": from_subject, "to_subject": to_subject})
26442624
return result # type: ignore[no-any-return]
26452625

26462626
def make_public(self, resource: tuple[str, str], tenant_id: str | None = None) -> str:
@@ -3064,9 +3044,7 @@ def list_saved_mounts(
30643044
>>> # List mounts for specific user
30653045
>>> alice_mounts = nx.list_saved_mounts(owner_user_id="google:alice123")
30663046
"""
3067-
result = self._call_rpc(
3068-
"list_saved_mounts", {"owner_user_id": owner_user_id, "tenant_id": tenant_id}
3069-
)
3047+
result = self._call_rpc("list_saved_mounts", {"owner_user_id": owner_user_id, "tenant_id": tenant_id})
30703048
return result # type: ignore[no-any-return]
30713049

30723050
def load_mount(self, mount_point: str) -> str:
@@ -3350,8 +3328,7 @@ def register_workspace(
33503328
created_by: str | None = None,
33513329
tags: builtins.list[str] | None = None,
33523330
metadata: dict[str, Any] | None = None,
3353-
session_id: str
3354-
| None = None, # v0.5.0: If provided, workspace is session-scoped (temporary)
3331+
session_id: str | None = None, # v0.5.0: If provided, workspace is session-scoped (temporary)
33553332
ttl: timedelta | None = None, # v0.5.0: Time-to-live for auto-expiry
33563333
) -> dict[str, Any]:
33573334
"""Register a directory as a workspace.
@@ -3755,9 +3732,7 @@ def ace_add_feedback(
37553732
result = self._call_rpc("ace_add_feedback", params)
37563733
return result # type: ignore[no-any-return]
37573734

3758-
def ace_get_trajectory_feedback(
3759-
self, trajectory_id: str, context: dict | None = None
3760-
) -> builtins.list[dict]:
3735+
def ace_get_trajectory_feedback(self, trajectory_id: str, context: dict | None = None) -> builtins.list[dict]:
37613736
"""Get all feedback for a trajectory.
37623737
37633738
Args:

src/nexus_client/exceptions.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,7 @@ def __init__(self, path: str, expected_etag: str, current_etag: str):
119119
class AuditLogError(NexusError):
120120
"""Raised when audit logging fails and audit_strict_mode is enabled."""
121121

122-
def __init__(
123-
self, message: str, path: str | None = None, original_error: Exception | None = None
124-
):
122+
def __init__(self, message: str, path: str | None = None, original_error: Exception | None = None):
125123
self.original_error = original_error
126124
super().__init__(message, path)
127125

src/nexus_client/langgraph/client.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ async def _get_nexus_client(config: RunnableConfig, state: dict[str, Any] | None
3939

4040
if not x_auth:
4141
raise ValueError(
42-
"Missing x_auth in metadata. "
43-
"Frontend must pass API key via metadata: {'x_auth': 'Bearer <token>'}"
42+
"Missing x_auth in metadata. Frontend must pass API key via metadata: {'x_auth': 'Bearer <token>'}"
4443
)
4544

4645
# Strip "Bearer " prefix if present

src/nexus_client/langgraph/tools.py

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,7 @@ async def read_file(
269269
# Parse read command
270270
parts = shlex.split(read_cmd.strip())
271271
if not parts:
272-
return (
273-
"Error: Empty read command. Usage: read_file('[cat|less] path [start] [end]')"
274-
)
272+
return "Error: Empty read command. Usage: read_file('[cat|less] path [start] [end]')"
275273

276274
# Determine command type, path, and line range
277275
start_line = None
@@ -352,9 +350,7 @@ async def read_file(
352350
if start_line < 1:
353351
return f"Error: Start line must be >= 1, got {start_line}"
354352
if start_line > total_lines:
355-
return (
356-
f"Error: Start line {start_line} exceeds file length ({total_lines} lines)"
357-
)
353+
return f"Error: Start line {start_line} exceeds file length ({total_lines} lines)"
358354

359355
if end_line is not None:
360356
if end_line < 1:
@@ -382,9 +378,7 @@ async def read_file(
382378
f"Try a smaller line range."
383379
)
384380

385-
output = (
386-
f"Content of {path} (lines {start_line or 1}-{end_idx} of {total_lines}):\n\n"
387-
)
381+
output = f"Content of {path} (lines {start_line or 1}-{end_idx} of {total_lines}):\n\n"
388382
output += content_str
389383
return output
390384

@@ -485,9 +479,7 @@ async def python(
485479
return "Error: sandbox_id not found in metadata. Please start a sandbox first."
486480

487481
# Execute Python code in sandbox
488-
result = await nx.sandbox_run(
489-
sandbox_id=sandbox_id, language="python", code=code, timeout=300
490-
)
482+
result = await nx.sandbox_run(sandbox_id=sandbox_id, language="python", code=code, timeout=300)
491483

492484
# Format output
493485
output_parts = []
@@ -542,9 +534,7 @@ async def bash(
542534
return "Error: sandbox_id not found in metadata. Please start a sandbox first."
543535

544536
# Execute bash command in sandbox
545-
result = await nx.sandbox_run(
546-
sandbox_id=sandbox_id, language="bash", code=command, timeout=300
547-
)
537+
result = await nx.sandbox_run(sandbox_id=sandbox_id, language="bash", code=command, timeout=300)
548538

549539
# Format output
550540
output_parts = []

src/nexus_client/protocol.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,7 @@ def default(self, obj: Any) -> Any:
156156
return {"__type__": "datetime", "data": obj.isoformat()}
157157
elif hasattr(obj, "__dict__"):
158158
# Convert objects to dictionaries, filtering out methods
159-
return {
160-
k: v for k, v in obj.__dict__.items() if not k.startswith("_") and not callable(v)
161-
}
159+
return {k: v for k, v in obj.__dict__.items() if not k.startswith("_") and not callable(v)}
162160
return super().default(obj)
163161

164162

@@ -203,11 +201,7 @@ def _prepare_for_orjson(obj: Any) -> Any:
203201
elif isinstance(obj, (list, tuple)):
204202
return [_prepare_for_orjson(item) for item in obj]
205203
elif hasattr(obj, "__dict__") and not isinstance(obj, type):
206-
return {
207-
k: _prepare_for_orjson(v)
208-
for k, v in obj.__dict__.items()
209-
if not k.startswith("_") and not callable(v)
210-
}
204+
return {k: _prepare_for_orjson(v) for k, v in obj.__dict__.items() if not k.startswith("_") and not callable(v)}
211205
else:
212206
return obj
213207

0 commit comments

Comments
 (0)