{"id":20471303,"url":"https://github.com/dpapathanasiou/simple-graph-pypi","last_synced_at":"2025-06-15T13:32:15.174Z","repository":{"id":65852266,"uuid":"374428371","full_name":"dpapathanasiou/simple-graph-pypi","owner":"dpapathanasiou","description":"This is the meta repository for packaging the simple-graph implementation in python for PyPI distribution","archived":false,"fork":false,"pushed_at":"2024-03-13T09:00:41.000Z","size":46,"stargazers_count":32,"open_issues_count":1,"forks_count":6,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-09T09:04:35.157Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dpapathanasiou.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-06-06T17:55:48.000Z","updated_at":"2024-12-24T14:48:49.000Z","dependencies_parsed_at":"2023-02-14T01:25:12.356Z","dependency_job_id":null,"html_url":"https://github.com/dpapathanasiou/simple-graph-pypi","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dpapathanasiou%2Fsimple-graph-pypi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dpapathanasiou%2Fsimple-graph-pypi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dpapathanasiou%2Fsimple-graph-pypi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dpapathanasiou%2Fsimple-graph-pypi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dpapathanasiou","download_url":"https://codeload.github.com/dpapathanasiou/simple-graph-pypi/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248703196,"owners_count":21148117,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T14:15:44.289Z","updated_at":"2025-04-13T10:58:08.399Z","avatar_url":"https://github.com/dpapathanasiou.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# About\n\nThis is the [PyPI](https://pypi.org/) package of the [simple-graph](https://github.com/dpapathanasiou/simple-graph/blob/main/python) implementation in [Python](https://www.python.org/), which is a simple [graph database](https://en.wikipedia.org/wiki/Graph_database) in [SQLite](https://www.sqlite.org/), inspired by \"[SQLite as a document database](https://dgl.cx/2020/06/sqlite-json-support)\".\n\n## Build and Test\n\nHow to [generate the distribution archive](https://packaging.python.org/tutorials/packaging-projects/#generating-distribution-archives) and confirm it on [test.pypi.org](https://packaging.python.org/tutorials/packaging-projects/#uploading-the-distribution-archives), also based on the [pypa/sampleproject](https://github.com/pypa/sampleproject):\n\n```sh\nrm -rf build dist src/simple_graph_sqlite.egg-info\npython -m build\npython -m twine upload --repository testpypi dist/*\n```\n\nCreate a virtual environment for the test package, activate it, pull from [test.pypi.org](https://test.pypi.org) (the `--extra-index-url` is necessary since the `graphviz` and/or `Jinja2` dependencies may not be in the test archive), and confirm the package is available:\n\n```sh\n$ pip install -i https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple simple-graph-sqlite graphviz==0.16 Jinja2==3.1.2\n$ python\nPython 3.6.13 |Anaconda, Inc.| (default, Jun  4 2021, 14:25:59) \n[GCC 7.5.0] on linux\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n\u003e\u003e\u003e from simple_graph_sqlite import database as db\n```\n\nWith the test package installed, update `PYTHONPATH` to include `./tests` and run `pytest` from the root of this repository. If the tests pass, rebuild and push to [pypi.org](https://pypi.org):\n\n```sh\nrm -rf build dist src/simple_graph_sqlite.egg-info\npython -m build\npython -m twine upload --repository pypi dist/*\n```\n\n# Structure\n\nThe [schema](https://github.com/dpapathanasiou/simple-graph/tree/main/sql/schema.sql) consists of just two structures:\n\n* Nodes - these are any [json](https://www.json.org/) objects, with the only constraint being that they each contain a unique `id` value\n* Edges - these are pairs of node `id` values, specifying the direction, with an optional json object as connection properties\n\nThere are also traversal functions as native SQLite [Common Table Expressions](https://www.sqlite.org/lang_with.html):\n\n* [Both directions](https://github.com/dpapathanasiou/simple-graph/tree/main/sql/traverse.sql)\n* [Inbound](https://github.com/dpapathanasiou/simple-graph/tree/main/sql/traverse-inbound.sql)\n* [Outbound](https://github.com/dpapathanasiou/simple-graph/tree/main/sql/traverse-outbound.sql)\n\n# Applications\n\n* [Social networks](https://en.wikipedia.org/wiki/Social_graph)\n* [Interest maps/recommendation finders](https://en.wikipedia.org/wiki/Interest_graph)\n* [To-do / task lists](https://en.wikipedia.org/wiki/Task_list)\n* [Bug trackers](https://en.wikipedia.org/wiki/Open-source_software_development#Bug_trackers_and_task_lists)\n* [Customer relationship management (CRM)](https://en.wikipedia.org/wiki/Customer_relationship_management)\n* [Gantt chart](https://en.wikipedia.org/wiki/Gantt_chart)\n\n# Usage\n\n## Installation Requirements\n\n* [SQLite](https://www.sqlite.org/), version 3.31.0 or higher; get the latest source or precompiled binaries from the [SQLite Download Page](https://www.sqlite.org/download.html)\n* [Graphviz](https://graphviz.org/) for visualization ([download page](https://www.graphviz.org/download/), [installation procedure for Windows](https://forum.graphviz.org/t/new-simplified-installation-procedure-on-windows/224))\n* [Jinja2](https://pypi.org/project/Jinja2/) for the search and traversal templates\n\n## Basic Functions\n\nThe [database script](src/simple_graph_sqlite/database.py) provides convenience functions for [atomic transactions](https://en.wikipedia.org/wiki/Atomicity_(database_systems)) to add, delete, connect, and search for nodes.\n\nAny single node or path of nodes can also be depicted graphically by using the `visualize` function within the database script to generate [dot](https://graphviz.org/doc/info/lang.html) files, which in turn can be converted to images with Graphviz.\n\n### Example\n\nDropping into a python shell, we can create, [upsert](https://en.wiktionary.org/wiki/upsert), and connect people from the early days of [Apple Computer](https://en.wikipedia.org/wiki/Apple_Inc.). The resulting database will be saved to a SQLite file named `apple.sqlite`:\n\n```\n\u003e\u003e\u003e apple = \"apple.sqlite\"\n\u003e\u003e\u003e from simple_graph_sqlite import database as db\n\u003e\u003e\u003e db.initialize(apple)\n\u003e\u003e\u003e db.atomic(apple, db.add_node({'name': 'Apple Computer Company', 'type':['company', 'start-up'], 'founded': 'April 1, 1976'}, 1))\n\u003e\u003e\u003e db.atomic(apple, db.add_node({'name': 'Steve Wozniak', 'type':['person','engineer','founder']}, 2))\n\u003e\u003e\u003e db.atomic(apple, db.add_node({'name': 'Steve Jobs', 'type':['person','designer','founder']}, 3))\n\u003e\u003e\u003e db.atomic(apple, db.add_node({'name': 'Ronald Wayne', 'type':['person','administrator','founder']}, 4))\n\u003e\u003e\u003e db.atomic(apple, db.add_node({'name': 'Mike Markkula', 'type':['person','investor']}, 5))\n\u003e\u003e\u003e db.atomic(apple, db.connect_nodes(2, 1, {'action': 'founded'}))\n\u003e\u003e\u003e db.atomic(apple, db.connect_nodes(3, 1, {'action': 'founded'}))\n\u003e\u003e\u003e db.atomic(apple, db.connect_nodes(4, 1, {'action': 'founded'}))\n\u003e\u003e\u003e db.atomic(apple, db.connect_nodes(5, 1, {'action': 'invested', 'equity': 80000, 'debt': 170000}))\n\u003e\u003e\u003e db.atomic(apple, db.connect_nodes(1, 4, {'action': 'divested', 'amount': 800, 'date': 'April 12, 1976'}))\n\u003e\u003e\u003e db.atomic(apple, db.connect_nodes(2, 3))\n\u003e\u003e\u003e db.atomic(apple, db.upsert_node(2, {'nickname': 'Woz'}))\n```\n\nThere are also bulk operations, to insert and connect lists of nodes in one transaction.\n\nThe nodes can be searched by their ids:\n\n```\n\u003e\u003e\u003e db.atomic(apple, db.find_node(1))\n{'name': 'Apple Computer Company', 'type': ['company', 'start-up'], 'founded': 'April 1, 1976', 'id': 1}\n```\n\nSearches can also use combinations of other attributes, both as strict equality, or using `LIKE` in combination with a trailing `%` for \"starts with\" or `%` at both ends for \"contains\":\n\n```\n\u003e\u003e\u003e db.atomic(apple, db.find_nodes([db._generate_clause('name', predicate='LIKE')], ('Steve%',)))\n[{'name': 'Steve Wozniak', 'type': ['person', 'engineer', 'founder'], 'id': 2, 'nickname': 'Woz'}, {'name': 'Steve Jobs', 'type': ['person', 'designer', 'founder'], 'id': 3}]\n\u003e\u003e\u003e db.atomic(apple, db.find_nodes([db._generate_clause('name', predicate='LIKE'), db._generate_clause('name', predicate='LIKE', joiner='OR')], ('%Woz%', '%Markkula',)))\n[{'name': 'Steve Wozniak', 'type': ['person', 'engineer', 'founder'], 'id': 2, 'nickname': 'Woz'}, {'name': 'Mike Markkula', 'type': ['person', 'investor'], 'id': 5}]\n```\n\nMore complex queries to introspect the json body, using the [sqlite json_tree() function](https://www.sqlite.org/json1.html), are also possible, such as this query for every node whose `type` array contains the value `founder`:\n\n```\n\u003e\u003e\u003e db.atomic(apple, db.find_nodes([db._generate_clause('type', tree=True)], ('founder',), tree_query=True, key='type'))\n[{'name': 'Steve Wozniak', 'type': ['person', 'engineer', 'founder'], 'id': 2, 'nickname': 'Woz'}, {'name': 'Steve Jobs', 'type': ['person', 'designer', 'founder'], 'id': 3}, {'name': 'Ronald Wayne', 'type': ['person', 'administrator', 'founder'], 'id': 4}]\n```\n\nSee the `_generate_clause()` and `_generate_query()` functions in [database.py](src/simple_graph_sqlite/database.py) for usage hints.\n\nPaths through the graph can be discovered with a starting node id, and an optional ending id; the default neighbor expansion is nodes connected nodes in either direction, but that can changed by specifying either `find_outbound_neighbors` or `find_inbound_neighbors` instead:\n\n```\n\u003e\u003e\u003e db.traverse(apple, 2, 3)\n['2', '1', '3']\n\u003e\u003e\u003e db.traverse(apple, 4, 5)\n['4', '1', '2', '3', '5']\n\u003e\u003e\u003e db.traverse(apple, 5, neighbors_fn=db.find_inbound_neighbors)\n['5']\n\u003e\u003e\u003e db.traverse(apple, 5, neighbors_fn=db.find_outbound_neighbors)\n['5', '1', '4']\n\u003e\u003e\u003e db.traverse(apple, 5, neighbors_fn=db.find_neighbors)\n['5', '1', '2', '3', '4']\n```\n\nAny path or list of nodes can rendered graphically by using the `visualize` function. This command produces [dot](https://graphviz.org/doc/info/lang.html) files, which are also rendered as images with Graphviz:\n\n```\n\u003e\u003e\u003e from visualizers import graphviz_visualize\n\u003e\u003e\u003e graphviz_visualize(apple, 'apple.dot', [4, 1, 5])\n```\n\nThe [resulting text file](tests/fixtures/apple-raw.dot) also comes with an associated image (the default is [png](https://en.wikipedia.org/wiki/Portable_Network_Graphics), but that can be changed by supplying a different value to the `format` parameter)\n\nThe default options include every key/value pair (excluding the id) in the node and edge objects, and there are display options to help refine what is produced:\n\n```\n\u003e\u003e\u003e graphviz_visualize(apple, 'apple.dot', [4, 1, 5], exclude_node_keys=['type'], hide_edge_key=True)\n```\n\nThe [resulting dot file](tests/fixtures/apple.dot) can be edited further as needed; the [dot guide](https://graphviz.org/pdf/dotguide.pdf) has more options and examples.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdpapathanasiou%2Fsimple-graph-pypi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdpapathanasiou%2Fsimple-graph-pypi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdpapathanasiou%2Fsimple-graph-pypi/lists"}