diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 5dbca7c..c0df8fa 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -1,7 +1,27 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later --- name: Lint -on: [push, pull_request, workflow_dispatch] +on: + pull_request: + paths: + - .github/workflows/lint.yaml + - poetry.lock + - pyproject.toml + - setup.cfg + - snagctl/**/*.py + - snagd/**/*.py + - snagd/db/alembic/script.py.mako + push: + paths: + - .github/workflows/lint.yaml + - poetry.lock + - pyproject.toml + - setup.cfg + - snagctl/**/*.py + - snagd/**/*.py + - snagd/db/alembic/script.py.mako + workflow_dispatch: jobs: test: @@ -16,7 +36,6 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 with: python-version: "3.10" @@ -26,11 +45,11 @@ jobs: sudo apt-get update sudo apt-get install -y git libpq-dev libsqlite3-dev python3-dev python3-wheel + # FIXME: poetry>=1.2,<2 once released - name: Install python package dependencies run: | - pip install poetry tox - poetry install + pip install poetry==1.2.0b1 + poetry install --only tox - name: Run ${{ matrix.name }} - run: | - poetry run tox -e ${{ matrix.name }} + run: poetry run tox -e ${{ matrix.name }} diff --git a/Dockerfile b/Dockerfile index f0433b3..d672b4e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,25 +5,29 @@ ENV PYTHONDONTWRITEBYTECODE="true" \ PYTHONPYCACHEPREFIX="/tmp" \ PYTHONUNBUFFERED="true" RUN dnf --refresh -y upgrade && \ - dnf -y install libpq openssl poetry sqlite && \ + dnf -y install libpq openssl sqlite && \ dnf -y autoremove && \ - dnf clean all && \ - ln -sf /usr/share/zoneinfo/UTC /etc/localtime + dnf clean all +RUN ln -sf /usr/share/zoneinfo/UTC /etc/localtime FROM core AS build RUN dnf --refresh -y install \ automake cargo cmake gcc-c++ git meson ninja-build patchelf rust \ - libpq-devel openssl-devel python3-devel python3-wheel sqlite-devel + libpq-devel openssl-devel python3-devel sqlite-devel COPY . /opt/snagem -WORKDIR /opt/snagem RUN python3 -m venv --upgrade-deps /opt/snagem/.venv ENV PATH="/opt/snagem/.venv/bin:$PATH" -RUN poetry install --no-dev +# FIXME: poetry>=1.2,<2 once released +RUN pip install poetry==1.2.0b1 +WORKDIR /opt/snagem +FROM build as build-release +RUN poetry install --only default + FROM core AS release -COPY --from=build --chown=root:root /opt/snagem/.venv /opt/snagem/.venv +COPY --from=build-release --chown=root:root /opt/snagem/.venv /opt/snagem/.venv ENV PATH="/opt/snagem/.venv/bin:$PATH" CMD ["snagd"] @@ -31,7 +35,6 @@ CMD ["snagd"] FROM build as build-devel RUN poetry install - FROM core as devel COPY --from=build-devel --chown=root:root /opt/snagem /opt/snagem ENV PATH="/opt/snagem/.venv/bin:$PATH" diff --git a/README.md b/README.md index 4b77596..2767a52 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -`snagem` provides a simple way to track, retrieve, and manage content from sites supported by -[youtube-dl](https://github.com/ytdl-org/youtube-dl) so it may be enjoyed on your schedule. +`snagem` provides a simple way to track, retrieve and manage content so it may be enjoyed on your +schedule. See the following for subcomponent documentation: * [snagctl](./snagctl/README.md) @@ -8,12 +8,14 @@ See the following for subcomponent documentation: Quickstart --- -This section outlines how to quickly run Snagem. +This section outlines how to quickly run snagem using Fedora 35 as an example. ### Local ```sh -$ sudo dnf --refresh -y install libpq-devel git poetry python3-devel sqlite-devel -$ poetry install --no-dev +$ sudo dnf --refresh -y install git libpq-devel python3-devel sqlite-devel +# FIXME: poetry>=1.2,<2 once released +$ pip install poetry==1.2.0b1 +$ poetry install --only default $ poetry run snagd INFO: Started server process [$PID] INFO: Waiting for application startup. @@ -31,14 +33,3 @@ INFO: Waiting for application startup. INFO: Application startup complete. INFO: Uvicorn running on http://127.0.0.1:5050 (Press CTRL+C to quit) ``` - - -Contributing ---- -### Getting Started -* https://fastapi.tiangolo.com/tutorial/ -* https://docs.sqlalchemy.org/en/20/tutorial/index.html -* https://pydantic-docs.helpmanual.io/ -* https://alembic.sqlalchemy.org/en/latest/tutorial.html -* https://docs.celeryproject.org/en/stable/getting-started/index.html -* https://docs.celeryproject.org/projects/kombu/en/stable/introduction.html diff --git a/poetry.lock b/poetry.lock index 6572e97..e75c94a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -80,17 +80,6 @@ docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] -[[package]] -name = "backports.zoneinfo" -version = "0.2.1" -description = "Backport of the standard library zoneinfo module" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.extras] -tzdata = ["tzdata"] - [[package]] name = "bandit" version = "1.7.4" @@ -165,6 +154,7 @@ click-plugins = ">=1.1.1" click-repl = ">=0.2.0" kombu = ">=5.2.3,<6.0" pytz = ">=2021.3" +setuptools = ">=59.1.1,<59.7.0" vine = ">=5.0.0,<6.0" [package.extras] @@ -768,26 +758,13 @@ python-versions = ">=3.6.2" wcwidth = "*" [[package]] -name = "psycopg" -version = "3.0.10" -description = "PostgreSQL database adapter for Python" +name = "psycopg2" +version = "2.9.3" +description = "psycopg2 - Python-PostgreSQL Database Adapter" category = "main" optional = false python-versions = ">=3.6" -[package.dependencies] -"backports.zoneinfo" = {version = ">=0.2.0", markers = "python_version < \"3.9\""} -typing-extensions = {version = ">=3.10", markers = "python_version < \"3.8\""} -tzdata = {version = "*", markers = "sys_platform == \"win32\""} - -[package.extras] -binary = ["psycopg-binary (==3.0.10)"] -c = ["psycopg-c (==3.0.10)"] -dev = ["black (>=21.12b0)", "dnspython (>=2.1)", "flake8 (>=4.0)", "mypy (>=0.920,!=0.930,!=0.931)", "types-setuptools (>=57.4)", "wheel (>=0.37)"] -docs = ["Sphinx (>=4.2)", "furo (==2021.11.23)", "sphinx-autobuild (>=2021.3.14)", "sphinx-autodoc-typehints (>=1.12)", "dnspython (>=2.1)", "shapely (>=1.7)"] -pool = ["psycopg-pool"] -test = ["mypy (>=0.920,!=0.930,!=0.931)", "pproxy (>=2.7)", "pytest (>=6.2.5)", "pytest-asyncio (>=0.16,<0.17)", "pytest-cov (>=3.0)", "pytest-randomly (>=3.10)"] - [[package]] name = "py" version = "1.11.0" @@ -934,7 +911,7 @@ python-versions = "*" [[package]] name = "pytest" -version = "7.1.0" +version = "7.1.1" description = "pytest: simple powerful testing with Python" category = "dev" optional = false @@ -1012,6 +989,7 @@ pydocstyle = {version = ">=2.0.0", optional = true, markers = "extra == \"pydocs pyflakes = {version = ">=2.4.0,<2.5.0", optional = true, markers = "extra == \"pyflakes\""} python-lsp-jsonrpc = ">=1.0.0" rope = {version = ">0.10.5", optional = true, markers = "extra == \"rope\""} +setuptools = ">=39.0.0" ujson = ">=3.0.0" [package.extras] @@ -1100,6 +1078,18 @@ python-versions = "*" [package.extras] dev = ["build", "pytest", "pytest-timeout"] +[[package]] +name = "setuptools" +version = "59.6.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "sphinx-inline-tabs", "sphinxcontrib-towncrier", "furo"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "mock", "flake8-2020", "virtualenv (>=13.0.0)", "pytest-virtualenv (>=1.2.7)", "wheel", "paver", "pip (>=19.1)", "jaraco.envs (>=2.2)", "pytest-xdist", "sphinx", "jaraco.path (>=3.2.0)", "pytest-black (>=0.3.7)", "pytest-mypy"] + [[package]] name = "six" version = "1.16.0" @@ -1133,46 +1123,48 @@ optional = false python-versions = "*" [[package]] -name = "SQLAlchemy" -version = "2.0.0b1.dev0dev" +name = "sqlalchemy" +version = "1.4.32" description = "Database Abstraction Library" category = "main" optional = false -python-versions = ">=3.7" -develop = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" [package.dependencies] -greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""} +greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} -typing-extensions = ">=4" [package.extras] aiomysql = ["greenlet (!=0.4.17)", "aiomysql"] -aiosqlite = ["greenlet (!=0.4.17)", "aiosqlite", "typing-extensions (!=3.10.0.1)"] +aiosqlite = ["typing_extensions (!=3.10.0.1)", "greenlet (!=0.4.17)", "aiosqlite"] asyncio = ["greenlet (!=0.4.17)"] asyncmy = ["greenlet (!=0.4.17)", "asyncmy (>=0.2.3)"] mariadb_connector = ["mariadb (>=1.0.1)"] mssql = ["pyodbc"] mssql_pymssql = ["pymssql"] mssql_pyodbc = ["pyodbc"] -mypy = ["mypy (>=0.910)", "sqlalchemy2-stubs"] -mysql = ["mysqlclient (>=1.4.0)"] +mypy = ["sqlalchemy2-stubs", "mypy (>=0.910)"] +mysql = ["mysqlclient (>=1.4.0,<2)", "mysqlclient (>=1.4.0)"] mysql_connector = ["mysql-connector-python"] -oracle = ["cx-oracle (>=7)"] +oracle = ["cx_oracle (>=7,<8)", "cx_oracle (>=7)"] postgresql = ["psycopg2 (>=2.7)"] postgresql_asyncpg = ["greenlet (!=0.4.17)", "asyncpg"] postgresql_pg8000 = ["pg8000 (>=1.16.6)"] -postgresql_psycopg = ["psycopg (>=3.0.7)"] postgresql_psycopg2binary = ["psycopg2-binary"] postgresql_psycopg2cffi = ["psycopg2cffi"] -pymysql = ["pymysql"] +pymysql = ["pymysql (<1)", "pymysql"] sqlcipher = ["sqlcipher3-binary"] -[package.source] -type = "git" -url = "https://github.com/sqlalchemy/sqlalchemy" -reference = "main" -resolved_reference = "6acf5d2fca4a988a77481b82662174e8015a6b37" +[[package]] +name = "sqlalchemy2-stubs" +version = "0.0.2a20" +description = "Typing Stubs for SQLAlchemy 1.4" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +typing-extensions = ">=3.7.4" [[package]] name = "starlette" @@ -1338,7 +1330,7 @@ python-versions = "*" [[package]] name = "types-requests" -version = "2.27.13" +version = "2.27.14" description = "Typing stubs for requests" category = "dev" optional = false @@ -1363,14 +1355,6 @@ category = "main" optional = false python-versions = ">=3.6" -[[package]] -name = "tzdata" -version = "2021.5" -description = "Provider of IANA time zone data" -category = "main" -optional = false -python-versions = ">=2" - [[package]] name = "ujson" version = "5.1.0" @@ -1419,7 +1403,7 @@ python-versions = ">=3.6" [[package]] name = "virtualenv" -version = "20.13.3" +version = "20.13.4" description = "Virtual Python Environment builder" category = "dev" optional = false @@ -1480,6 +1464,9 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[package.dependencies] +setuptools = "*" + [package.extras] docs = ["sphinx", "repoze.sphinx.autointerface"] test = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] @@ -1488,7 +1475,7 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "e6ab1136d820ee9486d0fdb8032f4d07d1577dcaa10c788b105d679484145639" +content-hash = "90569489d3cdba1ccca8d57e007bef99b72dfb87725ce18072630d063b1f33f7" [metadata.files] alembic = [ @@ -1515,24 +1502,6 @@ attrs = [ {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, ] -"backports.zoneinfo" = [ - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win32.whl", hash = "sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win32.whl", hash = "sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-win32.whl", hash = "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6"}, - {file = "backports.zoneinfo-0.2.1.tar.gz", hash = "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2"}, -] bandit = [ {file = "bandit-1.7.4-py3-none-any.whl", hash = "sha256:412d3f259dab4077d0e7f0c11f50f650cc7d10db905d98f6520a95a18049658a"}, {file = "bandit-1.7.4.tar.gz", hash = "sha256:2d63a8c573417bae338962d4b9b06fbc6080f74ecd955a092849e1e65c717bd2"}, @@ -2005,9 +1974,18 @@ prompt-toolkit = [ {file = "prompt_toolkit-3.0.28-py3-none-any.whl", hash = "sha256:30129d870dcb0b3b6a53efdc9d0a83ea96162ffd28ffe077e94215b233dc670c"}, {file = "prompt_toolkit-3.0.28.tar.gz", hash = "sha256:9f1cd16b1e86c2968f2519d7fb31dd9d669916f515612c269d14e9ed52b51650"}, ] -psycopg = [ - {file = "psycopg-3.0.10-py3-none-any.whl", hash = "sha256:8cf07019035f4933c522ccdae1954f458743a98a43aa3a731937869fe3857eaa"}, - {file = "psycopg-3.0.10.tar.gz", hash = "sha256:9c2ba4b3253af8cd1a31ba365cd8bfae7818cc917e409930abc5571ba66c12d8"}, +psycopg2 = [ + {file = "psycopg2-2.9.3-cp310-cp310-win32.whl", hash = "sha256:083707a696e5e1c330af2508d8fab36f9700b26621ccbcb538abe22e15485362"}, + {file = "psycopg2-2.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:d3ca6421b942f60c008f81a3541e8faf6865a28d5a9b48544b0ee4f40cac7fca"}, + {file = "psycopg2-2.9.3-cp36-cp36m-win32.whl", hash = "sha256:9572e08b50aed176ef6d66f15a21d823bb6f6d23152d35e8451d7d2d18fdac56"}, + {file = "psycopg2-2.9.3-cp36-cp36m-win_amd64.whl", hash = "sha256:a81e3866f99382dfe8c15a151f1ca5fde5815fde879348fe5a9884a7c092a305"}, + {file = "psycopg2-2.9.3-cp37-cp37m-win32.whl", hash = "sha256:cb10d44e6694d763fa1078a26f7f6137d69f555a78ec85dc2ef716c37447e4b2"}, + {file = "psycopg2-2.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:4295093a6ae3434d33ec6baab4ca5512a5082cc43c0505293087b8a46d108461"}, + {file = "psycopg2-2.9.3-cp38-cp38-win32.whl", hash = "sha256:34b33e0162cfcaad151f249c2649fd1030010c16f4bbc40a604c1cb77173dcf7"}, + {file = "psycopg2-2.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:0762c27d018edbcb2d34d51596e4346c983bd27c330218c56c4dc25ef7e819bf"}, + {file = "psycopg2-2.9.3-cp39-cp39-win32.whl", hash = "sha256:8cf3878353cc04b053822896bc4922b194792df9df2f1ad8da01fb3043602126"}, + {file = "psycopg2-2.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:06f32425949bd5fe8f625c49f17ebb9784e1e4fe928b7cce72edc36fb68e4c0c"}, + {file = "psycopg2-2.9.3.tar.gz", hash = "sha256:8e841d1bf3434da985cc5ef13e6f75c8981ced601fd70cc6bf33351b91562981"}, ] py = [ {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, @@ -2095,8 +2073,8 @@ pyreadline3 = [ {file = "pyreadline3-3.4.1.tar.gz", hash = "sha256:6f3d1f7b8a31ba32b73917cefc1f28cc660562f39aea8646d30bd6eff21f7bae"}, ] pytest = [ - {file = "pytest-7.1.0-py3-none-any.whl", hash = "sha256:b555252a95bbb2a37a97b5ac2eb050c436f7989993565f5e0c9128fcaacadd0e"}, - {file = "pytest-7.1.0.tar.gz", hash = "sha256:f1089d218cfcc63a212c42896f1b7fbf096874d045e1988186861a1a87d27b47"}, + {file = "pytest-7.1.1-py3-none-any.whl", hash = "sha256:92f723789a8fdd7180b6b06483874feca4c48a5c76968e03bb3e7f806a1869ea"}, + {file = "pytest-7.1.1.tar.gz", hash = "sha256:841132caef6b1ad17a9afde46dc4f6cfa59a05f9555aae5151f73bdf2820ca63"}, ] python-dateutil = [ {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, @@ -2168,6 +2146,10 @@ rope = [ {file = "rope-0.23.0-py3-none-any.whl", hash = "sha256:edf2ed3c9b35a8814752ffd3ea55b293c791e5087e252461de898e953cf9c146"}, {file = "rope-0.23.0.tar.gz", hash = "sha256:f87662c565086d660fc855cc07f37820267876634c3e9e51bddb32ff51547268"}, ] +setuptools = [ + {file = "setuptools-59.6.0-py3-none-any.whl", hash = "sha256:4ce92f1e1f8f01233ee9952c04f6b81d1e02939d6e1b488428154974a4d0783e"}, + {file = "setuptools-59.6.0.tar.gz", hash = "sha256:22c7348c6d2976a52632c67f7ab0cdf40147db7789f9aed18734643fe9cf3373"}, +] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, @@ -2184,7 +2166,47 @@ snowballstemmer = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] -SQLAlchemy = [] +sqlalchemy = [ + {file = "SQLAlchemy-1.4.32-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:4b2bcab3a914715d332ca783e9bda13bc570d8b9ef087563210ba63082c18c16"}, + {file = "SQLAlchemy-1.4.32-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:159c2f69dd6efd28e894f261ffca1100690f28210f34cfcd70b895e0ea7a64f3"}, + {file = "SQLAlchemy-1.4.32-cp27-cp27m-win_amd64.whl", hash = "sha256:d7e483f4791fbda60e23926b098702340504f7684ce7e1fd2c1bf02029288423"}, + {file = "SQLAlchemy-1.4.32-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:4aa96e957141006181ca58e792e900ee511085b8dae06c2d08c00f108280fb8a"}, + {file = "SQLAlchemy-1.4.32-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:576684771456d02e24078047c2567025f2011977aa342063468577d94e194b00"}, + {file = "SQLAlchemy-1.4.32-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fff677fa4522dafb5a5e2c0cf909790d5d367326321aeabc0dffc9047cb235bd"}, + {file = "SQLAlchemy-1.4.32-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8679f9aba5ac22e7bce54ccd8a77641d3aea3e2d96e73e4356c887ebf8ff1082"}, + {file = "SQLAlchemy-1.4.32-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7046f7aa2db445daccc8424f50b47a66c4039c9f058246b43796aa818f8b751"}, + {file = "SQLAlchemy-1.4.32-cp310-cp310-win32.whl", hash = "sha256:bedd89c34ab62565d44745212814e4b57ef1c24ad4af9b29c504ce40f0dc6558"}, + {file = "SQLAlchemy-1.4.32-cp310-cp310-win_amd64.whl", hash = "sha256:199dc6d0068753b6a8c0bd3aceb86a3e782df118260ebc1fa981ea31ee054674"}, + {file = "SQLAlchemy-1.4.32-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:8e1e5d96b744a4f91163290b01045430f3f32579e46d87282449e5b14d27d4ac"}, + {file = "SQLAlchemy-1.4.32-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edfcf93fd92e2f9eef640b3a7a40db20fe3c1d7c2c74faa41424c63dead61b76"}, + {file = "SQLAlchemy-1.4.32-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:04164e0063feb7aedd9d073db0fd496edb244be40d46ea1f0d8990815e4b8c34"}, + {file = "SQLAlchemy-1.4.32-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ba59761c19b800bc2e1c9324da04d35ef51e4ee9621ff37534bc2290d258f71"}, + {file = "SQLAlchemy-1.4.32-cp36-cp36m-win32.whl", hash = "sha256:708973b5d9e1e441188124aaf13c121e5b03b6054c2df59b32219175a25aa13e"}, + {file = "SQLAlchemy-1.4.32-cp36-cp36m-win_amd64.whl", hash = "sha256:316270e5867566376e69a0ac738b863d41396e2b63274616817e1d34156dff0e"}, + {file = "SQLAlchemy-1.4.32-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:9a0195af6b9050c9322a97cf07514f66fe511968e623ca87b2df5e3cf6349615"}, + {file = "SQLAlchemy-1.4.32-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7e4a3c0c3c596296b37f8427c467c8e4336dc8d50f8ed38042e8ba79507b2c9"}, + {file = "SQLAlchemy-1.4.32-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bca714d831e5b8860c3ab134c93aec63d1a4f493bed20084f54e3ce9f0a3bf99"}, + {file = "SQLAlchemy-1.4.32-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9a680d9665f88346ed339888781f5236347933906c5a56348abb8261282ec48"}, + {file = "SQLAlchemy-1.4.32-cp37-cp37m-win32.whl", hash = "sha256:9cb5698c896fa72f88e7ef04ef62572faf56809093180771d9be8d9f2e264a13"}, + {file = "SQLAlchemy-1.4.32-cp37-cp37m-win_amd64.whl", hash = "sha256:8b9a395122770a6f08ebfd0321546d7379f43505882c7419d7886856a07caa13"}, + {file = "SQLAlchemy-1.4.32-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:3f88a4ee192142eeed3fe173f673ea6ab1f5a863810a9d85dbf6c67a9bd08f97"}, + {file = "SQLAlchemy-1.4.32-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd93162615870c976dba43963a24bb418b28448fef584f30755990c134a06a55"}, + {file = "SQLAlchemy-1.4.32-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5a2e73508f939175363d8a4be9dcdc84cf16a92578d7fa86e6e4ca0e6b3667b2"}, + {file = "SQLAlchemy-1.4.32-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfec934aac7f9fa95fc82147a4ba5db0a8bdc4ebf1e33b585ab8860beb10232f"}, + {file = "SQLAlchemy-1.4.32-cp38-cp38-win32.whl", hash = "sha256:bb42f9b259c33662c6a9b866012f6908a91731a419e69304e1261ba3ab87b8d1"}, + {file = "SQLAlchemy-1.4.32-cp38-cp38-win_amd64.whl", hash = "sha256:7ff72b3cc9242d1a1c9b84bd945907bf174d74fc2519efe6184d6390a8df478b"}, + {file = "SQLAlchemy-1.4.32-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:5dc9801ae9884e822ba942ca493642fb50f049c06b6dbe3178691fce48ceb089"}, + {file = "SQLAlchemy-1.4.32-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4607d2d16330757818c9d6fba322c2e80b4b112ff24295d1343a80b876eb0ed"}, + {file = "SQLAlchemy-1.4.32-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:20e9eba7fd86ef52e0df25bea83b8b518dfdf0bce09b336cfe51671f52aaaa3f"}, + {file = "SQLAlchemy-1.4.32-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:290cbdf19129ae520d4bdce392648c6fcdbee763bc8f750b53a5ab51880cb9c9"}, + {file = "SQLAlchemy-1.4.32-cp39-cp39-win32.whl", hash = "sha256:1bbac3e8293b34c4403d297e21e8f10d2a57756b75cff101dc62186adec725f5"}, + {file = "SQLAlchemy-1.4.32-cp39-cp39-win_amd64.whl", hash = "sha256:b3f1d9b3aa09ab9adc7f8c4b40fc3e081eb903054c9a6f9ae1633fe15ae503b4"}, + {file = "SQLAlchemy-1.4.32.tar.gz", hash = "sha256:6fdd2dc5931daab778c2b65b03df6ae68376e028a3098eb624d0909d999885bc"}, +] +sqlalchemy2-stubs = [ + {file = "sqlalchemy2-stubs-0.0.2a20.tar.gz", hash = "sha256:3e96a5bb7d46a368c780ba57dcf2afbe2d3efdd75f7724ae7a859df0b0625f38"}, + {file = "sqlalchemy2_stubs-0.0.2a20-py3-none-any.whl", hash = "sha256:da31d0e30a2af2e5ad83dbce5738543a9f488089774f506de5ec7d28d425a202"}, +] starlette = [ {file = "starlette-0.17.1-py3-none-any.whl", hash = "sha256:26a18cbda5e6b651c964c12c88b36d9898481cd428ed6e063f5f29c418f73050"}, {file = "starlette-0.17.1.tar.gz", hash = "sha256:57eab3cc975a28af62f6faec94d355a410634940f10b30d68d31cb5ec1b44ae8"}, @@ -2272,8 +2294,8 @@ types-redis = [ {file = "types_redis-4.1.18-py3-none-any.whl", hash = "sha256:93bc85db6fb4634e85eff8b64cb662d47a55141b532085f4a99c70b174e65e8d"}, ] types-requests = [ - {file = "types-requests-2.27.13.tar.gz", hash = "sha256:cf0646031dd6307113b37814f743c04f0707a3357378c2bb1326f848412f5ba9"}, - {file = "types_requests-2.27.13-py3-none-any.whl", hash = "sha256:5d6f77f3c7565659bdb7b7bce1d33d1abb7d0b056138cac714860e13da2f19df"}, + {file = "types-requests-2.27.14.tar.gz", hash = "sha256:04579ee164f7c2659be46950e3c2f8d51a081ad252ef1b01d4b12faba5c3810b"}, + {file = "types_requests-2.27.14-py3-none-any.whl", hash = "sha256:c01838abfe3e8a83ba68346cd373afff97594c19c15c922ddee4a0e80ba7e329"}, ] types-urllib3 = [ {file = "types-urllib3-1.26.11.tar.gz", hash = "sha256:24d64e441168851eb05f1d022de18ae31558f5649c8f1117e384c2e85e31315b"}, @@ -2283,10 +2305,6 @@ typing-extensions = [ {file = "typing_extensions-4.1.1-py3-none-any.whl", hash = "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2"}, {file = "typing_extensions-4.1.1.tar.gz", hash = "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42"}, ] -tzdata = [ - {file = "tzdata-2021.5-py2.py3-none-any.whl", hash = "sha256:3eee491e22ebfe1e5cfcc97a4137cd70f092ce59144d81f8924a844de05ba8f5"}, - {file = "tzdata-2021.5.tar.gz", hash = "sha256:68dbe41afd01b867894bbdfd54fa03f468cfa4f0086bfb4adcd8de8f24f3ee21"}, -] ujson = [ {file = "ujson-5.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:644552d1e89983c08d0c24358fbcb5829ae5b5deee9d876e16d20085cfa7dc81"}, {file = "ujson-5.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0cae4a9c141856f7ad1a79c17ff1aaebf7fd8faa2f2c2614c37d6f82ed261d96"}, @@ -2352,8 +2370,8 @@ vine = [ {file = "vine-5.0.0.tar.gz", hash = "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e"}, ] virtualenv = [ - {file = "virtualenv-20.13.3-py2.py3-none-any.whl", hash = "sha256:dd448d1ded9f14d1a4bfa6bfc0c5b96ae3be3f2d6c6c159b23ddcfd701baa021"}, - {file = "virtualenv-20.13.3.tar.gz", hash = "sha256:e9dd1a1359d70137559034c0f5433b34caf504af2dc756367be86a5a32967134"}, + {file = "virtualenv-20.13.4-py2.py3-none-any.whl", hash = "sha256:c3e01300fb8495bc00ed70741f5271fc95fed067eb7106297be73d30879af60c"}, + {file = "virtualenv-20.13.4.tar.gz", hash = "sha256:ce8901d3bbf3b90393498187f2d56797a8a452fb2d0d7efc6fd837554d6f679c"}, ] wcwidth = [ {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, diff --git a/pyproject.toml b/pyproject.toml index 1d822ae..a615484 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,12 +2,12 @@ [build-system] build-backend = "poetry.core.masonry.api" -requires = ["poetry-core>=1.0.8"] +requires = ["poetry-core==1.1.0a7", "wheel>=0.36.2"] [tool.poetry] authors = ["Johnathan C. Maudlin "] description = "" -license = "MIT" +license = "AGPL-3.0-or-later" name = "snagem" packages = [{ include = "snagctl" }, { include = "snagd" }] readme = "README.md" @@ -29,33 +29,46 @@ itsdangerous = "^2.1.0" jinja2 = "^3.0.3" kombu = "^5.2.4" orjson = "^3.6.7" -psycopg = "^3.0.10" pydantic = "^1.8.2" python-dateutil = "2.8.2" python-multipart = "0.0.5" pyyaml = "^6.0" redis = "^4.1.4" requests = "^2.27.1" -sqlalchemy = { git = "https://github.com/sqlalchemy/sqlalchemy", branch = "main" } uvicorn = "^0.17.5" youtube_dl = "*" -[tool.poetry.dev-dependencies] +# FIXME: https://github.com/pypa/setuptools/pull/2872 +# FIXME: When resolved, remember to purge sqlalchemy types as they aren't needed in v2 +psycopg2 = "^2.9.3" +sqlalchemy = "^1.4.32" +#psycopg = "^3.0.10" +#sqlalchemy = { git = "https://github.com/sqlalchemy/sqlalchemy", rev = "c2fe4a2" } + +[tool.poetry.group.bandit.dependencies] bandit = "^1.7.0" -black = "^22.1.0" +toml = "*" + +[tool.poetry.group.coverage.dependencies] coverage = "^6.3.1" + +[tool.poetry.group.flake8.dependencies] +black = "^22.1.0" flake8 = "^4.0.1" flake8-black = "^0.2.4" flake8-docstrings = "^1.6.0" flake8-isort = "^4.0.2" isort = "^5.10.1" -mccabe = "^0.6.1" -mypy = ">=0.941" +mccabe = "*" +pycodestyle = "*" +pydocstyle = "*" +pyflakes = "*" + +[tool.poetry.group.lsp.dependencies] pyls-flake8 = "^0.4.0" pyls-isort = "^0.2.2" pylsp-mypy = "^0.5.7" pylsp-rope = "^0.1.8" -pytest = "^7.0.0" python-lsp-black = "^1.1.0" python-lsp-server = { version = "^1.3.3", extras = [ "mccabe", @@ -64,7 +77,12 @@ python-lsp-server = { version = "^1.3.3", extras = [ "pyflakes", "rope", ] } -tox = "^3.24.5" + +[tool.poetry.group.pytest.dependencies] +pytest = "^7.0.0" + +[tool.poetry.group.mypy.dependencies] +mypy = ">=0.941" types-click = "^7.1.8" types-cryptography = "^3.3.15" types-humanfriendly = "^9.2.4" @@ -74,6 +92,15 @@ types-orjson = "^3.6.2" types-pyyaml = "^6.0.4" types-redis = "^4.1.17" types-requests = "^2.27.11" +# Plugins +sqlalchemy = "*" + +# FIXME: https://github.com/pypa/setuptools/pull/2872 +# FIXME: When resolved, remember to purge sqlalchemy types as they aren't needed in v2 +sqlalchemy2-stubs = "*" + +[tool.poetry.group.tox.dependencies] +tox = "^3.24.5" [tool.poetry.scripts] snagctl = "snagctl.main:main" @@ -106,3 +133,4 @@ strict_optional = true disallow_any_generics = false disallow_subclassing_any = false disallow_untyped_calls = false +disallow_untyped_decorators = false diff --git a/setup.cfg b/setup.cfg index 1f5db54..f86cc1b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -28,10 +28,9 @@ minversion = 3.20.0 skip_missing_interpreters = true [testenv] -allowlist_externals = poetry -commands = - poetry --version - poetry install +deps = + # FIXME: poetry>=1.2,<2 once released + poetry==1.2.0b1 setenv = PYTHONDONTWRITEBYTECODE=true PYTHONPYCACHEPREFIX=/tmp @@ -40,26 +39,31 @@ skip_install = true [testenv:bandit] commands = + poetry install --only bandit poetry run bandit --version poetry run bandit -c "{toxinidir}/pyproject.toml" -r {toxinidir}/snagctl/ poetry run bandit -c "{toxinidir}/pyproject.toml" -r {toxinidir}/snagd/ [testenv:coverage] commands = + poetry install --only coverage poetry run coverage --version [testenv:flake8] commands = + poetry install --only flake8 poetry run flake8 --version poetry run flake8 {toxinidir}/snagctl/ poetry run flake8 {toxinidir}/snagd/ [testenv:mypy] commands = + poetry install --only mypy poetry run mypy --version poetry run mypy {toxinidir}/snagctl/ poetry run mypy {toxinidir}/snagd/ [testenv:pytest] commands = + poetry install --only pytest poetry run pytest --version diff --git a/snagd/README.md b/snagd/README.md index 5da7b86..f164c7e 100644 --- a/snagd/README.md +++ b/snagd/README.md @@ -1,10 +1,17 @@ +snagd is the snagem server which provides an API that can be run with or without external +dependencies such as PostgreSQL, RabbitMQ, Redis. + +This README briefly outlines how to test and contribute to snagd. + + Testing --- -* https://docs.celeryproject.org/en/stable/userguide/testing.html +In this section, we'll demonstrate how to test snagd locally as well as in a container. Either +method can be used based on whichever is more convenient for you. ### Local ```sh -$ sudo dnf --refresh -y install libpq-devel git poetry python3-devel sqlite-devel +$ sudo dnf --refresh -y install git libpq-devel poetry python3-devel sqlite-devel $ poetry install $ poetry run tox ``` @@ -17,9 +24,13 @@ $ podman run -it jcmdln/snagem:devel ``` -Alembic +Contributing --- -```sh -$ poetry run alembic revision --autogenerate -m "example" -$ poetry run alembic upgrade head -``` +### Getting Started +* https://python-poetry.org/docs +* https://fastapi.tiangolo.com/tutorial/ +* https://docs.sqlalchemy.org/en/20/tutorial/index.html +* https://pydantic-docs.helpmanual.io/ +* https://alembic.sqlalchemy.org/en/latest/tutorial.html +* https://docs.celeryproject.org/en/stable/getting-started/index.html +* https://docs.celeryproject.org/projects/kombu/en/stable/introduction.html diff --git a/snagd/db/crud/base.py b/snagd/db/crud/base.py index a3e4701..0502aeb 100644 --- a/snagd/db/crud/base.py +++ b/snagd/db/crud/base.py @@ -1,4 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later + from __future__ import annotations from typing import Generic, Optional, Type, TypeVar @@ -41,7 +42,7 @@ def delete(self, db: Session, obj: DeleteSchema) -> Optional[Model]: return db_data def get(self, db: Session, uuid: str) -> Optional[Model]: - result: Model = db.query(self.model).filter_by(uuid=uuid).first() + result: Optional[Model] = db.query(self.model).filter_by(uuid=uuid).first() return result def search(self, db: Session, obj: ReadSchema, limit: int = 100, skip: int = 0) -> list[Model]: diff --git a/snagd/db/session.py b/snagd/db/session.py index c4877ff..7743f9d 100644 --- a/snagd/db/session.py +++ b/snagd/db/session.py @@ -5,8 +5,8 @@ from os import getenv from typing import Iterator -from sqlalchemy import Engine, create_engine -from sqlalchemy.ext.declarative import DeclarativeMeta, declarative_base +from sqlalchemy import create_engine +from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import Session, sessionmaker db_args: dict = {} @@ -15,9 +15,9 @@ if "sqlite" in db_url.lower(): db_args = {"check_same_thread": False} -engine: Engine = create_engine(db_url, connect_args=db_args) -SessionLocal: sessionmaker = sessionmaker(autocommit=False, autoflush=False, bind=engine) -Base: DeclarativeMeta = declarative_base() +engine = create_engine(db_url, connect_args=db_args) +SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) +Base = declarative_base() def get_db() -> Iterator[Session]: