diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 0000000..3fc4590
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,17 @@
+{
+ "name": "pallets-eco/flask-rq",
+ "image": "mcr.microsoft.com/devcontainers/python:3.8",
+ "customizations": {
+ "vscode": {
+ "settings": {
+ "python.defaultInterpreterPath": "${workspaceFolder}/.venv",
+ "python.terminal.activateEnvInCurrentTerminal": true,
+ "python.terminal.launchArgs": [
+ "-X",
+ "dev"
+ ]
+ }
+ }
+ },
+ "onCreateCommand": ".devcontainer/on-create-command.sh"
+}
diff --git a/.devcontainer/on-create-command.sh b/.devcontainer/on-create-command.sh
new file mode 100644
index 0000000..98ac734
--- /dev/null
+++ b/.devcontainer/on-create-command.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -e
+python3 -m venv --upgrade-deps .venv
+. .venv/bin/activate
+pip install -r requirements/dev.txt
+pip install -e .
diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml
index 03a26a6..8a51950 100644
--- a/.github/workflows/tests.yaml
+++ b/.github/workflows/tests.yaml
@@ -27,6 +27,21 @@ jobs:
- {python: '3.10'}
- {python: '3.9'}
- {python: '3.8'}
+ # Service containers to run with `container-job`
+ services:
+ # Label used to access the service container
+ redis:
+ # Docker Hub image
+ image: redis
+ # Set health checks to wait until redis has started
+ options: >-
+ --health-cmd "redis-cli ping"
+ --health-interval 10s
+ --health-timeout 5s
+ --health-retries 5
+ ports:
+ # Maps port 6379 on service container to the host
+ - 6379:6379
steps:
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
- uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0
@@ -37,19 +52,3 @@ jobs:
cache-dependency-path: requirements*/*.txt
- run: pip install tox
- run: tox run -e ${{ matrix.tox || format('py{0}', matrix.python) }}
- typing:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
- - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0
- with:
- python-version: '3.x'
- cache: pip
- cache-dependency-path: requirements*/*.txt
- - name: cache mypy
- uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
- with:
- path: ./.mypy_cache
- key: mypy|${{ hashFiles('pyproject.toml') }}
- - run: pip install tox
- - run: tox run -e typing
diff --git a/flask_rq.py b/flask_rq.py
index 39729d0..602f951 100644
--- a/flask_rq.py
+++ b/flask_rq.py
@@ -15,7 +15,7 @@
import redis
from flask import current_app
-from redis._compat import urlparse
+from urllib.parse import urlparse
from rq import Queue, Worker
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..c10dbff
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,50 @@
+[project]
+name = "Flask-RQ"
+version = "0.2"
+description="RQ (Redis Queue) integration for Flask applications"
+readme = "README.md"
+license = { file = "LICENSE" }
+author = [{ name = "Matthew Wright"}]
+maintainers = [{name = "Pallets Ecosystem", email = "contact@palletsprojects.com"}]
+classifiers = [
+ "Development Status :: 4 - Beta",
+ "Framework :: Flask",
+ "Environment :: Web Environment",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: MIT License",
+ "Operating System :: OS Independent",
+ "Programming Language :: Python",
+ "Topic :: Internet :: WWW/HTTP :: Dynamic Content",
+ "Topic :: Software Development :: Libraries :: Python Modules",
+]
+requires-python = ">=3.8"
+dependencies = [
+ "flask>=2.3.0",
+ "rq>=1.16.2",
+]
+
+[project.urls]
+Documentation = "https://pythonhosted.org/Flask-RQ/"
+Changes = "https://github.com/pallets-eco/flask-rq/releases"
+Source = "https://github.com/pallets-eco/flask-rq"
+Chat = "https://discord.gg/pallets"
+
+[build-system]
+requires = ["flit_core<4"]
+build-backend = "flit_core.buildapi"
+
+[tool.flit.module]
+name = "flask_rq"
+
+[tool.pytest.ini_options]
+testpaths = ["tests"]
+filterwarnings = [
+ "error",
+]
+
+[tool.coverage.run]
+branch = true
+source = ["flask_rq", "tests"]
+
+[tool.coverage.paths]
+source = ["flask_rq.py"]
\ No newline at end of file
diff --git a/requirements/build.in b/requirements/build.in
new file mode 100644
index 0000000..fcb6a2f
--- /dev/null
+++ b/requirements/build.in
@@ -0,0 +1 @@
+build
diff --git a/requirements/build.txt b/requirements/build.txt
new file mode 100644
index 0000000..acae7e9
--- /dev/null
+++ b/requirements/build.txt
@@ -0,0 +1,18 @@
+#
+# This file is autogenerated by pip-compile with Python 3.8
+# by the following command:
+#
+# pip-compile build.in
+#
+build==1.2.1
+ # via -r build.in
+importlib-metadata==7.1.0
+ # via build
+packaging==24.0
+ # via build
+pyproject-hooks==1.1.0
+ # via build
+tomli==2.0.1
+ # via build
+zipp==3.18.2
+ # via importlib-metadata
diff --git a/requirements/dev.in b/requirements/dev.in
new file mode 100644
index 0000000..732d49d
--- /dev/null
+++ b/requirements/dev.in
@@ -0,0 +1,2 @@
+pre-commit
+tox
diff --git a/requirements/dev.txt b/requirements/dev.txt
new file mode 100644
index 0000000..fe81977
--- /dev/null
+++ b/requirements/dev.txt
@@ -0,0 +1,53 @@
+#
+# This file is autogenerated by pip-compile with Python 3.8
+# by the following command:
+#
+# pip-compile dev.in
+#
+cachetools==5.3.3
+ # via tox
+cfgv==3.4.0
+ # via pre-commit
+chardet==5.2.0
+ # via tox
+colorama==0.4.6
+ # via tox
+distlib==0.3.8
+ # via virtualenv
+filelock==3.14.0
+ # via
+ # tox
+ # virtualenv
+identify==2.5.36
+ # via pre-commit
+nodeenv==1.8.0
+ # via pre-commit
+packaging==24.0
+ # via
+ # pyproject-api
+ # tox
+platformdirs==4.2.2
+ # via
+ # tox
+ # virtualenv
+pluggy==1.5.0
+ # via tox
+pre-commit==3.5.0
+ # via -r dev.in
+pyproject-api==1.6.1
+ # via tox
+pyyaml==6.0.1
+ # via pre-commit
+tomli==2.0.1
+ # via
+ # pyproject-api
+ # tox
+tox==4.15.0
+ # via -r dev.in
+virtualenv==20.26.2
+ # via
+ # pre-commit
+ # tox
+
+# The following packages are considered to be unsafe in a requirements file:
+# setuptools
diff --git a/requirements/docs.in b/requirements/docs.in
new file mode 100644
index 0000000..532a51f
--- /dev/null
+++ b/requirements/docs.in
@@ -0,0 +1,4 @@
+pallets-sphinx-themes
+sphinx
+sphinxcontrib-log-cabinet
+sphinx-tabs
diff --git a/requirements/docs.txt b/requirements/docs.txt
new file mode 100644
index 0000000..452eda6
--- /dev/null
+++ b/requirements/docs.txt
@@ -0,0 +1,70 @@
+#
+# This file is autogenerated by pip-compile with Python 3.8
+# by the following command:
+#
+# pip-compile docs.in
+#
+alabaster==0.7.13
+ # via sphinx
+babel==2.15.0
+ # via sphinx
+certifi==2024.2.2
+ # via requests
+charset-normalizer==3.3.2
+ # via requests
+docutils==0.20.1
+ # via
+ # sphinx
+ # sphinx-tabs
+idna==3.7
+ # via requests
+imagesize==1.4.1
+ # via sphinx
+importlib-metadata==7.1.0
+ # via sphinx
+jinja2==3.1.4
+ # via sphinx
+markupsafe==2.1.5
+ # via jinja2
+packaging==24.0
+ # via
+ # pallets-sphinx-themes
+ # sphinx
+pallets-sphinx-themes==2.1.3
+ # via -r docs.in
+pygments==2.18.0
+ # via
+ # sphinx
+ # sphinx-tabs
+pytz==2024.1
+ # via babel
+requests==2.32.2
+ # via sphinx
+snowballstemmer==2.2.0
+ # via sphinx
+sphinx==7.1.2
+ # via
+ # -r docs.in
+ # pallets-sphinx-themes
+ # sphinx-tabs
+ # sphinxcontrib-log-cabinet
+sphinx-tabs==3.4.5
+ # via -r docs.in
+sphinxcontrib-applehelp==1.0.4
+ # via sphinx
+sphinxcontrib-devhelp==1.0.2
+ # via sphinx
+sphinxcontrib-htmlhelp==2.0.1
+ # via sphinx
+sphinxcontrib-jsmath==1.0.1
+ # via sphinx
+sphinxcontrib-log-cabinet==1.0.1
+ # via -r docs.in
+sphinxcontrib-qthelp==1.0.3
+ # via sphinx
+sphinxcontrib-serializinghtml==1.1.5
+ # via sphinx
+urllib3==2.2.1
+ # via requests
+zipp==3.18.2
+ # via importlib-metadata
diff --git a/requirements/tests.in b/requirements/tests.in
new file mode 100644
index 0000000..ae2ce46
--- /dev/null
+++ b/requirements/tests.in
@@ -0,0 +1,2 @@
+pytest
+rq
diff --git a/requirements/tests.txt b/requirements/tests.txt
new file mode 100644
index 0000000..4c8df4d
--- /dev/null
+++ b/requirements/tests.txt
@@ -0,0 +1,26 @@
+#
+# This file is autogenerated by pip-compile with Python 3.8
+# by the following command:
+#
+# pip-compile tests.in
+#
+async-timeout==4.0.3
+ # via redis
+click==8.1.7
+ # via rq
+exceptiongroup==1.2.1
+ # via pytest
+iniconfig==2.0.0
+ # via pytest
+packaging==24.0
+ # via pytest
+pluggy==1.5.0
+ # via pytest
+pytest==8.2.1
+ # via -r tests.in
+redis==5.0.4
+ # via rq
+rq==1.16.2
+ # via -r tests.in
+tomli==2.0.1
+ # via pytest
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index 736bfed..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,6 +0,0 @@
-[build_sphinx]
-source-dir = docs/
-build-dir = docs/_build
-
-[upload_sphinx]
-upload-dir = docs/_build/html
\ No newline at end of file
diff --git a/setup.py b/setup.py
deleted file mode 100644
index 0ac920e..0000000
--- a/setup.py
+++ /dev/null
@@ -1,43 +0,0 @@
-"""
-Flask-RQ
-========
-
-RQ (Redis Queue) integration for Flask applications
-
-
-Resources
----------
-
-- `Documentation `_
-- `Issue Tracker `_
-- `Code `_
-- `Development Version
- `_
-"""
-
-from setuptools import setup
-
-setup(
- name='Flask-RQ',
- version='0.2',
- url='http://packages.python.org/Flask-RQ/',
- license='MIT',
- author='Matthew Wright',
- author_email='matt@nobien.net',
- description='RQ (Redis Queue) integration for Flask applications',
- long_description=__doc__,
- py_modules=['flask_rq'],
- zip_safe=False,
- platforms='any',
- install_requires=['Flask', 'rq'],
- classifiers=[
- 'Development Status :: 4 - Beta',
- 'Environment :: Web Environment',
- 'Intended Audience :: Developers',
- 'License :: OSI Approved :: MIT License',
- 'Operating System :: OS Independent',
- 'Programming Language :: Python',
- 'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
- 'Topic :: Software Development :: Libraries :: Python Modules'
- ]
-)
diff --git a/tests/flaskrq_tests.py b/tests/test_flaskrq.py
similarity index 100%
rename from tests/flaskrq_tests.py
rename to tests/test_flaskrq.py
diff --git a/tox.ini b/tox.ini
new file mode 100644
index 0000000..2361431
--- /dev/null
+++ b/tox.ini
@@ -0,0 +1,29 @@
+[tox]
+envlist =
+ py3{13,12,11,10,9,8}
+ docs
+skip_missing_interpreters = true
+
+[testenv]
+package = wheel
+wheel_build_env = .pkg
+constrain_package_deps = true
+use_frozen_constraints = true
+deps = -r requirements/tests.txt
+commands = pytest -v --tb=short --basetemp={envtmpdir} {posargs}
+
+[testenv:docs]
+deps = -r requirements/docs.txt
+commands = sphinx-build -E -W -b dirhtml docs docs/_build/dirhtml
+
+[testenv:update-requirements]
+base_python = 3.8
+labels = update
+deps = pip-tools
+skip_install = true
+change_dir = requirements
+commands =
+ pip-compile build.in -q {posargs:-U}
+ pip-compile docs.in -q {posargs:-U}
+ pip-compile tests.in -q {posargs:-U}
+ pip-compile dev.in -q {posargs:-U}