annnet 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- annnet-0.0.1/.gitignore +69 -0
- annnet-0.0.1/LICENSE +28 -0
- annnet-0.0.1/PKG-INFO +241 -0
- annnet-0.0.1/README.md +169 -0
- annnet-0.0.1/annnet/__init__.py +89 -0
- annnet-0.0.1/annnet/_metadata.py +71 -0
- annnet-0.0.1/annnet/_version.py +1 -0
- annnet-0.0.1/annnet/adapters/GraphDir_Parquet_adapter.py +292 -0
- annnet-0.0.1/annnet/adapters/GraphML_adapter.py +115 -0
- annnet-0.0.1/annnet/adapters/SIF_adapter.py +502 -0
- annnet-0.0.1/annnet/adapters/__init__.py +44 -0
- annnet-0.0.1/annnet/adapters/_base.py +10 -0
- annnet-0.0.1/annnet/adapters/_proxy.py +18 -0
- annnet-0.0.1/annnet/adapters/_utils.py +64 -0
- annnet-0.0.1/annnet/adapters/dataframe_adapter.py +449 -0
- annnet-0.0.1/annnet/adapters/graphtool_adapter.py +1 -0
- annnet-0.0.1/annnet/adapters/igraph_adapter.py +1333 -0
- annnet-0.0.1/annnet/adapters/json_adapter.py +441 -0
- annnet-0.0.1/annnet/adapters/manager.py +57 -0
- annnet-0.0.1/annnet/adapters/networkx_adapter.py +1082 -0
- annnet-0.0.1/annnet/adapters/sbml_adapter.py +199 -0
- annnet-0.0.1/annnet/algorithms/__init__.py +3 -0
- annnet-0.0.1/annnet/algorithms/traversal.py +1 -0
- annnet-0.0.1/annnet/core/__init__.py +3 -0
- annnet-0.0.1/annnet/core/graph.py +7724 -0
- annnet-0.0.1/annnet/demo/__init__.py +1 -0
- annnet-0.0.1/annnet/demo/demo.py +84 -0
- annnet-0.0.1/annnet/io/__init__.py +4 -0
- annnet-0.0.1/annnet/io/csv.py +939 -0
- annnet-0.0.1/annnet/io/excel.py +96 -0
- annnet-0.0.1/annnet/io/io_annnet.py +539 -0
- annnet-0.0.1/annnet/io/json.py +0 -0
- annnet-0.0.1/annnet/io/registry.py +1 -0
- annnet-0.0.1/annnet/io/utils.py +1 -0
- annnet-0.0.1/annnet/utils/config.py +1 -0
- annnet-0.0.1/annnet/utils/plotting.py +544 -0
- annnet-0.0.1/annnet/utils/typing.py +120 -0
- annnet-0.0.1/annnet/utils/validation.py +67 -0
- annnet-0.0.1/docs/API_demo_notebook.ipynb +495 -0
- annnet-0.0.1/docs/Elowitz.sbml.xml +569 -0
- annnet-0.0.1/docs/about.md +3 -0
- annnet-0.0.1/docs/annnet-project/design-philosophy.md +0 -0
- annnet-0.0.1/docs/annnet-project/project.md +0 -0
- annnet-0.0.1/docs/annnet-project/use-cases.md +0 -0
- annnet-0.0.1/docs/annnet_showcase.ipynb +671 -0
- annnet-0.0.1/docs/community/contribute-codebase.md +333 -0
- annnet-0.0.1/docs/community/contribute-docs.md +34 -0
- annnet-0.0.1/docs/community/contribute.md +51 -0
- annnet-0.0.1/docs/community/index.md +25 -0
- annnet-0.0.1/docs/incidencegraph_stress_notebook.ipynb +968 -0
- annnet-0.0.1/docs/index.md +3 -0
- annnet-0.0.1/docs/installation.md +37 -0
- annnet-0.0.1/docs/io_annnet.md +107 -0
- annnet-0.0.1/docs/learn/explanation/index.md +0 -0
- annnet-0.0.1/docs/learn/guides/index.md +0 -0
- annnet-0.0.1/docs/learn/tutorials/quickstart.md +0 -0
- annnet-0.0.1/docs/learn/tutorials/tutorial0001_basics.md +0 -0
- annnet-0.0.1/docs/ppi_example.ipynb +1251 -0
- annnet-0.0.1/docs/reference/api.md +3 -0
- annnet-0.0.1/docs/reference/source/annnet/_metadata-docs.md +12 -0
- annnet-0.0.1/docs/sbml_io.ipynb +2163 -0
- annnet-0.0.1/pyproject.toml +389 -0
annnet-0.0.1/.gitignore
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
|
2
|
+
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
|
3
|
+
|
|
4
|
+
# User-specific stuff
|
|
5
|
+
.idea/
|
|
6
|
+
.vscode/
|
|
7
|
+
.ipynb_checkpoints/
|
|
8
|
+
|
|
9
|
+
# CMake
|
|
10
|
+
cmake-build-*/
|
|
11
|
+
|
|
12
|
+
# File-based project format
|
|
13
|
+
*.iws
|
|
14
|
+
|
|
15
|
+
# IntelliJ
|
|
16
|
+
out/
|
|
17
|
+
|
|
18
|
+
# JIRA plugin
|
|
19
|
+
atlassian-ide-plugin.xml
|
|
20
|
+
|
|
21
|
+
# Crashlytics plugin (for Android Studio and IntelliJ)
|
|
22
|
+
com_crashlytics_export_strings.xml
|
|
23
|
+
crashlytics.properties
|
|
24
|
+
crashlytics-build.properties
|
|
25
|
+
fabric.properties
|
|
26
|
+
|
|
27
|
+
# Editor-based Rest Client
|
|
28
|
+
.idea/httpRequests
|
|
29
|
+
|
|
30
|
+
# Android studio 3.1+ serialized cache file
|
|
31
|
+
.idea/caches/build_file_checksums.ser
|
|
32
|
+
|
|
33
|
+
# Exclude external libraries
|
|
34
|
+
/demo/lib/
|
|
35
|
+
|
|
36
|
+
# Exclude all demo output files
|
|
37
|
+
/data/output/
|
|
38
|
+
|
|
39
|
+
# Exclude all demo input files obtainable via demo script
|
|
40
|
+
/data/input/demo*
|
|
41
|
+
/data/input/custom*
|
|
42
|
+
/data/input/*sh
|
|
43
|
+
|
|
44
|
+
# Exclude all input files obtainable from GSE, GTEx, TCGS etc
|
|
45
|
+
/data/input/GTEx/
|
|
46
|
+
/data/input/GSE/
|
|
47
|
+
/data/input/KGs/
|
|
48
|
+
/data/input/mouse/
|
|
49
|
+
/data/input/TCGA/
|
|
50
|
+
/data/input/web_Google.txt
|
|
51
|
+
|
|
52
|
+
# Esclude eventual test plot files
|
|
53
|
+
/tests/*.pdf
|
|
54
|
+
|
|
55
|
+
# Exclude
|
|
56
|
+
*.pyc
|
|
57
|
+
__pycache__/
|
|
58
|
+
*.pyo
|
|
59
|
+
*.pyd
|
|
60
|
+
.Python
|
|
61
|
+
env/
|
|
62
|
+
venv/
|
|
63
|
+
ENV/
|
|
64
|
+
build/
|
|
65
|
+
dist/
|
|
66
|
+
*.egg-info/
|
|
67
|
+
test_venv/
|
|
68
|
+
*venv*/
|
|
69
|
+
test_venv/
|
annnet-0.0.1/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025, Saez Lab
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
16
|
+
contributors may be used to endorse or promote products derived from
|
|
17
|
+
this software without specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
annnet-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: annnet
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A Python tool to build, manipulate, and interoperate with flexible graph structures
|
|
5
|
+
Project-URL: Documentation, https://annnet.readthedocs.io/
|
|
6
|
+
Project-URL: Homepage, https://github.com/saezlab/annnet
|
|
7
|
+
Project-URL: Issues, https://github.com/saezlab/annnet/issues
|
|
8
|
+
Project-URL: Repository, https://github.com/saezlab/annnet
|
|
9
|
+
Author-email: Youssef Zerta <youssef.zerta@biomedtech.ueuromed.org>, Bottazzi Daniele <daniele.bottazzi@mail.polimi.it>, Denes Turei <turei.denes@gmail.com>
|
|
10
|
+
Maintainer-email: Bottazzi Daniele <daniele.bottazzi@mail.polimi.it>, Youssef Zerta <youssef.zerta@biomedtech.ueuromed.org>
|
|
11
|
+
License-Expression: GPL-3.0-or-later
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Requires-Dist: numpy>=2.2.6
|
|
24
|
+
Requires-Dist: polars>=0.20.0
|
|
25
|
+
Requires-Dist: scipy>=1.9.0
|
|
26
|
+
Provides-Extra: all
|
|
27
|
+
Requires-Dist: lxml>=5; extra == 'all'
|
|
28
|
+
Requires-Dist: matplotlib>=3.8; extra == 'all'
|
|
29
|
+
Requires-Dist: networkx>=3.3; extra == 'all'
|
|
30
|
+
Requires-Dist: numcodecs>=0.12; extra == 'all'
|
|
31
|
+
Requires-Dist: openpyxl>=3.1; extra == 'all'
|
|
32
|
+
Requires-Dist: pandas>=2.0.3; extra == 'all'
|
|
33
|
+
Requires-Dist: pyarrow>=14; extra == 'all'
|
|
34
|
+
Requires-Dist: python-igraph>=0.11; extra == 'all'
|
|
35
|
+
Requires-Dist: zarr>=2.18; extra == 'all'
|
|
36
|
+
Provides-Extra: dev
|
|
37
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
38
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
41
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
42
|
+
Requires-Dist: twine>=5.0; extra == 'dev'
|
|
43
|
+
Provides-Extra: docs
|
|
44
|
+
Requires-Dist: mkdocs-jupyter>=0.25; extra == 'docs'
|
|
45
|
+
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
|
|
46
|
+
Requires-Dist: mkdocs>=1.6; extra == 'docs'
|
|
47
|
+
Requires-Dist: mkdocstrings[python]>=0.25; extra == 'docs'
|
|
48
|
+
Provides-Extra: excel
|
|
49
|
+
Requires-Dist: openpyxl>=3.1; extra == 'excel'
|
|
50
|
+
Provides-Extra: igraph
|
|
51
|
+
Requires-Dist: python-igraph>=0.11; extra == 'igraph'
|
|
52
|
+
Provides-Extra: networkx
|
|
53
|
+
Requires-Dist: networkx>=3.3; extra == 'networkx'
|
|
54
|
+
Provides-Extra: pandas
|
|
55
|
+
Requires-Dist: pandas>=2.0.3; extra == 'pandas'
|
|
56
|
+
Provides-Extra: parquet
|
|
57
|
+
Requires-Dist: pyarrow>=14; extra == 'parquet'
|
|
58
|
+
Provides-Extra: plot
|
|
59
|
+
Requires-Dist: matplotlib>=3.8; extra == 'plot'
|
|
60
|
+
Provides-Extra: sbml
|
|
61
|
+
Requires-Dist: lxml>=5; extra == 'sbml'
|
|
62
|
+
Provides-Extra: tests
|
|
63
|
+
Requires-Dist: codecov-cli>=10.2.0; extra == 'tests'
|
|
64
|
+
Requires-Dist: coverage>=6.0; extra == 'tests'
|
|
65
|
+
Requires-Dist: diff-cover; extra == 'tests'
|
|
66
|
+
Requires-Dist: tox-gh>=1.5.0; extra == 'tests'
|
|
67
|
+
Requires-Dist: tox>=4.11; extra == 'tests'
|
|
68
|
+
Provides-Extra: zarr-io
|
|
69
|
+
Requires-Dist: numcodecs>=0.12; extra == 'zarr-io'
|
|
70
|
+
Requires-Dist: zarr>=2.18; extra == 'zarr-io'
|
|
71
|
+
Description-Content-Type: text/markdown
|
|
72
|
+
|
|
73
|
+
## Description
|
|
74
|
+
|
|
75
|
+
**annnet** is a lightweight, flexible, minimal-dependencies Python package for creating, manipulating, and interoperating with diverse graph data structures. It aims to be the connective tissue ("glue") between multiple graph ecosystems (NetworkX, igraph, graph-tool, etc.) while maintaining a clean and general-purpose internal representation.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 📌 Description
|
|
80
|
+
|
|
81
|
+
annnet provides a unified interface for:
|
|
82
|
+
|
|
83
|
+
- Building general-purpose graphs (simple, directed, hyper, signed, etc.)
|
|
84
|
+
- Managing node/edge annotations
|
|
85
|
+
- Indexing and fast lookups
|
|
86
|
+
- Importing from or exporting to various tools and file formats
|
|
87
|
+
|
|
88
|
+
Its design supports complex workflows in data science, bioinformatics, and network theory — without locking you into a specific graph backend.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## ✅ Features
|
|
93
|
+
|
|
94
|
+
### General Graph Modeling
|
|
95
|
+
- Simple graphs, directed graphs, multigraphs
|
|
96
|
+
- Hypergraphs (via edge sets or higher-order relationships)
|
|
97
|
+
- Signed and weighted edges
|
|
98
|
+
- Rich node/edge annotations
|
|
99
|
+
- Efficient indexing and lookups
|
|
100
|
+
|
|
101
|
+
### Import Support
|
|
102
|
+
- CSV, JSON, and flat files
|
|
103
|
+
- Native import from existing objects:
|
|
104
|
+
- `networkx.Graph`
|
|
105
|
+
- `igraph.Graph`
|
|
106
|
+
- `graph_tool.Graph`
|
|
107
|
+
- `corneto.Graph`
|
|
108
|
+
|
|
109
|
+
### Export & Interoperability
|
|
110
|
+
- NetworkX (`to_networkx()`)
|
|
111
|
+
- igraph (`to_igraph()`)
|
|
112
|
+
- graph-tool (`to_graphtool()`)
|
|
113
|
+
- [CORNETO](https://corneto.org/)
|
|
114
|
+
- CSV, JSON, and custom serializations
|
|
115
|
+
|
|
116
|
+
### Backend-specific Integration (if installed)
|
|
117
|
+
|
|
118
|
+
If `networkx` is installed, you can call any NetworkX algorithm directly using dot notation:
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
centrality = G.nx.degree_centrality()
|
|
122
|
+
```
|
|
123
|
+
**How it works:**
|
|
124
|
+
|
|
125
|
+
1. annnet converts `G` to a NetworkX object on demand, abstracting away all the non-needed attributes.
|
|
126
|
+
2. Runs the algorithm _as-is_.
|
|
127
|
+
3. Returns results directly, syncing any graph changes back to the internal representation of the `gg.Graph`.
|
|
128
|
+
|
|
129
|
+
This allows you to access the full power of NetworkX algorithms with zero boilerplate.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## 🛠️ Installation
|
|
134
|
+
To install annnet, you can use pip:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
pip install annnet
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Optional dependencies for extended functionality:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
pip install annnet[networkx,igraph]
|
|
144
|
+
pip install annnet[graph-tool]
|
|
145
|
+
pip install annnet[corneto]
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 🚀 Quick Start
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
import annnet as gg
|
|
154
|
+
|
|
155
|
+
# Create a new graph
|
|
156
|
+
G = gg.Graph(directed=True, backend="corneto")
|
|
157
|
+
|
|
158
|
+
# Add nodes and edges
|
|
159
|
+
G.add_node("A", type="gene")
|
|
160
|
+
G.add_node("B", type="protein")
|
|
161
|
+
G.add_edge("A", "B", sign="+", source="literature")
|
|
162
|
+
|
|
163
|
+
# Run a NetworkX algorithm (if installed)
|
|
164
|
+
path = G.nx.shortest_path(source="A", target="B")
|
|
165
|
+
|
|
166
|
+
# Export to JSON
|
|
167
|
+
G.to_json("graph.json")
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## 📦 Refined Package Structure
|
|
173
|
+
The package is organized to separate core functionality, I/O operations, adapters for external libraries, and algorithms. This modular design allows for easy extension and maintenance.
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
annnet/
|
|
177
|
+
│
|
|
178
|
+
├── __init__.py # Public API surface, version, re-exports
|
|
179
|
+
├── _version.py # Single source of truth for __version__
|
|
180
|
+
│
|
|
181
|
+
├── core/ # Core, always-installed logic
|
|
182
|
+
│ ├── __init__.py
|
|
183
|
+
│ ├── _base.py # BaseGraph class and common interfaces
|
|
184
|
+
│ ├── _graph.py # Graph class and internal state manager
|
|
185
|
+
│ ├── structure.py # Core data structures (nodes, edges, incidence)
|
|
186
|
+
│ ├── metadata.py # Node/edge attribute store and access helpers
|
|
187
|
+
│ ├── views.py # Subgraph views, shallow/deep copies
|
|
188
|
+
│ └── state.py # Graph history, change tracking, and lazy loading
|
|
189
|
+
│
|
|
190
|
+
├── io/ # Loaders and writers for files
|
|
191
|
+
│ ├── __init__.py
|
|
192
|
+
│ ├── csv.py # CSV format (edge list, node table)
|
|
193
|
+
│ ├── json.py # JSON or JSONL parsing (streamable)
|
|
194
|
+
│ ├── registry.py # Entry point registration for loaders/dumpers
|
|
195
|
+
│ └── utils.py # Format detection, path helpers
|
|
196
|
+
│
|
|
197
|
+
├── adapters/ # Lazy integration with external libraries
|
|
198
|
+
│ ├── __init__.py
|
|
199
|
+
│ ├── _base.py # AbstractAdapter, adapter interface
|
|
200
|
+
│ ├── _proxy.py # Tiny forwarding proxy
|
|
201
|
+
│ ├── manager.py # Adapter registry and lazy bridge logic
|
|
202
|
+
│ ├── networkx.py # If available: convert, cache, sync with NetworkX
|
|
203
|
+
│ ├── igraph.py # If available
|
|
204
|
+
│ ├── graphtool.py # If available
|
|
205
|
+
│ └── corneto.py # If available
|
|
206
|
+
│
|
|
207
|
+
├── algorithms/ # Pure-python algorithms using core only
|
|
208
|
+
│ ├── __init__.py
|
|
209
|
+
│ └── traversal.py # BFS/DFS etc.
|
|
210
|
+
│
|
|
211
|
+
└── utils/ # Generic helpers not tied to graph structure
|
|
212
|
+
├── validation.py
|
|
213
|
+
├── typing.py
|
|
214
|
+
└── config.py # Global options, logging, toggles
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## ⚙️ Internal Design
|
|
220
|
+
annnet intelligently adapts its internal representation for performance and compatibility:
|
|
221
|
+
|
|
222
|
+
- Chooses between edge lists, incidence matrices, and adjacency dicts automatically
|
|
223
|
+
- Keeps metadata (node/edge attributes) separate from core structure
|
|
224
|
+
- Lazy construction of external library representations (e.g., NetworkX) only when needed
|
|
225
|
+
- Copy-on-write design for subgraphs and structural mutations
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## 🧭 Philosophy
|
|
230
|
+
annnet vis designed with these principles in mind:
|
|
231
|
+
|
|
232
|
+
- **Simple**, consistent interface for all graph types
|
|
233
|
+
- **Interoperability-first**: integrate, don’t replace
|
|
234
|
+
- **Performance-aware**, not performance-obsessed
|
|
235
|
+
- **Extendable** and modular, not monolithic
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## 📜 License
|
|
240
|
+
annnet is licensed under the BSD-3 License. See the [LICENSE](LICENSE) file for details.
|
|
241
|
+
|
annnet-0.0.1/README.md
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
## Description
|
|
2
|
+
|
|
3
|
+
**annnet** is a lightweight, flexible, minimal-dependencies Python package for creating, manipulating, and interoperating with diverse graph data structures. It aims to be the connective tissue ("glue") between multiple graph ecosystems (NetworkX, igraph, graph-tool, etc.) while maintaining a clean and general-purpose internal representation.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 📌 Description
|
|
8
|
+
|
|
9
|
+
annnet provides a unified interface for:
|
|
10
|
+
|
|
11
|
+
- Building general-purpose graphs (simple, directed, hyper, signed, etc.)
|
|
12
|
+
- Managing node/edge annotations
|
|
13
|
+
- Indexing and fast lookups
|
|
14
|
+
- Importing from or exporting to various tools and file formats
|
|
15
|
+
|
|
16
|
+
Its design supports complex workflows in data science, bioinformatics, and network theory — without locking you into a specific graph backend.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## ✅ Features
|
|
21
|
+
|
|
22
|
+
### General Graph Modeling
|
|
23
|
+
- Simple graphs, directed graphs, multigraphs
|
|
24
|
+
- Hypergraphs (via edge sets or higher-order relationships)
|
|
25
|
+
- Signed and weighted edges
|
|
26
|
+
- Rich node/edge annotations
|
|
27
|
+
- Efficient indexing and lookups
|
|
28
|
+
|
|
29
|
+
### Import Support
|
|
30
|
+
- CSV, JSON, and flat files
|
|
31
|
+
- Native import from existing objects:
|
|
32
|
+
- `networkx.Graph`
|
|
33
|
+
- `igraph.Graph`
|
|
34
|
+
- `graph_tool.Graph`
|
|
35
|
+
- `corneto.Graph`
|
|
36
|
+
|
|
37
|
+
### Export & Interoperability
|
|
38
|
+
- NetworkX (`to_networkx()`)
|
|
39
|
+
- igraph (`to_igraph()`)
|
|
40
|
+
- graph-tool (`to_graphtool()`)
|
|
41
|
+
- [CORNETO](https://corneto.org/)
|
|
42
|
+
- CSV, JSON, and custom serializations
|
|
43
|
+
|
|
44
|
+
### Backend-specific Integration (if installed)
|
|
45
|
+
|
|
46
|
+
If `networkx` is installed, you can call any NetworkX algorithm directly using dot notation:
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
centrality = G.nx.degree_centrality()
|
|
50
|
+
```
|
|
51
|
+
**How it works:**
|
|
52
|
+
|
|
53
|
+
1. annnet converts `G` to a NetworkX object on demand, abstracting away all the non-needed attributes.
|
|
54
|
+
2. Runs the algorithm _as-is_.
|
|
55
|
+
3. Returns results directly, syncing any graph changes back to the internal representation of the `gg.Graph`.
|
|
56
|
+
|
|
57
|
+
This allows you to access the full power of NetworkX algorithms with zero boilerplate.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 🛠️ Installation
|
|
62
|
+
To install annnet, you can use pip:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install annnet
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Optional dependencies for extended functionality:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pip install annnet[networkx,igraph]
|
|
72
|
+
pip install annnet[graph-tool]
|
|
73
|
+
pip install annnet[corneto]
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 🚀 Quick Start
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
import annnet as gg
|
|
82
|
+
|
|
83
|
+
# Create a new graph
|
|
84
|
+
G = gg.Graph(directed=True, backend="corneto")
|
|
85
|
+
|
|
86
|
+
# Add nodes and edges
|
|
87
|
+
G.add_node("A", type="gene")
|
|
88
|
+
G.add_node("B", type="protein")
|
|
89
|
+
G.add_edge("A", "B", sign="+", source="literature")
|
|
90
|
+
|
|
91
|
+
# Run a NetworkX algorithm (if installed)
|
|
92
|
+
path = G.nx.shortest_path(source="A", target="B")
|
|
93
|
+
|
|
94
|
+
# Export to JSON
|
|
95
|
+
G.to_json("graph.json")
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 📦 Refined Package Structure
|
|
101
|
+
The package is organized to separate core functionality, I/O operations, adapters for external libraries, and algorithms. This modular design allows for easy extension and maintenance.
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
annnet/
|
|
105
|
+
│
|
|
106
|
+
├── __init__.py # Public API surface, version, re-exports
|
|
107
|
+
├── _version.py # Single source of truth for __version__
|
|
108
|
+
│
|
|
109
|
+
├── core/ # Core, always-installed logic
|
|
110
|
+
│ ├── __init__.py
|
|
111
|
+
│ ├── _base.py # BaseGraph class and common interfaces
|
|
112
|
+
│ ├── _graph.py # Graph class and internal state manager
|
|
113
|
+
│ ├── structure.py # Core data structures (nodes, edges, incidence)
|
|
114
|
+
│ ├── metadata.py # Node/edge attribute store and access helpers
|
|
115
|
+
│ ├── views.py # Subgraph views, shallow/deep copies
|
|
116
|
+
│ └── state.py # Graph history, change tracking, and lazy loading
|
|
117
|
+
│
|
|
118
|
+
├── io/ # Loaders and writers for files
|
|
119
|
+
│ ├── __init__.py
|
|
120
|
+
│ ├── csv.py # CSV format (edge list, node table)
|
|
121
|
+
│ ├── json.py # JSON or JSONL parsing (streamable)
|
|
122
|
+
│ ├── registry.py # Entry point registration for loaders/dumpers
|
|
123
|
+
│ └── utils.py # Format detection, path helpers
|
|
124
|
+
│
|
|
125
|
+
├── adapters/ # Lazy integration with external libraries
|
|
126
|
+
│ ├── __init__.py
|
|
127
|
+
│ ├── _base.py # AbstractAdapter, adapter interface
|
|
128
|
+
│ ├── _proxy.py # Tiny forwarding proxy
|
|
129
|
+
│ ├── manager.py # Adapter registry and lazy bridge logic
|
|
130
|
+
│ ├── networkx.py # If available: convert, cache, sync with NetworkX
|
|
131
|
+
│ ├── igraph.py # If available
|
|
132
|
+
│ ├── graphtool.py # If available
|
|
133
|
+
│ └── corneto.py # If available
|
|
134
|
+
│
|
|
135
|
+
├── algorithms/ # Pure-python algorithms using core only
|
|
136
|
+
│ ├── __init__.py
|
|
137
|
+
│ └── traversal.py # BFS/DFS etc.
|
|
138
|
+
│
|
|
139
|
+
└── utils/ # Generic helpers not tied to graph structure
|
|
140
|
+
├── validation.py
|
|
141
|
+
├── typing.py
|
|
142
|
+
└── config.py # Global options, logging, toggles
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## ⚙️ Internal Design
|
|
148
|
+
annnet intelligently adapts its internal representation for performance and compatibility:
|
|
149
|
+
|
|
150
|
+
- Chooses between edge lists, incidence matrices, and adjacency dicts automatically
|
|
151
|
+
- Keeps metadata (node/edge attributes) separate from core structure
|
|
152
|
+
- Lazy construction of external library representations (e.g., NetworkX) only when needed
|
|
153
|
+
- Copy-on-write design for subgraphs and structural mutations
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## 🧭 Philosophy
|
|
158
|
+
annnet vis designed with these principles in mind:
|
|
159
|
+
|
|
160
|
+
- **Simple**, consistent interface for all graph types
|
|
161
|
+
- **Interoperability-first**: integrate, don’t replace
|
|
162
|
+
- **Performance-aware**, not performance-obsessed
|
|
163
|
+
- **Extendable** and modular, not monolithic
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## 📜 License
|
|
168
|
+
annnet is licensed under the BSD-3 License. See the [LICENSE](LICENSE) file for details.
|
|
169
|
+
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# annnet/__init__.py
|
|
2
|
+
"""annnet: single import, full API."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
from importlib import import_module
|
|
7
|
+
from importlib.metadata import PackageNotFoundError
|
|
8
|
+
from importlib.metadata import version as _pkg_version
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
# Lazily exposed submodules (imported on first attribute access)
|
|
12
|
+
_lazy_submodules = {
|
|
13
|
+
# namespaces
|
|
14
|
+
"adapters": "annnet.adapters",
|
|
15
|
+
"io": "annnet.io",
|
|
16
|
+
"core": "annnet.core",
|
|
17
|
+
"algorithms": "annnet.algorithms",
|
|
18
|
+
"utils": "annnet.utils",
|
|
19
|
+
# adapter modules (direct convenience)
|
|
20
|
+
"graphml": "annnet.adapters.GraphML_adapter",
|
|
21
|
+
"sif": "annnet.adapters.SIF_adapter",
|
|
22
|
+
"sbml": "annnet.adapters.sbml_adapter",
|
|
23
|
+
"parquet": "annnet.adapters.GraphDir_Parquet_adapter",
|
|
24
|
+
"networkx": "annnet.adapters.networkx_adapter",
|
|
25
|
+
"igraph": "annnet.adapters.igraph_adapter",
|
|
26
|
+
"jsonio": "annnet.adapters.json_adapter",
|
|
27
|
+
"dataframe": "annnet.adapters.dataframe_adapter",
|
|
28
|
+
# io modules
|
|
29
|
+
"csvio": "annnet.io.csv",
|
|
30
|
+
"excelio": "annnet.io.excel",
|
|
31
|
+
"annnet": "annnet.io.io_annnet",
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
# Curated top-level symbols (lazy). name -> (module, attribute)
|
|
35
|
+
_lazy_symbols: dict[str, tuple[str, str]] = {
|
|
36
|
+
# Core
|
|
37
|
+
"Graph": ("annnet.core.graph", "Graph"),
|
|
38
|
+
"graph": ("annnet.core.graph", "Graph"),
|
|
39
|
+
# Stdlib JSON I/O
|
|
40
|
+
"to_json": ("annnet.adapters.json_adapter", "to_json"),
|
|
41
|
+
"from_json": ("annnet.adapters.json_adapter", "from_json"),
|
|
42
|
+
# NetworkX adapter (optional dependency)
|
|
43
|
+
"to_nx": ("annnet.adapters.networkx_adapter", "to_nx"),
|
|
44
|
+
"from_nx": ("annnet.adapters.networkx_adapter", "from_nx"),
|
|
45
|
+
"from_nx_only": ("annnet.adapters.networkx_adapter", "from_nx_only"),
|
|
46
|
+
# GraphML
|
|
47
|
+
"to_graphml": ("annnet.adapters.GraphML_adapter", "to_graphml"),
|
|
48
|
+
"from_graphml": ("annnet.adapters.GraphML_adapter", "from_graphml"),
|
|
49
|
+
# SIF
|
|
50
|
+
"to_sif": ("annnet.adapters.SIF_adapter", "to_sif"),
|
|
51
|
+
"from_sif": ("annnet.adapters.SIF_adapter", "from_sif"),
|
|
52
|
+
# SBML (common direction)
|
|
53
|
+
"from_sbml": ("annnet.adapters.sbml_adapter", "from_sbml"),
|
|
54
|
+
# If you add export later: "to_sbml": ("annnet.adapters.sbml_adapter", "to_sbml"),
|
|
55
|
+
# Parquet GraphDir
|
|
56
|
+
"write_parquet_graphdir": (
|
|
57
|
+
"annnet.adapters.GraphDir_Parquet_adapter",
|
|
58
|
+
"write_parquet_graphdir",
|
|
59
|
+
),
|
|
60
|
+
"read_parquet_graphdir": (
|
|
61
|
+
"annnet.adapters.GraphDir_Parquet_adapter",
|
|
62
|
+
"read_parquet_graphdir",
|
|
63
|
+
),
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
__all__ = sorted(set(list(_lazy_submodules) + list(_lazy_symbols)))
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def __getattr__(name: str) -> Any: # PEP 562: lazy attribute resolution
|
|
70
|
+
if name in _lazy_submodules:
|
|
71
|
+
return import_module(_lazy_submodules[name])
|
|
72
|
+
if name in _lazy_symbols:
|
|
73
|
+
mod, attr = _lazy_symbols[name]
|
|
74
|
+
return getattr(import_module(mod), attr)
|
|
75
|
+
raise AttributeError(name)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def __dir__() -> list[str]:
|
|
79
|
+
return sorted(list(globals().keys()) + list(__all__))
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
# Version: prefer internal, then fall back to distribution metadata
|
|
83
|
+
try:
|
|
84
|
+
from ._version import __version__ # type: ignore
|
|
85
|
+
except Exception:
|
|
86
|
+
try:
|
|
87
|
+
__version__ = _pkg_version("annnet")
|
|
88
|
+
except PackageNotFoundError:
|
|
89
|
+
__version__ = "0.0.0"
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# This file is part of the `annnet` Python module
|
|
5
|
+
#
|
|
6
|
+
# Copyright 2025
|
|
7
|
+
# Heidelberg University Hospital
|
|
8
|
+
#
|
|
9
|
+
# File author(s): Daniele Bottazzi (daniele.bottazzi@mail.polimi.it)
|
|
10
|
+
#
|
|
11
|
+
# Distributed under the MIT license
|
|
12
|
+
# See the file `LICENSE` or read a copy at
|
|
13
|
+
# https://opensource.org/license/mit
|
|
14
|
+
#
|
|
15
|
+
|
|
16
|
+
"""Package metadata (version, authors, etc)."""
|
|
17
|
+
|
|
18
|
+
__all__ = ["get_metadata"]
|
|
19
|
+
|
|
20
|
+
import importlib.metadata
|
|
21
|
+
import os
|
|
22
|
+
import pathlib
|
|
23
|
+
|
|
24
|
+
import toml
|
|
25
|
+
|
|
26
|
+
_VERSION = "0.0.1"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def get_metadata() -> dict:
|
|
30
|
+
"""Basic package metadata.
|
|
31
|
+
|
|
32
|
+
Retrieves package metadata from the current project directory or from
|
|
33
|
+
the installed package.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
here = pathlib.Path(__file__).parent
|
|
37
|
+
pyproj_toml = "pyproject.toml"
|
|
38
|
+
meta = {}
|
|
39
|
+
|
|
40
|
+
for project_dir in (here, here.parent):
|
|
41
|
+
toml_path = str(project_dir.joinpath(pyproj_toml).absolute())
|
|
42
|
+
|
|
43
|
+
if os.path.exists(toml_path):
|
|
44
|
+
pyproject = toml.load(toml_path)
|
|
45
|
+
|
|
46
|
+
meta = {
|
|
47
|
+
"name": pyproject["tool"]["poetry"]["name"],
|
|
48
|
+
"version": pyproject["tool"]["poetry"]["version"],
|
|
49
|
+
"author": pyproject["tool"]["poetry"]["authors"],
|
|
50
|
+
"license": pyproject["tool"]["poetry"]["license"],
|
|
51
|
+
"full_metadata": pyproject,
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
break
|
|
55
|
+
|
|
56
|
+
if not meta:
|
|
57
|
+
try:
|
|
58
|
+
meta = {k.lower(): v for k, v in importlib.metadata.metadata(here.name).items()}
|
|
59
|
+
|
|
60
|
+
except importlib.metadata.PackageNotFoundError:
|
|
61
|
+
pass
|
|
62
|
+
|
|
63
|
+
meta["version"] = meta.get("version", None) or _VERSION
|
|
64
|
+
|
|
65
|
+
return meta
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
metadata = get_metadata()
|
|
69
|
+
__version__ = metadata.get("version", None)
|
|
70
|
+
__author__ = metadata.get("author", None)
|
|
71
|
+
__license__ = "MIT"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|