Skip to content

Commit

Permalink
Merge pull request #1382 from Jaseci-Labs/feature/purge-graph
Browse files Browse the repository at this point in the history
[FEATURE]: purge_graph - purge whole graph excluding root
  • Loading branch information
ypkang authored Nov 15, 2024
2 parents ba152b9 + 55b0a4f commit a98cce3
Show file tree
Hide file tree
Showing 15 changed files with 896 additions and 40 deletions.
24 changes: 13 additions & 11 deletions jac-cloud/jac_cloud/core/architype.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,15 +387,15 @@ def _pull(self) -> dict:
def add_to_set(self, field: str, anchor: Anchor, remove: bool = False) -> None:
"""Add to set."""
if field not in (add_to_set := self._add_to_set):
add_to_set[field] = {"$each": set()}
add_to_set[field] = {"$each": []}

ops: set = add_to_set[field]["$each"]
ops: list = add_to_set[field]["$each"]

if remove:
if anchor in ops:
ops.remove(anchor)
else:
ops.add(anchor)
ops.append(anchor)
self.pull(field, anchor, True)

def pull(self, field: str, anchor: Anchor, remove: bool = False) -> None:
Expand Down Expand Up @@ -432,9 +432,10 @@ def make_stub(self: "BaseAnchor | TANCH") -> "BaseAnchor | TANCH":
"""Return unsynced copy of anchor."""
if self.is_populated():
unloaded = object.__new__(self.__class__)
unloaded.name = self.name
unloaded.id = self.id
return unloaded
# this will be refactored on abstraction
unloaded.name = self.name # type: ignore[attr-defined]
unloaded.id = self.id # type: ignore[attr-defined]
return unloaded # type: ignore[return-value]
return self

def populate(self) -> None:
Expand Down Expand Up @@ -535,7 +536,7 @@ def update(self, bulk_write: BulkWrite, propagate: bool = False) -> None:
_added_edges = []
for anchor in added_edges:
if propagate:
anchor.build_query(bulk_write)
anchor.build_query(bulk_write) # type: ignore[operator]
_added_edges.append(anchor.ref_id)
changes["$addToSet"]["edges"]["$each"] = _added_edges
else:
Expand All @@ -552,9 +553,10 @@ def update(self, bulk_write: BulkWrite, propagate: bool = False) -> None:
if pulled_edges:
_pulled_edges = []
for anchor in pulled_edges:
if propagate and anchor.state.deleted is not True:
anchor.state.deleted = True
bulk_write.del_edge(anchor.id)
# will be refactored on abstraction
if propagate and anchor.state.deleted is not True: # type: ignore[attr-defined]
anchor.state.deleted = True # type: ignore[attr-defined]
bulk_write.del_edge(anchor.id) # type: ignore[attr-defined, arg-type]
_pulled_edges.append(anchor.ref_id)

if added_edges:
Expand Down Expand Up @@ -643,7 +645,7 @@ class NodeAnchor(BaseAnchor, _NodeAnchor): # type: ignore[misc]
"""Node Anchor."""

architype: "NodeArchitype"
edges: list["EdgeAnchor"]
edges: list["EdgeAnchor"] # type: ignore[assignment]

class Collection(BaseCollection["NodeAnchor"]):
"""NodeAnchor collection interface."""
Expand Down
31 changes: 31 additions & 0 deletions jac-cloud/jac_cloud/plugin/jaseci.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,37 @@ def get_context() -> ExecutionContext:

return JaseciContext.get()

@staticmethod
@hookimpl
def reset_graph(root: Root | None = None) -> int:
"""Purge current or target graph."""
if not FastAPI.is_enabled():
return JacFeatureImpl.reset_graph(root=root) # type: ignore[arg-type]

ctx = JaseciContext.get()
ranchor = root.__jac__ if root else ctx.root

deleted_count = 0 # noqa: SIM113

for node in NodeAnchor.Collection.find(
{"_id": {"$ne": ranchor.id}, "root": ranchor.id}
):
ctx.mem.__mem__[node.id] = node
Jac.destroy(node)
deleted_count += 1

for edge in EdgeAnchor.Collection.find({"root": ranchor.id}):
ctx.mem.__mem__[edge.id] = edge
Jac.destroy(edge)
deleted_count += 1

for walker in WalkerAnchor.Collection.find({"root": ranchor.id}):
ctx.mem.__mem__[walker.id] = walker
Jac.destroy(walker)
deleted_count += 1

return deleted_count

@staticmethod
@hookimpl
def make_architype(
Expand Down
20 changes: 12 additions & 8 deletions jac-cloud/jac_cloud/plugin/mini/cli_mini.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,15 @@ def populate_apis(router: APIRouter, cls: Type[WalkerArchitype]) -> None:
files: dict[str, Any] = {}

hintings = get_type_hints(cls)
for f in fields(cls):
f_name = f.name
f_type = hintings[f_name]
if f_type in FILE_TYPES:
files[f_name] = gen_model_field(f_type, f, True)
else:
consts = gen_model_field(f_type, f)
body[f_name] = consts
if is_dataclass(cls):
for f in fields(cls):
f_name = f.name
f_type = hintings[f_name]
if f_type in FILE_TYPES:
files[f_name] = gen_model_field(f_type, f, True)
else:
consts = gen_model_field(f_type, f)
body[f_name] = consts

payload: dict[str, Any] = {
"files": (
Expand Down Expand Up @@ -134,6 +135,9 @@ def api_entry(
Jac.spawn_call(cls(**body, **pl["files"]), jctx.entry_node.architype)
jctx.close()

if jctx.custom is not MISSING:
return jctx.custom

return response(jctx.reports, getattr(jctx, "status", 200))

def api_root(
Expand Down
212 changes: 212 additions & 0 deletions jac-cloud/jac_cloud/tests/openapi_specs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,59 @@ paths:
tags:
- walker
- walker
/walker/check_populated_graph:
post:
operationId: api_root_walker_check_populated_graph_post
responses:
'200':
content:
application/json:
schema:
anyOf:
- $ref: '#/components/schemas/ContextResponse_NoneType_'
- {}
title: Response Api Root Walker Check Populated Graph Post
description: Successful Response
security:
- HTTPBearer: []
summary: /check_populated_graph
tags:
- walker
- walker
/walker/check_populated_graph/{node}:
post:
operationId: api_entry_walker_check_populated_graph__node__post
parameters:
- in: path
name: node
required: true
schema:
anyOf:
- type: string
- type: 'null'
title: Node
responses:
'200':
content:
application/json:
schema:
anyOf:
- $ref: '#/components/schemas/ContextResponse_NoneType_'
- {}
title: Response Api Entry Walker Check Populated Graph Node Post
description: Successful Response
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
security:
- HTTPBearer: []
summary: /check_populated_graph/{node}
tags:
- walker
- walker
/walker/combination1:
get:
operationId: api_root_walker_combination1_get
Expand Down Expand Up @@ -2789,6 +2842,59 @@ paths:
tags:
- walker
- walker
/walker/populate_graph:
post:
operationId: api_root_walker_populate_graph_post
responses:
'200':
content:
application/json:
schema:
anyOf:
- $ref: '#/components/schemas/ContextResponse_NoneType_'
- {}
title: Response Api Root Walker Populate Graph Post
description: Successful Response
security:
- HTTPBearer: []
summary: /populate_graph
tags:
- walker
- walker
/walker/populate_graph/{node}:
post:
operationId: api_entry_walker_populate_graph__node__post
parameters:
- in: path
name: node
required: true
schema:
anyOf:
- type: string
- type: 'null'
title: Node
responses:
'200':
content:
application/json:
schema:
anyOf:
- $ref: '#/components/schemas/ContextResponse_NoneType_'
- {}
title: Response Api Entry Walker Populate Graph Node Post
description: Successful Response
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
security:
- HTTPBearer: []
summary: /populate_graph/{node}
tags:
- walker
- walker
/walker/post_all_excluded:
post:
operationId: api_root_walker_post_all_excluded_post
Expand Down Expand Up @@ -3313,6 +3419,59 @@ paths:
tags:
- walker
- walker
/walker/purge_populated_graph:
post:
operationId: api_root_walker_purge_populated_graph_post
responses:
'200':
content:
application/json:
schema:
anyOf:
- $ref: '#/components/schemas/ContextResponse_NoneType_'
- {}
title: Response Api Root Walker Purge Populated Graph Post
description: Successful Response
security:
- HTTPBearer: []
summary: /purge_populated_graph
tags:
- walker
- walker
/walker/purge_populated_graph/{node}:
post:
operationId: api_entry_walker_purge_populated_graph__node__post
parameters:
- in: path
name: node
required: true
schema:
anyOf:
- type: string
- type: 'null'
title: Node
responses:
'200':
content:
application/json:
schema:
anyOf:
- $ref: '#/components/schemas/ContextResponse_NoneType_'
- {}
title: Response Api Entry Walker Purge Populated Graph Node Post
description: Successful Response
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
security:
- HTTPBearer: []
summary: /purge_populated_graph/{node}
tags:
- walker
- walker
/walker/traverse_graph:
post:
operationId: api_root_walker_traverse_graph_post
Expand Down Expand Up @@ -3366,6 +3525,59 @@ paths:
tags:
- walker
- walker
/walker/traverse_populated_graph:
post:
operationId: api_root_walker_traverse_populated_graph_post
responses:
'200':
content:
application/json:
schema:
anyOf:
- $ref: '#/components/schemas/ContextResponse_NoneType_'
- {}
title: Response Api Root Walker Traverse Populated Graph Post
description: Successful Response
security:
- HTTPBearer: []
summary: /traverse_populated_graph
tags:
- walker
- walker
/walker/traverse_populated_graph/{node}:
post:
operationId: api_entry_walker_traverse_populated_graph__node__post
parameters:
- in: path
name: node
required: true
schema:
anyOf:
- type: string
- type: 'null'
title: Node
responses:
'200':
content:
application/json:
schema:
anyOf:
- $ref: '#/components/schemas/ContextResponse_NoneType_'
- {}
title: Response Api Entry Walker Traverse Populated Graph Node Post
description: Successful Response
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
security:
- HTTPBearer: []
summary: /traverse_populated_graph/{node}
tags:
- walker
- walker
/walker/update_graph:
post:
operationId: api_root_walker_update_graph_post
Expand Down
Loading

0 comments on commit a98cce3

Please sign in to comment.