### Installing Dependencies (Bash) Source: https://github.com/ontolocy/neontology/blob/main/docs/fastapi.md Installs the necessary Python packages, FastAPI and uvicorn, using pip. These libraries are required to build and run the web application and server. ```bash pip install fastapi pip install "uvicorn[standard]" ``` -------------------------------- ### Example .env file for Neo4j Connection Source: https://github.com/ontolocy/neontology/blob/main/docs/usage.md Provides an example of a .env file containing Neo4j connection credentials (URI, username, password). neontology can automatically load these variables if the file is present, allowing connection without explicit configuration in code. ```text # .env NEO4J_URI=neo4j+s://myneo4j.example.com NEO4J_USERNAME=neo4j NEO4J_PASSWORD= ``` -------------------------------- ### Full neontology Python Example (Partial) Source: https://github.com/ontolocy/neontology/blob/main/docs/usage.md Provides a combined code snippet showing the class definitions for PersonNode and FollowsRel, along with the initial connection setup using explicit credentials. This snippet serves as a starting point for a complete script. Requires neontology, typing, pandas, and Neo4j connection details. ```python # demo.py from typing import ClassVar, Optional import pandas as pd from neontology import BaseNode, BaseRelationship, init_neontology class PersonNode(BaseNode): __primarylabel__: ClassVar[str] = "Person" __primaryproperty__: ClassVar[str] = "name" name: str age: Optional[int] = None class FollowsRel(BaseRelationship): __relationshiptype__: ClassVar[str] = "FOLLOWS" source: PersonNode target: PersonNode NEO4J_URI="neo4j+s://.databases.neo4j.io" # neo4j Aura example NEO4J_USERNAME="neo4j" NEO4J_PASSWORD="" ``` -------------------------------- ### Installing Neontology via pip Source: https://github.com/ontolocy/neontology/blob/main/README.md This command installs the neontology library from PyPI using the pip package manager. ```bash pip install neontology ``` -------------------------------- ### Installing Neontology with Pip (Bash) Source: https://github.com/ontolocy/neontology/blob/main/docs/index.md This command installs the Neontology library using the Python package installer, pip. It is the standard way to add Neontology to your Python environment. ```bash pip install neontology ``` -------------------------------- ### Initializing FastAPI and Neontology (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/fastapi.md Initializes the FastAPI application instance and sets up a startup event (`@app.on_event("startup")`) to configure and initialize Neontology with Neo4j connection details (URI, username, password). It also includes a basic root ('/') GET endpoint for testing. ```python app = FastAPI() @app.on_event("startup") async def startup_event(): # here we declare the neo4j connection details explicitly (this can be bad for security) # you could instead define them as environment variables or in a .env file NEO4J_URI="neo4j+s://.databases.neo4j.io" # neo4j Aura example NEO4J_USERNAME="neo4j" NEO4J_PASSWORD="" config = Neo4jConfig( uri=NEO4J_URI, username=NEO4J_USERNAME, password=NEO4J_PASSWORD ) init_neontology(config) @app.get("/") def read_root(): return {"foo": "bar"} ``` -------------------------------- ### Running the FastAPI Application (Bash) Source: https://github.com/ontolocy/neontology/blob/main/docs/fastapi.md Provides the command to start the FastAPI application using the uvicorn server. The `main:app` specifies the module and the FastAPI instance, and `--reload` enables automatic code reloading during development. ```bash uvicorn main:app --reload ``` -------------------------------- ### Initializing Neontology on Startup (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/fastapi.md Configures an asynchronous startup event handler for the FastAPI application. This function calls `init_neontology()` to establish the connection to the Neo4j database when the application starts, requiring specific environment variables. ```python @app.on_event("startup") async def startup_event(): # make sure you've set NEO4J_URI, NEO4J_USERNAME and NEO4J_PASSWORD environment variables # they could be defined in a .env file init_neontology() ``` -------------------------------- ### Comprehensive Neontology Example Source: https://github.com/ontolocy/neontology/blob/main/README.md This example demonstrates defining Node and Relationship models using Pydantic and Neontology's base classes, initializing the database connection, creating and merging individual node and relationship objects, and performing bulk merges using pandas DataFrames. ```python from typing import ClassVar, Optional, List import pandas as pd from neontology import BaseNode, BaseRelationship, init_neontology, Neo4jConfig # We define nodes by inheriting from BaseNode class PersonNode(BaseNode): __primarylabel__: ClassVar[str] = "Person" __primaryproperty__: ClassVar[str] = "name" __secondarylabels__: ClassVar[Optional[List]] = ["Individual", "Somebody"] name: str age: int # We define relationships by inheriting from BaseRelationship class FollowsRel(BaseRelationship): __relationshiptype__: ClassVar[str] = "FOLLOWS" source: PersonNode target: PersonNode # initialise the connection to the database config = Neo4jConfig( uri="neo4j+s://mydatabaseid.databases.neo4j.io", username="neo4j", password="" ) init_neontology(config) # Define a couple of people alice = PersonNode(name="Alice", age=40) bob = PersonNode(name="Bob", age=40) # Create them in the database alice.create() bob.create() # Create a follows relationship between them rel = FollowsRel(source=bob,target=alice) rel.merge() # We can also use pandas DataFrames to create multiple nodes node_records = [{"name": "Freddy", "age": 42}, {"name": "Philippa", "age":42}] node_df = pd.DataFrame.from_records(node_records) PersonNode.merge_df(node_df) # We can also merge relationships from a pandas DataFrame, using the primary property values of the nodes rel_records = [ {"source": "Freddy", "target": "Philippa"}, {"source": "Alice", "target": "Freddy"} ] rel_df = pd.DataFrame.from_records(rel_records) FollowsRel.merge_df(rel_df) ``` -------------------------------- ### Initializing Neontology with Neo4j Configuration (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/graph-engines.md Demonstrates how to configure Neontology to use Neo4j by explicitly creating a `Neo4jConfig` object with connection details (URI, username, password) and passing it to `init_neontology`. It then shows how to get a `GraphConnection` and execute a basic query to count nodes. Requires `neontology` and `neontology.graphengines.Neo4jConfig`. ```Python from neontology import GraphConnection, init_neontology from neontology.graphengines import Neo4jConfig config = Neo4jConfig( uri="bolt://localhost:7687", # OR use NEO4J_URI environment variable username="neo4j", # OR use NEO4J_USERNAME environment variable password="" # OR use NEO4J_PASSWORD environment variable ) init_neontology(config) gc = GraphConnection() gc.evaluate_query_single("MATCH (n) RETURN COUNT(n)") ``` -------------------------------- ### Full Example: Instantiating and Merging Nodes and Relationships - Python Source: https://github.com/ontolocy/neontology/blob/main/docs/advanced-usage.md Shows how to create instances of the `AugmentedPerson` and `FollowsRelationship` classes defined previously and merge them into the graph database. ```python alice = AugmentedPerson(name="Alice") alice.merge() bob = AugmentedPerson(name="Bob") bob.merge() follows = AugmentedPersonRelationship( source=alice, target=bob ) follows.merge() follows2 = AugmentedPersonRelationship( source=bob, target=alice ) follows2.merge() ``` -------------------------------- ### Neontology .env Configuration Source: https://github.com/ontolocy/neontology/blob/main/README.md Example content for a .env file to configure the Neo4j connection using environment variables, which Neontology can automatically pick up. ```text # .env NEO4J_URI=neo4j+s://myneo4j.example.com NEO4J_USERNAME=neo4j NEO4J_PASSWORD= ``` -------------------------------- ### Defining Models and Using Neontology (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/index.md This example demonstrates how to define Node and Relationship models using Pydantic and Neontology's base classes, initialize the connection to a Neo4j database, create individual nodes and relationships, and perform bulk merge operations using pandas DataFrames. It shows the core workflow for data ingestion. ```python from typing import ClassVar, Optional, List import pandas as pd from neontology import BaseNode, BaseRelationship, init_neontology, Neo4jConfig # We define nodes by inheriting from BaseNode class PersonNode(BaseNode): __primarylabel__: ClassVar[str] = "Person" __primaryproperty__: ClassVar[str] = "name" name: str age: int # We define relationships by inheriting from BaseRelationship class FollowsRel(BaseRelationship): __relationshiptype__: ClassVar[str] = "FOLLOWS" source: PersonNode target: PersonNode # initialise the connection to the database config = Neo4jConfig( uri="neo4j+s://mydatabaseid.databases.neo4j.io", username="neo4j", password="" ) init_neontology(config) # Define a couple of people alice = PersonNode(name="Alice", age=40) bob = PersonNode(name="Bob", age=40) # Create them in the database alice.create() bob.create() # Create a follows relationship between them rel = FollowsRel(source=bob,target=alice) rel.merge() # We can also use pandas DataFrames to create multiple nodes node_records = [{"name": "Freddy", "age": 42}, {"name": "Philippa", "age":42}] node_df = pd.DataFrame.from_records(node_records) PersonNode.merge_df(node_df) # We can also merge relationships from a pandas DataFrame, using the primary property values of the nodes rel_records = [ {"source": "Freddy", "target": "Philippa"}, {"source": "Alice", "target": "Freddy"} ] rel_df = pd.DataFrame.from_records(rel_records) FollowsRel.merge_df(rel_df) ``` -------------------------------- ### Full Example: Augmented Node and Relationship Definitions - Python Source: https://github.com/ontolocy/neontology/blob/main/docs/advanced-usage.md Provides a complete example defining `AugmentedPerson` (a `BaseNode` subclass with `@related_nodes` and `@related_property` methods) and `FollowsRelationship` (a `BaseRelationship` subclass) to model a social graph. ```python from neontology import BaseNode class AugmentedPerson(BaseNode): __primaryproperty__: ClassVar[GQLIdentifier] = "name" __primarylabel__: ClassVar[GQLIdentifier] = "AugmentedPerson" name: str @related_nodes def followers(self): return "MATCH (#ThisNode)<-[:FOLLOWS]-(o) RETURN o" @property @related_property def follower_count(self): return "MATCH (#ThisNode)<-[:FOLLOWS]-(o) RETURN COUNT(DISTINCT o)" @property @related_property def follower_names(self): return "MATCH (#ThisNode)<-[:FOLLOWS]-(o) RETURN COLLECT(DISTINCT o.name)" class FollowsRelationship(BaseRelationship): __relationshiptype__: ClassVar[str] = "FOLLOWS" source: AugmentedPerson target: AugmentedPerson ``` -------------------------------- ### Getting All Teams Endpoint (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/fastapi.md Defines a GET endpoint ('/teams/') to retrieve all Team nodes from the database. It uses the `match_nodes()` class method from neontology and returns a list of TeamNode objects. ```python @app.get("/teams/") async def get_teams() -> List[TeamNode]: return TeamNode.match_nodes() ``` -------------------------------- ### Defining Root Endpoint (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/fastapi.md Defines a simple GET endpoint at the root path ('/'). It returns a basic JSON dictionary, typically used for testing or a default response. ```python @app.get("/") def read_root(): return {"foo": "bar"} ``` -------------------------------- ### Getting All Team Members Endpoint (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/fastapi.md Defines a GET endpoint ('/team-members/') to retrieve all TeamMember nodes from the database. It uses the `match_nodes()` class method from neontology and returns a list of TeamMemberNode objects. ```python @app.get("/team-members/") async def get_team_members() -> List[TeamMemberNode]: return TeamMemberNode.match_nodes() ``` -------------------------------- ### Accessing Native Neo4j Driver via Neontology (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/graph-engines.md Illustrates how to get the underlying native Neo4j driver instance from a Neontology `GraphConnection` object (`gc.engine.driver`). It then shows how to use the driver's `execute_query` method to run a Cypher query and transform the result using `neo4j.Result.single`. Requires `neontology` and `neo4j`. ```Python import neo4j from neontology import init_neontology, GraphConnection init_neontology() gc = GraphConnection() cypher_query = """ MATCH (p:Person) RETURN COLLECT({name: p.name}) """ result = gc.engine.driver.execute_query(cypher_query, result_transformer_=neo4j.Result.single) print(result) # [{'name': 'Alice'}, {'name': 'Bob'}] ``` -------------------------------- ### Getting Specific Team Endpoint (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/fastapi.md Defines a GET endpoint ('/teams/{pp}') to retrieve a specific Team node by its primary property ('pp', which maps to 'teamname'). It uses the `match()` class method from neontology and returns the matching TeamNode object or None if not found. ```python @app.get("/teams/{pp}") async def get_team(pp: str) -> Optional[TeamNode]: return TeamNode.match(pp) ``` -------------------------------- ### Executing Simple Single Cypher Queries (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/queries.md Demonstrates using the `GraphConnection.evaluate_query_single` method to execute Cypher queries that are expected to return a single result. The method returns the result in the native Neo4j driver type. It shows examples without parameters, with counting, and with parameters. ```python from neontology import init_neontology, GraphConnection init_neontology() gc = GraphConnection() cypher_query = """ MATCH (p:Person) RETURN COLLECT({name: p.name}) """ result = gc.evaluate_query_single(cypher_query) print(result) # [{'name': 'Alice'}, {'name': 'Bob'}] cypher_query_count = """ MATCH (p:Person) RETURN COUNT(DISTINCT p) """ result_count = gc.evaluate_query_single(cypher_query_count) print(result_count) # 2 cypher_query_params = """ MATCH (p:Person) WHERE p.name = $name RETURN p.name """ params = {"name": "Bob"} result_params = gc.evaluate_query_single(cypher_query_params, params) print(result) # 'Bob' ``` -------------------------------- ### Resulting Graph Structure in Cypher Source: https://github.com/ontolocy/neontology/blob/main/docs/usage.md Shows the expected graph structure in Neo4j after running the preceding code examples. It depicts a chain of Person nodes connected by FOLLOWs relationships. ```cypher (Bob:Person)-[:FOLLOWS]->(Alice:Person)-[:FOLLOWS]->(Freddy:Person)-[:FOLLOWS]->(Philipa:Person) ``` -------------------------------- ### Getting Specific Team Member Endpoint (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/fastapi.md Defines a GET endpoint ('/team-members/{pp}') to retrieve a specific TeamMember node by its primary property ('pp', which maps to 'nickname'). It uses the `match()` class method from neontology and returns the matching TeamMemberNode object or None if not found. ```python @app.get("/team-members/{pp}") async def get_team_member(pp: str) -> Optional[TeamMemberNode]: return TeamMemberNode.match(pp) ``` -------------------------------- ### Retrieving Teams (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/fastapi.md Defines two FastAPI GET endpoints for retrieving TeamNode instances. The '/teams/' endpoint uses `TeamNode.match_nodes()` to fetch all team nodes, returning a list. The '/teams/{pp}' endpoint retrieves a specific team node by its primary property (`pp`) using `TeamNode.match(pp)`, returning an optional TeamNode. ```python @app.get("/teams/") async def get_teams() -> List[TeamNode]: return TeamNode.match_nodes() @app.get("/teams/{pp}") async def get_team(pp: str) -> Optional[TeamNode]: return TeamNode.match(pp) ``` -------------------------------- ### Build Documentation with mkdocs Source: https://github.com/ontolocy/neontology/blob/main/docs/.development.md Use mkdocs to serve the documentation locally during development or build a static HTML site for deployment. ```bash mkdocs serve mkdocs build ``` -------------------------------- ### Initializing FastAPI App (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/fastapi.md Initializes the FastAPI application instance, which will be used to define and manage the API endpoints. ```python app = FastAPI() ``` -------------------------------- ### Initializing Neontology with Memgraph Configuration (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/graph-engines.md Shows how to configure Neontology for Memgraph by creating a `MemgraphConfig` object with connection details (URI, username, password) and passing it to `init_neontology`. It then demonstrates obtaining a `GraphConnection` and executing a simple query to count nodes. Requires `neontology` and `neontology.graphengines.MemgraphConfig`. ```Python from neontology import GraphConnection, init_neontology from neontology.graphengines import MemgraphConfig config = MemgraphConfig( uri="bolt://localhost:7687", # OR use MEMGRAPH_URI environment variable username="memgraphuser", # OR use MEMGRAPH_USERNAME environment variable password="" # OR use MEMGRAPH_PASSWORD environment variable ) init_neontology(config) gc = GraphConnection() gc.evaluate_query_single("MATCH (n) RETURN COUNT(n)") ``` -------------------------------- ### Configuring and Initializing neontology (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/usage.md This snippet shows how to create a Neo4jConfig object using environment variables for connection details and initialize the neontology library with this configuration. ```python config = Neo4jConfig( uri=NEO4J_URI, username=NEO4J_USERNAME, password=NEO4J_PASSWORD ) init_neontology(config) ``` -------------------------------- ### Serve HTML Coverage Report Locally Source: https://github.com/ontolocy/neontology/blob/main/docs/.development.md Use Python's http.server module to host the generated HTML coverage report locally for easy viewing in a web browser. ```bash python -m http.server --directory htmlcov ``` -------------------------------- ### Tag and Push Git Release Version Source: https://github.com/ontolocy/neontology/blob/main/docs/.development.md Create a git tag for the new version (va.b.c) and push it to the origin repository, triggering the GitHub action for building and uploading to pypi. ```bash git tag va.b.c git push origin va.b.c ``` -------------------------------- ### Connecting to Neo4j using neontology with .env file Source: https://github.com/ontolocy/neontology/blob/main/docs/usage.md Shows how to connect to a Neo4j database using neontology when connection details are provided in a .env file. Calling init_neontology() without arguments will automatically attempt to load credentials from the environment or a .env file. Requires neontology and a correctly configured .env file or environment variables. ```python init_neontology() ``` -------------------------------- ### Defining Neo4j Community Service - Docker Compose (YAML) Source: https://github.com/ontolocy/neontology/blob/main/docs/setting-up-neo4j.md This Docker Compose snippet defines a service named 'neo4j' using the official 'neo4j:5-community' image. It maps the default Neo4j ports (7474, 7373, 7687) from the container to the host and includes a placeholder for the NEO4J_AUTH environment variable, which is required for authentication. ```YAML # docker-compose.yml version: "3" services: neo4j: image: neo4j:5-community ports: - 7474:7474 - 7373:7373 - 7687:7687 environment: - NEO4J_AUTH ``` -------------------------------- ### Check Code with flake8 Source: https://github.com/ontolocy/neontology/blob/main/docs/.development.md Run flake8 on the source directory to perform additional code style and quality checks, respecting the configuration in setup.cfg. ```bash flake8 --max-line-length=127 src ``` -------------------------------- ### Configuring Windows Firewall for WSL to Neo4j Desktop Connection - PowerShell Source: https://github.com/ontolocy/neontology/blob/main/docs/setting-up-neo4j.md This PowerShell command creates a new inbound firewall rule named 'WSL' on the 'vEthernet (WSL)' interface to allow connections. This is necessary when running Neo4j Desktop on Windows and accessing it from a development environment within WSL. ```PowerShell New-NetFirewallRule -DisplayName "WSL" -Direction Inbound -InterfaceAlias "vEthernet (WSL)" -Action Allow ``` -------------------------------- ### Check Docstrings with pydocstyle Source: https://github.com/ontolocy/neontology/blob/main/docs/.development.md Run pydocstyle on the source directory to check docstring conventions and style compliance. ```bash pydocstyle src ``` -------------------------------- ### Connecting to Neo4j using neontology with explicit config Source: https://github.com/ontolocy/neontology/blob/main/docs/usage.md Demonstrates how to establish a connection to a Neo4j database using neontology by explicitly providing connection details (URI, username, password) via a Neo4jConfig object to the init_neontology function. Requires neontology and connection credentials. ```python NEO4J_URI="neo4j+s://.databases.neo4j.io" # neo4j Aura example NEO4J_USERNAME="neo4j" NEO4J_PASSWORD="" # initialise the connection to the database config = Neo4jConfig( uri=NEO4J_URI, username=NEO4J_USERNAME, password=NEO4J_PASSWORD ) init_neontology(config) ``` -------------------------------- ### Initializing neontology with MemgraphConfig (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/graph-engines.md This snippet demonstrates how to explicitly initialize the neontology library to connect to a Memgraph database using a MemgraphConfig object. It requires the 'neontology' library and the 'MemgraphEngine'. ```python from neontology import init_neontology from neontology.graph_engines import MemgraphEngine init_neontology( engine=MemgraphConfig() ) ``` -------------------------------- ### Initializing Neontology and Graph Connection in Python Source: https://github.com/ontolocy/neontology/blob/main/README.md Initializes the Neontology framework and creates a connection object to interact with the graph database. Assumes default configuration or environment variables are set. ```python init_neontology() gc = GraphConnection() ``` -------------------------------- ### Connecting to Memgraph with Neontology in Python Source: https://github.com/ontolocy/neontology/blob/main/README.md Shows how to configure and initialize Neontology to connect to a Memgraph database using a specific configuration object, including URI, username, and password. ```python from neontology import init_neontology, MemgraphConfig from neontology.graphengines import MemgraphEngine config = MemgraphConfig( "uri": "bolt://localhost:9687", "username": "memgraphuser", "password": "" ) init_neontology(config) ``` -------------------------------- ### Run All Pytest Tests (Fail Fast) Source: https://github.com/ontolocy/neontology/blob/main/docs/.development.md Execute all tests using pytest, stopping immediately upon the first failure. ```bash pytest -x ``` -------------------------------- ### Creating and Merging Individual Nodes (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/usage.md Demonstrates creating instances of a PersonNode model and persisting them to the database using the create() and merge() methods for individual operations. ```python alice = PersonNode(name="Alice", age=40) alice.create() bob = PersonNode(name="Bob", age=40) bob.merge() ``` -------------------------------- ### Run Ruff Linting and Formatting Checks Source: https://github.com/ontolocy/neontology/blob/main/docs/.development.md Execute ruff commands to check for linting issues, automatically fix them, and check/apply code formatting according to project standards. ```bash ruff check ruff check --fix ruff format --check --diff ruff format ``` -------------------------------- ### Creating a Team (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/fastapi.md Defines a FastAPI POST endpoint at '/teams/' that accepts a TeamNode Pydantic model as input. FastAPI automatically validates the input data against the model, and Neontology's `create()` method is then called on the model instance to persist the team node in the Neo4j database. ```python @app.post("/teams/") async def create_team(team: TeamNode): team.create() return team ``` -------------------------------- ### Creating and Merging Follows Relationship in Neo4j Source: https://github.com/ontolocy/neontology/blob/main/docs/usage.md Shows how to create an instance of the FollowsRel class, linking existing PersonNode instances (bob and alice), and persist it to the Neo4j database using the merge() method. Requires the FollowsRel class definition, existing source and target nodes, and an active neontology connection. ```python rel = FollowsRel(source=bob,target=alice) rel.merge() ``` -------------------------------- ### Check Pytest Code Coverage Source: https://github.com/ontolocy/neontology/blob/main/docs/.development.md Run pytest with the --cov flag to measure code coverage for the specified source directory. The --cov-report=html option generates an HTML report. ```bash pytest --cov=src/neontology pytest --cov=src/neontology --cov-report=html ``` -------------------------------- ### Sort Python Imports with isort Source: https://github.com/ontolocy/neontology/blob/main/docs/.development.md Run isort on the source directory to automatically sort import statements according to configured rules, typically in black compatibility mode. ```bash isort src ``` -------------------------------- ### Merging an Individual Relationship (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/usage.md Shows how to create an instance of a FollowsRel relationship between two existing nodes and persist it to the database using the merge() method. ```python rel = FollowsRel(source=bob, target=alice) rel.merge() ``` -------------------------------- ### Creating Team Endpoint (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/fastapi.md Defines a POST endpoint ('/teams/') to create a new Team node. It accepts a TeamNode object in the request body, uses the `create()` method from neontology to save it to the database, and returns the created team object. ```python @app.post("/teams/") async def create_team(team: TeamNode): team.create() return team ``` -------------------------------- ### Preparing Relationship Data for Bulk Merge (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/usage.md Creates a list of dictionaries representing relationship data, referencing nodes by their properties, and converts it into a pandas DataFrame for bulk operations. ```python rel_records = [ {"source": "Freddy", "target": "Phillipa"}, {"source": "Alice", "target": "Freddy"} ] rel_df = pd.DataFrame.from_records(rel_records) ``` -------------------------------- ### Check Python Typing with mypy Source: https://github.com/ontolocy/neontology/blob/main/docs/.development.md Use mypy to perform static type checking on the source code, ensuring type hints are correctly used and consistent. ```bash mypy src ``` -------------------------------- ### Querying for Neontology Objects (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/queries.md Illustrates how to use the `GraphConnection.evaluate_query` method to execute Cypher queries and automatically hydrate the results into Neontology Pydantic node and relationship objects. Requires defining the Neontology node/relationship classes beforehand. ```python from neontology import init_neontology, GraphConnection, BaseNode from typing import ClassVar, Optional init_neontology() gc = GraphConnection() class PersonNode(BaseNode): __primarylabel__: ClassVar[str] = "Person" __primaryproperty__: ClassVar[str] = "name" name: str age: Optional[int] = None bob = PersonNode(name="Bob", age=40) bob.merge() cypher = "MATCH p RETURN p" results = gc.evaluate_query(cypher) print(results.nodes[0].name) # Bob ``` -------------------------------- ### Creating and Merging Person Nodes in Neo4j Source: https://github.com/ontolocy/neontology/blob/main/docs/usage.md Demonstrates creating instances of the PersonNode class and persisting them to the Neo4j database. The create() method attempts to create the node, while merge() updates it if it exists based on the primary property or creates it otherwise. Requires the PersonNode class definition and an active neontology connection. ```python alice = PersonNode(name="Alice", age=40) alice.create() bob = PersonNode(name="Bob", age=40) bob.merge() ``` -------------------------------- ### Merging Follows Relationships from Pandas DataFrame Source: https://github.com/ontolocy/neontology/blob/main/docs/usage.md Demonstrates how to load multiple FollowsRel instances into Neo4j from a pandas DataFrame. The DataFrame must contain columns corresponding to the source and target primary properties ("source", "target") and any relationship properties. The merge_df() class method handles the bulk operation. Requires the FollowsRel class, pandas, and an active neontology connection. ```python rel_records = [ {"source": "Freddy", "target": "Philipa"}, {"source": "Alice", "target": "Freddy"} ] rel_df = pd.DataFrame.from_records(rel_records) FollowsRel.merge_df(rel_df) ``` -------------------------------- ### Creating Team Member and Relationship Endpoint (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/fastapi.md Defines a POST endpoint ('/team-members/') to create a new TeamMember node and link it to an existing Team. It accepts a TeamMemberNode object and the target team's name, checks if the team exists, creates the member, creates a 'BELONGS_TO' relationship using the defined model, merges the relationship, and returns the created member. ```python @app.post("/team-members/") async def create_team_member(member: TeamMemberNode, team_name: str): team = TeamNode.match(team_name) if team is None: raise HTTPException(status_code=404, detail="Team doesn't exist") member.create() rel = BelongsTo(source=member, target=team) rel.merge() return member ``` -------------------------------- ### Preparing Node Data for Bulk Merge (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/usage.md Creates a list of dictionaries representing node data and converts it into a pandas DataFrame, which is the required format for neontology's bulk merge operations. ```python node_records = [{"name": "Freddy", "age": 42}, {"name": "Phillipa", "age": 42}] node_df = pd.DataFrame.from_records(node_records) ``` -------------------------------- ### Project Dependency List Source: https://github.com/ontolocy/neontology/blob/main/requirements.txt Specifies the necessary Python packages and their acceptable version ranges for the project to function correctly. This list is crucial for setting up the development or production environment. ```text neo4j>5,<6 pydantic~=2.7 pandas>2,<3 python-dotenv>1,<2 Jinja2>3,<4 ``` -------------------------------- ### Modeling Person Follows Relationship in Cypher Source: https://github.com/ontolocy/neontology/blob/main/docs/usage.md Defines a simple graph model where a Person node is connected to another Person node via a FOLLOWS relationship. This illustrates the basic structure being built. ```cypher (p1:Person)-[:FOLLOWS]->(p2:Person) ``` -------------------------------- ### Run Pytest Tests Against Specific Graph Engines Source: https://github.com/ontolocy/neontology/blob/main/docs/.development.md Use the -k flag with pytest to filter tests based on engine names, allowing execution against a specific engine or excluding one. ```bash pytest -k 'memgraph-engine' pytest -k 'not neo4j-engine' ``` -------------------------------- ### Accessing Query Results in Python Source: https://github.com/ontolocy/neontology/blob/main/README.md Demonstrates how to access the results returned by the `evaluate_query` method, showing how to retrieve specific nodes or relationships from records or the overall result object. ```python results = gc.evaluate_query(cypher_query, {"name": "bob"}) results.records[0]["nodes"]["o"] # Get the "o" result of the 1st record as a PersonNode results.nodes # The nodes returned by the query as PersonNode objects results.relationships # The relationships as FollowsRel objects ``` -------------------------------- ### Accessing Graph Connection Source: https://github.com/ontolocy/neontology/blob/main/README.md After initialization, the active graph connection can be accessed via the GraphConnection object to execute raw GQL/Cypher queries. ```python from neontology import init_neontology, GraphConnection ``` -------------------------------- ### Skip Graph-Dependent Pytest Tests Source: https://github.com/ontolocy/neontology/blob/main/docs/.development.md Run pytest tests while skipping those marked with the 'uses_graph' marker, useful when a database instance is not available. ```bash pytest -m "not uses_graph" ``` -------------------------------- ### Defining Team Member Node Model (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/fastapi.md Defines the data model for a 'TeamMember' node in Neo4j using neontology's BaseNode. It specifies 'nickname' as the primary property and 'TeamMember' as the label. ```python class TeamMemberNode(BaseNode): __primaryproperty__: ClassVar[str] = "nickname" __primarylabel__: ClassVar[str] = "TeamMember" nickname: str ``` -------------------------------- ### Merging Person Nodes from Pandas DataFrame Source: https://github.com/ontolocy/neontology/blob/main/docs/usage.md Illustrates how to efficiently load multiple PersonNode instances into Neo4j from a pandas DataFrame. The DataFrame columns should match the node properties. The merge_df() class method handles the bulk operation. Requires the PersonNode class, pandas, and an active neontology connection. ```python node_records = [{"name": "Freddy", "age": 42}, {"name": "Philipa", "age":42}] node_df = pd.DataFrame.from_records(node_records) PersonNode.merge_df(node_df) ``` -------------------------------- ### Defining Team Node Model (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/fastapi.md Defines the data model for a 'Team' node in Neo4j using neontology's BaseNode. It specifies 'teamname' as the primary property and 'Team' as the label, including a default slogan property. ```python class TeamNode(BaseNode): __primaryproperty__: ClassVar[str] = "teamname" __primarylabel__: ClassVar[str] = "Team" teamname: str slogan: str = "Better than the rest!" ``` -------------------------------- ### Defining Node and Relationship Schema in Python Source: https://github.com/ontolocy/neontology/blob/main/README.md Defines Python classes that map to graph database nodes and relationships, specifying primary labels, properties, and relationship types. This establishes the schema Neontology uses. ```python class PersonNode(BaseNode): __primarylabel__: ClassVar[str] = "Person" __primaryproperty__: ClassVar[str] = "name" name: str age: int class FollowsRel(BaseRelationship): __relationshiptype__: ClassVar[str] = "FOLLOWS" source: PersonNode target: PersonNode ``` -------------------------------- ### Defining Node Models (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/fastapi.md Defines Pydantic models for 'Team' and 'TeamMember' nodes in the Neo4j graph using Neontology's BaseNode. It specifies the primary property and label for each node type, which are used by Neontology for mapping to graph nodes. ```python # main.py from typing import ClassVar, Optional, List from fastapi import FastAPI, HTTPException from neontology import BaseNode, BaseRelationship, init_neontology, Neo4jConfig class TeamNode(BaseNode): __primaryproperty__: ClassVar[str] = "teamname" __primarylabel__: ClassVar[str] = "Team" teamname: str slogan: str = "Better than the rest!" class TeamMemberNode(BaseNode): __primaryproperty__: ClassVar[str] = "nickname" __primarylabel__: ClassVar[str] = "TeamMember" nickname: str ``` -------------------------------- ### Defining Relationship Model (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/fastapi.md Defines a Pydantic model for the 'BELONGS_TO' relationship using Neontology's BaseRelationship. It specifies the source (TeamMemberNode) and target (TeamNode) node types that this relationship connects. ```python class BelongsTo(BaseRelationship): __relationshiptype__: ClassVar[str] = "BELONGS_TO" source: TeamMemberNode target: TeamNode ``` -------------------------------- ### Defining Follows Relationship Class with neontology Source: https://github.com/ontolocy/neontology/blob/main/docs/usage.md Defines a Python class FollowsRel inheriting from BaseRelationship to represent a FOLLOWS relationship in Neo4j. It specifies the relationship type "FOLLOWS" and defines the source and target nodes as PersonNode instances. Requires neontology and the PersonNode definition. ```python class FollowsRel(BaseRelationship): __relationshiptype__: ClassVar[str] = "FOLLOWS" source: PersonNode target: PersonNode ``` -------------------------------- ### Setting Created and Merged Timestamps with Neontology and Pydantic (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/recipes.md Demonstrates how to automatically set 'created' and 'merged' timestamps on a Neontology BaseNode using Pydantic's default_factory and a field_validator. The 'merged' timestamp updates on every merge/modification, while 'created' is set only upon initial node creation, defaulting to the 'merged' value unless explicitly overridden. Requires datetime, typing, pydantic, and neontology. ```python from datetime import datetime from typing import Optional from pydantic import Field, field_validator, ValidationInfo from neontology import BaseNode class MyBaseNode(BaseNode): merged: datetime = Field( default_factory=datetime.now, ) # created property will only be set 'on create' - when the node is first created created: Optional[datetime] = Field( default=None, validate_default=True, json_schema_extra={"set_on_create": True}) # Use Pydantic's validator functionality to set created off the merged value @field_validator("created") def set_created_to_merged( cls, value: Optional[datetime], values: ValidationInfo ) -> datetime: """When the node is first created, we want the created value to be set equal to merged. Otherwise they will be a tiny amount of time different. """ # set created = merged (which was set to datetime.now()) if value is None: return values.data["merged"] # if the created value has been manually set, don't override it else: return value ``` -------------------------------- ### Querying Related Nodes with @related_nodes - Python Source: https://github.com/ontolocy/neontology/blob/main/docs/advanced-usage.md Illustrates using the `@related_nodes` decorator on a method within a `BaseNode` subclass. The method returns a GQL query string, and the decorator executes it, returning the results as Neontology Node objects. `(#ThisNode)` is a placeholder for the current node. ```python @related_nodes def followers(self): return "MATCH (#ThisNode)<-[:FOLLOWS]-(o) RETURN o" ``` -------------------------------- ### Performing Bulk Relationship Merge with DataFrame (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/usage.md Uses the static merge_df method of the FollowsRel class to efficiently merge multiple relationships into the database from a prepared pandas DataFrame. ```python FollowsRel.merge_df(rel_df) ``` -------------------------------- ### Querying Related Properties with @related_property - Python Source: https://github.com/ontolocy/neontology/blob/main/docs/advanced-usage.md Demonstrates using the `@related_property` decorator (often combined with `@property`) on a method. The method returns a GQL query string, and the decorator executes it, returning a single property value (string, list, dict, etc.) using `evaluate_query_single`. `(#ThisNode)` represents the current node. ```python @property @related_property def follower_count(self): return "MATCH (#ThisNode)<-[:FOLLOWS]-(o) RETURN COUNT(DISTINCT o)" ``` -------------------------------- ### Implementing Custom Serialization with Pydantic - Python Source: https://github.com/ontolocy/neontology/blob/main/docs/advanced-usage.md Shows how to use Pydantic's `@field_serializer` decorator within a `BaseNode` subclass to handle type conversion for complex types like UUID before writing to the database. ```python from pydantic import field_serializer from uuid import UUID class ElephantNode(BaseNode): __primaryproperty__: ClassVar[str] = "name" __primarylabel__: ClassVar[Optional[str]] = "Elephant" __secondarylabels__: ClassVar[Optional[list]] = ["Animal"] name: str id: UUID @field_serializer("id") def serialize_ref_url(self, id: UUID, _info): return str(id) ``` -------------------------------- ### Performing Bulk Node Merge with DataFrame (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/usage.md Uses the static merge_df method of the PersonNode class to efficiently merge multiple nodes into the database from a prepared pandas DataFrame. ```python PersonNode.merge_df(node_df) ``` -------------------------------- ### Querying Related Nodes and Properties in Neontology (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/advanced-usage.md Demonstrates how to retrieve related nodes using `get_related_nodes` and access properties like `follower_count` and `follower_names` on node objects in Neontology. This shows basic interaction with loaded graph data. ```python alice_rels = alice.get_related_nodes(relationship_types=["FOLLOWS"]) print(bob.follower_count) # 1 print(alice.follower_names) # ["Bob"] ``` -------------------------------- ### Executing a Cypher Query with Neontology Source: https://github.com/ontolocy/neontology/blob/main/README.md Defines a Cypher query string to find a node by name and optionally match related nodes via a specific relationship type. The query uses parameters for safe value injection. ```cypher MATCH (n) WHERE n.name = $name OPTIONAL MATCH (n)-[r:FOLLOWS]-(o:Person) RETURN r, o ``` -------------------------------- ### Generating Unique ID for Node with Neontology and Pydantic (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/recipes.md Illustrates how to automatically generate a unique identifier (UUID) for a Neontology BaseNode using Pydantic's default_factory combined with Python's uuid4 function. The generated UUID is stored as a hexadecimal string. Also shows how to define the primary label and primary property for the node class. Requires uuid and neontology. ```python from uuid import uuid4 from neontology import BaseNode class PersonNode(BaseNode): __primarylabel__: ClassVar[str] = "PersonLabel" __primaryproperty__: ClassVar[str] = "id" name: str age: int uuid: str = Field(default_factory=lambda: uuid4().hex) ``` -------------------------------- ### Defining Node Properties with Conditional Setting in Neontology (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/advanced-usage.md Shows how to define a Neontology `BaseNode` subclass and use `pydantic.Field` with `json_schema_extra` to control whether properties are set only on node match (`set_on_match`) or only on node creation (`set_on_create`) during MERGE operations. Fields marked `set_on_match` must be optional. ```python from typing import ClassVar, Optional from pydantic import Field from neontology import BaseNode class MyNode(BaseNode): __primaryproperty__: ClassVar[str] = "my_id" __primarylabel__: ClassVar[Optional[str]] = "MyNode" my_id: str = "test_node" only_set_on_match: Optional[str] = Field(json_schema_extra={"set_on_match": True}) only_set_on_create: Optional[str] = Field(json_schema_extra={"set_on_create": True}) normal_field: str ``` -------------------------------- ### Adding Secondary Labels to BaseNode - Python Source: https://github.com/ontolocy/neontology/blob/main/docs/advanced-usage.md Demonstrates how to add additional labels to a node beyond the primary label by using the `__secondarylabels__` class variable in a `BaseNode` subclass. ```python class ElephantNode(BaseNode): __primaryproperty__: ClassVar[str] = "name" __primarylabel__: ClassVar[Optional[str]] = "Elephant" __secondarylabels__: ClassVar[Optional[list]] = ["Animal"] name: str ellie = ElephantNode(name="Ellie") ``` -------------------------------- ### Defining BelongsTo Relationship Model (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/fastapi.md Defines the data model for a 'BELONGS_TO' relationship in Neo4j using neontology's BaseRelationship. It specifies the relationship type and the expected source (TeamMemberNode) and target (TeamNode) node types. ```python class BelongsTo(BaseRelationship): __relationshiptype__: ClassVar[str] = "BELONGS_TO" source: TeamMemberNode target: TeamNode ``` -------------------------------- ### Defining Person Node Class with neontology Source: https://github.com/ontolocy/neontology/blob/main/docs/usage.md Defines a Python class PersonNode inheriting from BaseNode to represent a Person node in Neo4j. It specifies the primary label "Person", the primary property "name", and includes properties for name (string) and optional age (integer). Requires neontology, typing, and pandas. ```python from typing import ClassVar, Optional import pandas as pd from neontology import BaseNode, BaseRelationship, init_neontology class PersonNode(BaseNode): __primarylabel__: ClassVar[str] = "Person" __primaryproperty__: ClassVar[str] = "name" name: str age: Optional[int] = None ``` -------------------------------- ### Controlling Relationship Merging in Neontology (Python) Source: https://github.com/ontolocy/neontology/blob/main/docs/advanced-usage.md Illustrates how to define a Neontology `BaseRelationship` subclass and use `pydantic.Field` with `json_schema_extra` and the `merge_on` key to specify a property that determines whether an existing relationship is updated or a new one is created during MERGE operations. Relationships with the same source, target, and `merge_on` property value will be updated. ```python from typing import ClassVar, Optional from pydantic import Field from neontology import BaseRelationship class MyRel(BaseRelationship): __relationshiptype__: ClassVar[Optional[str]] = "MY_RELATIONSHIP_TO" source: MyNode target: MyNode prop_to_merge_on: str = Field(json_schema_extra={"merge_on": True}) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.