{"id":13689191,"url":"https://github.com/EdisonLeeeee/GraphGallery","last_synced_at":"2025-05-01T23:33:01.020Z","repository":{"id":38376115,"uuid":"246315151","full_name":"EdisonLeeeee/GraphGallery","owner":"EdisonLeeeee","description":"GraphGallery is a gallery for benchmarking Graph Neural Networks, From InplusLab.","archived":false,"fork":false,"pushed_at":"2023-08-14T09:37:11.000Z","size":10029,"stargazers_count":458,"open_issues_count":4,"forks_count":64,"subscribers_count":13,"default_branch":"master","last_synced_at":"2024-10-02T15:47:19.192Z","etag":null,"topics":["adversarial-machine-learning","dgl","geometric-deep-learning","graph","graph-neural-networks","graphgallery","models","pyg","pytorch"],"latest_commit_sha":null,"homepage":"","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/EdisonLeeeee.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,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-03-10T13:57:10.000Z","updated_at":"2024-09-06T08:59:31.000Z","dependencies_parsed_at":"2024-01-17T06:18:23.067Z","dependency_job_id":"0eca2fd3-228f-45ff-b3ea-9e5a9c44c49e","html_url":"https://github.com/EdisonLeeeee/GraphGallery","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EdisonLeeeee%2FGraphGallery","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EdisonLeeeee%2FGraphGallery/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EdisonLeeeee%2FGraphGallery/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EdisonLeeeee%2FGraphGallery/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/EdisonLeeeee","download_url":"https://codeload.github.com/EdisonLeeeee/GraphGallery/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224282174,"owners_count":17285783,"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":["adversarial-machine-learning","dgl","geometric-deep-learning","graph","graph-neural-networks","graphgallery","models","pyg","pytorch"],"created_at":"2024-08-02T15:01:37.586Z","updated_at":"2025-05-01T23:33:00.998Z","avatar_url":"https://github.com/EdisonLeeeee.png","language":"Python","readme":"\u003cp align=\"center\"\u003e\r\n  \u003cimg width = \"700\" height = \"300\" src=\"https://github.com/EdisonLeeeee/GraphGallery/blob/master/imgs/graphgallery.svg\" alt=\"banner\"/\u003e\r\n  \u003cbr/\u003e\r\n\u003c/p\u003e\r\n\u003cp align=\"center\"\u003e\u003cstrong\u003e\u003cem\u003ePyTorch\u003c/em\u003e is all you need!\u003c/strong\u003e\u003c/p\u003e\r\n\r\n\u003cp align=center\u003e\r\n  \u003ca href=\"https://www.python.org/downloads/release/python-360/\"\u003e\r\n    \u003cimg src=\"https://img.shields.io/badge/Python-\u003e=3.6-3776AB?logo=python\" alt=\"Python\"\u003e\r\n  \u003c/a\u003e    \r\n  \u003c!-- \u003ca href=\"https://github.com/tensorflow/tensorflow/releases/tag/v2.1.0\"\u003e\r\n    \u003cimg src=\"https://img.shields.io/badge/TensorFlow-\u003e=2.1.0-FF6F00?logo=tensorflow\" alt=\"tensorflow\"\u003e\r\n  \u003c/a\u003e       --\u003e\r\n  \u003ca href=\"https://github.com/pytorch/pytorch\"\u003e\r\n    \u003cimg src=\"https://img.shields.io/badge/PyTorch-\u003e=1.4-FF6F00?logo=pytorch\" alt=\"pytorch\"\u003e\r\n  \u003c/a\u003e   \r\n  \u003ca href=\"https://pypi.org/project/graphgallery/\"\u003e\r\n    \u003cimg src=\"https://badge.fury.io/py/graphgallery.svg\" alt=\"pypi\"\u003e\r\n  \u003c/a\u003e       \r\n  \u003ca href=\"https://github.com/EdisonLeeeee/GraphGallery/blob/master/LICENSE\"\u003e\r\n    \u003cimg src=\"https://img.shields.io/github/license/EdisonLeeeee/GraphGallery\" alt=\"license\"\u003e\r\n  \u003c/a\u003e       \r\n\u003c/p\u003e\r\n\r\n# GraphGallery\r\nGraphGallery is a gallery for benchmarking Graph Neural Networks (GNNs) based on pure [PyTorch](https://github.com/pytorch/pytorch) backend. Alteratively, [Pytorch Geometric (PyG)](https://github.com/pyg-team/pytorch_geometric) and [Deep Graph Library (DGL)](https://www.dgl.ai/) backend are also available in GraphGallery to facilitate your implementations.\r\n\r\n\r\n# 💨 NEWS\r\n+ November 20, 2021: We now no longer support `TensorFlow` backend.\r\n+ November 20, 2021: The module `graphgallery.attack` is deprecated, users may refer to [GraphWar](https://github.com/EdisonLeeeee/GraphWar) for more information.\r\n\r\n# 🚀 Installation\r\nPlease make sure you have installed [PyTorch](https://pytorch.org/). Also, [Pytorch Geometric (PyG)](https://github.com/pyg-team/pytorch_geometric) and [Deep Graph Library (DGL)](https://www.dgl.ai/) are alternative choices.\r\n\r\nInstall from source:\r\n\r\n```bash\r\n# Recommended\r\ngit clone https://github.com/EdisonLeeeee/GraphGallery.git \u0026\u0026 cd GraphGallery\r\npip install -e . --verbose\r\n```\r\nwhere `-e` means \"editable\" mode so you don't have to reinstall every time you make changes. \r\n\r\n**NOTE**: GraphGallery is a frequently updated package and DO NOT install GraphGallery with `pip`, we're currently working on releasing a binary distribution on `PyPI`, stay tuned!\r\n\r\n# 🤖 Implementations\r\nIn detail, the following methods are currently implemented:\r\n\r\n## Node Classification\r\n| Method                    | Author                        | Paper                                                                                                                                                                     | PyTorch            | PyG                | DGL                |\r\n| ------------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ------------------ | ------------------ |\r\n| **ChebyNet**              | *Michaël Defferrard et al.*   | [Convolutional Neural Networks on Graphs with Fast Localized Spectral Filtering (NeurIPS'16)](https://arxiv.org/abs/1606.09375)                                           | :heavy_check_mark: |                    |                    |\r\n| **GCN**                   | *Thomas N. Kipf et al.*       | [Semi-Supervised Classification with Graph Convolutional Networks (ICLR'17)](https://arxiv.org/abs/1609.02907)                                                            | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |\r\n| **GraphSAGE**             | *William L. Hamilton et al.*  | [Inductive Representation Learning on Large Graphs (NeurIPS'17)](https://arxiv.org/abs/1706.02216)                                                                        | :heavy_check_mark: | :heavy_check_mark: |                    |\r\n| **FastGCN**               | *Jie Chen et al.*             | [FastGCN: Fast Learning with Graph Convolutional Networks via Importance Sampling (ICLR'18)](https://arxiv.org/abs/1801.10247)                                            | :heavy_check_mark: |                    |                    |\r\n| **GAT**                   | *Petar Veličković et al.*     | [Graph Attention Networks (ICLR'18)](https://arxiv.org/abs/1710.10903)                                                                                                    | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |\r\n| **SGC**                   | *Felix Wu et al.*             | [Simplifying Graph Convolutional Networks (ICLR'19)](https://arxiv.org/abs/1902.07153)                                                                                    | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |\r\n| **GWNN**                  | *Bingbing Xu et al.*          | [Graph Wavelet Neural Network (ICLR'19)](https://arxiv.org/abs/1904.07785)                                                                                                | :heavy_check_mark: |                    |                    |\r\n| **ClusterGCN**            | *Wei-Lin Chiang et al.*       | [Cluster-GCN: An Efficient Algorithm for Training Deep and Large Graph Convolutional Networks (KDD'19)](https://arxiv.org/abs/1905.07953)                                 | :heavy_check_mark: |                    |                    |\r\n| **DAGNN**                 | *Meng Liu et al.*             | [Towards Deeper Graph Neural Networks (KDD'20)](https://arxiv.org/abs/2007.09296)                                                                                         | :heavy_check_mark: |                    | :heavy_check_mark: |\r\n| **GDC**                   | *Johannes Klicpera et al.*    | [Diffusion Improves Graph Learning (NeurIPS'19)](https://www.in.tum.de/daml/gdc/)                                                                                         | :heavy_check_mark: |                    |                    |\r\n| **TAGCN**                 | *Jian Du et al.*              | [Topology Adaptive Graph Convolutional Networks (arxiv'17)](https://arxiv.org/abs/1710.10370)                                                                             | :heavy_check_mark: |                    |                    |\r\n| **APPNP, PPNP**           | *Johannes Klicpera et al.*    | [Predict then Propagate: Graph Neural Networks meet Personalized PageRank (ICLR'19)](https://arxiv.org/abs/1810.05997)                                                    | :heavy_check_mark: |                    | :heavy_check_mark: |\r\n| **PDN**                   | *Benedek Rozemberczki et al.* | [Pathfinder Discovery Networks for Neural Message Passing (ICLR'21)](https://arxiv.org/abs/2010.12878)                                                                    |                    | :heavy_check_mark: |                    |\r\n| **SSGC**                  | *Zhu et al.*                  | [Simple Spectral Graph Convolution (ICLR'21)](https://openreview.net/forum?id=CYO5T-YjWZV)                                                                                | :heavy_check_mark: |                    |                    |\r\n| **AGNN**                  | *Kiran K. Thekumparampil al.* | [Attention-based Graph Neural Network for semi-supervised learning (ICLR'18 openreview)](https://arxiv.org/abs/1803.03735)                                                | :heavy_check_mark: |                    |                    |\r\n| **ARMA**                  | *Bianchi et al.*              | [Graph Neural Networks with convolutional ARMA filters (Arxiv'19)](https://arxiv.org/abs/1901.01343)                                                                      |                    |                    |                    |\r\n| **GraphML*P***            | *Yang Hu et al.*              | [Graph-MLP: Node Classification without Message Passing in Graph (Arxiv'21)](https://arxiv.org/abs/2106.04051)                                                            | :heavy_check_mark: |                    |                    |\r\n| **LGC, EGC, hLGC**        | *Luca Pasa et al.*            | [Simple Graph Convolutional Networks (Arxiv'21)](https://arxiv.org/abs/2106.05809)                                                                                        |                    |                    | :heavy_check_mark: |\r\n| **GRAND**                 | *Wenzheng Feng et al.*        | [Graph Random Neural Network for Semi-Supervised Learning on Graphs (NeurIPS'20)](https://arxiv.org/abs/2005.11079)                                                       |                    |                    | :heavy_check_mark: |\r\n| **AlaGCN, AlaGAT**        | *Yiqing Xie et al.*           | [When Do GNNs Work: Understanding and Improving Neighborhood Aggregation (IJCAI'20)](https://www.ijcai.org/Proceedings/2020/0181.pdf)                                     |                    |                    | :heavy_check_mark: |\r\n| **JKNet**                 | *Keyulu Xu et al.*            | [Representation Learning on Graphs with Jumping Knowledge Networks (ICML'18)](https://arxiv.org/abs/1806.03536)                                                           |                    |                    | :heavy_check_mark: |\r\n| **MixHop**                | *Sami Abu-El-Haija et al.*    | [MixHop: Higher-Order Graph Convolutional Architecturesvia Sparsified Neighborhood Mixing (ICML'19)](https://arxiv.org/abs/1905.00067)                                    |                    |                    | :heavy_check_mark: |\r\n| **DropEdge**              | *Yu Rong et al.*              | [DropEdge: Towards Deep Graph Convolutional Networks on Node Classification (ICML'20)](https://arxiv.org/abs/1907.10903)                                                  |                    | :heavy_check_mark: |                    |\r\n| **Node2Grids**            | *Dalong Yang et al.*          | [Node2Grids: A Cost-Efficient Uncoupled Training Framework for Large-Scale Graph Learning (CIKM'21)](https://arxiv.org/abs/2003.09638)                                    | :heavy_check_mark: |                    |                    |\r\n| **RobustGCN**             | *Dingyuan Zhu et al.*         | [Robust Graph Convolutional Networks Against Adversarial Attacks (KDD'19)](https://dl.acm.org/doi/10.1145/3292500.3330851)                                                | :heavy_check_mark: |                    | :heavy_check_mark: |\r\n| **SBVAT, OBVAT**          | *Zhijie Deng et al.*          | [Batch Virtual Adversarial Training for Graph Convolutional Networks (ICML'19)](https://arxiv.org/abs/1902.09192)                                                         | :heavy_check_mark: |                    |                    |\r\n| **SimPGCN**               | *Wei Jin et al.*              | [Node Similarity Preserving Graph Convolutional Networks (WSDM'21)](https://arxiv.org/abs/2011.09643)                                                                     | :heavy_check_mark: |                    |                    |\r\n| **GraphVAT**              | *Fuli Feng et al.*            | [Graph Adversarial Training: Dynamically Regularizing Based on Graph Structure (TKDE'19)](https://arxiv.org/abs/1902.08226)                                               | :heavy_check_mark: |                    |                    |\r\n| **LATGCN**                | *Hongwei Jin et al.*          | [Latent Adversarial Training of Graph Convolution Networks (ICML@LRGSD'19)](https://graphreason.github.io/papers/35.pdf)                                                  | :heavy_check_mark: |                    |                    |\r\n| **DGAT**                  | *Weibo Hu et al.*             | [Robust graph convolutional networks with directional graph adversarial training (Applied Intelligence'19)](https://link.springer.com/article/10.1007/s10489-021-02272-y) | :heavy_check_mark: |                    |                    |\r\n| **MedianGCN, TrimmedGCN** | *Liang Chen et al.*           | [Understanding Structural Vulnerability in Graph Convolutional Networks](https://arxiv.org/abs/2108.06280)                                                                | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |\r\n\r\n#### Graph Purification\r\n\r\nThe graph purification methods are universal for all models, just specify:\r\n\r\n```python\r\ngraph_transform=\"purification_method\"\r\n```\r\n\r\nso, here we only give the examples of `GCN` with purification methods, other models should work.\r\n\r\n| Method          | Author                  | Paper                                                                                                                                       |\r\n| --------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |\r\n| **GCN-Jaccard** | *Huijun Wu et al.*      | [Adversarial Examples on Graph Data: Deep Insights into Attack and Defense (IJCAI'19)](https://arxiv.org/abs/1903.01610)                    |\r\n| **GCN-SVD**     | *Negin Entezari et al.* | [All You Need Is Low (Rank): Defending Against Adversarial Attacks on Graphs (WSDM'20)](https://dl.acm.org/doi/abs/10.1145/3336191.3371789) |\r\n\r\n## LinkPrediction\r\n| Method        | Author                  | Paper                                                                           | PyTorch            | PyG                | DGL |\r\n| ------------- | ----------------------- | ------------------------------------------------------------------------------- | ------------------ | ------------------ | --- |\r\n| **GAE, VGAE** | *Thomas N. Kipf et al.* | [Variational Graph Auto-Encoders (NeuIPS'16)](https://arxiv.org/abs/1611.07308) | :heavy_check_mark: | :heavy_check_mark: |     |\r\n\r\n## Node Embedding\r\nThe following methods are framework-agnostic.\r\n\r\n| Method        | Author                            | Paper                                                                                                           |\r\n| ------------- | --------------------------------- | --------------------------------------------------------------------------------------------------------------- |\r\n| **Deepwalk**  | *Bryan Perozzi et al.*            | [DeepWalk: Online Learning of Social Representations (KDD'14)](https://arxiv.org/abs/1403.6652)                 |\r\n| **Node2vec**  | *Aditya Grover and Jure Leskovec* | [node2vec: Scalable Feature Learning for Networks (KDD'16)](https://arxiv.org/abs/1607.00653)                   |\r\n| **Node2vec+** | *Renming Liu et al.*              | [Accurately Modeling Biased Random Walks on Weighted Graphs Using  Node2vec+](https://arxiv.org/abs/2109.08031) |\r\n| **BANE**      | *Hong Yang et al.*                | [Binarized attributed network embedding (ICDM'18)](https://ieeexplore.ieee.org/document/8626170)                |\r\n\r\n\r\n\r\n# ⚡ Quick Start\r\n## Datasets\r\n+ [Planetoid](https://github.com/kimiyoung/planetoid): a collection of widely used benchmark datasets in graph learning tasks, including 'cora', 'citeseerr', 'pubmed' and 'nell' datasets.\r\n+ NPZDataset: a collection of graph datasets stored with numpy `.npz` format.\r\n\r\nyou can simply run `dataset.available_datasets()` to see the available datasets, e.g.,:\r\n\r\n```python\r\nfrom graphgallery.datasets import Planetoid\r\nprint(Planetoid.available_datasets())\r\n```\r\n\r\nmore details please refer to [GraphData](https://github.com/EdisonLeeeee/GraphData).\r\n## Example of GCN (Node Classification Task)\r\nIt takes just a few lines of code.\r\n```python\r\nimport torch\r\nimport graphgallery\r\nfrom graphgallery.datasets import Planetoid\r\nfrom graphgallery.gallery import callbacks\r\n\r\ndata = Planetoid('cora', root=\"~/GraphData/datasets/\", verbose=True)\r\ngraph = data.graph\r\nsplits = data.split_nodes()\r\ndevice = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')\r\n\r\ngraphgallery.set_backend(\"torch\")\r\nfrom graphgallery.gallery.nodeclas import GCN\r\n\r\ntrainer = GCN(device=device, seed=123).setup_graph(graph, feat_transform=\"normalize_feat\").build()\r\ncb = callbacks.ModelCheckpoint('model.pth', monitor='val_accuracy')\r\ntrainer.fit(splits.train_nodes, splits.val_nodes, verbose=1, callbacks=[cb])\r\nresults = trainer.evaluate(splits.test_nodes)\r\nprint(f'Test loss {results.loss:.5}, Test accuracy {results.accuracy:.2%}')\r\n```\r\n## Example of GAE (Link Prediction Task)\r\n\r\n```python\r\nimport torch\r\nimport graphgallery\r\nfrom graphgallery.gallery import callbacks\r\nfrom graphgallery.datasets import Planetoid\r\n\r\ndata = Planetoid('cora', root=\"~/GraphData/datasets/\", verbose=True)\r\ngraph = data.graph\r\nsplits = data.split_edges(random_state=15)\r\ndevice = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')\r\n\r\ngraphgallery.set_backend(\"torch\")\r\n\r\nfrom graphgallery.gallery.linkpred import GAE\r\ntrainer = GAE(device=device, seed=123).setup_graph(graph).build()\r\ncb = callbacks.ModelCheckpoint('model.pth', monitor='val_ap')\r\ntrainer.fit(splits.train_pos_edge_index,\r\n            val_data=(splits.val_pos_edge_index, splits.val_neg_edge_index), \r\n            verbose=1, callbacks=[cb])\r\nresults = trainer.evaluate((splits.test_pos_edge_index, splits.test_neg_edge_index))\r\nprint(results)\r\n```\r\n\r\nIf you have any troubles, you can simply run `trainer.help()` for more information.\r\n\r\n## Other Backends\r\n```python\r\n\u003e\u003e\u003e import graphgallery\r\n# Default: PyTorch backend\r\n\u003e\u003e\u003e graphgallery.backend()\r\nPyTorch 1.9.0+cu111 Backend\r\n# Switch to PyTorch Geometric backend\r\n\u003e\u003e\u003e graphgallery.set_backend(\"pyg\")\r\n# Switch to DGL PyTorch backend\r\n\u003e\u003e\u003e graphgallery.set_backend(\"dgl\")\r\n# Switch to PyTorch backend\r\n\u003e\u003e\u003e graphgallery.set_backend(\"th\") # \"torch\", \"pytorch\"\r\n```\r\nBut your codes don't even need to change.\r\n\r\n# ❓ How to add your datasets\r\nThis is motivated by [gnn-benchmark](https://github.com/shchur/gnn-benchmark/)\r\n```python\r\nfrom graphgallery.data import Graph\r\n\r\n# Load the adjacency matrix A, attribute (feature) matrix X and labels vector y\r\n# A - scipy.sparse.csr_matrix of shape [num_nodes, num_nodes]\r\n# X - scipy.sparse.csr_matrix or numpy.ndarray of shape [num_nodes, num_feats]\r\n# y - numpy.ndarray of shape [num_nodes]\r\n\r\nmydataset = Graph(adj_matrix=A, attr_matrix=X, label=y)\r\n# save dataset\r\nmydataset.to_npz('path/to/mydataset.npz')\r\n# load dataset\r\nmydataset = Graph.from_npz('path/to/mydataset.npz')\r\n```\r\n\r\n\r\n# ⭐ Road Map\r\n- [x] Add PyTorch trainers support\r\n- [x] Add other frameworks (PyG and DGL) support\r\n- [x] set tensorflow as optional dependency when using graphgallery\r\n- [ ] Add more GNN trainers\r\n- [ ] Support for more tasks, e.g., `graph Classification` and `link prediction`\r\n- [x] Support for more types of graphs, e.g., Heterogeneous graph\r\n- [ ] Add Docstrings and Documentation (Building)\r\n- [ ] Comprehensive tutorials\r\n\r\n# ❓ FAQ\r\nPlease fell free to contact me if you have any troubles.\r\n\r\n# 😘 Acknowledgement\r\nThis project is motivated by [Pytorch Geometric](https://github.com/rusty1s/pytorch_geometric), [Stellargraph](https://github.com/stellargraph/stellargraph) and [DGL](https://www.dgl.ai/), etc., and the original implementations of the authors, thanks for their excellent works!\r\n\r\n# Cite\r\nPlease cite our [paper](https://www.computer.org/csdl/proceedings-article/icse-companion/2021/121900a013/1sET5DXNWJG) (and the respective papers of the methods used) if you use this code in your own work:\r\n```bibtex\r\n@inproceedings{li2021graphgallery,\r\nauthor = {Jintang Li and Kun Xu and Liang Chen and Zibin Zheng and Xiao Liu},\r\nbooktitle = {2021 IEEE/ACM 43rd International Conference on Software Engineering: Companion Proceedings (ICSE-Companion)},\r\ntitle = {GraphGallery: A Platform for Fast Benchmarking and Easy Development of Graph Neural Networks Based Intelligent Software},\r\nyear = {2021},\r\npages = {13-16},\r\npublisher = {IEEE Computer Society},\r\naddress = {Los Alamitos, CA, USA},\r\n}\r\n```\r\n","funding_links":[],"categories":["Python","图机器学习库"],"sub_categories":["网络服务_其他"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FEdisonLeeeee%2FGraphGallery","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FEdisonLeeeee%2FGraphGallery","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FEdisonLeeeee%2FGraphGallery/lists"}