inputlayer-client-dev 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 (67) hide show
  1. inputlayer_client_dev-0.1.0/.gitignore +71 -0
  2. inputlayer_client_dev-0.1.0/PKG-INFO +364 -0
  3. inputlayer_client_dev-0.1.0/README.md +348 -0
  4. inputlayer_client_dev-0.1.0/examples/01_quickstart.py +46 -0
  5. inputlayer_client_dev-0.1.0/examples/02_social_network.py +56 -0
  6. inputlayer_client_dev-0.1.0/examples/03_rag_pipeline.py +47 -0
  7. inputlayer_client_dev-0.1.0/examples/04_ecommerce.py +42 -0
  8. inputlayer_client_dev-0.1.0/examples/05_rbac.py +61 -0
  9. inputlayer_client_dev-0.1.0/examples/06_realtime_dashboard.py +46 -0
  10. inputlayer_client_dev-0.1.0/examples/07_dataframe_etl.py +42 -0
  11. inputlayer_client_dev-0.1.0/examples/08_session_rules.py +58 -0
  12. inputlayer_client_dev-0.1.0/examples/09_access_control.py +43 -0
  13. inputlayer_client_dev-0.1.0/examples/10_migrations.py +130 -0
  14. inputlayer_client_dev-0.1.0/pyproject.toml +33 -0
  15. inputlayer_client_dev-0.1.0/src/inputlayer/__init__.py +151 -0
  16. inputlayer_client_dev-0.1.0/src/inputlayer/_ast.py +133 -0
  17. inputlayer_client_dev-0.1.0/src/inputlayer/_naming.py +44 -0
  18. inputlayer_client_dev-0.1.0/src/inputlayer/_protocol.py +225 -0
  19. inputlayer_client_dev-0.1.0/src/inputlayer/_proxy.py +244 -0
  20. inputlayer_client_dev-0.1.0/src/inputlayer/aggregations.py +126 -0
  21. inputlayer_client_dev-0.1.0/src/inputlayer/auth.py +70 -0
  22. inputlayer_client_dev-0.1.0/src/inputlayer/client.py +178 -0
  23. inputlayer_client_dev-0.1.0/src/inputlayer/client_sync.py +231 -0
  24. inputlayer_client_dev-0.1.0/src/inputlayer/compiler.py +672 -0
  25. inputlayer_client_dev-0.1.0/src/inputlayer/connection.py +314 -0
  26. inputlayer_client_dev-0.1.0/src/inputlayer/derived.py +141 -0
  27. inputlayer_client_dev-0.1.0/src/inputlayer/exceptions.py +76 -0
  28. inputlayer_client_dev-0.1.0/src/inputlayer/functions.py +285 -0
  29. inputlayer_client_dev-0.1.0/src/inputlayer/index.py +40 -0
  30. inputlayer_client_dev-0.1.0/src/inputlayer/knowledge_graph.py +589 -0
  31. inputlayer_client_dev-0.1.0/src/inputlayer/migrations/__init__.py +51 -0
  32. inputlayer_client_dev-0.1.0/src/inputlayer/migrations/autodetector.py +120 -0
  33. inputlayer_client_dev-0.1.0/src/inputlayer/migrations/cli.py +254 -0
  34. inputlayer_client_dev-0.1.0/src/inputlayer/migrations/executor.py +95 -0
  35. inputlayer_client_dev-0.1.0/src/inputlayer/migrations/loader.py +91 -0
  36. inputlayer_client_dev-0.1.0/src/inputlayer/migrations/operations.py +298 -0
  37. inputlayer_client_dev-0.1.0/src/inputlayer/migrations/recorder.py +44 -0
  38. inputlayer_client_dev-0.1.0/src/inputlayer/migrations/state.py +107 -0
  39. inputlayer_client_dev-0.1.0/src/inputlayer/migrations/writer.py +183 -0
  40. inputlayer_client_dev-0.1.0/src/inputlayer/notifications.py +83 -0
  41. inputlayer_client_dev-0.1.0/src/inputlayer/py.typed +0 -0
  42. inputlayer_client_dev-0.1.0/src/inputlayer/relation.py +102 -0
  43. inputlayer_client_dev-0.1.0/src/inputlayer/result.py +89 -0
  44. inputlayer_client_dev-0.1.0/src/inputlayer/session.py +75 -0
  45. inputlayer_client_dev-0.1.0/src/inputlayer/types.py +192 -0
  46. inputlayer_client_dev-0.1.0/tests/__init__.py +0 -0
  47. inputlayer_client_dev-0.1.0/tests/conftest.py +40 -0
  48. inputlayer_client_dev-0.1.0/tests/test_aggregations.py +118 -0
  49. inputlayer_client_dev-0.1.0/tests/test_ast.py +155 -0
  50. inputlayer_client_dev-0.1.0/tests/test_autodetector.py +251 -0
  51. inputlayer_client_dev-0.1.0/tests/test_cli.py +231 -0
  52. inputlayer_client_dev-0.1.0/tests/test_compiler.py +510 -0
  53. inputlayer_client_dev-0.1.0/tests/test_connection.py +202 -0
  54. inputlayer_client_dev-0.1.0/tests/test_derived.py +189 -0
  55. inputlayer_client_dev-0.1.0/tests/test_executor.py +240 -0
  56. inputlayer_client_dev-0.1.0/tests/test_functions.py +308 -0
  57. inputlayer_client_dev-0.1.0/tests/test_integration.py +228 -0
  58. inputlayer_client_dev-0.1.0/tests/test_loader.py +232 -0
  59. inputlayer_client_dev-0.1.0/tests/test_naming.py +64 -0
  60. inputlayer_client_dev-0.1.0/tests/test_operations.py +243 -0
  61. inputlayer_client_dev-0.1.0/tests/test_protocol.py +294 -0
  62. inputlayer_client_dev-0.1.0/tests/test_proxy.py +186 -0
  63. inputlayer_client_dev-0.1.0/tests/test_relation.py +111 -0
  64. inputlayer_client_dev-0.1.0/tests/test_result.py +105 -0
  65. inputlayer_client_dev-0.1.0/tests/test_state.py +199 -0
  66. inputlayer_client_dev-0.1.0/tests/test_types.py +131 -0
  67. inputlayer_client_dev-0.1.0/tests/test_writer.py +173 -0
@@ -0,0 +1,71 @@
1
+ # Rust build artifacts
2
+ /target/
3
+ **/*.rs.bk
4
+ *.pdb
5
+
6
+ # Cargo lock for libraries (keep for binaries)
7
+ Cargo.lock
8
+
9
+ # IDE / Editor files
10
+ .vscode/
11
+ .idea/
12
+ *.swp
13
+ *.swo
14
+ *~
15
+ .DS_Store
16
+
17
+ # Local configuration (git-ignored overrides)
18
+ config.local.toml
19
+
20
+ # Data directory (storage engine data)
21
+ /data/
22
+
23
+ # Test temporary files
24
+ tmp/
25
+ *.tmp
26
+
27
+ # GUI (Next.js) - Build artifacts and dependencies
28
+ gui/node_modules/
29
+ gui/.next/
30
+ gui/dist/
31
+ gui/out/
32
+
33
+ # GUI - Package manager lock files (keep package.json only)
34
+ gui/pnpm-lock.yaml
35
+ gui/package-lock.json
36
+
37
+ # GUI - Editor/IDE cache
38
+ gui/.turbo/
39
+ gui/.vercel/
40
+
41
+ # Front (marketing site) - Build artifacts and dependencies
42
+ front/node_modules/
43
+ front/.next/
44
+ front/dist/
45
+ front/out/
46
+
47
+ # Front - Auto-generated docs bundle
48
+ front/lib/docs-bundle.ts
49
+
50
+ # Docs site (legacy Nextra) - Build artifacts
51
+ docs/site/node_modules/
52
+ docs/site/.next/
53
+ docs/site/dist/
54
+ docs/site/out/
55
+ docs/site/package-lock.json
56
+
57
+ rfcs/
58
+ proposals/
59
+
60
+ .gback/
61
+
62
+ .inputlayer-credentials.toml
63
+
64
+ # Python
65
+ __pycache__/
66
+ *.pyc
67
+ *.pyo
68
+ *.egg-info/
69
+ dist/
70
+ build/
71
+ .pytest_cache/
@@ -0,0 +1,364 @@
1
+ Metadata-Version: 2.4
2
+ Name: inputlayer-client-dev
3
+ Version: 0.1.0
4
+ Summary: Python Object-Logic Mapper for InputLayer knowledge graph engine
5
+ License-Expression: AGPL-3.0
6
+ Requires-Python: >=3.10
7
+ Requires-Dist: pydantic>=2.0
8
+ Requires-Dist: websockets>=12.0
9
+ Provides-Extra: dev
10
+ Requires-Dist: pandas>=1.5; extra == 'dev'
11
+ Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
12
+ Requires-Dist: pytest>=7.0; extra == 'dev'
13
+ Provides-Extra: pandas
14
+ Requires-Dist: pandas>=1.5; extra == 'pandas'
15
+ Description-Content-Type: text/markdown
16
+
17
+ # inputlayer-client-dev
18
+
19
+ Python Object-Logic Mapper (OLM) for [InputLayer](https://github.com/inputlayer/inputlayer) - the symbolic reasoning engine for AI agents.
20
+
21
+ Write Python. No query syntax required. The OLM compiles typed Python classes into InputLayer queries over WebSocket.
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ pip install inputlayer-client-dev
27
+
28
+ # With pandas DataFrame support
29
+ pip install inputlayer-client-dev[pandas]
30
+ ```
31
+
32
+ Requirements: Python 3.10+ and a running InputLayer server.
33
+
34
+ This also installs the `il` CLI for managing schema migrations.
35
+
36
+ ## Quick Start
37
+
38
+ ```python
39
+ import asyncio
40
+ from inputlayer import InputLayer, Relation
41
+
42
+ class Employee(Relation):
43
+ id: int
44
+ name: str
45
+ department: str
46
+ salary: float
47
+ active: bool
48
+
49
+ async def main():
50
+ async with InputLayer("ws://localhost:8080/ws", username="admin", password="admin") as il:
51
+ kg = il.knowledge_graph("demo")
52
+
53
+ # Define schema (idempotent)
54
+ await kg.define(Employee)
55
+
56
+ # Insert data
57
+ await kg.insert([
58
+ Employee(id=1, name="Alice", department="eng", salary=120000.0, active=True),
59
+ Employee(id=2, name="Bob", department="hr", salary=90000.0, active=True),
60
+ Employee(id=3, name="Charlie", department="eng", salary=110000.0, active=False),
61
+ ])
62
+
63
+ # Query with filter
64
+ engineers = await kg.query(
65
+ Employee,
66
+ where=lambda e: (e.department == "eng") & (e.active == True),
67
+ )
68
+ for emp in engineers:
69
+ print(f"{emp.name}: ${emp.salary}")
70
+
71
+ asyncio.run(main())
72
+ ```
73
+
74
+ ## Core Concepts
75
+
76
+ ### Relations
77
+
78
+ Define typed schemas as Python classes. Each `Relation` subclass maps to an InputLayer relation.
79
+
80
+ ```python
81
+ from inputlayer import Relation, Vector, Timestamp
82
+
83
+ class Document(Relation):
84
+ id: int
85
+ title: str
86
+ embedding: Vector[384]
87
+ created_at: Timestamp
88
+ ```
89
+
90
+ Supported types: `int`, `float`, `str`, `bool`, `Vector[N]`, `VectorInt8[N]`, `Timestamp`
91
+
92
+ ### Derived Relations (Rules)
93
+
94
+ Define computed views using `Derived` and the `From(...).where(...).select(...)` builder. InputLayer keeps derived data up to date automatically when the underlying facts change.
95
+
96
+ ```python
97
+ from typing import ClassVar
98
+ from inputlayer import Derived, From, Relation
99
+
100
+ class Edge(Relation):
101
+ src: int
102
+ dst: int
103
+
104
+ class Reachable(Derived):
105
+ src: int
106
+ dst: int
107
+ rules: ClassVar[list] = []
108
+
109
+ Reachable.rules = [
110
+ # Base case: direct edges
111
+ From(Edge).select(src=Edge.src, dst=Edge.dst),
112
+ # Recursive: transitive closure
113
+ From(Reachable, Edge)
114
+ .where(lambda r, e: r.dst == e.src)
115
+ .select(src=Reachable.src, dst=Edge.dst),
116
+ ]
117
+ ```
118
+
119
+ ### Queries
120
+
121
+ Filter, join, aggregate, and sort - all with Python expressions:
122
+
123
+ ```python
124
+ from inputlayer import count, sum_, avg
125
+
126
+ # Filter
127
+ result = await kg.query(Employee, where=lambda e: e.salary > 100000)
128
+
129
+ # Aggregation by group
130
+ result = await kg.query(
131
+ Employee.department,
132
+ count(Employee.id),
133
+ avg(Employee.salary),
134
+ join=[Employee],
135
+ )
136
+
137
+ # Order + limit
138
+ result = await kg.query(
139
+ Employee,
140
+ order_by=Employee.salary.desc(),
141
+ limit=10,
142
+ )
143
+ ```
144
+
145
+ ### Vector Search
146
+
147
+ ```python
148
+ from inputlayer import HnswIndex
149
+
150
+ await kg.create_index(HnswIndex(
151
+ name="doc_emb_idx",
152
+ relation=Document,
153
+ column="embedding",
154
+ metric="cosine",
155
+ ))
156
+
157
+ result = await kg.vector_search(
158
+ Document,
159
+ query_vec=[0.1, 0.2, ...],
160
+ k=10,
161
+ metric="cosine",
162
+ )
163
+ ```
164
+
165
+ ### Session Rules
166
+
167
+ Ephemeral views that exist only for the current connection:
168
+
169
+ ```python
170
+ await kg.session.define_rules(ActiveEngineer)
171
+ result = await kg.query(ActiveEngineer, join=[ActiveEngineer])
172
+ await kg.session.clear()
173
+ ```
174
+
175
+ ### DataFrames
176
+
177
+ Load from and export to pandas:
178
+
179
+ ```python
180
+ import pandas as pd
181
+
182
+ df = pd.DataFrame({"id": [1, 2], "name": ["Alice", "Bob"], "score": [95.0, 87.0]})
183
+ await kg.insert(Student, data=df)
184
+
185
+ result = await kg.query(Student)
186
+ export_df = result.to_df()
187
+ ```
188
+
189
+ ### Notifications
190
+
191
+ Subscribe to real-time data change events:
192
+
193
+ ```python
194
+ @il.on("persistent_update", relation="sensor_reading")
195
+ def on_update(event):
196
+ print(f"{event.count} new readings")
197
+ ```
198
+
199
+ ## Sync Client
200
+
201
+ For scripts, notebooks, and non-async contexts:
202
+
203
+ ```python
204
+ from inputlayer import InputLayerSync
205
+
206
+ with InputLayerSync("ws://localhost:8080/ws", username="admin", password="admin") as il:
207
+ kg = il.knowledge_graph("demo")
208
+ kg.define(Employee)
209
+ kg.insert(Employee(id=1, name="Alice", department="eng", salary=120000.0, active=True))
210
+ result = kg.query(Employee)
211
+ ```
212
+
213
+ ## Migrations
214
+
215
+ The SDK includes a Django-style migration system for production schema management. The `il` CLI is installed with the package.
216
+
217
+ ```bash
218
+ # Generate a migration from your models
219
+ il makemigrations --models myapp.models
220
+
221
+ # Apply pending migrations
222
+ il migrate --url ws://localhost:8080/ws --kg production
223
+
224
+ # Check status
225
+ il showmigrations --url ws://localhost:8080/ws --kg production
226
+
227
+ # Rollback
228
+ il revert --url ws://localhost:8080/ws --kg production 0001_initial
229
+ ```
230
+
231
+ The autodetector diffs your current Python models against the last migration's state and generates the minimal set of operations (create/drop relations, create/drop/replace rules, create/drop indexes). Each migration file is self-contained with a full state snapshot.
232
+
233
+ ## API Reference
234
+
235
+ ### `InputLayer` / `InputLayerSync`
236
+
237
+ | Method | Description |
238
+ |--------|-------------|
239
+ | `knowledge_graph(name)` | Get or create a knowledge graph handle |
240
+ | `list_knowledge_graphs()` | List all knowledge graphs |
241
+ | `drop_knowledge_graph(name)` | Drop a knowledge graph |
242
+ | `create_user(username, password, role)` | Create a user |
243
+ | `drop_user(username)` | Drop a user |
244
+ | `set_role(username, role)` | Change a user's role |
245
+ | `set_password(username, password)` | Change a user's password |
246
+ | `list_users()` | List all users |
247
+ | `create_api_key(label)` | Create an API key |
248
+ | `list_api_keys()` | List active API keys |
249
+ | `revoke_api_key(label)` | Revoke an API key |
250
+ | `on(event_type, ...)` | Register notification callback |
251
+ | `notifications()` | Async iterator over events |
252
+
253
+ ### `KnowledgeGraph` / `KnowledgeGraphSync`
254
+
255
+ | Method | Description |
256
+ |--------|-------------|
257
+ | `define(*relations)` | Deploy schema definitions (idempotent) |
258
+ | `relations()` | List all relations |
259
+ | `describe(relation)` | Describe a relation's schema |
260
+ | `drop_relation(relation)` | Drop a relation |
261
+ | `insert(facts, data=None)` | Insert facts (objects, dicts, or DataFrame) |
262
+ | `delete(facts, where=None)` | Delete facts |
263
+ | `query(*select, join=, where=, order_by=, limit=, offset=)` | Query the knowledge graph |
264
+ | `vector_search(relation, query_vec, k=, radius=, metric=, where=)` | Vector similarity search |
265
+ | `define_rules(*targets)` | Deploy persistent rules |
266
+ | `list_rules()` | List all rules |
267
+ | `rule_definition(name)` | Get compiled rule clauses |
268
+ | `drop_rule(name)` | Drop a rule |
269
+ | `clear_rule(name)` | Clear materialized rule data |
270
+ | `create_index(HnswIndex(...))` | Create HNSW index |
271
+ | `list_indexes()` | List indexes |
272
+ | `index_stats(name)` | Get index statistics |
273
+ | `drop_index(name)` | Drop an index |
274
+ | `rebuild_index(name)` | Rebuild an index |
275
+ | `grant_access(username, role)` | Grant per-KG access |
276
+ | `revoke_access(username)` | Revoke per-KG access |
277
+ | `list_acl()` | List access control entries |
278
+ | `explain(*select, ...)` | Show query plan without executing |
279
+ | `execute(datalog)` | Execute raw Datalog |
280
+ | `status()` | Get server status |
281
+ | `compact()` | Trigger storage compaction |
282
+
283
+ ### `Session`
284
+
285
+ | Method | Description |
286
+ |--------|-------------|
287
+ | `insert(facts)` | Insert session-scoped facts |
288
+ | `define_rules(*targets)` | Define session-scoped rules |
289
+ | `list_rules()` | List session rules |
290
+ | `drop_rule(name)` | Drop a session rule |
291
+ | `clear()` | Clear all session state |
292
+
293
+ ### `ResultSet`
294
+
295
+ | Method/Property | Description |
296
+ |--------|-------------|
297
+ | `__iter__` | Iterate as typed objects |
298
+ | `__len__` | Row count |
299
+ | `first()` | First row or `None` |
300
+ | `scalar()` | Single value from 1x1 result |
301
+ | `to_dicts()` | List of dicts |
302
+ | `to_tuples()` | List of tuples |
303
+ | `to_df()` | pandas DataFrame |
304
+ | `row_count` | Number of rows returned |
305
+ | `total_count` | Total count (with limit/offset) |
306
+ | `execution_time_ms` | Query execution time |
307
+ | `truncated` | Whether results were truncated |
308
+
309
+ ### `il` CLI
310
+
311
+ | Command | Description |
312
+ |---------|-------------|
313
+ | `il makemigrations --models <module>` | Generate migration from model diff |
314
+ | `il migrate --url <ws> --kg <name>` | Apply pending migrations |
315
+ | `il revert --url <ws> --kg <name> <target>` | Revert to a target migration |
316
+ | `il showmigrations --url <ws> --kg <name>` | Show applied/pending status |
317
+
318
+ ### Aggregation Functions
319
+
320
+ `count`, `count_distinct`, `sum_`, `min_`, `max_`, `avg`, `top_k`, `top_k_threshold`, `within_radius`
321
+
322
+ ### Built-in Functions
323
+
324
+ Access via `from inputlayer import functions as fn`:
325
+
326
+ - **Distance**: `fn.cosine`, `fn.euclidean`, `fn.dot`, `fn.manhattan`
327
+ - **Vector ops**: `fn.normalize`, `fn.vec_dim`, `fn.vec_add`, `fn.vec_scale`
328
+ - **Int8 distance**: `fn.cosine_int8`, `fn.euclidean_int8`, `fn.dot_int8`, `fn.manhattan_int8`
329
+ - **Quantization**: `fn.quantize_linear`, `fn.quantize_symmetric`, `fn.dequantize`, `fn.dequantize_scaled`
330
+ - **LSH**: `fn.lsh_bucket`, `fn.lsh_probes`, `fn.lsh_multi_probe`
331
+ - **Temporal**: `fn.time_now`, `fn.time_diff`, `fn.time_add`, `fn.time_sub`, `fn.time_decay`, `fn.time_decay_linear`, `fn.time_before`, `fn.time_after`, `fn.time_between`, `fn.within_last`, `fn.intervals_overlap`, `fn.interval_contains`, `fn.interval_duration`, `fn.point_in_interval`
332
+ - **Math**: `fn.abs_`, `fn.sqrt`, `fn.pow_`, `fn.log`, `fn.exp`, `fn.sin`, `fn.cos`, `fn.tan`, `fn.floor`, `fn.ceil`, `fn.sign`, `fn.min_val`, `fn.max_val`
333
+ - **String**: `fn.len_`, `fn.upper`, `fn.lower`, `fn.trim`, `fn.substr`, `fn.replace`, `fn.concat`
334
+ - **Type conversion**: `fn.to_int`, `fn.to_float`
335
+ - **HNSW**: `fn.hnsw_nearest`
336
+
337
+ ## Examples
338
+
339
+ See the [`examples/`](examples/) directory:
340
+
341
+ | Example | Description |
342
+ |---------|-------------|
343
+ | `01_quickstart.py` | Basic connect, define, insert, query |
344
+ | `02_social_network.py` | Graph traversal, transitive closure, mutual follows |
345
+ | `03_rag_pipeline.py` | Vector + structured hybrid search |
346
+ | `04_ecommerce.py` | Collaborative filtering, revenue aggregation |
347
+ | `05_rbac.py` | Transitive role inheritance |
348
+ | `06_realtime_dashboard.py` | Notifications + aggregation |
349
+ | `07_dataframe_etl.py` | Pandas DataFrame load/export |
350
+ | `08_session_rules.py` | Ad-hoc ephemeral views |
351
+ | `09_access_control.py` | User/ACL management |
352
+ | `10_migrations.py` | Django-style schema versioning |
353
+
354
+ ## Development
355
+
356
+ ```bash
357
+ cd packages/inputlayer-py
358
+ pip install -e ".[dev]"
359
+ python -m pytest tests/ -v
360
+ ```
361
+
362
+ ## License
363
+
364
+ AGPL-3.0