cli: replace prompt_utils with libdib
This commit is contained in:
parent
22481da4fa
commit
d3bb47036c
@ -14,6 +14,7 @@ dependencies = [
|
||||
"flask-sqlalchemy>=3.1.1",
|
||||
"flask>=3.0.3",
|
||||
"isbnlib>=3.10.14",
|
||||
"libdib",
|
||||
"psycopg2-binary>=2.9.9",
|
||||
"requests>=2.32.3",
|
||||
"sqlalchemy>=2.0.34",
|
||||
@ -46,3 +47,6 @@ downmigrate = "alembic downgrade -1"
|
||||
# Be careful with cleanmigrations. If you run migrate a database and then
|
||||
# delete the migration file with this, there will be no easy way of downgrading
|
||||
cleanmigrations = "git clean -f worblehat/models/migrations/versions"
|
||||
|
||||
[tool.uv.sources]
|
||||
libdib = { git = "https://git.pvv.ntnu.no/Projects/libdib.git" }
|
||||
|
@ -6,6 +6,12 @@ from sqlalchemy import (
|
||||
)
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from libdib.repl import (
|
||||
NumberedCmd,
|
||||
InteractiveItemSelector,
|
||||
prompt_yes_no,
|
||||
)
|
||||
|
||||
from worblehat.services import (
|
||||
create_bookcase_item_from_isbn,
|
||||
is_valid_isbn,
|
||||
@ -13,7 +19,6 @@ from worblehat.services import (
|
||||
|
||||
from worblehat.models import *
|
||||
|
||||
from .prompt_utils import *
|
||||
from .subclis import (
|
||||
AdvancedOptionsCli,
|
||||
BookcaseItemCli,
|
||||
@ -268,4 +273,4 @@ class WorblehatCli(NumberedCmd):
|
||||
'f': do_exit,
|
||||
'doc': 'Exit',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -1,213 +0,0 @@
|
||||
from cmd import Cmd
|
||||
from datetime import datetime
|
||||
from typing import Any, Callable
|
||||
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
def prompt_yes_no(question: str, default: bool | None = None) -> bool:
|
||||
prompt = {
|
||||
None: '[y/n]',
|
||||
True: '[Y/n]',
|
||||
False: '[y/N]',
|
||||
}[default]
|
||||
|
||||
while not any([
|
||||
(answer := input(f'{question} {prompt} ').lower()) in ('y','n'),
|
||||
(default != None and answer.strip() == '')
|
||||
]):
|
||||
pass
|
||||
|
||||
return {
|
||||
'y': True,
|
||||
'n': False,
|
||||
'': default,
|
||||
}[answer]
|
||||
|
||||
|
||||
def format_date(date: datetime):
|
||||
return date.strftime("%a %b %d, %Y")
|
||||
|
||||
|
||||
class InteractiveItemSelector(Cmd):
|
||||
def __init__(
|
||||
self,
|
||||
cls: type,
|
||||
sql_session: Session,
|
||||
execute_selection: Callable[[Session, type, str], list[Any]] = lambda session, cls, arg: session.scalars(
|
||||
select(cls)
|
||||
.where(cls.name == arg),
|
||||
).all(),
|
||||
complete_selection: Callable[[Session, type, str], list[str]] = lambda session, cls, text: session.scalars(
|
||||
select(cls.name)
|
||||
.where(cls.name.ilike(f'{text}%')),
|
||||
).all(),
|
||||
default: Any | None = None,
|
||||
):
|
||||
"""
|
||||
This is a utility class for prompting the user to select an
|
||||
item from the database. The default functions assumes that
|
||||
the item has a name attribute, and that the name is unique.
|
||||
However, this can be overridden by passing in custom functions.
|
||||
"""
|
||||
|
||||
super().__init__()
|
||||
|
||||
self.cls = cls
|
||||
self.sql_session = sql_session
|
||||
self.execute_selection = execute_selection
|
||||
self.complete_selection = complete_selection
|
||||
self.default_item = default
|
||||
self.result = None
|
||||
|
||||
if default is not None:
|
||||
self.prompt = f'Select {cls.__name__} [{default.name}]> '
|
||||
else:
|
||||
self.prompt = f'Select {cls.__name__}> '
|
||||
|
||||
|
||||
def emptyline(self) -> bool:
|
||||
if self.default_item is not None:
|
||||
self.result = self.default_item
|
||||
return True
|
||||
|
||||
|
||||
def default(self, arg: str):
|
||||
result = self.execute_selection(self.sql_session, self.cls, arg)
|
||||
|
||||
if len(result) != 1:
|
||||
print(f'No such {self.cls.__name__} found: {arg}')
|
||||
return
|
||||
|
||||
self.result = result[0]
|
||||
return True
|
||||
|
||||
# TODO: Override this function to not act as an argument completer
|
||||
# but to complete the entire value name
|
||||
def completedefault(self, text: str, line: str, *_) -> list[str]:
|
||||
return []
|
||||
|
||||
def completenames(self, text: str, *_) -> list[str]:
|
||||
x = self.complete_selection(self.sql_session, self.cls, text)
|
||||
return x
|
||||
|
||||
|
||||
class NumberedCmd(Cmd):
|
||||
"""
|
||||
This is a utility class for creating a numbered command line.
|
||||
|
||||
It will automatically generate a prompt that lists all the
|
||||
available commands, and will automatically call the correct
|
||||
function based on the user input.
|
||||
|
||||
If the user input is not a number, it will call the default
|
||||
function, which can be overridden by the subclass.
|
||||
|
||||
Example:
|
||||
```
|
||||
class MyCmd(NumberedCmd):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def do_foo(self, arg: str):
|
||||
pass
|
||||
|
||||
def do_bar(self, arg: str):
|
||||
pass
|
||||
|
||||
funcs = {
|
||||
1: {
|
||||
'f': do_foo,
|
||||
'doc': 'do foo',
|
||||
},
|
||||
2: {
|
||||
'f': do_bar,
|
||||
'doc': 'do bar',
|
||||
},
|
||||
}
|
||||
```
|
||||
"""
|
||||
|
||||
|
||||
prompt_header: str | None = None
|
||||
funcs: dict[int, dict[str, str | Callable[[Any, str], bool | None]]]
|
||||
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
|
||||
def _generate_usage_list(self) -> str:
|
||||
result = ''
|
||||
for i, func in self.funcs.items():
|
||||
if i == 0:
|
||||
i = '*'
|
||||
result += f'{i}) {func["doc"]}\n'
|
||||
return result
|
||||
|
||||
|
||||
def _default(self, arg: str):
|
||||
try:
|
||||
i = int(arg)
|
||||
self.funcs[i]
|
||||
except (ValueError, KeyError):
|
||||
return
|
||||
|
||||
return self.funcs[i]['f'](self, arg)
|
||||
|
||||
|
||||
def default(self, arg: str):
|
||||
return self._default(arg)
|
||||
|
||||
|
||||
def _postcmd(self, stop: bool, _: str) -> bool:
|
||||
if not stop:
|
||||
print()
|
||||
print('-----------------')
|
||||
print()
|
||||
return stop
|
||||
|
||||
|
||||
def postcmd(self, stop: bool, line: str) -> bool:
|
||||
return self._postcmd(stop, line)
|
||||
|
||||
|
||||
@property
|
||||
def prompt(self):
|
||||
result = ''
|
||||
|
||||
if self.prompt_header != None:
|
||||
result += self.prompt_header + '\n'
|
||||
|
||||
result += self._generate_usage_list()
|
||||
|
||||
if self.lastcmd == '':
|
||||
result += f'> '
|
||||
else:
|
||||
result += f'[{self.lastcmd}]> '
|
||||
|
||||
return result
|
||||
|
||||
|
||||
class NumberedItemSelector(NumberedCmd):
|
||||
def __init__(
|
||||
self,
|
||||
items: list[Any],
|
||||
stringify: Callable[[Any], str] = lambda x: str(x),
|
||||
):
|
||||
super().__init__()
|
||||
self.items = items
|
||||
self.stringify = stringify
|
||||
self.result = None
|
||||
self.funcs = {
|
||||
i: {
|
||||
'f': self._select_item,
|
||||
'doc': self.stringify(item),
|
||||
}
|
||||
for i, item in enumerate(items, start=1)
|
||||
}
|
||||
|
||||
|
||||
def _select_item(self, *a):
|
||||
self.result = self.items[int(self.lastcmd)-1]
|
||||
return True
|
@ -1,7 +1,7 @@
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from worblehat.cli.prompt_utils import (
|
||||
from libdib.repl import (
|
||||
InteractiveItemSelector,
|
||||
NumberedCmd,
|
||||
format_date,
|
||||
@ -132,4 +132,4 @@ class AdvancedOptionsCli(NumberedCmd):
|
||||
'f': do_done,
|
||||
'doc': 'Done',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ from sqlalchemy import select
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from worblehat.cli.prompt_utils import (
|
||||
from libdib.repl import (
|
||||
InteractiveItemSelector,
|
||||
NumberedCmd,
|
||||
NumberedItemSelector,
|
||||
@ -393,4 +393,3 @@ class EditBookcaseCli(NumberedCmd):
|
||||
'doc': 'Done',
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from worblehat.cli.prompt_utils import InteractiveItemSelector
|
||||
from libdib.repl import InteractiveItemSelector
|
||||
|
||||
from worblehat.models import (
|
||||
Bookcase,
|
||||
BookcaseShelf,
|
||||
@ -42,4 +43,4 @@ def select_bookcase_shelf(
|
||||
)
|
||||
|
||||
bookcase_shelf_selector.cmdloop()
|
||||
return bookcase_shelf_selector.result
|
||||
return bookcase_shelf_selector.result
|
||||
|
@ -2,7 +2,7 @@ from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
|
||||
from worblehat.cli.prompt_utils import (
|
||||
from libdib.repl import (
|
||||
NumberedCmd,
|
||||
NumberedItemSelector,
|
||||
)
|
||||
@ -143,4 +143,4 @@ class SearchCli(NumberedCmd):
|
||||
'f': do_done,
|
||||
'doc': 'Done',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
120
uv.lock
generated
120
uv.lock
generated
@ -216,6 +216,14 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/0f/2ba5fbcd631e3e88689309dbe978c5769e883e4b84ebfe7da30b43275c5a/jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb", size = 134596 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libdib"
|
||||
version = "0.1.0"
|
||||
source = { git = "https://git.pvv.ntnu.no/Projects/libdib.git#240424b3f30f4c41d1edae72116904697b71e823" }
|
||||
dependencies = [
|
||||
{ name = "sqlalchemy" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mako"
|
||||
version = "1.3.9"
|
||||
@ -266,6 +274,28 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pastel"
|
||||
version = "0.2.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/76/f1/4594f5e0fcddb6953e5b8fe00da8c317b8b41b547e2b3ae2da7512943c62/pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d", size = 7555 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/18/a8444036c6dd65ba3624c63b734d3ba95ba63ace513078e1580590075d21/pastel-0.2.1-py2.py3-none-any.whl", hash = "sha256:4349225fcdf6c2bb34d483e523475de5bb04a5c10ef711263452cb37d7dd4364", size = 5955 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "poethepoet"
|
||||
version = "0.32.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pastel" },
|
||||
{ name = "pyyaml" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ee/c6/4bc7e21166726fc96f82f58b31fd032fdf8864d3aa17e2622578cb96c24d/poethepoet-0.32.2.tar.gz", hash = "sha256:1d68871dac1b191e27bd68fea57d0e01e9afbba3fcd01dbe6f6bc3fcb071fe4c", size = 61381 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/1f/4e7a9b6b33a085172a826d1f9d0a19a2e77982298acea13d40442f14ef28/poethepoet-0.32.2-py3-none-any.whl", hash = "sha256:97e165de8e00b07d33fd8d72896fad8b20ccafcd327b1118bb6a3da26af38d33", size = 81726 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "psycopg2-binary"
|
||||
version = "2.9.10"
|
||||
@ -297,6 +327,32 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/08/50/d13ea0a054189ae1bc21af1d85b6f8bb9bbc5572991055d70ad9006fe2d6/psycopg2_binary-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:27422aa5f11fbcd9b18da48373eb67081243662f9b46e6fd07c3eb46e4535142", size = 2569224 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyyaml"
|
||||
version = "6.0.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 },
|
||||
{ url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 },
|
||||
{ url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.32.3"
|
||||
@ -323,31 +379,31 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "sqlalchemy"
|
||||
version = "2.0.38"
|
||||
version = "2.0.39"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "greenlet", marker = "(python_full_version < '3.14' and platform_machine == 'AMD64') or (python_full_version < '3.14' and platform_machine == 'WIN32') or (python_full_version < '3.14' and platform_machine == 'aarch64') or (python_full_version < '3.14' and platform_machine == 'amd64') or (python_full_version < '3.14' and platform_machine == 'ppc64le') or (python_full_version < '3.14' and platform_machine == 'win32') or (python_full_version < '3.14' and platform_machine == 'x86_64')" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e4/08/9a90962ea72acd532bda71249a626344d855c4032603924b1b547694b837/sqlalchemy-2.0.38.tar.gz", hash = "sha256:e5a4d82bdb4bf1ac1285a68eab02d253ab73355d9f0fe725a97e1e0fa689decb", size = 9634782 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/00/8e/e77fcaa67f8b9f504b4764570191e291524575ddbfe78a90fc656d671fdc/sqlalchemy-2.0.39.tar.gz", hash = "sha256:5d2d1fe548def3267b4c70a8568f108d1fed7cbbeccb9cc166e05af2abc25c22", size = 9644602 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/f8/6d0424af1442c989b655a7b5f608bc2ae5e4f94cdf6df9f6054f629dc587/SQLAlchemy-2.0.38-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12d5b06a1f3aeccf295a5843c86835033797fea292c60e72b07bcb5d820e6dd3", size = 2104927 },
|
||||
{ url = "https://files.pythonhosted.org/packages/25/80/fc06e65fca0a19533e2bfab633a5633ed8b6ee0b9c8d580acf84609ce4da/SQLAlchemy-2.0.38-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e036549ad14f2b414c725349cce0772ea34a7ab008e9cd67f9084e4f371d1f32", size = 2095317 },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/2d/5d66605f76b8e344813237dc160a01f03b987201e974b46056a7fb94a874/SQLAlchemy-2.0.38-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee3bee874cb1fadee2ff2b79fc9fc808aa638670f28b2145074538d4a6a5028e", size = 3244735 },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/8d/b0539e8dce90861efc38fea3eefb15a5d0cfeacf818614762e77a9f192f9/SQLAlchemy-2.0.38-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e185ea07a99ce8b8edfc788c586c538c4b1351007e614ceb708fd01b095ef33e", size = 3255581 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/a5/94e1e44bf5bdffd1782807fcc072542b110b950f0be53f49e68b5f5eca1b/SQLAlchemy-2.0.38-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b79ee64d01d05a5476d5cceb3c27b5535e6bb84ee0f872ba60d9a8cd4d0e6579", size = 3190877 },
|
||||
{ url = "https://files.pythonhosted.org/packages/91/13/f08b09996dce945aec029c64f61c13b4788541ac588d9288e31e0d3d8850/SQLAlchemy-2.0.38-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:afd776cf1ebfc7f9aa42a09cf19feadb40a26366802d86c1fba080d8e5e74bdd", size = 3217485 },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/8f/8cfe2ba5ba6d8090f4de0e658330c53be6b7bf430a8df1b141c2b180dcdf/SQLAlchemy-2.0.38-cp312-cp312-win32.whl", hash = "sha256:a5645cd45f56895cfe3ca3459aed9ff2d3f9aaa29ff7edf557fa7a23515a3725", size = 2075254 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/5c/e3c77fae41862be1da966ca98eec7fbc07cdd0b00f8b3e1ef2a13eaa6cca/SQLAlchemy-2.0.38-cp312-cp312-win_amd64.whl", hash = "sha256:1052723e6cd95312f6a6eff9a279fd41bbae67633415373fdac3c430eca3425d", size = 2100865 },
|
||||
{ url = "https://files.pythonhosted.org/packages/21/77/caa875a1f5a8a8980b564cc0e6fee1bc992d62d29101252561d0a5e9719c/SQLAlchemy-2.0.38-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ecef029b69843b82048c5b347d8e6049356aa24ed644006c9a9d7098c3bd3bfd", size = 2100201 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/ec/94bb036ec78bf9a20f8010c807105da9152dd84f72e8c51681ad2f30b3fd/SQLAlchemy-2.0.38-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c8bcad7fc12f0cc5896d8e10fdf703c45bd487294a986903fe032c72201596b", size = 2090678 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/61/63ff1893f146e34d3934c0860209fdd3925c25ee064330e6c2152bacc335/SQLAlchemy-2.0.38-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a0ef3f98175d77180ffdc623d38e9f1736e8d86b6ba70bff182a7e68bed7727", size = 3177107 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a9/4f/b933bea41a602b5f274065cc824fae25780ed38664d735575192490a021b/SQLAlchemy-2.0.38-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b0ac78898c50e2574e9f938d2e5caa8fe187d7a5b69b65faa1ea4648925b096", size = 3190435 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/23/9e654b4059e385988de08c5d3b38a369ea042f4c4d7c8902376fd737096a/SQLAlchemy-2.0.38-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9eb4fa13c8c7a2404b6a8e3772c17a55b1ba18bc711e25e4d6c0c9f5f541b02a", size = 3123648 },
|
||||
{ url = "https://files.pythonhosted.org/packages/83/59/94c6d804e76ebc6412a08d2b086a8cb3e5a056cd61508e18ddaf3ec70100/SQLAlchemy-2.0.38-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5dba1cdb8f319084f5b00d41207b2079822aa8d6a4667c0f369fce85e34b0c86", size = 3151789 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/27/17f143013aabbe1256dce19061eafdce0b0142465ce32168cdb9a18c04b1/SQLAlchemy-2.0.38-cp313-cp313-win32.whl", hash = "sha256:eae27ad7580529a427cfdd52c87abb2dfb15ce2b7a3e0fc29fbb63e2ed6f8120", size = 2073023 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e2/3e/259404b03c3ed2e7eee4c179e001a07d9b61070334be91124cf4ad32eec7/SQLAlchemy-2.0.38-cp313-cp313-win_amd64.whl", hash = "sha256:b335a7c958bc945e10c522c069cd6e5804f4ff20f9a744dd38e748eb602cbbda", size = 2096908 },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/e4/592120713a314621c692211eba034d09becaf6bc8848fabc1dc2a54d8c16/SQLAlchemy-2.0.38-py3-none-any.whl", hash = "sha256:63178c675d4c80def39f1febd625a6333f44c0ba269edd8a468b156394b27753", size = 1896347 },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/86/b2cb432aeb00a1eda7ed33ce86d943c2452dc1642f3ec51bfe9eaae9604b/sqlalchemy-2.0.39-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c457a38351fb6234781d054260c60e531047e4d07beca1889b558ff73dc2014b", size = 2107210 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/b0/b2479edb3419ca763ba1b587161c292d181351a33642985506a530f9162b/sqlalchemy-2.0.39-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:018ee97c558b499b58935c5a152aeabf6d36b3d55d91656abeb6d93d663c0c4c", size = 2097599 },
|
||||
{ url = "https://files.pythonhosted.org/packages/58/5e/c5b792a4abcc71e68d44cb531c4845ac539d558975cc61db1afbc8a73c96/sqlalchemy-2.0.39-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5493a8120d6fc185f60e7254fc056a6742f1db68c0f849cfc9ab46163c21df47", size = 3247012 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e0/a8/055fa8a7c5f85e6123b7e40ec2e9e87d63c566011d599b4a5ab75e033017/sqlalchemy-2.0.39-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2cf5b5ddb69142511d5559c427ff00ec8c0919a1e6c09486e9c32636ea2b9dd", size = 3257851 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/40/aec16681e91a22ddf03dbaeb3c659bce96107c5f47d2a7c665eb7f24a014/sqlalchemy-2.0.39-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9f03143f8f851dd8de6b0c10784363712058f38209e926723c80654c1b40327a", size = 3193155 },
|
||||
{ url = "https://files.pythonhosted.org/packages/21/9d/cef697b137b9eb0b66ab8e9cf193a7c7c048da3b4bb667e5fcea4d90c7a2/sqlalchemy-2.0.39-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:06205eb98cb3dd52133ca6818bf5542397f1dd1b69f7ea28aa84413897380b06", size = 3219770 },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/05/e109ca7dde837d8f2f1b235357e4e607f8af81ad8bc29c230fed8245687d/sqlalchemy-2.0.39-cp312-cp312-win32.whl", hash = "sha256:7f5243357e6da9a90c56282f64b50d29cba2ee1f745381174caacc50d501b109", size = 2077567 },
|
||||
{ url = "https://files.pythonhosted.org/packages/97/c6/25ca068e38c29ed6be0fde2521888f19da923dbd58f5ff16af1b73ec9b58/sqlalchemy-2.0.39-cp312-cp312-win_amd64.whl", hash = "sha256:2ed107331d188a286611cea9022de0afc437dd2d3c168e368169f27aa0f61338", size = 2103136 },
|
||||
{ url = "https://files.pythonhosted.org/packages/32/47/55778362642344324a900b6b2b1b26f7f02225b374eb93adc4a363a2d8ae/sqlalchemy-2.0.39-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fe193d3ae297c423e0e567e240b4324d6b6c280a048e64c77a3ea6886cc2aa87", size = 2102484 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1b/e1/f5f26f67d095f408138f0fb2c37f827f3d458f2ae51881546045e7e55566/sqlalchemy-2.0.39-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:79f4f502125a41b1b3b34449e747a6abfd52a709d539ea7769101696bdca6716", size = 2092955 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c5/c2/0db0022fc729a54fc7aef90a3457bf20144a681baef82f7357832b44c566/sqlalchemy-2.0.39-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a10ca7f8a1ea0fd5630f02feb055b0f5cdfcd07bb3715fc1b6f8cb72bf114e4", size = 3179367 },
|
||||
{ url = "https://files.pythonhosted.org/packages/33/b7/f33743d87d0b4e7a1f12e1631a4b9a29a8d0d7c0ff9b8c896d0bf897fb60/sqlalchemy-2.0.39-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6b0a1c7ed54a5361aaebb910c1fa864bae34273662bb4ff788a527eafd6e14d", size = 3192705 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/74/6814f31719109c973ddccc87bdfc2c2a9bc013bec64a375599dc5269a310/sqlalchemy-2.0.39-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:52607d0ebea43cf214e2ee84a6a76bc774176f97c5a774ce33277514875a718e", size = 3125927 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e8/6b/18f476f4baaa9a0e2fbc6808d8f958a5268b637c8eccff497bf96908d528/sqlalchemy-2.0.39-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c08a972cbac2a14810463aec3a47ff218bb00c1a607e6689b531a7c589c50723", size = 3154055 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/60/76714cecb528da46bc53a0dd36d1ccef2f74ef25448b630a0a760ad07bdb/sqlalchemy-2.0.39-cp313-cp313-win32.whl", hash = "sha256:23c5aa33c01bd898f879db158537d7e7568b503b15aad60ea0c8da8109adf3e7", size = 2075315 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5b/7c/76828886d913700548bac5851eefa5b2c0251ebc37921fe476b93ce81b50/sqlalchemy-2.0.39-cp313-cp313-win_amd64.whl", hash = "sha256:4dabd775fd66cf17f31f8625fc0e4cfc5765f7982f94dc09b9e5868182cb71c0", size = 2099175 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/0f/d69904cb7d17e65c65713303a244ec91fd3c96677baf1d6331457fd47e16/sqlalchemy-2.0.39-py3-none-any.whl", hash = "sha256:a1c6b0a5e3e326a466d809b651c63f278b1256146a377a528b6938a279da334f", size = 1898621 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -392,23 +448,37 @@ dependencies = [
|
||||
{ name = "flask-admin" },
|
||||
{ name = "flask-sqlalchemy" },
|
||||
{ name = "isbnlib" },
|
||||
{ name = "libdib" },
|
||||
{ name = "psycopg2-binary" },
|
||||
{ name = "requests" },
|
||||
{ name = "sqlalchemy" },
|
||||
]
|
||||
|
||||
[package.dev-dependencies]
|
||||
dev = [
|
||||
{ name = "poethepoet" },
|
||||
{ name = "werkzeug" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "alembic", specifier = ">=1.14.1" },
|
||||
{ name = "beautifulsoup4", specifier = ">=4.13.3" },
|
||||
{ name = "click", specifier = ">=8.1.8" },
|
||||
{ name = "flask", specifier = ">=3.1.0" },
|
||||
{ name = "alembic", specifier = ">=1.13.3" },
|
||||
{ name = "beautifulsoup4", specifier = ">=4.12.3" },
|
||||
{ name = "click", specifier = ">=8.1.7" },
|
||||
{ name = "flask", specifier = ">=3.0.3" },
|
||||
{ name = "flask-admin", specifier = ">=1.6.1" },
|
||||
{ name = "flask-sqlalchemy", specifier = ">=3.1.1" },
|
||||
{ name = "isbnlib", specifier = ">=3.10.14" },
|
||||
{ name = "psycopg2-binary", specifier = ">=2.9.10" },
|
||||
{ name = "libdib", git = "https://git.pvv.ntnu.no/Projects/libdib.git" },
|
||||
{ name = "psycopg2-binary", specifier = ">=2.9.9" },
|
||||
{ name = "requests", specifier = ">=2.32.3" },
|
||||
{ name = "sqlalchemy", specifier = ">=2.0.38" },
|
||||
{ name = "sqlalchemy", specifier = ">=2.0.34" },
|
||||
]
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
dev = [
|
||||
{ name = "poethepoet" },
|
||||
{ name = "werkzeug" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
Loading…
x
Reference in New Issue
Block a user