Skip to content

Commit

Permalink
added age <3
Browse files Browse the repository at this point in the history
  • Loading branch information
jhnnsrs committed Aug 19, 2024
1 parent 70b8db3 commit 33118e6
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 9 deletions.
99 changes: 99 additions & 0 deletions core/age.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
from contextlib import contextmanager
from django.db import connections
from core import models


@contextmanager
def graph_cursor():
with connections["default"].cursor() as cursor:
cursor.execute("LOAD 'age';")
cursor.execute('SET search_path = ag_catalog, "$user", public')
yield cursor


def create_age_ontology(name: str):
with graph_cursor() as cursor:
cursor.execute(
"SELECT EXISTS(SELECT 1 FROM ag_catalog.ag_graph WHERE name = %s);",
[name]
)
exists = cursor.fetchone()[0]
if exists:
return exists
else:
cursor.execute(
"SELECT create_graph(%s);",
[name]
)
print(cursor.fetchone())


def create_age_entity_kind(graph_name, kind_name):
with graph_cursor() as cursor:
try:
cursor.execute(
"SELECT create_vlabel(%s, %s);",
(graph_name, kind_name)
)
print(cursor.fetchone())
except Exception as e:
print(e)


def create_age_relation_kind(graph_name, kind_name):
with graph_cursor() as cursor:
try:
cursor.execute(
"SELECT create_elabel(%s, %s);",
(graph_name, kind_name)
)
print(cursor.fetchone())
except Exception as e:
print(e)


def create_age_entity(graph_name, kind_name, entity_id):
with graph_cursor() as cursor:
cursor.execute(
f"""
SELECT *
FROM cypher(%s, $$
CREATE (n:{kind_name})
RETURN n.id
$$) as (id agtype);
""",
(graph_name,)
)
print(cursor.fetchone())



def create_age_relation(relation_kind: models.EntityRelationKind, left_id, right_id):
with graph_cursor() as cursor:
cursor.execute(
f"""
SELECT *
FROM cypher(%s, $$
MATCH (a:{relation_kind.left_kind.age_name} {{id: %s}})
MATCH (b:{relation_kind.right_kind.age_name} {{id: %s}})
CREATE (a)-[:{relation_kind.age_name}]->(b)
$$) as (id agtype);
""",
(relation_kind.kind.ontology.age_name, left_id, right_id)
)
print(cursor.fetchone())


def select_all_entities(graph_name):
with graph_cursor() as cursor:
cursor.execute(
f"""
SELECT *
FROM cypher(%s, $$
MATCH (n)
RETURN n.id
$$) as (id agtype);
""",
[graph_name]
)
print(cursor.fetchall())
33 changes: 33 additions & 0 deletions core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,25 @@ class ProtocolStep(models.Model):






class Reagent(models.Model):
entity_kind = models.ForeignKey("EntityKind", on_delete=models.CASCADE, related_name="reagents", help_text="The associated entity")
protocol = models.ForeignKey(
Protocol,
on_delete=models.CASCADE,
null=True,
blank=True,
related_name="reagents",
)
volume = models.FloatField(
help_text="The volume of the reagent in the protocol",
null=True,
blank=True,
)


class Specimen(models.Model):
entity = models.ForeignKey("Entity", on_delete=models.CASCADE, related_name="specimens", help_text="The associated entity")
protocol = models.ForeignKey(
Expand Down Expand Up @@ -1066,6 +1085,11 @@ class Ontology(models.Model):

def __str__(self) -> str:
return self.name


@property
def age_name(self) -> str:
return self.name.replace(" ", "_").lower()



Expand Down Expand Up @@ -1093,6 +1117,10 @@ class EntityRelationKind(models.Model):
help_text="The kind of the relation",
)

@property
def age_name(self) -> str:
return self.kind.label.replace(" ", "_").lower() + "_relation"



def random_color():
Expand Down Expand Up @@ -1155,6 +1183,11 @@ def create_entity(self, group, name: str = None, instance_kind: str = None, met
def rgb_color_string(self) -> str:
return f"rgb({self.color[0]}, {self.color[1]}, {self.color[2]})"


@property
def age_name(self) -> str:
return self.label.replace(" ", "_").lower()


class EntityGroup(models.Model):
"""An EntityGroup is a collection of Entities.
Expand Down
11 changes: 8 additions & 3 deletions core/mutations/entity.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from kante.types import Info
import strawberry
from core import types, models
from core import types, models, age
import uuid


Expand Down Expand Up @@ -35,17 +35,22 @@ def create_entity(
input_kind = models.EntityKind.objects.get(id=input.kind)


id = uuid.uuid4().hex

item, _ = models.Entity.objects.get_or_create(
name=input.name or uuid.uuid4().hex,
name=id,
group=group,
kind=input_kind,
defaults=dict(
name=input.name or uuid.uuid4().hex,
name=id,
instance_kind=input.instance_kind,
)
)

age.create_age_entity(input_kind.ontology.age_name, input_kind.age_name, id)





assert item.kind.id == input_kind.id, f"Entity kind mismatch {item.kind} vs {input_kind}"
Expand Down
12 changes: 12 additions & 0 deletions core/mutations/entity_kind.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from kante.types import Info
import strawberry
from core import types, models
from core import age


@strawberry.input
Expand Down Expand Up @@ -35,6 +36,10 @@ def create_entity_kind(
description="Default ontology for {}".format(user.username),)
)

age.create_age_ontology(ontology.age_name)



if input.color:
assert len(input.color) == 3 or len(input.color) == 4, "Color must be a list of 3 or 4 values RGBA"

Expand All @@ -46,6 +51,13 @@ def create_entity_kind(
color=input.color or models.random_color(),
)
)

age.create_age_entity_kind(ontology.age_name, item.age_name)





return item


Expand Down
18 changes: 16 additions & 2 deletions core/mutations/entity_relation.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from kante.types import Info
import strawberry
from core import types, models
from core import types, models, age


@strawberry.input
Expand Down Expand Up @@ -32,6 +32,12 @@ def create_entity_relation_kind(
right_kind=models.EntityKind.objects.get(id=input.right_kind),
kind=models.EntityKind.objects.get(id=input.kind),
)


age.create_age_relation_kind(item.kind.ontology.age_name, item.age_name)



return item


Expand All @@ -40,11 +46,19 @@ def create_entity_relation(
info: Info,
input: EntityRelationInput,
) -> types.EntityRelation:

kind = models.EntityRelationKind.objects.get(id=input.kind)
item, _ = models.EntityRelation.objects.get_or_create(
left=models.Entity.objects.get(id=input.left),
right=models.Entity.objects.get(id=input.right),
kind=models.EntityRelationKind.objects.get(id=input.kind),
kind=kind
)

age.create_age_relation(kind, input.left, input.right)




return item


Expand Down
24 changes: 21 additions & 3 deletions core/mutations/ontology.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from kante.types import Info
import strawberry
from core import types, models
from core import types, models, age
from django.db import connections
from contextlib import contextmanager



@strawberry.input
Expand All @@ -15,18 +18,23 @@ class DeleteOntologyInput:
id: strawberry.ID


def to_snake_case(string):
return string.replace(" ", "_").lower()


def create_ontology(
info: Info,
input: OntologyInput,
) -> types.Ontology:

item, _ = models.Ontology.objects.update_or_create(
name=input.name,
name=to_snake_case(input.name),
defaults=dict(
description=input.description or "",
purl=input.purl)
)

age.create_age_ontology(item.name)

return item

Expand All @@ -35,7 +43,17 @@ def delete_ontology(
info: Info,
input: DeleteOntologyInput,
) -> strawberry.ID:
item = models.Entity.objects.get(id=input.id)
item = models.Ontology.objects.get(id=input.id)


with graph_cursor() as cursor:
cursor.execute(
"SELECT delete_graph(%s);",
[item.name]
)
print(cursor.fetchone())

item.delete()

return input.id

7 changes: 6 additions & 1 deletion core/queries/entity_graph.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import strawberry
from core import models
from core import models, age


@strawberry.type
Expand Down Expand Up @@ -52,6 +52,11 @@ def entity_graph(id: strawberry.ID) -> EntityGraph:
entity = models.Entity.objects.get(id=id)


print(age.select_all_entities(entity.kind.ontology.age_name))




def parse_entity(entity: models.Entity, is_root=False):

node = EntityNode(id=entity.id, subtitle=entity.name, metrics=[], label=entity.kind.label, is_root=is_root, color=entity.kind.rgb_color_string)
Expand Down
8 changes: 8 additions & 0 deletions mikro_server/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,14 @@
"PASSWORD": conf.db.password,
"HOST": conf.db.host,
"PORT": conf.db.port,
},
"graph": {
"ENGINE": conf.db.engine,
"NAME": "mikro_graph",
"USER": conf.db.username,
"PASSWORD": conf.db.password,
"HOST": "age",
"PORT": conf.db.port,
}
}

Expand Down

0 comments on commit 33118e6

Please sign in to comment.