class Institution(GraphObject): __primarykey__ = "name" name = Property() mayor = RelatedFrom("Politician", "MAYOR") located = RelatedTo(Region) def __init__(self, name, region_name): self.name = name if (region_name): region = Region(region_name) self.located.add(region) def serialize(self): return {'name': self.name}
class Pathway(GraphObject): """ Pathway """ __primarykey__ = 'accession' accession = Property() _type = Property() species = Property() _class = Property() name = Property() compartment = Property() # Description summation = Property() protein = RelatedFrom("Protein", "INVOLVED_IN")
class Article(GraphObject): __primarykey__ = "articleId" articleId = Property() title = Property() summary = Property() author = Property() tag = Property() url = Property() date = Property() star = Property() score = Property() views = Property() comments = Property() source = Property() # (a-from-b <=> b->a ) like = RelatedFrom("User", "LIKE")
class Film(MovieModel): __primarylabel__ = "Movie" __primarykey__ = "title" awesome = Label() musical = Label() science_fiction = Label(name="SciFi") title = Property() tag_line = Property(key="tagline", default="Bit boring") year_of_release = Property(key="released") actors = RelatedFrom("Person", "ACTED_IN") def __init__(self, title): self.title = title
class Student(GraphObject): __primarykey__ = "name" # properties name = Property() born = Property() discipline = Property() belt = Property() degree = Property() # Optional # relationships trains_at = RelatedFrom(School) taught_by = RelatedTo("Instructor", "") # Compare def __lt__(self, other): return self.name < other.name
class GenreModel(BaseModel): __primarykey__ = "name" __primarylabel__ = "Genre" id = Property() name = Property() movies = RelatedFrom("Movie", "IN_GENRE") def find_movies(self): return self.find_related_from("IN_GENRE") def json(self): return { **dict(self.__node__), "movies": self.find_movies() }
class Keyword(BaseModel): __primarykey__ = "value" value = Property() papers = RelatedFrom("Paper", HAS_KEYWORD_RELATIONSHIP) def fetch(self): graph = get_graph() return Keyword.match(graph, self.value).first() def fetch_papers(self): return [{ **paper[0].asdict() } for paper in self.papers._related_objects] def asdict(self): return {"value": self.value}
class EntityNode(GraphObject): __primarylabel__ = "Entity" __primarykey__ = "name" name = Property() tag = Property() #count = Property() #weight = Property() synonyms = Property() occurs_with = Related("EntityNode", "OCCURS_WITH") occurs_in = RelatedFrom(ArticleNode) def __init__(self, entity): self.name = entity.name self.tag = entity.tag self.synonyms = entity.synonyms
class Tag(GraphObject): """ Class for Tag node """ __primarykey__ = "tag_id" tag_id = Property() tag_name = Property() books = RelatedFrom("Book", "TAGGED_TO") def __init__(self, tag_id, tag_name=None): self.tag_id = tag_id self.tag_name = tag_name def insert(self): """ Insert tag to graph""" graph.push(self)
class UserGraphObj(GraphObject): # The primary node label used for Cypher MATCH and MERGE operations __primarylabel__ = 'User' # The primary property key used for Cypher MATCH and MERGE operations __primarykey__ = 'twitch_uid' # PROPERTIES twitch_uid = Property('twitch_uid') name = Property('name') display_name = Property('display_name') broadcaster_type = Property('broadcaster_type') # RELATIONSHIPS is_following = RelatedTo('Streamer', 'IS_FOLLOWING') is_followed_by = RelatedFrom('User', 'IS_FOLLOWED_BY') def __init__(self, twitch_uid): self.twitch_uid = twitch_uid
class Connection(BaseModel): __primarykey__ = '__id__' creator = RelatedTo("User", 'CREATED_BY') copied_by = RelatedTo("User", 'COPIED_BY') statement_from = RelatedTo("Statement", 'LEADS_FROM') statement_to = RelatedFrom("Statement", 'LEADS_TO') def __init__(self, **kwargs): super().__init__(**kwargs) def fetch_by_id(self, id): return graph.nodes.get(id) def submit_connection(self, statement_from, statement_to, creator): from_id = statement_from.identity statement_from = Statement(type=statement_from.get('type'), text=statement_from.get('text')).fetch_by_text_and_type() to_id = statement_to.as_dict()['id'] user_id = creator.as_dict()['id'] if self.__verify_not_connected_by_user(from_id, to_id, user_id): self.__link_statements(statement_from, statement_to) self.creator.add(creator) self.save() def copy_connection(self, statement_from, statement_to, copier): from_id = statement_from.identity to_id = statement_to.identity statement_from = Statement(type=statement_from.get('type'), text=statement_from.get('text')).fetch_by_text_and_type() statement_to = Statement(type=statement_to.get('type'), text=statement_to.get('text')).fetch_by_text_and_type() user_id = copier.as_dict()['id'] if self.__verify_not_connected_by_user(from_id, to_id, user_id): self.__link_statements(statement_from, statement_to) self.copied_by.add(copier) self.save() def __link_statements(self, statement_from, statement_to): self.statement_from.add(statement_from) self.statement_to.add(statement_to) def __verify_not_connected_by_user(self, id_from, id_to, user_id): result = graph.run("MATCH (a:Statement)<-[r:LEADS_FROM]-(c:Connection)<-[s:LEADS_TO]-(b:Statement)" + "WHERE id(a) = {id_from} AND id(b) = {id_to} MATCH (c)-[]->(u:User) WHERE id(u) = {user_id} RETURN c" .format(id_from=id_from, id_to=id_to, user_id=user_id)) return result.evaluate() is None
class FeedItem(Model): attribute = Property() value = Property() source = RelatedTo(Feed, "SOURCE") properties = RelatedFrom("FeedItem", "PROPERTY") parent_item = RelatedTo("FeedItem", "PROPERTY") def get(self, key): graph = self.__ogm__.node.graph results = graph.run(""" match (a:FeedItem {{attribute:\"{}\"}})-[:PROPERTY*..4]->(n:FeedItem) where ID(n)={} return a limit 1; """.format(key, self.__primaryvalue__)) return FeedItem.wrap(results.evaluate()) def get_properties(self, properties: List[str]): match_clause = ( "match (a:FeedItem )-[:PROPERTY*..4]->(self)-[:SOURCE]->(feed:Feed)" ) # WHERE print("Primary value", self.__primaryvalue__) id_clause = "id(feed)={} and id(self)={}".format( self.source._related_objects[0][0].__primaryvalue__, self.__primaryvalue__) property_table = [("$a_{}".format(i), a) for i, a in enumerate(properties)] properties_clause = " or ".join([ 'a.attribute="{}"'.format(attribute) for title, attribute in property_table ]) return_clause = "a" query = f"{match_clause} where {id_clause} and ({properties_clause}) return {return_clause}" print(query) print("source: ", ) key_dict = { **dict(property_table), **{ "self_id": self.__primaryvalue__, "feed_id": "2" }, } data = graph.run(query).data() return dict([(v["a"]["attribute"], v["a"]["value"]) for v in data])
class Change(NeoGraphObject): __primarylabel__ = "Change" __primarykey__ = "id" __unique_constraints__ = [ "id", ] id = Property("id") old_path = Property("old_path") new_path = Property("new_path") a_mode = Property("a_mode") b_mode = Property("b_mode") new_file = Property("new_file") renamed_file = Property("renamed_file") deleted_file = Property("deleted_file") diff = Property("diff") changed_in_merge = RelatedFrom("MergeRequest", "HAS_CHANGE")
class Tweet(BaseModel): content = Property() user = RelatedFrom('User', 'TWEETED') def addUser(self, username): user = User(username=username).fetch() if user is None: raise GraphQLError("User was not found") self.user.add(user) def as_dict(self): return {'content': self.content} def getAllTweetsForUser(self, username): data = graph.run( f"MATCH (u:User)-[:TWEETED]->(t:Tweet) WHERE u.username=\"{username}\" return t" ).data() return [dict(tweet['t']) for tweet in data]
class Status(Model, metaclass=MetaKeepingModelAttrs): __primarylabel__ = "Status" text = Property() in_reply_to_statuses = RelatedTo(__primarylabel__, "REPLY") in_reply_from_statuses = RelatedFrom(__primarylabel__, "REPLY") def __init__(self, **properties) -> None: all_properties = self.__model_attributes__["property"] for key, value in properties.items(): if key in all_properties: setattr(self, key, value) def reply_to(self, model: "Status") -> None: self.in_reply_to_statuses.add(model) model.in_reply_from_statuses.add(self) def reply_from(self, model: "Status") -> None: self.in_reply_from_statuses.add(model) model.in_reply_to_statuses.add(self)
class Publication(GraphObject): """ Publication from PubMed """ __primarykey__ = 'pmid' pmid = Property() title = Property() volumetitle = Property() volume = Property() series_name = Property() issue = Property() year = Property() pages = Property() miniref = Property() uniquename = Property() is_obsolete = Property() publisher = Property() pubplace = Property() author = RelatedFrom("Author", "WROTE")
class Company(GraphObject): __primarykey__ = "key" scraped = Property() key = Property() name = Property() jurisdiction = Property() number = Property() external_reference = Property() raw_data = Property() directors = RelatedFrom("Person", "IN_DIRECTION") def from_oc(oc): c = Company() c.name = oc["name"] c.number = oc["company_number"] c.jurisdiction = oc["jurisdiction_code"] c.key = "%s%s" % (c.jurisdiction, c.number) c.raw_data = json.dumps(oc) return c
class User(GraphObject): __primarykey__ = 'username' # fields for registration username = Property() email = Property() password = Property() # additional fields for profile name = Property() surname = Property() preferences = Property() image = Property() # relationships follow = RelatedTo("User") read = RelatedTo("Book") wrote = RelatedTo("Review") subscribe = RelatedTo("Author") prefer = RelatedTo("Genre") wishes = RelatedTo("Book") follower = RelatedFrom("User", "FOLLOWS")
class Candidate(GraphObject): __primarykey__ = "CAND_ID" CAND_ID = Property() CAND_NAME = Property() CAND_ICI = Property() CAND_PCC = Property() CAND_ST1 = Property() CAND_ST2 = Property() CAND_PTY_AFFILIATION = RelatedTo("Party") CAND_ELECTION_YR = RelatedTo("ElectionYear") CAND_STATUS = RelatedTo("Status") CAND_CITY = RelatedTo("City") CAND_ZIP = RelatedTo("Zipcode") CAND_OFFICE_ST = RelatedTo("State") CAND_OFFICE = RelatedTo("Office") CAND_OFFICE_DISTRICT = RelatedTo("District") COM_CAND_ID = RelatedFrom("Committee", "CAND_ID")
class Equipments(GraphObject): __primarylabel__ = "equipments" __primarykey__ = "EID" EID = Property() aperture = Property() Fov = Property() pixel_scale = Property() tracking_accurcay = Property() lim_magnitude = Property() elevation_lim = Property() mount_type = Property() camera_type1 = Property() camera_type2 = Property() JohnsonB = Property() JohnsonV = Property() JohnsonR = Property() SDSSu = Property() SDSSg = Property() SDSSr = Property() SDSSi = Property() SDSSz = Property() owner = RelatedFrom(User, "UHAVEE")
class Tweet(GraphObject): text = Property() timestamp = Property() # Comment posted by a Person poster = RelatedFrom("Person", "COMMENT_POSTED") def add_or_update(self, **kwargs): for key, value in kwargs.items(): if hasattr(self, key): setattr(self, key, value) def __init__(self, **kwargs): self.add_or_update(**kwargs) def as_dict(self): return { 'key': self.__primaryvalue__, 'text': self.text, 'timestamp': self.timestamp } def update(self, **kwargs): self.add_or_update(**kwargs) # List interfaces def add_or_update_poster(self, poster): self.poster.update(poster) def remove_poster(self, poster): self.poster.remove(poster) # Object level interfaces def save(self, graph): graph.push(self) def delete(self, graph): graph.delete(self)
class ReviewModel(BaseModel): def __init__(self, *args, **kwargs): compositeId = { "movieId": kwargs['movieId'], "userId": kwargs['userId'] } self.compositeId = json.dumps(compositeId) super(ReviewModel, self).__init__(*args, **kwargs) __primarykey__ = "compositeId" __primarylabel__ = "Review" id = Property() compositeId = Property() userId = Property() movieId = Property() title = Property() description = Property() rating = Property() createdAt = Property() updatedAt = Property() user = RelatedFrom("User", "WROTE_REVIEW") reviewed_movie = RelatedTo(MovieModel, "REVIEWED_MOVIE") def find_reviewed_movie(self): return self.find_related_to(self.reviewed_movie) def find_user(self): return self.find_related_from("WROTE_REVIEW") def json(self): return { **dict(self.__node__), "user": self.find_user(), "reviewed_movie": self.find_reviewed_movie(), }
class EventNode(GraphObject): # 实现一个对象和Node的关联 __primarykey__ = 'title' theme = Property() # 事件主题, 例如李文星、魏则西等等 title = Property() time = Property() locations = Property() # 以空格/逗号做分割的字符串形式 persons = Property() organizations = Property() keywords = Property() next_events = RelatedTo('EventNode', 'NEXT_EVENT') triggers = RelatedFrom('TriggerNode', 'BELONG_TO') def __eq__(self, other): if isinstance(other, self.__class__): return self.title == other.title else: return False def __hash__(self): return hash(self.title)
class Version(GraphObject): __primarykey__ = "id" id = Property() number = Property() publish_timestamp = Property() created_timestamp = Property() updated_timestamp = Property() project = RelatedTo("Project") version = RelatedFrom("Version", "DEPENDENT_ON") def __init__(self, version): self.id = version['ID'] self.number = None version_parsed = re.findall("\\b\\d+\\b", version['Number']) if len(version_parsed) != 0: self.number = version_parsed[0] self.id = version['Project ID'] + '_' + self.number self.publish_timestamp = version['Published Timestamp'] self.created_timestamp = version['Created Timestamp'] self.updated_timestamp = version['Updated Timestamp']
class Project(GraphObject): __primarykey__ = "project_id" project_id = Property() name = Property() created_timestamp = Property() updated_timestamp = Property() description = Property() homepage = Property() source_rank = Property() latest_release_publish_timestamp = Property() latest_release_number = Property() last_synced_timestamp = Property() versions = RelatedFrom("Version", "BELONGS_TO") repositories = RelatedTo("Repository") platform = RelatedTo("Platform") language = RelatedTo("Language") status = RelatedTo("Status") licence = RelatedTo("Licence") def __init__(self, project): self.project_id = project['ID'] self.name = project['Name'] self.created_timestamp = project['Created Timestamp'] self.updated_timestamp = project['Updated Timestamp'] self.description = project['Description'] self.homepage = project['Homepage URL'] self.source_rank = project['SourceRank'] self.latest_release_publish_timestamp = project['Latest Release Publish Timestamp'] self.latest_release_number = None if project['Latest Release Number'] is not None: version_parsed = re.findall("\\b\\d+\\b", project['Latest Release Number']) if len(version_parsed) !=0: self.latest_release_number = version_parsed[0] self.last_synced_timestamp = project['Last synced Timestamp']
class GOTerm(GraphObject): """ Gene Ontology Terms """ __primarykey__ = 'accession' accession = Property() name = Property() definition = Property() is_obsolete = Property() ontology = Property() # same as namespace namespace = Property() is_a = RelatedTo("GOTerm", "IS_A") protein = RelatedFrom("Protein", "ASSOCIATED_WITH") # part_of = RelatedTo("GOTerm", "PART_OF") # feature = RelatedFrom("Feature", "ASSOC_WITH") def __init__(self, accession, name=None, definition=None, is_obsolete=None): self.accession = accession self.name = name self.definition = definition self.is_obsolete = is_obsolete
class Issue(NeoGraphObject): __primarylabel__ = "Issue" __primarykey__ = "id" __unique_constraints__ = ["id", "iid"] id = Property("id") iid = Property("iid") title = Property("title") description = Property("description") state = Property("state") weight = Property("weight") merge_requests_count = Property("merge_requests_count") created_at = Property("created_at") updated_at = Property("updated_at") closed_at = Property("updated_at") confidential = Property("confidential") due_date = Property("due_date") upvotes = Property("upvotes") downvotes = Property("downvotes") has_tasks = Property("has_tasks") task_status = Property("task_status") task_count = Property("task_count") task_completed = Property("task_completed") has_label = RelatedTo(Label) has_milestone = RelatedTo(Milestone) belongs_to = RelatedTo(Project) created_by = RelatedTo(User) was_assigned = RelatedTo(User) is_assigned = RelatedTo(User) closed_by = RelatedTo(User) is_merge_annotated = RelatedFrom("MergeRequest", "IS_RELATED") has_note = RelatedTo(Note) was_awarded_with = RelatedTo("AwardEmoji")
class Book(GraphObject): """ Class for Book node """ __primarykey__ = "book_id" book_id = Property() authors = Property() year = Property() title = Property() language = Property() tagged_to = RelatedTo("Tag") reader = RelatedFrom("User", "READS") likes = RelatedFrom("User", "LIKES") def __init__(self, book_id=None, authors=None, year=None, title=None, language=None): self.book_id = book_id self.authors = authors self.year = year self.title = title self.language = language def insert(self): """Inserting book node to graph""" graph.push(self) def find_by_id(self): book = Book.match(graph, self.book_id).first() return book def linked_tags(self): """Return list of tags for specific book""" book = Book.match(graph, self.book_id).first() tags = [tag.tag_name for tag in book.tags] return tags def link_to_tag(self, tag_id): """ Create relationship (Book)-[:TAGGED_TO]->(Tag) """ tag = Tag.match(graph, int(tag_id)).first() graph.create(Relationship(self.__node__, "TAGGED_TO", tag.__node__)) @staticmethod def books(): """ Return list of all books """ books = graph.run("MATCH (b:Book) RETURN b.username").data() return books @staticmethod def most_popular_books(): """ Return books which are read by most amount of users """ query = """ MATCH (book:Book)<-[reads:READS]-(u:User) WITH book, count(reads) AS readers RETURN book ORDER BY readers LIMIT 16 """ # TODO use run instead of cypher return graph.cypher.execute(query)
class Producer(GraphObject): __primarykey__ = "name" name = Property() drugs = RelatedFrom("Drug", "PRODUCED_BY")
class Feed(Model): name = Property("name") url = Property("url") subscribers = RelatedFrom("User", "SUBSCRIBED") items = RelatedFrom("FeedItem", "SOURCE")