laketower 0.4.0__tar.gz → 0.4.1__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.
Potentially problematic release.
This version of laketower might be problematic. Click here for more details.
- {laketower-0.4.0 → laketower-0.4.1}/CHANGELOG.md +12 -1
- {laketower-0.4.0 → laketower-0.4.1}/PKG-INFO +1 -1
- laketower-0.4.1/laketower/__about__.py +1 -0
- {laketower-0.4.0 → laketower-0.4.1}/laketower/templates/queries/view.html +13 -1
- {laketower-0.4.0 → laketower-0.4.1}/laketower/templates/tables/query.html +5 -1
- {laketower-0.4.0 → laketower-0.4.1}/laketower/templates/tables/view.html +1 -1
- {laketower-0.4.0 → laketower-0.4.1}/pyproject.toml +1 -1
- {laketower-0.4.0 → laketower-0.4.1}/tests/test_web.py +29 -14
- {laketower-0.4.0 → laketower-0.4.1}/uv.lock +4 -4
- laketower-0.4.0/laketower/__about__.py +0 -1
- {laketower-0.4.0 → laketower-0.4.1}/.github/workflows/ci-cd.yml +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/.gitignore +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/.python-version +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/LICENSE.md +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/README.md +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/demo/generate.py +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/demo/laketower.yml +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/demo/sample_table/_delta_log/00000000000000000000.json +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/demo/sample_table/_delta_log/00000000000000000001.json +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/demo/sample_table/_delta_log/00000000000000000002.json +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/demo/sample_table/_delta_log/00000000000000000003.json +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/demo/sample_table/part-00001-1a31a393-6db6-4d1a-bf4e-81ea061ff8cd-c000.snappy.parquet +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/demo/sample_table/part-00001-5af77102-9207-4c89-aaf6-37e1f815ec26-c000.snappy.parquet +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/demo/sample_table/part-00001-b11bab55-43d0-4d05-ae88-5b9481ae57db-c000.snappy.parquet +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/demo/weather/_delta_log/00000000000000000000.json +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/demo/weather/_delta_log/00000000000000000001.json +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/demo/weather/_delta_log/00000000000000000002.json +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/demo/weather/part-00001-2323b963-be56-44e0-8c10-e237e7e6d4b9-c000.snappy.parquet +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/demo/weather/part-00001-6360cbf8-f8a9-475f-8729-6f20b4ca64a9-c000.snappy.parquet +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/laketower/__init__.py +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/laketower/__main__.py +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/laketower/cli.py +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/laketower/config.py +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/laketower/static/.gitkeep +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/laketower/tables.py +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/laketower/templates/_base.html +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/laketower/templates/index.html +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/laketower/templates/tables/_macros.html +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/laketower/templates/tables/history.html +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/laketower/templates/tables/index.html +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/laketower/templates/tables/statistics.html +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/laketower/web.py +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/renovate.json +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/tasks.py +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/tests/__init__.py +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/tests/conftest.py +0 -0
- {laketower-0.4.0 → laketower-0.4.1}/tests/test_cli.py +0 -0
|
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.4.1] - 2025-03-02
|
|
11
|
+
Minor release with fixes.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- web: allow editing queries
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- web: missing tables query page title
|
|
18
|
+
- web: urlencode table view sql query link
|
|
19
|
+
|
|
10
20
|
## [0.4.0] - 2025-03-01
|
|
11
21
|
Introducing new features:
|
|
12
22
|
- Display tables statistics
|
|
@@ -59,7 +69,8 @@ Initial release of `laketower`.
|
|
|
59
69
|
- View a given table with simple query builder
|
|
60
70
|
- Query all registered tables with DuckDB SQL dialect
|
|
61
71
|
|
|
62
|
-
[Unreleased]: https://github.com/datalpia/laketower/compare/0.4.
|
|
72
|
+
[Unreleased]: https://github.com/datalpia/laketower/compare/0.4.1...HEAD
|
|
73
|
+
[0.4.1]: https://github.com/datalpia/laketower/compare/0.4.0...0.4.1
|
|
63
74
|
[0.4.0]: https://github.com/datalpia/laketower/compare/0.3.0...0.4.0
|
|
64
75
|
[0.3.0]: https://github.com/datalpia/laketower/compare/0.2.0...0.3.0
|
|
65
76
|
[0.2.0]: https://github.com/datalpia/laketower/compare/0.1.0...0.2.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.4.1"
|
|
@@ -12,7 +12,19 @@
|
|
|
12
12
|
|
|
13
13
|
<div class="mb-3">
|
|
14
14
|
<div class="d-flex justify-content-end">
|
|
15
|
-
<
|
|
15
|
+
<div class="row">
|
|
16
|
+
<div class="col">
|
|
17
|
+
<a href="/tables/query?sql={{ query.sql | urlencode }}" class="btn btn-secondary" type="button" >
|
|
18
|
+
<i class="bi-code" aria-hidden="true"></i> Edit SQL
|
|
19
|
+
</a>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<div class="col-auto">
|
|
23
|
+
<button type="submit" class="btn btn-primary">
|
|
24
|
+
<i class="bi-lightning" aria-hidden="true"></i> Execute
|
|
25
|
+
</button>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
16
28
|
</div>
|
|
17
29
|
</div>
|
|
18
30
|
</form>
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
{% block body %}
|
|
5
5
|
<div class="row">
|
|
6
6
|
<div class="col">
|
|
7
|
+
<h2 class="mb-3">SQL Query</h2>
|
|
8
|
+
|
|
7
9
|
<form action="{{ request.url.path }}" method="get">
|
|
8
10
|
<div class="mb-3">
|
|
9
11
|
<textarea name="sql" rows="5" class="form-control">{{ sql_query }}</textarea>
|
|
@@ -11,7 +13,9 @@
|
|
|
11
13
|
|
|
12
14
|
<div class="mb-3">
|
|
13
15
|
<div class="d-flex justify-content-end">
|
|
14
|
-
<button type="submit" class="btn btn-primary">
|
|
16
|
+
<button type="submit" class="btn btn-primary">
|
|
17
|
+
<i class="bi-lightning" aria-hidden="true"></i> Execute
|
|
18
|
+
</button>
|
|
15
19
|
</div>
|
|
16
20
|
</div>
|
|
17
21
|
</form>
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
</form>
|
|
87
87
|
</div>
|
|
88
88
|
|
|
89
|
-
<a
|
|
89
|
+
<a href="/tables/query?sql={{ sql_query | urlencode }}" class="btn btn-primary" role="button">
|
|
90
90
|
<i class="bi-code" aria-hidden="true"></i> SQL Query
|
|
91
91
|
</a>
|
|
92
92
|
</div>
|
|
@@ -324,7 +324,7 @@ def test_tables_view_version(
|
|
|
324
324
|
)
|
|
325
325
|
|
|
326
326
|
|
|
327
|
-
def
|
|
327
|
+
def test_tables_query(
|
|
328
328
|
client: TestClient, sample_config: dict[str, Any], delta_table: deltalake.DeltaTable
|
|
329
329
|
) -> None:
|
|
330
330
|
selected_column = delta_table.schema().fields[0].name
|
|
@@ -336,13 +336,20 @@ def test_table_query(
|
|
|
336
336
|
assert response.status_code == HTTPStatus.OK
|
|
337
337
|
|
|
338
338
|
html = response.content.decode()
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
assert
|
|
339
|
+
soup = BeautifulSoup(html, "html.parser")
|
|
340
|
+
|
|
341
|
+
assert soup.find("h2", string="SQL Query")
|
|
342
|
+
assert (textarea := soup.find("textarea")) and textarea.text.strip() == sql_query
|
|
343
|
+
assert next(filter(lambda a: a.text.strip() == "Execute", soup.find_all("button")))
|
|
344
|
+
|
|
345
|
+
all_th = [th.text.strip() for th in soup.find_all("th")]
|
|
346
|
+
assert selected_column in all_th
|
|
347
|
+
assert not all(col in all_th for col in filtered_columns)
|
|
342
348
|
|
|
343
349
|
df = delta_table.to_pandas()
|
|
344
|
-
|
|
345
|
-
assert
|
|
350
|
+
all_td = [td.text.strip() for td in soup.find_all("td")]
|
|
351
|
+
assert all(str(row) in all_td for row in df[selected_column][0:selected_limit])
|
|
352
|
+
assert not all(str(row) in all_td for row in df[selected_column][selected_limit:])
|
|
346
353
|
|
|
347
354
|
|
|
348
355
|
def test_tables_query_invalid(
|
|
@@ -354,12 +361,20 @@ def test_tables_query_invalid(
|
|
|
354
361
|
assert response.status_code == HTTPStatus.OK
|
|
355
362
|
|
|
356
363
|
html = response.content.decode()
|
|
364
|
+
soup = BeautifulSoup(html, "html.parser")
|
|
365
|
+
|
|
366
|
+
assert soup.find("h2", string="SQL Query")
|
|
367
|
+
assert (textarea := soup.find("textarea")) and textarea.text.strip() == sql_query
|
|
368
|
+
assert next(filter(lambda a: a.text.strip() == "Execute", soup.find_all("button")))
|
|
357
369
|
assert "Error" in html
|
|
358
|
-
|
|
370
|
+
|
|
371
|
+
all_th = [th.text.strip() for th in soup.find_all("th")]
|
|
372
|
+
assert not all(field.name in all_th for field in delta_table.schema().fields)
|
|
359
373
|
|
|
360
374
|
df = delta_table.to_pandas()
|
|
375
|
+
all_td = [td.text.strip() for td in soup.find_all("td")]
|
|
361
376
|
assert not all(
|
|
362
|
-
str(row[col]) in
|
|
377
|
+
str(row[col]) in all_td for _, row in df.iterrows() for col in row.index
|
|
363
378
|
)
|
|
364
379
|
|
|
365
380
|
|
|
@@ -373,9 +388,9 @@ def test_queries_view(client: TestClient, sample_config: dict[str, Any]) -> None
|
|
|
373
388
|
soup = BeautifulSoup(html, "html.parser")
|
|
374
389
|
|
|
375
390
|
assert soup.find("h2", string=query["title"])
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
assert
|
|
391
|
+
assert (textarea := soup.find("textarea")) and textarea.text.strip() == query["sql"]
|
|
392
|
+
assert next(filter(lambda a: a.text.strip() == "Edit SQL", soup.find_all("a")))
|
|
393
|
+
assert next(filter(lambda a: a.text.strip() == "Execute", soup.find_all("button")))
|
|
379
394
|
|
|
380
395
|
all_th = [th.text.strip() for th in soup.find_all("th")]
|
|
381
396
|
assert all(col in all_th for col in {"day", "avg_temperature"})
|
|
@@ -399,9 +414,9 @@ def test_queries_view_invalid(
|
|
|
399
414
|
soup = BeautifulSoup(html, "html.parser")
|
|
400
415
|
|
|
401
416
|
assert soup.find("h2", string=query["title"])
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
assert
|
|
417
|
+
assert (textarea := soup.find("textarea")) and textarea.text.strip() == query["sql"]
|
|
418
|
+
assert next(filter(lambda a: a.text.strip() == "Edit SQL", soup.find_all("a")))
|
|
419
|
+
assert next(filter(lambda a: a.text.strip() == "Execute", soup.find_all("button")))
|
|
405
420
|
|
|
406
421
|
all_th = [th.text.strip() for th in soup.find_all("th")]
|
|
407
422
|
assert not all(col in all_th for col in {"day", "avg_temperature"})
|
|
@@ -490,7 +490,7 @@ dev = [
|
|
|
490
490
|
{ name = "pandas-stubs", specifier = "==2.2.3.241126" },
|
|
491
491
|
{ name = "pip-audit", specifier = "==2.8.0" },
|
|
492
492
|
{ name = "pyarrow-stubs", specifier = "==17.17" },
|
|
493
|
-
{ name = "pytest", specifier = "==8.3.
|
|
493
|
+
{ name = "pytest", specifier = "==8.3.5" },
|
|
494
494
|
{ name = "pytest-cov", specifier = "==6.0.0" },
|
|
495
495
|
{ name = "ruff", specifier = "==0.9.9" },
|
|
496
496
|
{ name = "types-pyyaml", specifier = "==6.0.12.20241230" },
|
|
@@ -1097,7 +1097,7 @@ wheels = [
|
|
|
1097
1097
|
|
|
1098
1098
|
[[package]]
|
|
1099
1099
|
name = "pytest"
|
|
1100
|
-
version = "8.3.
|
|
1100
|
+
version = "8.3.5"
|
|
1101
1101
|
source = { registry = "https://pypi.org/simple" }
|
|
1102
1102
|
dependencies = [
|
|
1103
1103
|
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
|
@@ -1107,9 +1107,9 @@ dependencies = [
|
|
|
1107
1107
|
{ name = "pluggy" },
|
|
1108
1108
|
{ name = "tomli", marker = "python_full_version < '3.11'" },
|
|
1109
1109
|
]
|
|
1110
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1110
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891 }
|
|
1111
1111
|
wheels = [
|
|
1112
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1112
|
+
{ url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634 },
|
|
1113
1113
|
]
|
|
1114
1114
|
|
|
1115
1115
|
[[package]]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.4.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|