semblance-databricks 0.1.0__tar.gz → 0.1.2__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 (47) hide show
  1. {semblance_databricks-0.1.0/src/semblance_databricks.egg-info → semblance_databricks-0.1.2}/PKG-INFO +4 -4
  2. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/README.md +2 -2
  3. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/pyproject.toml +2 -2
  4. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/app.py +1 -1
  5. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/cli.py +25 -7
  6. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/compatibility.yaml +3 -3
  7. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/services/dbfs/routes.py +11 -2
  8. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/services/dbsql/routes.py +11 -1
  9. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/services/jobs/routes.py +3 -0
  10. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/state.py +0 -1
  11. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2/src/semblance_databricks.egg-info}/PKG-INFO +4 -4
  12. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks.egg-info/requires.txt +1 -1
  13. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/LICENSE.md +0 -0
  14. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/setup.cfg +0 -0
  15. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/__init__.py +0 -0
  16. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/auth.py +0 -0
  17. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/compatibility.py +0 -0
  18. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/config.py +0 -0
  19. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/errors.py +0 -0
  20. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/fixtures/__init__.py +0 -0
  21. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/fixtures/defaults/__init__.py +0 -0
  22. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/fixtures/defaults/acme.yaml +0 -0
  23. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/fixtures/loaders.py +0 -0
  24. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/http.py +0 -0
  25. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/ids.py +0 -0
  26. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/models/__init__.py +0 -0
  27. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/pagination.py +0 -0
  28. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/py.typed +0 -0
  29. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/registry.py +0 -0
  30. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/services/__init__.py +0 -0
  31. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/services/clusters/__init__.py +0 -0
  32. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/services/clusters/routes.py +0 -0
  33. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/services/dbfs/__init__.py +0 -0
  34. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/services/dbsql/__init__.py +0 -0
  35. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/services/deps.py +0 -0
  36. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/services/jobs/__init__.py +0 -0
  37. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/services/permissions/__init__.py +0 -0
  38. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/services/permissions/routes.py +0 -0
  39. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/services/secrets/__init__.py +0 -0
  40. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/services/secrets/routes.py +0 -0
  41. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/services/workspace/__init__.py +0 -0
  42. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/services/workspace/routes.py +0 -0
  43. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks/testing.py +0 -0
  44. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks.egg-info/SOURCES.txt +0 -0
  45. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks.egg-info/dependency_links.txt +0 -0
  46. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks.egg-info/entry_points.txt +0 -0
  47. {semblance_databricks-0.1.0 → semblance_databricks-0.1.2}/src/semblance_databricks.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: semblance-databricks
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Unofficial local HTTP simulation of selected Databricks workspace REST operations
5
5
  Author: Semblance Contributors
6
6
  License-Expression: MIT
@@ -18,7 +18,7 @@ Classifier: Topic :: Software Development :: Testing
18
18
  Requires-Python: >=3.10
19
19
  Description-Content-Type: text/markdown
20
20
  License-File: LICENSE.md
21
- Requires-Dist: semblance<0.8,>=0.7.0
21
+ Requires-Dist: semblance<1.0,>=0.8.0
22
22
  Requires-Dist: pydantic>=2.0.0
23
23
  Requires-Dist: pyyaml>=6.0
24
24
  Provides-Extra: dev
@@ -39,7 +39,7 @@ This package is **not affiliated with, endorsed by, or equivalent to Databricks*
39
39
 
40
40
  Verified against public workspace REST documentation dated **2026-08-19**. See `compatibility.yaml` (also served at `/.well-known/semblance-databricks-compat.json`).
41
41
 
42
- Requires `semblance` 0.7.x.
42
+ Requires `semblance` 0.8.x or 0.9.x (`>=0.8.0,<1.0`).
43
43
 
44
44
  ## Install
45
45
 
@@ -107,7 +107,7 @@ YAML/JSON version 1. Extra fields are rejected. Fixtures are **data only**. Secr
107
107
 
108
108
  List endpoints use `page_size` or `limit` plus `page_token` / `next_page_token`. Tokens are opaque and checksummed. Tampering returns 400 `INVALID_PARAMETER_VALUE`.
109
109
 
110
- ## Known unsupported (0.1.0)
110
+ ## Known unsupported (0.1.2)
111
111
 
112
112
  - Unity Catalog, Model Serving, DLT / Spark Declarative Pipelines
113
113
  - Jobs API 2.0 as primary (optional 2.1 aliases are representative)
@@ -6,7 +6,7 @@ This package is **not affiliated with, endorsed by, or equivalent to Databricks*
6
6
 
7
7
  Verified against public workspace REST documentation dated **2026-08-19**. See `compatibility.yaml` (also served at `/.well-known/semblance-databricks-compat.json`).
8
8
 
9
- Requires `semblance` 0.7.x.
9
+ Requires `semblance` 0.8.x or 0.9.x (`>=0.8.0,<1.0`).
10
10
 
11
11
  ## Install
12
12
 
@@ -74,7 +74,7 @@ YAML/JSON version 1. Extra fields are rejected. Fixtures are **data only**. Secr
74
74
 
75
75
  List endpoints use `page_size` or `limit` plus `page_token` / `next_page_token`. Tokens are opaque and checksummed. Tampering returns 400 `INVALID_PARAMETER_VALUE`.
76
76
 
77
- ## Known unsupported (0.1.0)
77
+ ## Known unsupported (0.1.2)
78
78
 
79
79
  - Unity Catalog, Model Serving, DLT / Spark Declarative Pipelines
80
80
  - Jobs API 2.0 as primary (optional 2.1 aliases are representative)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "semblance-databricks"
7
- version = "0.1.0"
7
+ version = "0.1.2"
8
8
  description = "Unofficial local HTTP simulation of selected Databricks workspace REST operations"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -22,7 +22,7 @@ classifiers = [
22
22
  "Topic :: Software Development :: Testing",
23
23
  ]
24
24
  dependencies = [
25
- "semblance>=0.7.0,<0.8",
25
+ "semblance>=0.8.0,<1.0",
26
26
  "pydantic>=2.0.0",
27
27
  "pyyaml>=6.0",
28
28
  ]
@@ -37,7 +37,7 @@ def _distribution_version() -> str:
37
37
  try:
38
38
  return pkg_version("semblance-databricks")
39
39
  except PackageNotFoundError:
40
- return "0.1.0"
40
+ return "0.1.2"
41
41
 
42
42
 
43
43
  class DatabricksMock:
@@ -8,9 +8,14 @@ import sys
8
8
  from pathlib import Path
9
9
 
10
10
  from semblance_databricks.app import DatabricksMock
11
- from semblance_databricks.config import DatabricksMockConfig
12
- from semblance_databricks.fixtures.loaders import bundled_acme_path, load_fixture_file
11
+ from semblance_databricks.config import DatabricksMockConfig, TokenGrant
12
+ from semblance_databricks.fixtures.loaders import (
13
+ apply_fixture,
14
+ bundled_acme_path,
15
+ load_fixture_file,
16
+ )
13
17
  from semblance_databricks.registry import registered_operations
18
+ from semblance_databricks.state import DatabricksState
14
19
 
15
20
 
16
21
  def cmd_serve(args: argparse.Namespace) -> None:
@@ -19,8 +24,11 @@ def cmd_serve(args: argparse.Namespace) -> None:
19
24
  if args.seed is not None
20
25
  else int(os.environ.get("SEMBLANCE_DATABRICKS_SEED", "42"))
21
26
  )
22
- host = os.environ.get("SEMBLANCE_DATABRICKS_HOST", args.host)
23
- config = DatabricksMockConfig(seed=seed, auth=args.auth)
27
+ host = args.host
28
+ tokens = tuple(TokenGrant(token) for token in (args.token or []))
29
+ if args.auth == "strict" and not tokens:
30
+ raise SystemExit("strict auth requires at least one --token")
31
+ config = DatabricksMockConfig(seed=seed, auth=args.auth, tokens=tokens)
24
32
  mock = DatabricksMock(config)
25
33
  mock.load_fixture(args.fixture or bundled_acme_path())
26
34
  app = mock.as_fastapi()
@@ -28,14 +36,15 @@ def cmd_serve(args: argparse.Namespace) -> None:
28
36
  import uvicorn
29
37
  except ImportError as exc:
30
38
  raise SystemExit(
31
- "uvicorn not found. Install semblance (pulls uvicorn)."
39
+ "uvicorn not found. Install semblance-databricks (pulls uvicorn via semblance)."
32
40
  ) from exc
33
41
  uvicorn.run(app, host=host, port=args.port)
34
42
 
35
43
 
36
44
  def cmd_validate(args: argparse.Namespace) -> None:
37
45
  try:
38
- load_fixture_file(args.fixture)
46
+ doc = load_fixture_file(args.fixture)
47
+ apply_fixture(doc, DatabricksState(seed=42))
39
48
  except Exception as exc:
40
49
  raise SystemExit(f"Invalid fixture: {exc}") from exc
41
50
  print("OK")
@@ -76,7 +85,10 @@ def build_parser() -> argparse.ArgumentParser:
76
85
  default=None,
77
86
  help="YAML or JSON fixture path (default: bundled acme example)",
78
87
  )
79
- serve.add_argument("--host", default="127.0.0.1")
88
+ serve.add_argument(
89
+ "--host",
90
+ default=os.environ.get("SEMBLANCE_DATABRICKS_HOST", "127.0.0.1"),
91
+ )
80
92
  serve.add_argument("--port", type=int, default=8766)
81
93
  serve.add_argument("--seed", type=int, default=None)
82
94
  serve.add_argument(
@@ -84,6 +96,12 @@ def build_parser() -> argparse.ArgumentParser:
84
96
  default="optional",
85
97
  choices=["disabled", "optional", "strict"],
86
98
  )
99
+ serve.add_argument(
100
+ "--token",
101
+ action="append",
102
+ default=[],
103
+ help="Bearer token accepted in strict mode (repeatable)",
104
+ )
87
105
  serve.set_defaults(func=cmd_serve)
88
106
 
89
107
  validate = sub.add_parser("validate", help="Validate a fixture without serving")
@@ -1,4 +1,4 @@
1
- packageVersion: "0.1.0"
1
+ packageVersion: "0.1.2"
2
2
  documentedAt: "2026-08-19"
3
3
  source: "https://docs.databricks.com/api/workspace/"
4
4
  operations:
@@ -130,7 +130,7 @@ operations:
130
130
  - tests/contract/test_warehouses.py::test_list_warehouses
131
131
  - operationId: GetWarehouse
132
132
  method: GET
133
- path: /api/2.0/sql/warehouses/{id}
133
+ path: /api/2.0/sql/warehouses/{warehouse_id}
134
134
  supportLevel: exact
135
135
  docsUrl: https://docs.databricks.com/api/workspace/warehouses/get
136
136
  tests:
@@ -144,7 +144,7 @@ operations:
144
144
  - tests/contract/test_warehouses.py::test_create_delete_warehouse
145
145
  - operationId: DeleteWarehouse
146
146
  method: DELETE
147
- path: /api/2.0/sql/warehouses/{id}
147
+ path: /api/2.0/sql/warehouses/{warehouse_id}
148
148
  supportLevel: representative
149
149
  docsUrl: https://docs.databricks.com/api/workspace/warehouses/delete
150
150
  tests:
@@ -87,6 +87,10 @@ def create_dbfs_router() -> APIRouter:
87
87
  node = mock.state.dbfs.get(_normalize(path))
88
88
  if node is None or node.is_dir:
89
89
  raise DatabricksError(404, "RESOURCE_DOES_NOT_EXIST", "File not found")
90
+ if offset < 0 or length < 0:
91
+ raise DatabricksError(
92
+ 400, "INVALID_PARAMETER_VALUE", "offset and length must be >= 0"
93
+ )
90
94
  data = node.data[offset : offset + length]
91
95
  return {
92
96
  "bytes_read": len(data),
@@ -105,7 +109,8 @@ def create_dbfs_router() -> APIRouter:
105
109
  path = _normalize(str(body.get("path", "")))
106
110
  if not path or path == "/":
107
111
  raise DatabricksError(400, "INVALID_PARAMETER_VALUE", "path required")
108
- if len(mock.state.dbfs) >= mock.config.dbfs_max_files:
112
+ replacing = path in mock.state.dbfs
113
+ if not replacing and len(mock.state.dbfs) >= mock.config.dbfs_max_files:
109
114
  raise DatabricksError(400, "MAX_BLOCK_SIZE_EXCEEDED", "DBFS file cap")
110
115
  raw = str(body.get("contents", ""))
111
116
  try:
@@ -114,7 +119,11 @@ def create_dbfs_router() -> APIRouter:
114
119
  raise DatabricksError(
115
120
  400, "INVALID_PARAMETER_VALUE", "contents must be base64"
116
121
  ) from exc
117
- total = sum(len(n.data) for n in mock.state.dbfs.values()) + len(content)
122
+ existing = mock.state.dbfs.get(path)
123
+ old_size = len(existing.data) if existing is not None else 0
124
+ total = (
125
+ sum(len(n.data) for n in mock.state.dbfs.values()) - old_size + len(content)
126
+ )
118
127
  if total > mock.config.dbfs_max_bytes:
119
128
  raise DatabricksError(400, "MAX_BLOCK_SIZE_EXCEEDED", "DBFS size cap")
120
129
  mock.state.dbfs[path] = DbfsNode(path=path, is_dir=False, data=content)
@@ -17,7 +17,16 @@ from semblance_databricks.state import WarehouseRecord
17
17
  def _statement_payload(statement_id: str, rec: dict[str, Any]) -> dict[str, Any]:
18
18
  chunks: list[Any] = rec.get("chunks") or []
19
19
  index = int(rec.get("chunk_index", 0))
20
- chunk = chunks[index] if index < len(chunks) else []
20
+ if index < 0:
21
+ raise DatabricksError(
22
+ 400, "INVALID_PARAMETER_VALUE", "chunk_index must be >= 0"
23
+ )
24
+ if not chunks:
25
+ chunk: Any = []
26
+ elif index >= len(chunks):
27
+ raise DatabricksError(404, "RESOURCE_DOES_NOT_EXIST", "Chunk not found")
28
+ else:
29
+ chunk = chunks[index]
21
30
  next_chunk = None
22
31
  if index + 1 < len(chunks):
23
32
  next_chunk = index + 1
@@ -115,6 +124,7 @@ def create_dbsql_router() -> APIRouter:
115
124
  if warehouse_id not in mock.state.warehouses:
116
125
  raise DatabricksError(404, "RESOURCE_DOES_NOT_EXIST", "Warehouse not found")
117
126
  del mock.state.warehouses[warehouse_id]
127
+ mock.state.permissions.pop(("warehouses", warehouse_id), None)
118
128
  mock.state.bump()
119
129
  return {}
120
130
 
@@ -112,6 +112,7 @@ def _add_jobs_routes(router: APIRouter, prefix: str) -> None:
112
112
  if jid not in mock.state.jobs:
113
113
  raise DatabricksError(404, "RESOURCE_DOES_NOT_EXIST", "Job not found")
114
114
  del mock.state.jobs[jid]
115
+ mock.state.permissions.pop(("jobs", jid), None)
115
116
  mock.state.bump()
116
117
  return {}
117
118
 
@@ -121,6 +122,8 @@ def _add_jobs_routes(router: APIRouter, prefix: str) -> None:
121
122
  body = await json_object(request)
122
123
  rid = mock.state.allocate_numeric_id(mock.state.runs, 2000)
123
124
  job_id = str(body["job_id"]) if body.get("job_id") is not None else None
125
+ if job_id is not None and job_id not in mock.state.jobs:
126
+ raise DatabricksError(404, "RESOURCE_DOES_NOT_EXIST", "Job not found")
124
127
  mock.state.runs[rid] = RunRecord(
125
128
  run_id=rid,
126
129
  job_id=job_id,
@@ -126,7 +126,6 @@ class DatabricksState:
126
126
  self.workspace_objects.clear()
127
127
  self.permissions.clear()
128
128
  self.statements.clear()
129
- self.statement_callbacks.clear()
130
129
  self.revision = 0
131
130
  self.seq = 0
132
131
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: semblance-databricks
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Unofficial local HTTP simulation of selected Databricks workspace REST operations
5
5
  Author: Semblance Contributors
6
6
  License-Expression: MIT
@@ -18,7 +18,7 @@ Classifier: Topic :: Software Development :: Testing
18
18
  Requires-Python: >=3.10
19
19
  Description-Content-Type: text/markdown
20
20
  License-File: LICENSE.md
21
- Requires-Dist: semblance<0.8,>=0.7.0
21
+ Requires-Dist: semblance<1.0,>=0.8.0
22
22
  Requires-Dist: pydantic>=2.0.0
23
23
  Requires-Dist: pyyaml>=6.0
24
24
  Provides-Extra: dev
@@ -39,7 +39,7 @@ This package is **not affiliated with, endorsed by, or equivalent to Databricks*
39
39
 
40
40
  Verified against public workspace REST documentation dated **2026-08-19**. See `compatibility.yaml` (also served at `/.well-known/semblance-databricks-compat.json`).
41
41
 
42
- Requires `semblance` 0.7.x.
42
+ Requires `semblance` 0.8.x or 0.9.x (`>=0.8.0,<1.0`).
43
43
 
44
44
  ## Install
45
45
 
@@ -107,7 +107,7 @@ YAML/JSON version 1. Extra fields are rejected. Fixtures are **data only**. Secr
107
107
 
108
108
  List endpoints use `page_size` or `limit` plus `page_token` / `next_page_token`. Tokens are opaque and checksummed. Tampering returns 400 `INVALID_PARAMETER_VALUE`.
109
109
 
110
- ## Known unsupported (0.1.0)
110
+ ## Known unsupported (0.1.2)
111
111
 
112
112
  - Unity Catalog, Model Serving, DLT / Spark Declarative Pipelines
113
113
  - Jobs API 2.0 as primary (optional 2.1 aliases are representative)
@@ -1,4 +1,4 @@
1
- semblance<0.8,>=0.7.0
1
+ semblance<1.0,>=0.8.0
2
2
  pydantic>=2.0.0
3
3
  pyyaml>=6.0
4
4