hinge 0.1.0__py3-none-any.whl

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.
Files changed (111) hide show
  1. hinge/__init__.py +3 -0
  2. hinge/config/__init__.py +0 -0
  3. hinge/config/logging_setup.py +63 -0
  4. hinge/config/settings.py +23 -0
  5. hinge/config/types.yaml +42 -0
  6. hinge/dbt/.user.yml +1 -0
  7. hinge/dbt/dbt_project.yml +18 -0
  8. hinge/dbt/macros/apply_time_window.sql +11 -0
  9. hinge/dbt/macros/assert_recipe_supported.sql +59 -0
  10. hinge/dbt/macros/build_incidence.sql +46 -0
  11. hinge/dbt/macros/collapse_path.sql +26 -0
  12. hinge/dbt/macros/filter_bots.sql +23 -0
  13. hinge/dbt/macros/network_edges.sql +39 -0
  14. hinge/dbt/macros/project_bipartite.sql +33 -0
  15. hinge/dbt/macros/slice_edges.sql +41 -0
  16. hinge/dbt/models/hin/hin_accounts.sql +14 -0
  17. hinge/dbt/models/hin/hin_artifacts.sql +23 -0
  18. hinge/dbt/models/hin/hin_capabilities.sql +42 -0
  19. hinge/dbt/models/hin/hin_edges.sql +57 -0
  20. hinge/dbt/models/hin/hin_nodes.sql +44 -0
  21. hinge/dbt/models/hin/hin_repositories.sql +15 -0
  22. hinge/dbt/models/intermediate/int_developer_repo_affiliation.sql +27 -0
  23. hinge/dbt/models/intermediate/int_user_artifact_incidence.sql +21 -0
  24. hinge/dbt/models/networks/artifact_reference.sql +27 -0
  25. hinge/dbt/models/networks/co_commit_user_user.sql +48 -0
  26. hinge/dbt/models/networks/co_edit_file_user_user.sql +48 -0
  27. hinge/dbt/models/networks/co_edit_line_user_user.sql +48 -0
  28. hinge/dbt/models/networks/dev_interaction.sql +98 -0
  29. hinge/dbt/models/networks/developer_repo_affiliation.sql +20 -0
  30. hinge/dbt/models/networks/follow_user_user.sql +27 -0
  31. hinge/dbt/models/networks/fork_repo_repo.sql +27 -0
  32. hinge/dbt/models/networks/issue_co_participation.sql +50 -0
  33. hinge/dbt/models/networks/issue_participation.sql +40 -0
  34. hinge/dbt/models/networks/pr_author_reviewer.sql +66 -0
  35. hinge/dbt/models/networks/pr_participation.sql +40 -0
  36. hinge/dbt/models/networks/pr_reviewer_coreview.sql +48 -0
  37. hinge/dbt/models/networks/repo_shared_contributors.sql +41 -0
  38. hinge/dbt/models/networks/star_user_repo.sql +27 -0
  39. hinge/dbt/models/networks/user_mention_user.sql +60 -0
  40. hinge/dbt/models/networks/watch_user_repo.sql +27 -0
  41. hinge/dbt/models/sources/sources.yml +63 -0
  42. hinge/dbt/models/staging/stg_accounts.sql +4 -0
  43. hinge/dbt/models/staging/stg_adapter_manifest.sql +4 -0
  44. hinge/dbt/models/staging/stg_artifacts.sql +4 -0
  45. hinge/dbt/models/staging/stg_relations.sql +4 -0
  46. hinge/dbt/models/staging/stg_repositories.sql +4 -0
  47. hinge/dbt/profiles.yml +9 -0
  48. hinge/dbt/seeds/ref_recipe_requirements.csv +35 -0
  49. hinge/frontends/__init__.py +0 -0
  50. hinge/frontends/cli/__init__.py +3 -0
  51. hinge/frontends/cli/app.py +189 -0
  52. hinge/frontends/lib.py +148 -0
  53. hinge/frontends/tui/__init__.py +7 -0
  54. hinge/frontends/web/__init__.py +6 -0
  55. hinge/kernel/__init__.py +0 -0
  56. hinge/kernel/projection/__init__.py +9 -0
  57. hinge/kernel/projection/projected_graph.py +32 -0
  58. hinge/kernel/projection/projection_spec.py +35 -0
  59. hinge/kernel/protocols/__init__.py +24 -0
  60. hinge/kernel/protocols/dataset_view.py +30 -0
  61. hinge/kernel/protocols/exporter_stage.py +24 -0
  62. hinge/kernel/protocols/projection_stage.py +36 -0
  63. hinge/kernel/protocols/reader_stage.py +52 -0
  64. hinge/kernel/protocols/store_stage.py +71 -0
  65. hinge/kernel/registry.py +71 -0
  66. hinge/kernel/runner.py +236 -0
  67. hinge/kernel/schema/__init__.py +12 -0
  68. hinge/kernel/schema/hin_schema.py +38 -0
  69. hinge/kernel/schema/schema_violation.py +21 -0
  70. hinge/kernel/schema/typed_edge.py +20 -0
  71. hinge/kernel/schema/typed_node.py +17 -0
  72. hinge/stages/__init__.py +0 -0
  73. hinge/stages/exporters/__init__.py +0 -0
  74. hinge/stages/exporters/csv_exporter.py +77 -0
  75. hinge/stages/exporters/dot_exporter.py +13 -0
  76. hinge/stages/exporters/gexf_exporter.py +13 -0
  77. hinge/stages/exporters/gml_exporter.py +79 -0
  78. hinge/stages/exporters/graphml_exporter.py +13 -0
  79. hinge/stages/exporters/jsonld_exporter.py +13 -0
  80. hinge/stages/exporters/networkx_exporter.py +57 -0
  81. hinge/stages/exporters/parquet_exporter.py +13 -0
  82. hinge/stages/projection/__init__.py +0 -0
  83. hinge/stages/projection/dbt_projection.py +342 -0
  84. hinge/stages/projection/specs/__init__.py +0 -0
  85. hinge/stages/projection/specs/artifact_reference.py +14 -0
  86. hinge/stages/projection/specs/co_commit_user_user.py +14 -0
  87. hinge/stages/projection/specs/co_edit_file_user_user.py +14 -0
  88. hinge/stages/projection/specs/co_edit_line_user_user.py +14 -0
  89. hinge/stages/projection/specs/dev_interaction.py +26 -0
  90. hinge/stages/projection/specs/developer_repo_affiliation.py +15 -0
  91. hinge/stages/projection/specs/follow_user_user.py +14 -0
  92. hinge/stages/projection/specs/fork_repo_repo.py +14 -0
  93. hinge/stages/projection/specs/issue_co_participation.py +14 -0
  94. hinge/stages/projection/specs/issue_participation.py +14 -0
  95. hinge/stages/projection/specs/pr_author_reviewer.py +14 -0
  96. hinge/stages/projection/specs/pr_participation.py +14 -0
  97. hinge/stages/projection/specs/pr_reviewer_coreview.py +14 -0
  98. hinge/stages/projection/specs/repo_shared_contributors.py +14 -0
  99. hinge/stages/projection/specs/star_user_repo.py +15 -0
  100. hinge/stages/projection/specs/user_mention_user.py +14 -0
  101. hinge/stages/projection/specs/watch_user_repo.py +14 -0
  102. hinge/stages/readers/__init__.py +0 -0
  103. hinge/stages/readers/_numfocus_contract_adapter.py +314 -0
  104. hinge/stages/readers/numfocus_reader.py +69 -0
  105. hinge/stages/store/__init__.py +0 -0
  106. hinge/stages/store/duckdb_store.py +466 -0
  107. hinge-0.1.0.dist-info/METADATA +309 -0
  108. hinge-0.1.0.dist-info/RECORD +111 -0
  109. hinge-0.1.0.dist-info/WHEEL +4 -0
  110. hinge-0.1.0.dist-info/entry_points.txt +35 -0
  111. hinge-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,309 @@
1
+ Metadata-Version: 2.4
2
+ Name: hinge
3
+ Version: 0.1.0
4
+ Summary: Heterogeneous Information Network tool for GitHub research datasets
5
+ Project-URL: Homepage, https://github.com/marcotonnarelli/hinge
6
+ Project-URL: Repository, https://github.com/marcotonnarelli/hinge
7
+ Project-URL: Issues, https://github.com/marcotonnarelli/hinge/issues
8
+ Author-email: Filippo Scaramuzza <f.scaramuzza@tue.nl>, Marco Tonnarelli <m.tonnarelli@tue.nl>, Gergő Bocsárdi <a.g.bocsardi@tue.nl>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: dbt,duckdb,github,graph,heterogeneous-information-network,mining
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Python: >=3.12
21
+ Requires-Dist: dbt-core>=1.8
22
+ Requires-Dist: dbt-duckdb>=1.8
23
+ Requires-Dist: duckdb>=1.0
24
+ Requires-Dist: networkx>=3.3
25
+ Requires-Dist: orjson>=3.10
26
+ Requires-Dist: pyarrow>=16.0
27
+ Requires-Dist: pydantic>=2.7
28
+ Requires-Dist: pyyaml>=6.0
29
+ Requires-Dist: rich>=13.7
30
+ Requires-Dist: typer>=0.12
31
+ Provides-Extra: dev
32
+ Requires-Dist: import-linter>=2.0; extra == 'dev'
33
+ Requires-Dist: mypy>=1.10; extra == 'dev'
34
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
35
+ Requires-Dist: pytest>=8.2; extra == 'dev'
36
+ Requires-Dist: ruff>=0.5; extra == 'dev'
37
+ Requires-Dist: types-pyyaml; extra == 'dev'
38
+ Provides-Extra: tui
39
+ Requires-Dist: textual>=0.70; extra == 'tui'
40
+ Provides-Extra: web
41
+ Requires-Dist: fastapi>=0.111; extra == 'web'
42
+ Requires-Dist: uvicorn>=0.30; extra == 'web'
43
+ Description-Content-Type: text/markdown
44
+
45
+ # HINGE — Heterogeneous Information Network for Generalized Extraction
46
+
47
+ `hinge` ingests GitHub activity datasets (JSONL today; CSV/Parquet planned), persists
48
+ them as a typed multi-relational graph in DuckDB, and exposes **projections** —
49
+ dbt SQL models that derive task-specific sub-graphs and export them to formats
50
+ consumed by Gephi, NetworkX, igraph, etc.
51
+
52
+ This is a research artefact accompanying an ICSME 2026 Tools and Data Showcase submission.
53
+
54
+ ---
55
+
56
+ ## Quick start
57
+
58
+ ```bash
59
+ # 1. Install (uv is the only supported package manager)
60
+ uv sync --all-extras
61
+
62
+ # 2. Ingest a dataset
63
+ uv run hinge ingest path/to/events.jsonl --reader numfocus
64
+ # → ingested 48 elements → 29 nodes, 19 edges (0 violations)
65
+ # → Dataset ID: 78fc87c370944dc2b4a4e2d4bdd97ce1
66
+
67
+ # 3. Use the printed Dataset ID to run a projection and export
68
+ uv run hinge export \
69
+ --dataset 78fc87c370944dc2b4a4e2d4bdd97ce1 \
70
+ --projection user-user-repo-collaboration \
71
+ --format gml \
72
+ -o out/graph.gml
73
+
74
+ # 4. Inspect all ingested datasets
75
+ uv run hinge list datasets
76
+ ```
77
+
78
+ Or via Docker:
79
+
80
+ ```bash
81
+ docker compose build
82
+ cp path/to/events.jsonl ./data/
83
+ docker compose run --rm hinge hinge ingest /data/events.jsonl --reader numfocus
84
+ docker compose run --rm hinge hinge export \
85
+ --dataset <id> --projection user-user-repo-collaboration --format gml -o /output/graph.gml
86
+ ```
87
+
88
+ The DuckDB store lives at `$HINGE_STORE_PATH` (default `./network.duckdb`
89
+ locally, `/store/network.duckdb` inside the container). Multiple datasets
90
+ can coexist in the same file — each ingest run gets a unique Dataset ID.
91
+
92
+ ---
93
+
94
+ ## HIN contract + adapters
95
+
96
+ The source-agnostic core starts at the adapter contract tables:
97
+
98
+ ```text
99
+ source-specific adapter
100
+ -> contract_accounts / contract_repositories / contract_artifacts / contract_relations
101
+ -> hin_nodes / hin_edges
102
+ -> dbt projections
103
+ -> exporters
104
+ ```
105
+
106
+ The `numfocus` reader uses a DuckDB adapter for this repo's NumFocus Actions
107
+ JSONL scrape. It is intentionally source-specific: it knows paths like
108
+ `$.actor.login` and `$.details.pull_request.id`. Other data sources should
109
+ implement their own adapter that writes the same `contract_*` tables; then the
110
+ HIN views and dbt recipes can run unchanged.
111
+
112
+ The generic Python `ReaderStage` path is still available for simple custom
113
+ readers, but large JSONL ingests should use a DuckDB/SQL contract adapter where
114
+ possible.
115
+
116
+ ---
117
+
118
+ ## Adding a new projection
119
+
120
+ A projection is a dbt SQL model that derives a task-specific sub-graph from
121
+ the typed HIN stored in DuckDB. Adding one requires exactly four files/edits
122
+ and no changes to the kernel.
123
+
124
+ ### Step 1 — Write the SQL model
125
+
126
+ Create `hinge/dbt/models/networks/<name>.sql`. The model should read from
127
+ the canonical HIN dbt models and produce a fixed set of columns:
128
+
129
+ ```sql
130
+ -- Inputs (prefer these canonical HIN models, never the raw tables)
131
+ {{ ref('hin_nodes') }}
132
+ {{ ref('hin_edges') }}
133
+
134
+ -- Output (prefer the network_edges macro; it emits this standard schema)
135
+ network_edges(
136
+ recipe_name, recipe_version,
137
+ source_node_id, source_node_type,
138
+ target_node_id, target_node_type,
139
+ directed, edge_type,
140
+ weight, weight_kind,
141
+ n_contexts, n_events,
142
+ first_seen_at, last_seen_at,
143
+ time_bin, bot_policy,
144
+ properties
145
+ )
146
+ ```
147
+
148
+ `DbtProjection` converts this richer schema into `TypedEdge` objects for existing
149
+ exporters, merging standard fields and `properties` into edge attrs.
150
+
151
+ The upstream HIN models are built from `active_*` views created by the store
152
+ immediately before dbt runs — they are already filtered to the requested
153
+ `dataset_id`, so network SQL never needs to reference `dataset_id` at all.
154
+
155
+ **Nodes-only projections:** the pipeline derives output nodes from the union
156
+ of `source_node_id` and `target_node_id` in the result table. A projection that
157
+ emits no edges will therefore produce no nodes either. The workaround is to use
158
+ **self-loop edges** (`source_node_id = target_node_id`): they make the nodes
159
+ visible to the exporter, carry metadata in `properties`, and can be filtered out
160
+ in downstream tools with `G.remove_edges_from(nx.selfloop_edges(G))`.
161
+
162
+ See [dev_interaction.sql](hinge/dbt/models/networks/dev_interaction.sql)
163
+ for a full working example with a documented input/output contract.
164
+
165
+ ### Step 2 — Create the spec module
166
+
167
+ Create `hinge/stages/projection/specs/<name>.py` and expose a `SPEC` constant:
168
+
169
+ ```python
170
+ from hinge.kernel.projection.projection_spec import ProjectionSpec
171
+
172
+ SPEC = ProjectionSpec(
173
+ name="my-projection", # CLI key: --projection my-projection
174
+ description="...",
175
+ model_name="my_projection", # must match the .sql file stem
176
+ output_node_types=["user"],
177
+ output_edge_types=["my_edge_label"],
178
+ )
179
+ ```
180
+
181
+ This is a plain value object — no class, no inheritance. The registry loads
182
+ the module and returns the `SPEC` attribute directly.
183
+
184
+ ### Step 3 — Register the entry-point
185
+
186
+ Add one line to `pyproject.toml`:
187
+
188
+ ```toml
189
+ [project.entry-points."hinge.projection_specs"]
190
+ my-projection = "hinge.stages.projection.specs.my_projection:SPEC"
191
+ ```
192
+
193
+ Third-party packages can register projections the same way — no fork required.
194
+
195
+ ### Step 4 — Re-install so the entry-point is picked up
196
+
197
+ ```bash
198
+ uv sync --all-extras
199
+ uv run hinge list projections # → my-projection should appear
200
+ ```
201
+
202
+ Entry-points are baked into `.dist-info/entry_points.txt` at install time.
203
+ Without this step the registry will not find the new spec.
204
+
205
+ ### Run it
206
+
207
+ ```bash
208
+ uv run hinge export \
209
+ --dataset <id> \
210
+ --projection my-projection \
211
+ --format gml \
212
+ -o output/result.gml
213
+ ```
214
+
215
+ ### Local SQL custom projection
216
+
217
+ For research-specific variants, write a local dbt model and run it without
218
+ packaging or entry-points:
219
+
220
+ ```bash
221
+ uv run hinge export-sql custom_star_user_repo.sql \
222
+ --dataset <id> \
223
+ --format gml \
224
+ -o output/custom.gml
225
+ ```
226
+
227
+ The SQL file is temporarily added to the built-in dbt project, so it can use
228
+ `ref('hin_edges')`, `ref('int_user_artifact_incidence')`, and all macros under
229
+ `hinge/dbt/macros/`. It must still emit the standard `network_edges` schema.
230
+ Use `--name valid_model_name` if the filename is not a valid dbt identifier.
231
+
232
+ See [docs/custom-projections.md](docs/custom-projections.md).
233
+
234
+ ---
235
+
236
+ ## Logging
237
+
238
+ Logs go to **stderr** by default. Use env vars to control verbosity and persistence:
239
+
240
+ | Variable | Purpose | Default |
241
+ |---|---|---|
242
+ | `HINGE_LOG_LEVEL` | `DEBUG` / `INFO` / `WARNING` / `ERROR` | `INFO` |
243
+ | `HINGE_LOG_FILE` | Also write logs to this file at full `DEBUG` detail | _(none)_ |
244
+
245
+ ```bash
246
+ # See all pipeline milestones (default)
247
+ uv run hinge ingest events.jsonl --reader numfocus
248
+
249
+ # See every batch, dbt SQL, store open/close
250
+ HINGE_LOG_LEVEL=DEBUG uv run hinge ingest events.jsonl --reader numfocus
251
+
252
+ # Persist a full debug log to disk (useful for long ingest runs)
253
+ HINGE_LOG_FILE=hinge.log uv run hinge ingest events.jsonl --reader numfocus
254
+ tail -f hinge.log
255
+ ```
256
+
257
+ ---
258
+
259
+ ## Common commands
260
+
261
+ ```bash
262
+ # Ingest NumFocus Actions JSONL via the DuckDB -> HIN contract adapter
263
+ uv run hinge ingest events.jsonl --reader numfocus
264
+
265
+ # Inspect stored datasets
266
+ uv run hinge list datasets
267
+ uv run hinge list projections
268
+ uv run hinge list readers
269
+ uv run hinge list exporters
270
+
271
+ # Export
272
+ uv run hinge export --dataset <id> --projection user-user-repo-collaboration --format gml -o out.gml
273
+
274
+ # Dev / CI
275
+ uv run pytest # tests
276
+ uv run ruff check . # lint
277
+ uv run ruff format . # format
278
+ uv run mypy hinge/kernel hinge/frontends # strict type-check
279
+ uv run lint-imports # enforce kernel/stages/frontends boundary
280
+ ```
281
+
282
+ ---
283
+
284
+ ## Makefile (development)
285
+
286
+ A `Makefile` is provided for quick local iteration. It uses hardcoded defaults
287
+ (fixture file, `numfocus` reader, `user-user-repo-collaboration` projection, GML format) so
288
+ you don't have to remember arguments during development — **not intended for
289
+ production use**.
290
+
291
+ ```bash
292
+ make install # uv sync --all-extras
293
+ make run # ingest fixture + export graph in one shot
294
+ make ingest # ingest tests/fixtures/events_10.jsonl --reader numfocus
295
+ make export # export the latest dataset (auto-detects ID from the store)
296
+ make test # pytest
297
+ make lint # ruff check
298
+ make fmt # ruff format
299
+ make typecheck # mypy on kernel + frontends
300
+ make clean # delete output/, dbt artefacts, caches
301
+ make reset # clean + delete network.duckdb (full fresh start)
302
+ ```
303
+
304
+ Any default can be overridden on the command line:
305
+
306
+ ```bash
307
+ make run READER=numfocus LOG_LEVEL=DEBUG
308
+ make export FORMAT=graphml OUTPUT=output/graph.graphml
309
+ ```
@@ -0,0 +1,111 @@
1
+ hinge/__init__.py,sha256=yVsheukxlHtBh1mKOtlZ441hdyycWVEPKlPNer_J_EM,175
2
+ hinge/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ hinge/config/logging_setup.py,sha256=LJeJuoyraOQgIfxpm71OWQuPwZ2XWi_8Fy7wNR2OXNA,2038
4
+ hinge/config/settings.py,sha256=fWAuyKPxBIcKEStfX1WYGWs3uPBL_SQ_sFeP_DiHCRk,589
5
+ hinge/config/types.yaml,sha256=ZmVJQu22HJ9YDRLc19iaxu92IxFS0uUjsr3m1Nk-auM,1110
6
+ hinge/dbt/.user.yml,sha256=mJg0YPvdYshUURVJfSSgmJPBXTd9uvgTwN-RWj06DvQ,41
7
+ hinge/dbt/dbt_project.yml,sha256=BDvNgBk8tAEXx_pDYL2TcNQWluY8TJ09HOfFbesuEJM,290
8
+ hinge/dbt/profiles.yml,sha256=oMvY5y8Nzpx5RSVRk9L1QMB51BjKv8tgooJPAt5nxF8,253
9
+ hinge/dbt/macros/apply_time_window.sql,sha256=_DQBWR9eUbKaDVUYNWtGKTyjA0OhGR0b13x9OB_8s0s,364
10
+ hinge/dbt/macros/assert_recipe_supported.sql,sha256=B4LcXQ7gPxsD9Rp8tw3syj_XnBH8SD-CxcLX0juHQuA,3288
11
+ hinge/dbt/macros/build_incidence.sql,sha256=BWh5OLstIp1FY1ebapieC5KS0Dfr9G3wOn0BNkpgCt8,1284
12
+ hinge/dbt/macros/collapse_path.sql,sha256=2LMT_cRGMGGSQjJPBpT-aqg6VfQPD94t9UCGARsCoQ4,984
13
+ hinge/dbt/macros/filter_bots.sql,sha256=fRcYdqE3JE5AAX-MNxkyV6eN_uk3OmGe6-U2vO62Z1Y,983
14
+ hinge/dbt/macros/network_edges.sql,sha256=k0myGty2oDeKz2ePjnhvTCpDtJITTVbuqDcuduOCMvw,1177
15
+ hinge/dbt/macros/project_bipartite.sql,sha256=kKZwWc5yInls089Z-SiFWkEBdvsY1DozqPJt6B2TUo8,1238
16
+ hinge/dbt/macros/slice_edges.sql,sha256=hnp4Qwa2g6G5xAltAqtjj5GWIxQlXwH_8M_3bCYlh1I,1342
17
+ hinge/dbt/models/hin/hin_accounts.sql,sha256=JvHdFsq2GTvyOaolOuHR4VyJZF4iu-aycLhvXv1wf6c,398
18
+ hinge/dbt/models/hin/hin_artifacts.sql,sha256=t6MuGYkXp-dmkPqeOCCDftEG7fN6riD0bP8WKOErURE,468
19
+ hinge/dbt/models/hin/hin_capabilities.sql,sha256=hkDJYDybIf3JkLsVqZqsT2bU5_7TnHk0C0Lq5HwnQkI,2684
20
+ hinge/dbt/models/hin/hin_edges.sql,sha256=oTF0JrdcloxAj2HSCnpg9x8hXta-pRFR7FaRHBjGq3Q,1662
21
+ hinge/dbt/models/hin/hin_nodes.sql,sha256=m3IMoUwYvUTYCxsDjyFGki1qhv0WtA744TLYluqWrrQ,925
22
+ hinge/dbt/models/hin/hin_repositories.sql,sha256=lGRLQTHsXeDEBMxfbxx6C7e95p-6PheBRIpNwAy_KsQ,453
23
+ hinge/dbt/models/intermediate/int_developer_repo_affiliation.sql,sha256=ynP_X1DN6dBFWC_gT0rqJz6eK1Lgz9_ZWj3tsik0zmg,846
24
+ hinge/dbt/models/intermediate/int_user_artifact_incidence.sql,sha256=FPqqsZP5i9sjmF9jLHioR_MHJ2A9fgZoNRhqAr9EfC0,412
25
+ hinge/dbt/models/networks/artifact_reference.sql,sha256=z_IR0t-V5Hlimuz88fbzG6kiIL7DUK7OiGmah3YSufY,806
26
+ hinge/dbt/models/networks/co_commit_user_user.sql,sha256=7-u2EzZcU7yhC1p5Wxas7SUDzQWN1lkVAFrFKn9uiEw,1315
27
+ hinge/dbt/models/networks/co_edit_file_user_user.sql,sha256=Vs6Gp6qtCkFEc7Ei4oDGIDopDw4KhvXy06NDPIa2-DA,1282
28
+ hinge/dbt/models/networks/co_edit_line_user_user.sql,sha256=M3JMuqVYO2qT8ZQW2GChqvqGbBCLrtEg99kWtOAhpoc,1292
29
+ hinge/dbt/models/networks/dev_interaction.sql,sha256=RCA9MIt-wmh3koIntS_3ohsqilboIGTZFrH9i8nxHkY,4822
30
+ hinge/dbt/models/networks/developer_repo_affiliation.sql,sha256=NmIikSKba95ysDeSsDijTPhIvqpK79APoxtnWy1ZO18,596
31
+ hinge/dbt/models/networks/follow_user_user.sql,sha256=m7h24h8Hq7HDlOmtIeqzIsjqFJ4NxvdhUnqsxHnu9CQ,701
32
+ hinge/dbt/models/networks/fork_repo_repo.sql,sha256=METms8QZm9OST6Y8eh8DbqHm8THg7sU18fUkFLu-onA,693
33
+ hinge/dbt/models/networks/issue_co_participation.sql,sha256=8Z_dqSRn0-FIVqapOo6lre3B8XsSn0Qj5WBrE5k_pFE,1446
34
+ hinge/dbt/models/networks/issue_participation.sql,sha256=ja1D7JRzIJ6rQh3eNG_saYMjbErV_FrpDAZaEapE9nE,1150
35
+ hinge/dbt/models/networks/pr_author_reviewer.sql,sha256=TI9qovx-wxVyeCC82iL5l0pvdPAv-fyJpKeS8J1znuM,1987
36
+ hinge/dbt/models/networks/pr_participation.sql,sha256=oP6TkntxNnCvfLs42Z3yRL8T6vjiGjdUDHOdco9EoIY,1171
37
+ hinge/dbt/models/networks/pr_reviewer_coreview.sql,sha256=S9G-Bk0slp-qWFHDw19wXZWPuPdfJqt5ClPVsWueghs,1307
38
+ hinge/dbt/models/networks/repo_shared_contributors.sql,sha256=UxMALaxzolxR3g5FP5cHAsKn-YiWAQoj00fERMS1vEE,1155
39
+ hinge/dbt/models/networks/star_user_repo.sql,sha256=cROUkE5ecFll1dFlLIEViFP457H-Ol1J0B5-RIbzKoc,699
40
+ hinge/dbt/models/networks/user_mention_user.sql,sha256=eZ8WMxySPA_UoyTl4KYAfCy9eM3tiyYHM1X8SP1I8eE,1938
41
+ hinge/dbt/models/networks/watch_user_repo.sql,sha256=yp2gl3SzpiAp2e7dvcl8Ki3P9Wl5vLNmUgAD41olmGY,697
42
+ hinge/dbt/models/sources/sources.yml,sha256=9g_nw6bndhlrMWH3mjcVC1vp8RUMj_vxmEwVg-WjcW4,2358
43
+ hinge/dbt/models/staging/stg_accounts.sql,sha256=kf2D__UMe5RQbMd_3qxW33ljg6UOgrnpxnoNWOtc6Nw,97
44
+ hinge/dbt/models/staging/stg_adapter_manifest.sql,sha256=dHAnBRQYPy6crCChP_lZAqCW6HdhBUAp1tljVmcqaDM,105
45
+ hinge/dbt/models/staging/stg_artifacts.sql,sha256=T-oUZTSHZYI7X3NH-65KZCRi3qRvEGAqIAsmdHfQKzI,98
46
+ hinge/dbt/models/staging/stg_relations.sql,sha256=hSIMOiuI5-tQ8YrqUct9yR5NsYPfiSf46lYyBnTtP5E,98
47
+ hinge/dbt/models/staging/stg_repositories.sql,sha256=QPbEdFeQYZg8VAaE7kLlZl4xXubFQGFjdvaVDbZct1c,101
48
+ hinge/dbt/seeds/ref_recipe_requirements.csv,sha256=Wd5PcN4MSSHyq4CppT8sulHtb3oEdH2GzjAsSSQBYPs,1210
49
+ hinge/frontends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
+ hinge/frontends/lib.py,sha256=rZztKwXP3yljJzHnJqLjrUY2-RT54jKAML2kemN_OTQ,4627
51
+ hinge/frontends/cli/__init__.py,sha256=8lzSTHavtyxQaXcuqkD5EBY6MPHn-icoIw7Am6MCSTQ,59
52
+ hinge/frontends/cli/app.py,sha256=C-mSzUtqBHenYbPui1H7Z4cqtaSYEbjcBKxLcKoQgoU,6638
53
+ hinge/frontends/tui/__init__.py,sha256=JHkc1MUsZYwDl-iNVBq939qznQo3ol0X7S32XYQv8eU,284
54
+ hinge/frontends/web/__init__.py,sha256=XcrUOdp_DJNe8Pi2CiOnZXRqZfWB-zKBdE-ovmyVeLE,205
55
+ hinge/kernel/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
+ hinge/kernel/registry.py,sha256=ryAzebg4JwcplxVs8QWzmBY7FNoVtuCH8BMe-6al3pQ,2381
57
+ hinge/kernel/runner.py,sha256=HDbz-Bv7NefsRMgRksRLOLK9tSc6N095Iv01T4_1R2w,8137
58
+ hinge/kernel/projection/__init__.py,sha256=4iZA_OXzqOCq5lACPfcbTp4EMxDx7AkcirvlN3SrpMw,285
59
+ hinge/kernel/projection/projected_graph.py,sha256=U1koWmW5GCzL2fIocTjpFnPqhm4J3IvJiC8r2Wch0lw,931
60
+ hinge/kernel/projection/projection_spec.py,sha256=gbKtj9oUPzPoysGQSjqOncspnMM_G0rcSC5iRjKddVI,1084
61
+ hinge/kernel/protocols/__init__.py,sha256=i0MUWeLlxQXCktqaqSrXzifgKmSwtkq5o-THoEt7Q9g,674
62
+ hinge/kernel/protocols/dataset_view.py,sha256=Z8Nv0QvVTRTWX67y8fZ1dkecblKwuEAq0V1PQ8Rm-0Y,988
63
+ hinge/kernel/protocols/exporter_stage.py,sha256=e2Gb8QbJU9qZp9U3PSVKoCq69ipHmCn7NAO5efhioS8,635
64
+ hinge/kernel/protocols/projection_stage.py,sha256=bxFvvXfMRfvs0Z6CiXILtQlZOn07UVkrqcy0wPfC9zM,1051
65
+ hinge/kernel/protocols/reader_stage.py,sha256=svnloypqoxqYcB6GIpnH8FVk3VkxRTh2JC4zjakcuyI,1823
66
+ hinge/kernel/protocols/store_stage.py,sha256=zUQfloR1aaK4YrRbo_OY_Ih3Lpoio77lbhnutr5V3-g,2272
67
+ hinge/kernel/schema/__init__.py,sha256=MhSCAbx5jJX7PiqxGoHmF3106C80H3yctMJYAgfDLvs,363
68
+ hinge/kernel/schema/hin_schema.py,sha256=u2RazJ2nSVGrza8XNs4zZMqsm5y-eP1YoB4D6Nf3B1k,1277
69
+ hinge/kernel/schema/schema_violation.py,sha256=ahZHb1XlWIixp2xMYsfSvaXuCsZyQb5M2rnrfjSprAY,525
70
+ hinge/kernel/schema/typed_edge.py,sha256=dhdFYbeExR1Nvuj4kM7b_kiAe6KIJYx4B5uG0jM_G1k,592
71
+ hinge/kernel/schema/typed_node.py,sha256=enZ2JlKQzuKMsNAAWjxloxgKV34QRJUwsqVCVfBj3bQ,444
72
+ hinge/stages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
+ hinge/stages/exporters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
+ hinge/stages/exporters/csv_exporter.py,sha256=5uJsIvLufFoSSNRbaQ3A1w8utoP9fTeooL12niyAbpk,2369
75
+ hinge/stages/exporters/dot_exporter.py,sha256=JCY8PMs2BdnaFyMHzfgDauFTIl_BSvTCGtiZiDsUBu4,434
76
+ hinge/stages/exporters/gexf_exporter.py,sha256=iU3gUT3NyK6wimi_Hy_AxbKdjU1K6A7QTUNxg3p-t28,436
77
+ hinge/stages/exporters/gml_exporter.py,sha256=2M1ZsJ3l55W_P3th8Nhy668dndLAGaSk6xWj8CyIRbY,2524
78
+ hinge/stages/exporters/graphml_exporter.py,sha256=U028uKovQf4QRK2Hf-P1Q9qga_4Ez_W0mt0DIT5Z43c,442
79
+ hinge/stages/exporters/jsonld_exporter.py,sha256=ja6O0-aH7JTT8s36J7LjU4x2ILbZaHO4Fqyfqag2tHc,440
80
+ hinge/stages/exporters/networkx_exporter.py,sha256=hm4JAYkIQqujvbe_K6723QVOEnnUTfWuB8hLXb7Xnbs,1790
81
+ hinge/stages/exporters/parquet_exporter.py,sha256=oA6a7qnSc20yIorPDpSwz_PnCoaDHTAuXqZbF8gsoSk,442
82
+ hinge/stages/projection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
83
+ hinge/stages/projection/dbt_projection.py,sha256=IBRf3dAd-VU8jvwTrntAnSD90D8W0MCpObM9XZCTzSQ,13867
84
+ hinge/stages/projection/specs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
85
+ hinge/stages/projection/specs/artifact_reference.py,sha256=MnlDLdsH28GgYrJnd-i6KVrU-VjOu33sEMjBChwYCWA,513
86
+ hinge/stages/projection/specs/co_commit_user_user.py,sha256=VBh_BznSk_MocXdthVULhcyOar_ujui67D9KZHjyAao,456
87
+ hinge/stages/projection/specs/co_edit_file_user_user.py,sha256=Uo6dn2eKwfac2elaH2eyhX7My_hGmTl-vSqD9W0JMVY,438
88
+ hinge/stages/projection/specs/co_edit_line_user_user.py,sha256=Z2c-QzkXkakub02ys5La8lCXEVEPwNJTY47bN3TWjwc,447
89
+ hinge/stages/projection/specs/dev_interaction.py,sha256=VyD08reBNg_ONliDEqeUb7iMnGGvY99TJN-aigi8Zng,1010
90
+ hinge/stages/projection/specs/developer_repo_affiliation.py,sha256=s7kRN7bZvHpTDDn_JQdoN6TjBdOx5HTAPY7dUV24fSI,545
91
+ hinge/stages/projection/specs/follow_user_user.py,sha256=7NuanWqd375m4pKObLgRlU3Y5cXyT_zAhV2OKdlT4z8,434
92
+ hinge/stages/projection/specs/fork_repo_repo.py,sha256=o2qH9mc93yjI5LKEDNTTD2-XUvqORAruTCTF6uMSCs0,427
93
+ hinge/stages/projection/specs/issue_co_participation.py,sha256=bhLDyii34qeNpgOMSFHJkeK2ZzX_rYKq7f4YSbS9TZ0,457
94
+ hinge/stages/projection/specs/issue_participation.py,sha256=QNEzGOcL0PIrzAzqCOkc-LTCUXf9S5BEbi4j8UzXnew,466
95
+ hinge/stages/projection/specs/pr_author_reviewer.py,sha256=h2b3uBHpQowuJXVud3QtUp5WyAazCAUZ9nu3yBzLRkA,438
96
+ hinge/stages/projection/specs/pr_participation.py,sha256=eD8uN3gJTPABIWmn4S7Fq0TkTlaJ5Y8WyyK4pYWfKx8,471
97
+ hinge/stages/projection/specs/pr_reviewer_coreview.py,sha256=ibxg38M6rtE900WYbyMyplf2HiNYfIysFaEFAtCJkOU,442
98
+ hinge/stages/projection/specs/repo_shared_contributors.py,sha256=KzZkKv1_sKN4x8T2kLdbvIooZZGAs9BgH1IGnvzNvuY,472
99
+ hinge/stages/projection/specs/star_user_repo.py,sha256=5ib-u7KSavgbtVd_BdSKzeZiFc2eSrZ51BVrhpVl7_w,476
100
+ hinge/stages/projection/specs/user_mention_user.py,sha256=WFYAn915_ZOUl4FCirHJln3cTdKrAp3loRxJqYMhJC8,443
101
+ hinge/stages/projection/specs/watch_user_repo.py,sha256=ZJylv-XXe-4urBrdWpgiuOLctsAounPEh47ffq8r-Ic,455
102
+ hinge/stages/readers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
103
+ hinge/stages/readers/_numfocus_contract_adapter.py,sha256=5owQzuMgaaFqFLdWUvUQVeC9qCGuinnoR8QhmJ2RU1A,21924
104
+ hinge/stages/readers/numfocus_reader.py,sha256=dXFCjUGIy69CscNo2dctRFn01qE35EsXNYz9cnq282E,2653
105
+ hinge/stages/store/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
106
+ hinge/stages/store/duckdb_store.py,sha256=eZ9NLbodc_vtZ90hzR7rdo8WLfGD7Hyh8gLEML1xuoc,20155
107
+ hinge-0.1.0.dist-info/METADATA,sha256=dZSn08Ct9oeGFoPyx4pFXaQc_ATMCDPam3WewpkBINw,10404
108
+ hinge-0.1.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
109
+ hinge-0.1.0.dist-info/entry_points.txt,sha256=R0nw4ZNq1CBh87Y0NU6wXCIIgZNwEeMEhqvmSNcRGVY,1856
110
+ hinge-0.1.0.dist-info/licenses/LICENSE,sha256=Yc8_1CXgv6_b-qpi-CU0Sq0fqJr570EtDQEgc-rs5CA,1075
111
+ hinge-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,35 @@
1
+ [console_scripts]
2
+ hinge = hinge.frontends.cli.app:app
3
+
4
+ [hinge.exporters]
5
+ csv = hinge.stages.exporters.csv_exporter:CsvExporter
6
+ gml = hinge.stages.exporters.gml_exporter:GmlExporter
7
+ networkx = hinge.stages.exporters.networkx_exporter:NetworkXExporter
8
+
9
+ [hinge.projection_specs]
10
+ artifact-artifact-reference = hinge.stages.projection.specs.artifact_reference:SPEC
11
+ repo-repo-fork = hinge.stages.projection.specs.fork_repo_repo:SPEC
12
+ repo-repo-shared-contributors = hinge.stages.projection.specs.repo_shared_contributors:SPEC
13
+ user-issue-participation = hinge.stages.projection.specs.issue_participation:SPEC
14
+ user-pr-participation = hinge.stages.projection.specs.pr_participation:SPEC
15
+ user-repo-affiliation = hinge.stages.projection.specs.developer_repo_affiliation:SPEC
16
+ user-repo-star = hinge.stages.projection.specs.star_user_repo:SPEC
17
+ user-repo-watch = hinge.stages.projection.specs.watch_user_repo:SPEC
18
+ user-user-co-commit = hinge.stages.projection.specs.co_commit_user_user:SPEC
19
+ user-user-co-edit-file = hinge.stages.projection.specs.co_edit_file_user_user:SPEC
20
+ user-user-co-edit-line = hinge.stages.projection.specs.co_edit_line_user_user:SPEC
21
+ user-user-follow = hinge.stages.projection.specs.follow_user_user:SPEC
22
+ user-user-issue-co-participation = hinge.stages.projection.specs.issue_co_participation:SPEC
23
+ user-user-mention = hinge.stages.projection.specs.user_mention_user:SPEC
24
+ user-user-pr-author-reviewer = hinge.stages.projection.specs.pr_author_reviewer:SPEC
25
+ user-user-pr-co-review = hinge.stages.projection.specs.pr_reviewer_coreview:SPEC
26
+ user-user-repo-collaboration = hinge.stages.projection.specs.dev_interaction:SPEC
27
+
28
+ [hinge.projections]
29
+ dbt = hinge.stages.projection.dbt_projection:DbtProjection
30
+
31
+ [hinge.readers]
32
+ numfocus = hinge.stages.readers.numfocus_reader:NumFocusReader
33
+
34
+ [hinge.stores]
35
+ duckdb = hinge.stages.store.duckdb_store:DuckDBStore
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Filippo Scaramuzza
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.