fieldz-kb 0.1.0__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.
Files changed (59) hide show
  1. fieldz_kb-0.1.0/.commitlintrc.json +5 -0
  2. fieldz_kb-0.1.0/.github/workflows/docs.yml +56 -0
  3. fieldz_kb-0.1.0/.github/workflows/release.yml +202 -0
  4. fieldz_kb-0.1.0/.github/workflows/tests.yml +63 -0
  5. fieldz_kb-0.1.0/.gitignore +168 -0
  6. fieldz_kb-0.1.0/.pre-commit-config.yaml +7 -0
  7. fieldz_kb-0.1.0/AGENTS.md +1 -0
  8. fieldz_kb-0.1.0/CLAUDE.md +89 -0
  9. fieldz_kb-0.1.0/PKG-INFO +46 -0
  10. fieldz_kb-0.1.0/README.md +3 -0
  11. fieldz_kb-0.1.0/cliff.toml +52 -0
  12. fieldz_kb-0.1.0/docs/about.md +3 -0
  13. fieldz_kb-0.1.0/docs/api_reference/biocypher/adapter.md +3 -0
  14. fieldz_kb-0.1.0/docs/api_reference/biocypher/utils.md +3 -0
  15. fieldz_kb-0.1.0/docs/api_reference/clingo/core.md +3 -0
  16. fieldz_kb-0.1.0/docs/api_reference/clingo/plugins.md +3 -0
  17. fieldz_kb-0.1.0/docs/api_reference/clingo/session.md +3 -0
  18. fieldz_kb-0.1.0/docs/api_reference/clingo/utils.md +3 -0
  19. fieldz_kb-0.1.0/docs/api_reference/lpg/backends/falkordb.md +3 -0
  20. fieldz_kb-0.1.0/docs/api_reference/lpg/backends/falkordblite.md +3 -0
  21. fieldz_kb-0.1.0/docs/api_reference/lpg/backends/neo4j.md +3 -0
  22. fieldz_kb-0.1.0/docs/api_reference/lpg/core.md +3 -0
  23. fieldz_kb-0.1.0/docs/api_reference/lpg/graph.md +3 -0
  24. fieldz_kb-0.1.0/docs/api_reference/lpg/plugins.md +3 -0
  25. fieldz_kb-0.1.0/docs/api_reference/lpg/session.md +3 -0
  26. fieldz_kb-0.1.0/docs/api_reference/lpg/utils.md +3 -0
  27. fieldz_kb-0.1.0/docs/api_reference/typeinfo.md +3 -0
  28. fieldz_kb-0.1.0/docs/getting_started.md +210 -0
  29. fieldz_kb-0.1.0/docs/index.md +83 -0
  30. fieldz_kb-0.1.0/mkdocs.yml +69 -0
  31. fieldz_kb-0.1.0/pyproject.toml +61 -0
  32. fieldz_kb-0.1.0/src/fieldz_kb/__init__.py +28 -0
  33. fieldz_kb-0.1.0/src/fieldz_kb/biocypher/__init__.py +5 -0
  34. fieldz_kb-0.1.0/src/fieldz_kb/biocypher/adapter.py +72 -0
  35. fieldz_kb-0.1.0/src/fieldz_kb/biocypher/utils.py +72 -0
  36. fieldz_kb-0.1.0/src/fieldz_kb/clingo/__init__.py +4 -0
  37. fieldz_kb-0.1.0/src/fieldz_kb/clingo/core.py +350 -0
  38. fieldz_kb-0.1.0/src/fieldz_kb/clingo/plugins.py +411 -0
  39. fieldz_kb-0.1.0/src/fieldz_kb/clingo/session.py +111 -0
  40. fieldz_kb-0.1.0/src/fieldz_kb/clingo/utils.py +97 -0
  41. fieldz_kb-0.1.0/src/fieldz_kb/lpg/__init__.py +11 -0
  42. fieldz_kb-0.1.0/src/fieldz_kb/lpg/backends/__init__.py +0 -0
  43. fieldz_kb-0.1.0/src/fieldz_kb/lpg/backends/falkordb.py +13 -0
  44. fieldz_kb-0.1.0/src/fieldz_kb/lpg/backends/falkordblite.py +13 -0
  45. fieldz_kb-0.1.0/src/fieldz_kb/lpg/backends/neo4j.py +13 -0
  46. fieldz_kb-0.1.0/src/fieldz_kb/lpg/core.py +352 -0
  47. fieldz_kb-0.1.0/src/fieldz_kb/lpg/graph.py +104 -0
  48. fieldz_kb-0.1.0/src/fieldz_kb/lpg/plugins.py +834 -0
  49. fieldz_kb-0.1.0/src/fieldz_kb/lpg/session.py +176 -0
  50. fieldz_kb-0.1.0/src/fieldz_kb/lpg/utils.py +158 -0
  51. fieldz_kb-0.1.0/src/fieldz_kb/typeinfo.py +126 -0
  52. fieldz_kb-0.1.0/tests/__init__.py +1 -0
  53. fieldz_kb-0.1.0/tests/conftest.py +197 -0
  54. fieldz_kb-0.1.0/tests/test_biocypher.py +169 -0
  55. fieldz_kb-0.1.0/tests/test_clingo_core.py +385 -0
  56. fieldz_kb-0.1.0/tests/test_lpg_core.py +574 -0
  57. fieldz_kb-0.1.0/tests/test_typeinfo.py +251 -0
  58. fieldz_kb-0.1.0/tox.ini +16 -0
  59. fieldz_kb-0.1.0/uv.lock +1127 -0
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": [
3
+ "@commitlint/config-conventional"
4
+ ]
5
+ }
@@ -0,0 +1,56 @@
1
+ name: Deploy documentation
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ workflow_run:
6
+ workflows: ["Release"]
7
+ types: [completed]
8
+
9
+ jobs:
10
+ deploy-docs:
11
+ name: Deploy documentation
12
+ runs-on: ubuntu-latest
13
+ if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
14
+ permissions:
15
+ contents: write
16
+
17
+ steps:
18
+ - uses: actions/checkout@v5
19
+ with:
20
+ ref: main
21
+ fetch-depth: 0
22
+
23
+ - name: Get latest tag and checkout
24
+ id: get_tag
25
+ run: |
26
+ LATEST_TAG=$(git describe --tags --abbrev=0 --match "v[0-9]*" origin/main)
27
+ echo "tag=$LATEST_TAG" >> $GITHUB_OUTPUT
28
+ git checkout $LATEST_TAG
29
+
30
+ - name: Configure Git Credentials
31
+ run: |
32
+ git config user.name github-actions[bot]
33
+ git config user.email 41898282+github-actions[bot]@users.noreply.github.com
34
+ - uses: actions/setup-python@v6
35
+ with:
36
+ python-version: 3.x
37
+ - name: Cache dependencies
38
+ uses: actions/cache@v5
39
+ with:
40
+ key: mkdocs-material-${{ github.run_id }}
41
+ path: ~/.cache
42
+ restore-keys: |
43
+ mkdocs-material-
44
+ - name: Install MkDocs and dependencies
45
+ run: pip install mkdocs-material griffe-fieldz mkdocstrings-python griffe-inherited-docstrings
46
+ - name: Generate changelog
47
+ uses: orhun/git-cliff-action@v4
48
+ with:
49
+ config: cliff.toml
50
+ args: --verbose
51
+ env:
52
+ OUTPUT: docs/CHANGELOG.md
53
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
54
+
55
+ - name: Deploy documentation
56
+ run: mkdocs gh-deploy --force
@@ -0,0 +1,202 @@
1
+ name: Release
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ tags:
7
+ - "v[0-9]+.[0-9]+.[0-9]+"
8
+
9
+ jobs:
10
+ test:
11
+ name: Run tests
12
+ uses: ./.github/workflows/tests.yml
13
+
14
+ build:
15
+ name: Build package
16
+ needs:
17
+ - test
18
+ runs-on: ubuntu-latest
19
+
20
+ steps:
21
+ - uses: actions/checkout@v5
22
+ with:
23
+ persist-credentials: false
24
+ ref: main
25
+ fetch-depth: 0
26
+
27
+ - name: Get latest tag
28
+ id: get_tag
29
+ run: |
30
+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
31
+ LATEST_TAG=$(git describe --tags --abbrev=0 --match "v[0-9]*" origin/main)
32
+ echo "tag=$LATEST_TAG" >> $GITHUB_OUTPUT
33
+ git checkout $LATEST_TAG
34
+ else
35
+ echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
36
+ fi
37
+ - name: Set up Python
38
+ uses: actions/setup-python@v6
39
+ with:
40
+ python-version: "3.13"
41
+ - name: Install pypa/build
42
+ run: python3 -m pip install build --user
43
+ - name: Build a binary wheel and a source tarball
44
+ run: python3 -m build
45
+ - name: Store the packages
46
+ uses: actions/upload-artifact@v5
47
+ with:
48
+ name: python-package-distributions
49
+ path: dist/
50
+
51
+ testpypi:
52
+ name: Publish package to TestPyPI
53
+ needs:
54
+ - build
55
+ runs-on: ubuntu-latest
56
+
57
+ environment:
58
+ name: testpypi
59
+ url: https://test.pypi.org/p/fieldz_kb
60
+
61
+ permissions:
62
+ id-token: write
63
+
64
+ steps:
65
+ - name: Download all the dists
66
+ uses: actions/download-artifact@v5
67
+ with:
68
+ name: python-package-distributions
69
+ path: dist/
70
+ - name: Publish package to TestPyPI
71
+ uses: pypa/gh-action-pypi-publish@release/v1
72
+ with:
73
+ repository-url: https://test.pypi.org/legacy/
74
+
75
+ pypi:
76
+ name: Publish package to PyPI
77
+ needs:
78
+ - testpypi
79
+ runs-on: ubuntu-latest
80
+ environment:
81
+ name: pypi
82
+ url: https://pypi.org/p/fieldz_kb
83
+ permissions:
84
+ id-token: write
85
+
86
+ steps:
87
+ - name: Download all the dists
88
+ uses: actions/download-artifact@v5
89
+ with:
90
+ name: python-package-distributions
91
+ path: dist/
92
+ - name: Publish package to PyPI
93
+ uses: pypa/gh-action-pypi-publish@release/v1
94
+
95
+ changelog:
96
+ name: Generate changelog
97
+ needs:
98
+ - build
99
+ runs-on: ubuntu-latest
100
+ permissions:
101
+ contents: write
102
+ steps:
103
+ - uses: actions/checkout@v5
104
+ with:
105
+ ref: main
106
+ fetch-depth: 0
107
+
108
+ - name: Get tag
109
+ id: get_tag
110
+ run: |
111
+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
112
+ LATEST_TAG=$(git describe --tags --abbrev=0 --match "v[0-9]*" origin/main)
113
+ echo "tag=$LATEST_TAG" >> $GITHUB_OUTPUT
114
+ else
115
+ echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
116
+ fi
117
+
118
+ - name: Generate changelog for this release
119
+ uses: orhun/git-cliff-action@v4
120
+ id: cliff
121
+ with:
122
+ config: cliff.toml
123
+ args: --latest --strip header
124
+ env:
125
+ OUTPUT: CHANGELOG_RELEASE.md
126
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
127
+
128
+ - name: Upload changelog snippet
129
+ uses: actions/upload-artifact@v5
130
+ with:
131
+ name: changelog-snippet
132
+ path: CHANGELOG_RELEASE.md
133
+
134
+ github-release:
135
+ name: Create GitHub Release
136
+ needs:
137
+ - pypi
138
+ - changelog
139
+ runs-on: ubuntu-latest
140
+
141
+ permissions:
142
+ contents: write
143
+
144
+ steps:
145
+ - name: Checkout to get tag info
146
+ uses: actions/checkout@v5
147
+ with:
148
+ ref: main
149
+ fetch-depth: 0
150
+
151
+ - name: Get latest tag
152
+ id: get_tag
153
+ run: |
154
+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
155
+ LATEST_TAG=$(git describe --tags --abbrev=0 --match "v[0-9]*" origin/main)
156
+ echo "tag=$LATEST_TAG" >> $GITHUB_OUTPUT
157
+ else
158
+ echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
159
+ fi
160
+
161
+ - name: Download dist artifacts
162
+ uses: actions/download-artifact@v5
163
+ with:
164
+ name: python-package-distributions
165
+ path: dist/
166
+
167
+ - name: Download changelog snippet
168
+ uses: actions/download-artifact@v5
169
+ with:
170
+ name: changelog-snippet
171
+
172
+ - name: Extract version from tag
173
+ run: |
174
+ TAG="${{ steps.get_tag.outputs.tag }}"
175
+ echo "VERSION=${TAG#v}" >> $GITHUB_ENV
176
+
177
+ - name: Build release body
178
+ run: |
179
+ cat > RELEASE_BODY.md << 'HEADER'
180
+ ## What's Changed
181
+ HEADER
182
+ cat CHANGELOG_RELEASE.md >> RELEASE_BODY.md
183
+ cat >> RELEASE_BODY.md << EOF
184
+
185
+ ## Installation
186
+
187
+ \`\`\`bash
188
+ pip install fieldz_kb==${{ env.VERSION }}
189
+ \`\`\`
190
+
191
+ ## Links
192
+
193
+ - [Documentation](https://adrienrougny.github.io/fieldz_kb/)
194
+ - [PyPI](https://pypi.org/project/fieldz_kb/${{ env.VERSION }}/)
195
+ EOF
196
+
197
+ - name: Create GitHub Release
198
+ uses: softprops/action-gh-release@v2
199
+ with:
200
+ tag_name: ${{ steps.get_tag.outputs.tag }}
201
+ files: dist/*
202
+ body_path: RELEASE_BODY.md
@@ -0,0 +1,63 @@
1
+ name: Tests
2
+
3
+ on:
4
+ workflow_call:
5
+ push:
6
+ branches:
7
+ - testing
8
+ - main
9
+
10
+ jobs:
11
+ test:
12
+ name: Test on ${{ matrix.os }}
13
+ runs-on: ${{ matrix.os }}
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ os: [ubuntu-latest]
18
+ services:
19
+ neo4j:
20
+ image: neo4j:5
21
+ env:
22
+ NEO4J_AUTH: neo4j/testpassword
23
+ ports:
24
+ - 7687:7687
25
+ options: >-
26
+ --health-cmd "cypher-shell -u neo4j -p testpassword 'RETURN 1'"
27
+ --health-interval 10s
28
+ --health-timeout 5s
29
+ --health-retries 10
30
+ falkordb:
31
+ image: falkordb/falkordb:latest
32
+ ports:
33
+ - 6379:6379
34
+ options: >-
35
+ --health-cmd "redis-cli ping"
36
+ --health-interval 10s
37
+ --health-timeout 5s
38
+ --health-retries 5
39
+ steps:
40
+ - name: Checkout code
41
+ uses: actions/checkout@v5
42
+ - name: Set up Python 3.10
43
+ uses: actions/setup-python@v6
44
+ with:
45
+ python-version: '3.10'
46
+ - name: Set up Python 3.11
47
+ uses: actions/setup-python@v6
48
+ with:
49
+ python-version: '3.11'
50
+ - name: Set up Python 3.12
51
+ uses: actions/setup-python@v6
52
+ with:
53
+ python-version: '3.12'
54
+ - name: Set up Python 3.13
55
+ uses: actions/setup-python@v6
56
+ with:
57
+ python-version: '3.13'
58
+ - name: Install uv and tox
59
+ run: pip install uv tox tox-uv
60
+ - name: Run tests with tox
61
+ env:
62
+ CI: true
63
+ run: tox -e py310-min,py311-min,py312-min,py313-min
@@ -0,0 +1,168 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # poetry
98
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102
+ #poetry.lock
103
+
104
+ # pdm
105
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
106
+ #pdm.lock
107
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
108
+ # in version control.
109
+ # https://pdm-project.org/#use-with-ide
110
+ .pdm.toml
111
+ .pdm-python
112
+ .pdm-build/
113
+
114
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
115
+ __pypackages__/
116
+
117
+ # Celery stuff
118
+ celerybeat-schedule
119
+ celerybeat.pid
120
+
121
+ # SageMath parsed files
122
+ *.sage.py
123
+
124
+ # Environments
125
+ .env
126
+ .venv
127
+ .venv-sandbox
128
+ env/
129
+ venv/
130
+ ENV/
131
+ env.bak/
132
+ venv.bak/
133
+
134
+ # Spyder project settings
135
+ .spyderproject
136
+ .spyproject
137
+
138
+ # Rope project settings
139
+ .ropeproject
140
+
141
+ # mkdocs documentation
142
+ /site
143
+
144
+ # mypy
145
+ .mypy_cache/
146
+ .dmypy.json
147
+ dmypy.json
148
+
149
+ # Pyre type checker
150
+ .pyre/
151
+
152
+ # pytype static type analyzer
153
+ .pytype/
154
+
155
+ # Cython debug symbols
156
+ cython_debug/
157
+
158
+ # PyCharm
159
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
160
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
161
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
162
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
163
+ #.idea/
164
+
165
+
166
+ # opencode plans and artifacts
167
+ .opencode/
168
+ plans/
@@ -0,0 +1,7 @@
1
+ repos:
2
+ - repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook
3
+ rev: v9.20.0
4
+ hooks:
5
+ - id: commitlint
6
+ stages: [commit-msg]
7
+ additional_dependencies: ['@commitlint/config-conventional']
@@ -0,0 +1 @@
1
+ CLAUDE.md
@@ -0,0 +1,89 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ fieldz_kb converts Python dataclass-like objects (via the `fieldz` library) into knowledge base representations: Neo4j graphs, clingo/ASP predicates, and BioCypher-compatible formats.
8
+
9
+ ## Commands
10
+
11
+ ```bash
12
+ # Install with dev dependencies
13
+ uv pip install -e ".[dev]"
14
+
15
+ # Run all tests (requires a running Neo4j instance, see tests/credentials.py)
16
+ pytest tests/
17
+
18
+ # Run a single test
19
+ pytest tests/test_typeinfo.py::TestIsFieldzClass::test_returns_true_for_fieldz_class
20
+
21
+ # Lint and format
22
+ ruff check src/ tests/
23
+ ruff check src/ tests/ --fix
24
+ ruff format src/ tests/
25
+
26
+ # Multi-version testing
27
+ tox # all versions (3.10-3.13)
28
+ tox -e py312 # specific version
29
+ ```
30
+
31
+ ## Architecture
32
+
33
+ ### Shared layers
34
+
35
+ - **`typeinfo.py`** — Extracts structured type information from type hints. Returns nested `(type_origin, type_args)` tuples. Handles unions, optionals, generics, and forward references via `typing._eval_type()`.
36
+
37
+ ### LPG backends (`_lpg/`)
38
+
39
+ All labeled property graph backends follow the **Backend + Session** pattern:
40
+
41
+ ```python
42
+ from fieldz_kb.neo4j import Session, Neo4jBackend
43
+ with Session(Neo4jBackend(hostname="localhost")) as session:
44
+ session.save_from_object(person)
45
+ session.execute_query_as_objects("MATCH (n:Person) RETURN n")
46
+ ```
47
+
48
+ - **`_lpg/core.py`** — Plugin system for pylpg: dynamically generates `pylpg.Node` subclasses from Python types. Base types become value nodes, collections become container nodes, dataclasses become node classes with relationship descriptors. Plugin-based extensibility via `PylpgTypePlugin` and `PylpgContext`.
49
+
50
+ - **`_lpg/session.py`** — Session wrapping `pylpg.Session`. Provides `save_from_object()`, `save_from_objects()`, `make_object_from_node()`, `execute_query()`, `execute_query_as_objects()`, `delete_all()`. Uses batch save for performance.
51
+
52
+ - **`_lpg/utils.py`** — Shared helpers for type classification, relationship naming, and field introspection.
53
+
54
+ - **`neo4j/`**, **`falkordb/`**, **`falkordblite/`** — Re-export modules for convenience imports. Each provides `Session` and the corresponding pylpg backend class (e.g., `Neo4jBackend`).
55
+
56
+ ### Other backends
57
+
58
+ - **`clingo/core.py`** — Generates `clorm.Predicate` classes from types. Each dataclass produces a base predicate plus per-field predicates. Caches in `_type_to_predicate_class` / `_field_key_to_predicate_class`. Key public API: `get_or_make_predicate_classes_from_type()`, `make_facts_from_object()`, `make_ontology_rules_from_type()`.
59
+
60
+ - **`biocypher/`** — Adapter layer producing `(id, label, properties)` tuples and YAML schema files for BioCypher ingestion.
61
+
62
+ ### Key design patterns
63
+
64
+ - **Backend + Session** for all LPG backends. Users create a Backend, pass it to Session, and use session methods.
65
+ - **Plugin-based type conversion** via `PylpgTypePlugin` ABC and `PylpgContext` dispatcher.
66
+ - **Global caches** for dynamically generated classes (node classes, predicate classes).
67
+ - **Guard sets** prevent infinite recursion when processing cyclic/self-referential type definitions.
68
+ - **Integration modes** for `save_from_objects()`: `"hash"` (dedup by hash), `"id"` (dedup by Python `id()`).
69
+ - **Relationship naming**: field names are singularized via `inflect` and uppercased (e.g., `employees` → `HAS_EMPLOYEE`).
70
+ - **Custom function registration**: `register_make_nodes_function()` and `register_make_object_function()` allow overriding conversion for specific types.
71
+
72
+ ## Forward References
73
+
74
+ Dataclasses with forward references (e.g., `List["Employee"]`) **must be defined at module level**, not inside functions or test methods. `get_types_from_type_hint()` resolves forward refs using the module's namespace, so locally-defined classes won't resolve. In test files, define such classes at the top of the file and reference them from test methods.
75
+
76
+ ## Code Style
77
+
78
+ - Always use **absolute imports** (never relative)
79
+ - Import order: stdlib, third-party, local (separated by blank lines)
80
+ - Type hints on all function signatures; prefer `str | None` over `Optional[str]`
81
+ - Docstrings (triple double quotes) on all public functions with Args/Returns/Raises sections
82
+ - No inline comments — use docstrings
83
+ - Max line length: 88 characters
84
+
85
+ ## Testing
86
+
87
+ - Neo4j tests require a **real database** — no mocks. Credentials in `tests/credentials.py` (not in git): `URI`, `USERNAME`, `PASSWORD`.
88
+ - Database is cleaned before/after each test via fixtures.
89
+ - Tests grouped in classes; fixtures in `conftest.py`.
@@ -0,0 +1,46 @@
1
+ Metadata-Version: 2.4
2
+ Name: fieldz_kb
3
+ Version: 0.1.0
4
+ Summary: A library store dataclass-like objects into knowledge bases
5
+ Project-URL: Homepage, https://github.com/adrienrougny/fieldz_kb
6
+ Project-URL: Issues, https://github.com/adrienrougny/fieldz_kb/issues
7
+ Author-email: Adrien Rougny <adrienrougny@gmail.com>
8
+ License: GPL-3.0-or-later
9
+ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Requires-Python: >=3.10
17
+ Requires-Dist: fieldz>=0.1.2
18
+ Requires-Dist: inflect>=7.5.0
19
+ Provides-Extra: all
20
+ Requires-Dist: clorm>=1.6.1; extra == 'all'
21
+ Requires-Dist: frozendict>=2.4.7; extra == 'all'
22
+ Requires-Dist: pylpg>=0.2.0; extra == 'all'
23
+ Requires-Dist: pylpg[falkordb]>=0.2.0; extra == 'all'
24
+ Requires-Dist: pylpg[falkordblite]>=0.2.0; extra == 'all'
25
+ Requires-Dist: pylpg[neo4j]>=0.2.0; extra == 'all'
26
+ Requires-Dist: pyyaml>=6.0; extra == 'all'
27
+ Provides-Extra: biocypher
28
+ Requires-Dist: frozendict>=2.4.7; extra == 'biocypher'
29
+ Requires-Dist: pylpg>=0.2.0; extra == 'biocypher'
30
+ Requires-Dist: pyyaml>=6.0; extra == 'biocypher'
31
+ Provides-Extra: clingo
32
+ Requires-Dist: clorm>=1.6.1; extra == 'clingo'
33
+ Provides-Extra: falkordb
34
+ Requires-Dist: frozendict>=2.4.7; extra == 'falkordb'
35
+ Requires-Dist: pylpg[falkordb]>=0.2.0; extra == 'falkordb'
36
+ Provides-Extra: falkordblite
37
+ Requires-Dist: frozendict>=2.4.7; extra == 'falkordblite'
38
+ Requires-Dist: pylpg[falkordblite]>=0.2.0; extra == 'falkordblite'
39
+ Provides-Extra: neo4j
40
+ Requires-Dist: frozendict>=2.4.7; extra == 'neo4j'
41
+ Requires-Dist: pylpg[neo4j]>=0.2.0; extra == 'neo4j'
42
+ Description-Content-Type: text/markdown
43
+
44
+ # fieldz_kb
45
+
46
+ A library to store dataclass-like objects into knowledge bases.
@@ -0,0 +1,3 @@
1
+ # fieldz_kb
2
+
3
+ A library to store dataclass-like objects into knowledge bases.
@@ -0,0 +1,52 @@
1
+ [changelog]
2
+ header = """# Changelog
3
+
4
+ All notable changes to fieldz_kb will be documented in this file.
5
+
6
+ The format is based on [Keep a Changelog](https://keepachangelog.com/),
7
+ and this project adheres to [Conventional Commits](https://www.conventionalcommits.org/).
8
+
9
+ """
10
+ body = """
11
+ {%- macro remote_url() -%}
12
+ https://github.com/adrienrougny/fieldz_kb
13
+ {%- endmacro -%}
14
+
15
+ {% if version -%}
16
+ ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
17
+ {% else -%}
18
+ ## [Unreleased]
19
+ {% endif -%}
20
+
21
+ {% for group, commits in commits | group_by(attribute="group") %}
22
+ ### {{ group | upper_first }}
23
+ {% for commit in commits %}
24
+ - {{ commit.message | upper_first | trim }}\
25
+ {% if commit.scope %} *({{ commit.scope }})*{% endif %}\
26
+ {% if commit.breaking %} **BREAKING**{% endif -%}
27
+ {% endfor %}
28
+ {% endfor %}
29
+ """
30
+ footer = ""
31
+ trim = true
32
+
33
+ [git]
34
+ conventional_commits = true
35
+ filter_unconventional = false
36
+ split_commits = false
37
+ commit_parsers = [
38
+ { message = "^feat", group = "Added" },
39
+ { message = "^fix", group = "Fixed" },
40
+ { message = "^perf", group = "Performance" },
41
+ { message = "^refactor", group = "Changed" },
42
+ { message = "^doc", group = "Documentation" },
43
+ { message = "^style", group = "Styling" },
44
+ { message = "^test", group = "Testing" },
45
+ { message = "^ci", group = "CI/CD" },
46
+ { message = "^chore", group = "Miscellaneous" },
47
+ { message = ".*", group = "Other" },
48
+ ]
49
+ protect_breaking_commits = false
50
+ filter_commits = false
51
+ tag_pattern = "v[0-9]+\\.[0-9]+\\.[0-9]+"
52
+ sort_commits = "newest"