webgate 0.3.0__tar.gz → 0.3.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.
Files changed (84) hide show
  1. {webgate-0.3.0 → webgate-0.3.1}/CHANGELOG.md +12 -0
  2. {webgate-0.3.0 → webgate-0.3.1}/PKG-INFO +3 -5
  3. {webgate-0.3.0 → webgate-0.3.1}/README.md +1 -2
  4. {webgate-0.3.0 → webgate-0.3.1}/pyproject.toml +2 -4
  5. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/db/engine.py +11 -7
  6. {webgate-0.3.0 → webgate-0.3.1}/uv.lock +51 -1
  7. {webgate-0.3.0 → webgate-0.3.1}/.dockerignore +0 -0
  8. {webgate-0.3.0 → webgate-0.3.1}/.github/workflows/docs.yml +0 -0
  9. {webgate-0.3.0 → webgate-0.3.1}/.gitignore +0 -0
  10. {webgate-0.3.0 → webgate-0.3.1}/Dockerfile +0 -0
  11. {webgate-0.3.0 → webgate-0.3.1}/Dockerfile.demo +0 -0
  12. {webgate-0.3.0 → webgate-0.3.1}/Dockerfile.ssh-demo +0 -0
  13. {webgate-0.3.0 → webgate-0.3.1}/LICENSE +0 -0
  14. {webgate-0.3.0 → webgate-0.3.1}/ROADMAP.md +0 -0
  15. {webgate-0.3.0 → webgate-0.3.1}/VERSION +0 -0
  16. {webgate-0.3.0 → webgate-0.3.1}/compose.dev.yml +0 -0
  17. {webgate-0.3.0 → webgate-0.3.1}/compose.yml +0 -0
  18. {webgate-0.3.0 → webgate-0.3.1}/docs/api/auth.md +0 -0
  19. {webgate-0.3.0 → webgate-0.3.1}/docs/api/files.md +0 -0
  20. {webgate-0.3.0 → webgate-0.3.1}/docs/api/servers.md +0 -0
  21. {webgate-0.3.0 → webgate-0.3.1}/docs/api/terminal.md +0 -0
  22. {webgate-0.3.0 → webgate-0.3.1}/docs/changelog.md +0 -0
  23. {webgate-0.3.0 → webgate-0.3.1}/docs/getting-started/installation.md +0 -0
  24. {webgate-0.3.0 → webgate-0.3.1}/docs/getting-started/quickstart.md +0 -0
  25. {webgate-0.3.0 → webgate-0.3.1}/docs/guide/files.md +0 -0
  26. {webgate-0.3.0 → webgate-0.3.1}/docs/guide/servers.md +0 -0
  27. {webgate-0.3.0 → webgate-0.3.1}/docs/guide/split.md +0 -0
  28. {webgate-0.3.0 → webgate-0.3.1}/docs/guide/terminal.md +0 -0
  29. {webgate-0.3.0 → webgate-0.3.1}/docs/guide/users.md +0 -0
  30. {webgate-0.3.0 → webgate-0.3.1}/docs/index.md +0 -0
  31. {webgate-0.3.0 → webgate-0.3.1}/docs/screenshots/access-control.png +0 -0
  32. {webgate-0.3.0 → webgate-0.3.1}/docs/screenshots/audit.png +0 -0
  33. {webgate-0.3.0 → webgate-0.3.1}/docs/screenshots/edit-access-control.png +0 -0
  34. {webgate-0.3.0 → webgate-0.3.1}/docs/screenshots/editor.png +0 -0
  35. {webgate-0.3.0 → webgate-0.3.1}/docs/screenshots/light-theme.png +0 -0
  36. {webgate-0.3.0 → webgate-0.3.1}/docs/screenshots/login.png +0 -0
  37. {webgate-0.3.0 → webgate-0.3.1}/docs/screenshots/new-server-form.png +0 -0
  38. {webgate-0.3.0 → webgate-0.3.1}/docs/screenshots/sftp-restricted.png +0 -0
  39. {webgate-0.3.0 → webgate-0.3.1}/docs/screenshots/sftp.png +0 -0
  40. {webgate-0.3.0 → webgate-0.3.1}/docs/screenshots/site-manager.png +0 -0
  41. {webgate-0.3.0 → webgate-0.3.1}/docs/screenshots/split-view.png +0 -0
  42. {webgate-0.3.0 → webgate-0.3.1}/docs/screenshots/ssh-disabled.png +0 -0
  43. {webgate-0.3.0 → webgate-0.3.1}/docs/screenshots/terminal.png +0 -0
  44. {webgate-0.3.0 → webgate-0.3.1}/docs/screenshots/users.png +0 -0
  45. {webgate-0.3.0 → webgate-0.3.1}/fly.toml +0 -0
  46. {webgate-0.3.0 → webgate-0.3.1}/mkdocs.yml +0 -0
  47. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/__init__.py +0 -0
  48. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/__main__.py +0 -0
  49. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/app.py +0 -0
  50. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/audit/__init__.py +0 -0
  51. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/audit/models.py +0 -0
  52. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/audit/service.py +0 -0
  53. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/auth/__init__.py +0 -0
  54. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/auth/models.py +0 -0
  55. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/auth/routes.py +0 -0
  56. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/auth/service.py +0 -0
  57. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/config.py +0 -0
  58. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/db/__init__.py +0 -0
  59. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/demo.py +0 -0
  60. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/files/__init__.py +0 -0
  61. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/files/models.py +0 -0
  62. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/files/pool.py +0 -0
  63. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/files/routes.py +0 -0
  64. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/files/sftp_service.py +0 -0
  65. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/servers/__init__.py +0 -0
  66. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/servers/crypto.py +0 -0
  67. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/servers/models.py +0 -0
  68. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/servers/monitor.py +0 -0
  69. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/servers/routes.py +0 -0
  70. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/servers/service.py +0 -0
  71. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/snippets/__init__.py +0 -0
  72. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/snippets/models.py +0 -0
  73. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/snippets/routes.py +0 -0
  74. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/static/index.html +0 -0
  75. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/terminal/__init__.py +0 -0
  76. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/terminal/routes.py +0 -0
  77. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/terminal/ssh_session.py +0 -0
  78. {webgate-0.3.0 → webgate-0.3.1}/src/webgate/terminal/ws_handler.py +0 -0
  79. {webgate-0.3.0 → webgate-0.3.1}/tests/__init__.py +0 -0
  80. {webgate-0.3.0 → webgate-0.3.1}/tests/conftest.py +0 -0
  81. {webgate-0.3.0 → webgate-0.3.1}/tests/test_auth.py +0 -0
  82. {webgate-0.3.0 → webgate-0.3.1}/tests/test_files.py +0 -0
  83. {webgate-0.3.0 → webgate-0.3.1}/tests/test_servers.py +0 -0
  84. {webgate-0.3.0 → webgate-0.3.1}/tests/test_terminal.py +0 -0
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.3.1 (2026-04-15)
4
+
5
+ ### Fixed
6
+
7
+ - **PostgreSQL actually works in Docker now.** v0.3.0 advertised PostgreSQL support but two bugs prevented it from working:
8
+ 1. `asyncpg` was an optional extra (`webgate[postgres]`), so the official Docker image (and `pip install webgate`) didn't have the driver. Now bundled by default.
9
+ 2. Lightweight migrations ran inside the same transaction as `create_all`. PostgreSQL aborts the entire transaction on any error (even when caught), so the first "column already exists" error rolled back table creation on subsequent runs. Each migration now uses its own transaction.
10
+
11
+ Verified end-to-end against a real `postgres:16-alpine` container: tables created, login works, server creation and persistence across restarts confirmed.
12
+
13
+ ---
14
+
3
15
  ## v0.3.0 (2026-04-15)
4
16
 
5
17
  ### Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: webgate
3
- Version: 0.3.0
3
+ Version: 0.3.1
4
4
  Summary: Self-hosted web application for remote server management via SSH terminal and SFTP file browser
5
5
  Project-URL: Homepage, https://github.com/kalexnolasco/webgate
6
6
  Project-URL: Documentation, https://kalexnolasco.github.io/webgate/
@@ -27,6 +27,7 @@ Classifier: Typing :: Typed
27
27
  Requires-Python: >=3.11
28
28
  Requires-Dist: aiofiles>=24.1.0
29
29
  Requires-Dist: aiosqlite>=0.21.0
30
+ Requires-Dist: asyncpg>=0.30.0
30
31
  Requires-Dist: asyncssh>=2.18.0
31
32
  Requires-Dist: bcrypt>=4.2.0
32
33
  Requires-Dist: cryptography>=44.0.0
@@ -42,8 +43,6 @@ Requires-Dist: slowapi>=0.1.9
42
43
  Requires-Dist: sqlalchemy>=2.0.36
43
44
  Requires-Dist: uvicorn[standard]>=0.34.0
44
45
  Requires-Dist: websockets>=14.0
45
- Provides-Extra: postgres
46
- Requires-Dist: asyncpg>=0.30.0; extra == 'postgres'
47
46
  Description-Content-Type: text/markdown
48
47
 
49
48
  # webgate
@@ -457,10 +456,9 @@ All settings are configurable via environment variables with the `WEBGATE_` pref
457
456
 
458
457
  ### PostgreSQL
459
458
 
460
- SQLite is the default. To use PostgreSQL instead:
459
+ SQLite is the default. To use PostgreSQL, just point `WEBGATE_DB_URL` at it (the `asyncpg` driver is bundled as of v0.3.1):
461
460
 
462
461
  ```bash
463
- pip install 'webgate[postgres]' # adds asyncpg
464
462
  export WEBGATE_DB_URL='postgresql+asyncpg://user:pass@host:5432/webgate'
465
463
  ```
466
464
 
@@ -409,10 +409,9 @@ All settings are configurable via environment variables with the `WEBGATE_` pref
409
409
 
410
410
  ### PostgreSQL
411
411
 
412
- SQLite is the default. To use PostgreSQL instead:
412
+ SQLite is the default. To use PostgreSQL, just point `WEBGATE_DB_URL` at it (the `asyncpg` driver is bundled as of v0.3.1):
413
413
 
414
414
  ```bash
415
- pip install 'webgate[postgres]' # adds asyncpg
416
415
  export WEBGATE_DB_URL='postgresql+asyncpg://user:pass@host:5432/webgate'
417
416
  ```
418
417
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "webgate"
3
- version = "0.3.0"
3
+ version = "0.3.1"
4
4
  description = "Self-hosted web application for remote server management via SSH terminal and SFTP file browser"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -40,11 +40,9 @@ dependencies = [
40
40
  "slowapi>=0.1.9",
41
41
  "pyotp>=2.9.0",
42
42
  "qrcode[pil]>=8.2",
43
+ "asyncpg>=0.30.0",
43
44
  ]
44
45
 
45
- [project.optional-dependencies]
46
- postgres = ["asyncpg>=0.30.0"]
47
-
48
46
  [project.urls]
49
47
  Homepage = "https://github.com/kalexnolasco/webgate"
50
48
  Documentation = "https://kalexnolasco.github.io/webgate/"
@@ -48,15 +48,19 @@ async def init_db() -> None:
48
48
  dialect = engine.dialect.name # "sqlite", "postgresql", ...
49
49
  async with engine.begin() as conn:
50
50
  await conn.run_sync(Base.metadata.create_all)
51
- # Lightweight migrations for columns added after initial release
52
- for table, column, sqlite_def, pg_def in _MIGRATIONS:
53
- col_def = pg_def if dialect == "postgresql" else sqlite_def
54
- sql = f"ALTER TABLE {table} ADD COLUMN {column} {col_def}"
55
- try:
51
+ # Lightweight migrations: each in its OWN transaction. PostgreSQL aborts
52
+ # the whole transaction on any error (even one we catch), so running
53
+ # multiple ALTERs in a single txn would poison create_all on a fresh DB
54
+ # the moment the first "column already exists" fires.
55
+ for table, column, sqlite_def, pg_def in _MIGRATIONS:
56
+ col_def = pg_def if dialect == "postgresql" else sqlite_def
57
+ sql = f"ALTER TABLE {table} ADD COLUMN {column} {col_def}"
58
+ try:
59
+ async with engine.begin() as conn:
56
60
  await conn.execute(text(sql))
57
61
  logger.info("Migration applied: %s.%s", table, column)
58
- except Exception:
59
- pass # Column already exists
62
+ except Exception:
63
+ pass # Column already exists, or table not yet present on fresh DB
60
64
 
61
65
 
62
66
  async def close_db() -> None:
@@ -51,6 +51,54 @@ wheels = [
51
51
  { url = "https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708", size = 114353, upload-time = "2026-03-24T12:59:08.246Z" },
52
52
  ]
53
53
 
54
+ [[package]]
55
+ name = "asyncpg"
56
+ version = "0.31.0"
57
+ source = { registry = "https://pypi.org/simple" }
58
+ sdist = { url = "https://files.pythonhosted.org/packages/fe/cc/d18065ce2380d80b1bcce927c24a2642efd38918e33fd724bc4bca904877/asyncpg-0.31.0.tar.gz", hash = "sha256:c989386c83940bfbd787180f2b1519415e2d3d6277a70d9d0f0145ac73500735", size = 993667, upload-time = "2025-11-24T23:27:00.812Z" }
59
+ wheels = [
60
+ { url = "https://files.pythonhosted.org/packages/08/17/cc02bc49bc350623d050fa139e34ea512cd6e020562f2a7312a7bcae4bc9/asyncpg-0.31.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:eee690960e8ab85063ba93af2ce128c0f52fd655fdff9fdb1a28df01329f031d", size = 643159, upload-time = "2025-11-24T23:25:36.443Z" },
61
+ { url = "https://files.pythonhosted.org/packages/a4/62/4ded7d400a7b651adf06f49ea8f73100cca07c6df012119594d1e3447aa6/asyncpg-0.31.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2657204552b75f8288de08ca60faf4a99a65deef3a71d1467454123205a88fab", size = 638157, upload-time = "2025-11-24T23:25:37.89Z" },
62
+ { url = "https://files.pythonhosted.org/packages/d6/5b/4179538a9a72166a0bf60ad783b1ef16efb7960e4d7b9afe9f77a5551680/asyncpg-0.31.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a429e842a3a4b4ea240ea52d7fe3f82d5149853249306f7ff166cb9948faa46c", size = 2918051, upload-time = "2025-11-24T23:25:39.461Z" },
63
+ { url = "https://files.pythonhosted.org/packages/e6/35/c27719ae0536c5b6e61e4701391ffe435ef59539e9360959240d6e47c8c8/asyncpg-0.31.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c0807be46c32c963ae40d329b3a686356e417f674c976c07fa49f1b30303f109", size = 2972640, upload-time = "2025-11-24T23:25:41.512Z" },
64
+ { url = "https://files.pythonhosted.org/packages/43/f4/01ebb9207f29e645a64699b9ce0eefeff8e7a33494e1d29bb53736f7766b/asyncpg-0.31.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e5d5098f63beeae93512ee513d4c0c53dc12e9aa2b7a1af5a81cddf93fe4e4da", size = 2851050, upload-time = "2025-11-24T23:25:43.153Z" },
65
+ { url = "https://files.pythonhosted.org/packages/3e/f4/03ff1426acc87be0f4e8d40fa2bff5c3952bef0080062af9efc2212e3be8/asyncpg-0.31.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37fc6c00a814e18eef51833545d1891cac9aa69140598bb076b4cd29b3e010b9", size = 2962574, upload-time = "2025-11-24T23:25:44.942Z" },
66
+ { url = "https://files.pythonhosted.org/packages/c7/39/cc788dfca3d4060f9d93e67be396ceec458dfc429e26139059e58c2c244d/asyncpg-0.31.0-cp311-cp311-win32.whl", hash = "sha256:5a4af56edf82a701aece93190cc4e094d2df7d33f6e915c222fb09efbb5afc24", size = 521076, upload-time = "2025-11-24T23:25:46.486Z" },
67
+ { url = "https://files.pythonhosted.org/packages/28/fc/735af5384c029eb7f1ca60ccb8fa95521dbdaeef788edf4cecfc604c3cab/asyncpg-0.31.0-cp311-cp311-win_amd64.whl", hash = "sha256:480c4befbdf079c14c9ca43c8c5e1fe8b6296c96f1f927158d4f1e750aacc047", size = 584980, upload-time = "2025-11-24T23:25:47.938Z" },
68
+ { url = "https://files.pythonhosted.org/packages/2a/a6/59d0a146e61d20e18db7396583242e32e0f120693b67a8de43f1557033e2/asyncpg-0.31.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b44c31e1efc1c15188ef183f287c728e2046abb1d26af4d20858215d50d91fad", size = 662042, upload-time = "2025-11-24T23:25:49.578Z" },
69
+ { url = "https://files.pythonhosted.org/packages/36/01/ffaa189dcb63a2471720615e60185c3f6327716fdc0fc04334436fbb7c65/asyncpg-0.31.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0c89ccf741c067614c9b5fc7f1fc6f3b61ab05ae4aaa966e6fd6b93097c7d20d", size = 638504, upload-time = "2025-11-24T23:25:51.501Z" },
70
+ { url = "https://files.pythonhosted.org/packages/9f/62/3f699ba45d8bd24c5d65392190d19656d74ff0185f42e19d0bbd973bb371/asyncpg-0.31.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:12b3b2e39dc5470abd5e98c8d3373e4b1d1234d9fbdedf538798b2c13c64460a", size = 3426241, upload-time = "2025-11-24T23:25:53.278Z" },
71
+ { url = "https://files.pythonhosted.org/packages/8c/d1/a867c2150f9c6e7af6462637f613ba67f78a314b00db220cd26ff559d532/asyncpg-0.31.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:aad7a33913fb8bcb5454313377cc330fbb19a0cd5faa7272407d8a0c4257b671", size = 3520321, upload-time = "2025-11-24T23:25:54.982Z" },
72
+ { url = "https://files.pythonhosted.org/packages/7a/1a/cce4c3f246805ecd285a3591222a2611141f1669d002163abef999b60f98/asyncpg-0.31.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3df118d94f46d85b2e434fd62c84cb66d5834d5a890725fe625f498e72e4d5ec", size = 3316685, upload-time = "2025-11-24T23:25:57.43Z" },
73
+ { url = "https://files.pythonhosted.org/packages/40/ae/0fc961179e78cc579e138fad6eb580448ecae64908f95b8cb8ee2f241f67/asyncpg-0.31.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bd5b6efff3c17c3202d4b37189969acf8927438a238c6257f66be3c426beba20", size = 3471858, upload-time = "2025-11-24T23:25:59.636Z" },
74
+ { url = "https://files.pythonhosted.org/packages/52/b2/b20e09670be031afa4cbfabd645caece7f85ec62d69c312239de568e058e/asyncpg-0.31.0-cp312-cp312-win32.whl", hash = "sha256:027eaa61361ec735926566f995d959ade4796f6a49d3bde17e5134b9964f9ba8", size = 527852, upload-time = "2025-11-24T23:26:01.084Z" },
75
+ { url = "https://files.pythonhosted.org/packages/b5/f0/f2ed1de154e15b107dc692262395b3c17fc34eafe2a78fc2115931561730/asyncpg-0.31.0-cp312-cp312-win_amd64.whl", hash = "sha256:72d6bdcbc93d608a1158f17932de2321f68b1a967a13e014998db87a72ed3186", size = 597175, upload-time = "2025-11-24T23:26:02.564Z" },
76
+ { url = "https://files.pythonhosted.org/packages/95/11/97b5c2af72a5d0b9bc3fa30cd4b9ce22284a9a943a150fdc768763caf035/asyncpg-0.31.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c204fab1b91e08b0f47e90a75d1b3c62174dab21f670ad6c5d0f243a228f015b", size = 661111, upload-time = "2025-11-24T23:26:04.467Z" },
77
+ { url = "https://files.pythonhosted.org/packages/1b/71/157d611c791a5e2d0423f09f027bd499935f0906e0c2a416ce712ba51ef3/asyncpg-0.31.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:54a64f91839ba59008eccf7aad2e93d6e3de688d796f35803235ea1c4898ae1e", size = 636928, upload-time = "2025-11-24T23:26:05.944Z" },
78
+ { url = "https://files.pythonhosted.org/packages/2e/fc/9e3486fb2bbe69d4a867c0b76d68542650a7ff1574ca40e84c3111bb0c6e/asyncpg-0.31.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0e0822b1038dc7253b337b0f3f676cadc4ac31b126c5d42691c39691962e403", size = 3424067, upload-time = "2025-11-24T23:26:07.957Z" },
79
+ { url = "https://files.pythonhosted.org/packages/12/c6/8c9d076f73f07f995013c791e018a1cd5f31823c2a3187fc8581706aa00f/asyncpg-0.31.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bef056aa502ee34204c161c72ca1f3c274917596877f825968368b2c33f585f4", size = 3518156, upload-time = "2025-11-24T23:26:09.591Z" },
80
+ { url = "https://files.pythonhosted.org/packages/ae/3b/60683a0baf50fbc546499cfb53132cb6835b92b529a05f6a81471ab60d0c/asyncpg-0.31.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0bfbcc5b7ffcd9b75ab1558f00db2ae07db9c80637ad1b2469c43df79d7a5ae2", size = 3319636, upload-time = "2025-11-24T23:26:11.168Z" },
81
+ { url = "https://files.pythonhosted.org/packages/50/dc/8487df0f69bd398a61e1792b3cba0e47477f214eff085ba0efa7eac9ce87/asyncpg-0.31.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:22bc525ebbdc24d1261ecbf6f504998244d4e3be1721784b5f64664d61fbe602", size = 3472079, upload-time = "2025-11-24T23:26:13.164Z" },
82
+ { url = "https://files.pythonhosted.org/packages/13/a1/c5bbeeb8531c05c89135cb8b28575ac2fac618bcb60119ee9696c3faf71c/asyncpg-0.31.0-cp313-cp313-win32.whl", hash = "sha256:f890de5e1e4f7e14023619399a471ce4b71f5418cd67a51853b9910fdfa73696", size = 527606, upload-time = "2025-11-24T23:26:14.78Z" },
83
+ { url = "https://files.pythonhosted.org/packages/91/66/b25ccb84a246b470eb943b0107c07edcae51804912b824054b3413995a10/asyncpg-0.31.0-cp313-cp313-win_amd64.whl", hash = "sha256:dc5f2fa9916f292e5c5c8b2ac2813763bcd7f58e130055b4ad8a0531314201ab", size = 596569, upload-time = "2025-11-24T23:26:16.189Z" },
84
+ { url = "https://files.pythonhosted.org/packages/3c/36/e9450d62e84a13aea6580c83a47a437f26c7ca6fa0f0fd40b6670793ea30/asyncpg-0.31.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f6b56b91bb0ffc328c4e3ed113136cddd9deefdf5f79ab448598b9772831df44", size = 660867, upload-time = "2025-11-24T23:26:17.631Z" },
85
+ { url = "https://files.pythonhosted.org/packages/82/4b/1d0a2b33b3102d210439338e1beea616a6122267c0df459ff0265cd5807a/asyncpg-0.31.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:334dec28cf20d7f5bb9e45b39546ddf247f8042a690bff9b9573d00086e69cb5", size = 638349, upload-time = "2025-11-24T23:26:19.689Z" },
86
+ { url = "https://files.pythonhosted.org/packages/41/aa/e7f7ac9a7974f08eff9183e392b2d62516f90412686532d27e196c0f0eeb/asyncpg-0.31.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98cc158c53f46de7bb677fd20c417e264fc02b36d901cc2a43bd6cb0dc6dbfd2", size = 3410428, upload-time = "2025-11-24T23:26:21.275Z" },
87
+ { url = "https://files.pythonhosted.org/packages/6f/de/bf1b60de3dede5c2731e6788617a512bc0ebd9693eac297ee74086f101d7/asyncpg-0.31.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9322b563e2661a52e3cdbc93eed3be7748b289f792e0011cb2720d278b366ce2", size = 3471678, upload-time = "2025-11-24T23:26:23.627Z" },
88
+ { url = "https://files.pythonhosted.org/packages/46/78/fc3ade003e22d8bd53aaf8f75f4be48f0b460fa73738f0391b9c856a9147/asyncpg-0.31.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:19857a358fc811d82227449b7ca40afb46e75b33eb8897240c3839dd8b744218", size = 3313505, upload-time = "2025-11-24T23:26:25.235Z" },
89
+ { url = "https://files.pythonhosted.org/packages/bf/e9/73eb8a6789e927816f4705291be21f2225687bfa97321e40cd23055e903a/asyncpg-0.31.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ba5f8886e850882ff2c2ace5732300e99193823e8107e2c53ef01c1ebfa1e85d", size = 3434744, upload-time = "2025-11-24T23:26:26.944Z" },
90
+ { url = "https://files.pythonhosted.org/packages/08/4b/f10b880534413c65c5b5862f79b8e81553a8f364e5238832ad4c0af71b7f/asyncpg-0.31.0-cp314-cp314-win32.whl", hash = "sha256:cea3a0b2a14f95834cee29432e4ddc399b95700eb1d51bbc5bfee8f31fa07b2b", size = 532251, upload-time = "2025-11-24T23:26:28.404Z" },
91
+ { url = "https://files.pythonhosted.org/packages/d3/2d/7aa40750b7a19efa5d66e67fc06008ca0f27ba1bd082e457ad82f59aba49/asyncpg-0.31.0-cp314-cp314-win_amd64.whl", hash = "sha256:04d19392716af6b029411a0264d92093b6e5e8285ae97a39957b9a9c14ea72be", size = 604901, upload-time = "2025-11-24T23:26:30.34Z" },
92
+ { url = "https://files.pythonhosted.org/packages/ce/fe/b9dfe349b83b9dee28cc42360d2c86b2cdce4cb551a2c2d27e156bcac84d/asyncpg-0.31.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bdb957706da132e982cc6856bb2f7b740603472b54c3ebc77fe60ea3e57e1bd2", size = 702280, upload-time = "2025-11-24T23:26:32Z" },
93
+ { url = "https://files.pythonhosted.org/packages/6a/81/e6be6e37e560bd91e6c23ea8a6138a04fd057b08cf63d3c5055c98e81c1d/asyncpg-0.31.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6d11b198111a72f47154fa03b85799f9be63701e068b43f84ac25da0bda9cb31", size = 682931, upload-time = "2025-11-24T23:26:33.572Z" },
94
+ { url = "https://files.pythonhosted.org/packages/a6/45/6009040da85a1648dd5bc75b3b0a062081c483e75a1a29041ae63a0bf0dc/asyncpg-0.31.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:18c83b03bc0d1b23e6230f5bf8d4f217dc9bc08644ce0502a9d91dc9e634a9c7", size = 3581608, upload-time = "2025-11-24T23:26:35.638Z" },
95
+ { url = "https://files.pythonhosted.org/packages/7e/06/2e3d4d7608b0b2b3adbee0d0bd6a2d29ca0fc4d8a78f8277df04e2d1fd7b/asyncpg-0.31.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e009abc333464ff18b8f6fd146addffd9aaf63e79aa3bb40ab7a4c332d0c5e9e", size = 3498738, upload-time = "2025-11-24T23:26:37.275Z" },
96
+ { url = "https://files.pythonhosted.org/packages/7d/aa/7d75ede780033141c51d83577ea23236ba7d3a23593929b32b49db8ed36e/asyncpg-0.31.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3b1fbcb0e396a5ca435a8826a87e5c2c2cc0c8c68eb6fadf82168056b0e53a8c", size = 3401026, upload-time = "2025-11-24T23:26:39.423Z" },
97
+ { url = "https://files.pythonhosted.org/packages/ba/7a/15e37d45e7f7c94facc1e9148c0e455e8f33c08f0b8a0b1deb2c5171771b/asyncpg-0.31.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8df714dba348efcc162d2adf02d213e5fab1bd9f557e1305633e851a61814a7a", size = 3429426, upload-time = "2025-11-24T23:26:41.032Z" },
98
+ { url = "https://files.pythonhosted.org/packages/13/d5/71437c5f6ae5f307828710efbe62163974e71237d5d46ebd2869ea052d10/asyncpg-0.31.0-cp314-cp314t-win32.whl", hash = "sha256:1b41f1afb1033f2b44f3234993b15096ddc9cd71b21a42dbd87fc6a57b43d65d", size = 614495, upload-time = "2025-11-24T23:26:42.659Z" },
99
+ { url = "https://files.pythonhosted.org/packages/3c/d7/8fb3044eaef08a310acfe23dae9a8e2e07d305edc29a53497e52bc76eca7/asyncpg-0.31.0-cp314-cp314t-win_amd64.whl", hash = "sha256:bd4107bb7cdd0e9e65fae66a62afd3a249663b844fa34d479f6d5b3bef9c04c3", size = 706062, upload-time = "2025-11-24T23:26:44.086Z" },
100
+ ]
101
+
54
102
  [[package]]
55
103
  name = "asyncssh"
56
104
  version = "2.22.0"
@@ -1787,11 +1835,12 @@ wheels = [
1787
1835
 
1788
1836
  [[package]]
1789
1837
  name = "webgate"
1790
- version = "0.2.0"
1838
+ version = "0.3.1"
1791
1839
  source = { editable = "." }
1792
1840
  dependencies = [
1793
1841
  { name = "aiofiles" },
1794
1842
  { name = "aiosqlite" },
1843
+ { name = "asyncpg" },
1795
1844
  { name = "asyncssh" },
1796
1845
  { name = "bcrypt" },
1797
1846
  { name = "cryptography" },
@@ -1826,6 +1875,7 @@ dev = [
1826
1875
  requires-dist = [
1827
1876
  { name = "aiofiles", specifier = ">=24.1.0" },
1828
1877
  { name = "aiosqlite", specifier = ">=0.21.0" },
1878
+ { name = "asyncpg", specifier = ">=0.30.0" },
1829
1879
  { name = "asyncssh", specifier = ">=2.18.0" },
1830
1880
  { name = "bcrypt", specifier = ">=4.2.0" },
1831
1881
  { name = "cryptography", specifier = ">=44.0.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