From e381c1b52243d4e5c9b04a79e7b5d29226d01073 Mon Sep 17 00:00:00 2001 From: Giacomo Leidi Date: Sun, 28 Jan 2024 21:08:17 +0100 Subject: [PATCH] Migrate to importlib and update some dependencies (#189) * Migrate to importlib. * Update CI --- .github/workflows/main.yml | 60 ++++-- .pre-commit-config.yaml | 2 +- channels-lock.scm | 2 +- guix.scm | 29 ++- manifest.scm | 2 +- mobilizon_reshare/config/config.py | 26 +-- mobilizon_reshare/publishers/abstract.py | 47 ++++- .../publishers/platforms/facebook.py | 13 -- .../publishers/platforms/mastodon.py | 13 -- .../publishers/platforms/telegram.py | 13 -- .../publishers/platforms/twitter.py | 13 -- .../publishers/platforms/zulip.py | 13 -- mobilizon_reshare/storage/db.py | 8 +- poetry.lock | 196 +++++++++--------- pyproject.toml | 10 +- 15 files changed, 219 insertions(+), 228 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a437581..816877b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,10 +5,34 @@ name: CI # Controls when the workflow will run on: pull_request: + paths-ignore: + - 'guix.scm' + - 'manifest.scm' + - 'channels-lock.scm' + - '.envrc' + - '.gitignore' + - 'pre-commit-*.yaml' + - Dockerfile + - README.* + - LICENSE + - 'sample_settings/**' + - 'etc/**' push: # Sequence of patterns matched against refs/tags branches: ["master"] + paths-ignore: + - 'guix.scm' + - 'manifest.scm' + - 'channels-lock.scm' + - '.envrc' + - '.gitignore' + - 'pre-commit-*.yaml' + - Dockerfile + - README.* + - LICENSE + - 'sample_settings/**' + - 'etc/**' # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -16,20 +40,32 @@ on: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: run-tests-dev: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job + strategy: + fail-fast: false + matrix: + python-version: ["3.10", "3.11"] + poetry-version: ["1.1.12", "1.7.0"] + os: [ubuntu-latest] + runs-on: ${{ matrix.os }} steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - # Runs a single command using the runners shell - - name: Set up Python 3.10 - uses: actions/setup-python@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: ${{ matrix.python-version }} + - name: Run image + uses: abatilo/actions-poetry@v2 + with: + poetry-version: ${{ matrix.poetry-version }} + - name: Setup a local virtual environment + run: | + poetry config virtualenvs.create true --local + poetry config virtualenvs.in-project true --local + - uses: actions/cache@v3 + name: Define a cache for the virtual environment based on the dependencies lock file + with: + path: ./.venv + key: venv-${{ hashFiles('poetry.lock') }} - name: Install dependencies run: scripts/install_github_actions_dev_dependencies.sh - name: Run tests in dev env - run: scripts/run_pipeline_tests.sh \ No newline at end of file + run: scripts/run_pipeline_tests.sh diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fc95d1a..684126e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ repos: rev: stable hooks: - id: black - language_version: python3.9 + language_version: python3.10 - repo: https://github.com/pre-commit/pre-commit-hooks rev: v1.2.3 hooks: diff --git a/channels-lock.scm b/channels-lock.scm index 107f7f9..e677426 100644 --- a/channels-lock.scm +++ b/channels-lock.scm @@ -10,7 +10,7 @@ (name 'guix) (url "https://git.savannah.gnu.org/git/guix.git") (commit - "79a3cd34c0318928186a04b6481c4d22c0051d04") + "e7403acb345a59d580607fbfe7ef2aa0c410767a") (introduction (make-channel-introduction "afb9f2752315f131e4ddd44eba02eed403365085" diff --git a/guix.scm b/guix.scm index 196be88..7a93a69 100644 --- a/guix.scm +++ b/guix.scm @@ -1,18 +1,12 @@ -(define-module (guix) - #:use-module (guix git-download) - #:use-module (guix build-system python) - #:use-module (guix gexp) - #:use-module (guix packages) - #:use-module (guix utils) - #:use-module (gnu packages databases) ;; for python-tortoise-orm - #:use-module (gnu packages markup) ;; for python-markdownify - #:use-module (gnu packages python) - #:use-module (gnu packages python-web) ;; for python-uvicorn - #:use-module (gnu packages python-xyz) ;; for dynaconf - #:use-module (mobilizon-reshare package) - #:use-module (mobilizon-reshare dependencies) - #:use-module (ice-9 rdelim) - #:use-module (ice-9 popen)) +(use-modules (guix git-download) + (guix build-system python) + (guix gexp) + (guix packages) + (guix utils) + (gnu packages markup) ;; for python-markdownify + (mobilizon-reshare package) + (ice-9 rdelim) + (ice-9 popen)) (define %source-dir (getcwd)) @@ -32,7 +26,10 @@ (package (inherit mobilizon-reshare) (name "mobilizon-reshare.git") (version (git-version source-version revision commit)) - (source mobilizon-reshare-git-origin)))) + (source mobilizon-reshare-git-origin) + (propagated-inputs + (modify-inputs (package-propagated-inputs mobilizon-reshare) + (replace "python-markdownify" python-markdownify)))))) (define-public mobilizon-reshare-scheduler (package (inherit mobilizon-reshare.git) diff --git a/manifest.scm b/manifest.scm index 359a7d8..d446eee 100644 --- a/manifest.scm +++ b/manifest.scm @@ -12,6 +12,6 @@ (map cadr (package-direct-inputs mobilizon-reshare)) (map specification->package+output '("git-cal" "man-db" "texinfo" - "python-pre-commit" "cloc" + "pre-commit" "cloc" "ripgrep" "python-semver" "fd" "docker-compose" "poetry")))) diff --git a/mobilizon_reshare/config/config.py b/mobilizon_reshare/config/config.py index fe4469f..0cbd79c 100644 --- a/mobilizon_reshare/config/config.py +++ b/mobilizon_reshare/config/config.py @@ -1,10 +1,9 @@ -import importlib.resources +import importlib import logging from logging.config import dictConfig from pathlib import Path from typing import Optional -import pkg_resources from appdirs import AppDirs from dynaconf import Dynaconf, Validator @@ -48,17 +47,18 @@ def init_logging(settings: Optional[Dynaconf] = None): def get_settings_files_paths() -> Optional[str]: dirs = AppDirs(appname="mobilizon-reshare", version=current_version()) - bundled_settings_path = pkg_resources.resource_filename( - "mobilizon_reshare", "settings.toml" - ) - for config_path in [ - Path(dirs.user_config_dir, "mobilizon_reshare.toml").absolute(), - Path(dirs.site_config_dir, "mobilizon_reshare.toml").absolute(), - bundled_settings_path, - ]: - if config_path and Path(config_path).exists(): - logger.debug(f"Loading configuration from {config_path}") - return config_path + bundled_settings_ref = importlib.resources.files( + "mobilizon_reshare" + ) / "settings.toml" + with importlib.resources.as_file(bundled_settings_ref) as bundled_settings_path: + for config_path in [ + Path(dirs.user_config_dir, "mobilizon_reshare.toml").absolute(), + Path(dirs.site_config_dir, "mobilizon_reshare.toml").absolute(), + bundled_settings_path.absolute(), + ]: + if config_path and Path(config_path).exists(): + logger.debug(f"Loading configuration from {config_path}") + return config_path def build_settings(validators: Optional[list[Validator]] = None) -> Dynaconf: diff --git a/mobilizon_reshare/publishers/abstract.py b/mobilizon_reshare/publishers/abstract.py index fa14dd7..3fb4b4a 100644 --- a/mobilizon_reshare/publishers/abstract.py +++ b/mobilizon_reshare/publishers/abstract.py @@ -1,3 +1,4 @@ +import importlib import inspect import logging from abc import ABC, abstractmethod @@ -124,6 +125,33 @@ class AbstractEventFormatter(LoggerMixin, ConfLoaderMixin): """ raise NotImplementedError # pragma: no cover + def _get_name(self) -> str: + return self._conf[1] + + + def _get_template(self, configured_template, default_generator) -> Template: + if configured_template: + return JINJA_ENV.get_template(configured_template) + else: + template_ref = default_generator() + with importlib.resources.as_file(template_ref) as template_path: + return JINJA_ENV.get_template(template_path.as_posix()) + + + def get_default_template_path(self, type=""): + return importlib.resources.files( + "mobilizon_reshare.publishers.templates" + ) / f"{self._get_name()}{type}.tmpl.j2" + + + def get_default_recap_template_path(self): + return self.get_default_template_path(type="_recap") + + + def get_default_recap_header_template_path(self): + return self.get_default_template_path(type="_recap_header") + + def validate_event(self, event: _MobilizonEvent) -> None: self._validate_event(event) self._validate_message(self.get_message_from_event(event)) @@ -148,21 +176,20 @@ class AbstractEventFormatter(LoggerMixin, ConfLoaderMixin): """ Retrieves publisher's message template. """ - template_path = self.conf.msg_template_path or self.default_template_path - return JINJA_ENV.get_template(template_path) + return self._get_template(self.conf.msg_template_path, self.get_default_template_path) - def get_recap_header(self): - template_path = ( - self.conf.recap_header_template_path - or self.default_recap_header_template_path + def get_recap_header(self) -> Template: + return self._get_template( + self.conf.recap_header_template_path, + self.get_default_recap_header_template_path ) - return JINJA_ENV.get_template(template_path).render() + def get_recap_fragment_template(self) -> Template: - template_path = ( - self.conf.recap_template_path or self.default_recap_template_path + return self._get_template( + self.conf.recap_template_path, + self.get_default_recap_template_path ) - return JINJA_ENV.get_template(template_path) def get_recap_fragment(self, event: _MobilizonEvent) -> str: """ diff --git a/mobilizon_reshare/publishers/platforms/facebook.py b/mobilizon_reshare/publishers/platforms/facebook.py index 9b6a862..93b56a1 100644 --- a/mobilizon_reshare/publishers/platforms/facebook.py +++ b/mobilizon_reshare/publishers/platforms/facebook.py @@ -1,7 +1,6 @@ from typing import Optional import facebook -import pkg_resources from facebook import GraphAPIError from mobilizon_reshare.dataclasses import MobilizonEvent @@ -19,19 +18,7 @@ from mobilizon_reshare.publishers.exceptions import ( class FacebookFormatter(AbstractEventFormatter): - _conf = ("publisher", "facebook") - default_template_path = pkg_resources.resource_filename( - "mobilizon_reshare.publishers.templates", "facebook.tmpl.j2" - ) - - default_recap_template_path = pkg_resources.resource_filename( - "mobilizon_reshare.publishers.templates", "facebook_recap.tmpl.j2" - ) - - default_recap_header_template_path = pkg_resources.resource_filename( - "mobilizon_reshare.publishers.templates", "facebook_recap_header.tmpl.j2" - ) def _validate_event(self, event: MobilizonEvent) -> None: text = event.description diff --git a/mobilizon_reshare/publishers/platforms/mastodon.py b/mobilizon_reshare/publishers/platforms/mastodon.py index 09df153..4199bb3 100644 --- a/mobilizon_reshare/publishers/platforms/mastodon.py +++ b/mobilizon_reshare/publishers/platforms/mastodon.py @@ -1,7 +1,6 @@ from typing import Optional from urllib.parse import urljoin -import pkg_resources import requests from requests import Response @@ -20,19 +19,7 @@ from mobilizon_reshare.publishers.exceptions import ( class MastodonFormatter(AbstractEventFormatter): - _conf = ("publisher", "mastodon") - default_template_path = pkg_resources.resource_filename( - "mobilizon_reshare.publishers.templates", "mastodon.tmpl.j2" - ) - - default_recap_template_path = pkg_resources.resource_filename( - "mobilizon_reshare.publishers.templates", "mastodon_recap.tmpl.j2" - ) - - default_recap_header_template_path = pkg_resources.resource_filename( - "mobilizon_reshare.publishers.templates", "mastodon_recap_header.tmpl.j2" - ) def _validate_event(self, event: MobilizonEvent) -> None: text = event.description diff --git a/mobilizon_reshare/publishers/platforms/telegram.py b/mobilizon_reshare/publishers/platforms/telegram.py index 84715b7..01729d4 100644 --- a/mobilizon_reshare/publishers/platforms/telegram.py +++ b/mobilizon_reshare/publishers/platforms/telegram.py @@ -1,7 +1,6 @@ import re from typing import Optional -import pkg_resources import requests from bs4 import BeautifulSoup from requests import Response @@ -20,18 +19,6 @@ from mobilizon_reshare.publishers.exceptions import ( class TelegramFormatter(AbstractEventFormatter): - default_template_path = pkg_resources.resource_filename( - "mobilizon_reshare.publishers.templates", "telegram.tmpl.j2" - ) - - default_recap_template_path = pkg_resources.resource_filename( - "mobilizon_reshare.publishers.templates", "telegram_recap.tmpl.j2" - ) - - default_recap_header_template_path = pkg_resources.resource_filename( - "mobilizon_reshare.publishers.templates", "telegram_recap_header.tmpl.j2" - ) - _conf = ("publisher", "telegram") def _validate_event(self, event: MobilizonEvent) -> None: diff --git a/mobilizon_reshare/publishers/platforms/twitter.py b/mobilizon_reshare/publishers/platforms/twitter.py index 90a8bb3..4b1ad70 100644 --- a/mobilizon_reshare/publishers/platforms/twitter.py +++ b/mobilizon_reshare/publishers/platforms/twitter.py @@ -1,6 +1,5 @@ from typing import Optional -import pkg_resources from tweepy import OAuthHandler, API, TweepyException from tweepy.models import Status @@ -17,19 +16,7 @@ from mobilizon_reshare.publishers.exceptions import ( class TwitterFormatter(AbstractEventFormatter): - _conf = ("publisher", "twitter") - default_template_path = pkg_resources.resource_filename( - "mobilizon_reshare.publishers.templates", "twitter.tmpl.j2" - ) - - default_recap_template_path = pkg_resources.resource_filename( - "mobilizon_reshare.publishers.templates", "twitter_recap.tmpl.j2" - ) - - default_recap_header_template_path = pkg_resources.resource_filename( - "mobilizon_reshare.publishers.templates", "twitter_recap_header.tmpl.j2" - ) def _validate_event(self, event: MobilizonEvent) -> None: pass # pragma: no cover diff --git a/mobilizon_reshare/publishers/platforms/zulip.py b/mobilizon_reshare/publishers/platforms/zulip.py index 3b4195e..4b7c3f3 100644 --- a/mobilizon_reshare/publishers/platforms/zulip.py +++ b/mobilizon_reshare/publishers/platforms/zulip.py @@ -1,7 +1,6 @@ from typing import Optional from urllib.parse import urljoin -import pkg_resources import requests from requests import Response from requests.auth import HTTPBasicAuth @@ -23,19 +22,7 @@ from mobilizon_reshare.publishers.exceptions import ( class ZulipFormatter(AbstractEventFormatter): - _conf = ("publisher", "zulip") - default_template_path = pkg_resources.resource_filename( - "mobilizon_reshare.publishers.templates", "zulip.tmpl.j2" - ) - - default_recap_template_path = pkg_resources.resource_filename( - "mobilizon_reshare.publishers.templates", "zulip_recap.tmpl.j2" - ) - - default_recap_header_template_path = pkg_resources.resource_filename( - "mobilizon_reshare.publishers.templates", "zulip_recap_header.tmpl.j2" - ) def _validate_event(self, event: MobilizonEvent) -> None: text = event.description diff --git a/mobilizon_reshare/storage/db.py b/mobilizon_reshare/storage/db.py index 7658ec5..9299627 100644 --- a/mobilizon_reshare/storage/db.py +++ b/mobilizon_reshare/storage/db.py @@ -1,7 +1,7 @@ import logging from pathlib import Path -import pkg_resources +import importlib import urllib3.util from aerich import Command from tortoise import Tortoise @@ -47,9 +47,9 @@ TORTOISE_ORM = get_tortoise_orm() class MoReDB: def get_migration_location(self): scheme = get_db_url().scheme - return pkg_resources.resource_filename( - "mobilizon_reshare", f"migrations/{scheme}" - ) + scheme_ref = importlib.resources.files("mobilizon_reshare") / "migrations" / f"{scheme}" + with importlib.resources.as_file(scheme_ref) as scheme_path: + return scheme_path async def _implement_db_changes(self): logging.info("Performing aerich migrations.") diff --git a/poetry.lock b/poetry.lock index 2813997..a15336c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -38,20 +38,22 @@ python-versions = ">=3.6" [[package]] name = "anyio" -version = "3.6.2" +version = "4.2.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" category = "main" optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.8" [package.dependencies] +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" +typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} [package.extras] -doc = ["packaging", "sphinx-rtd-theme", "sphinx-autodoc-typehints (>=1.2.0)"] -test = ["coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "contextlib2", "uvloop (<0.15)", "mock (>=4)", "uvloop (>=0.15)"] -trio = ["trio (>=0.16,<0.22)"] +doc = ["packaging", "Sphinx (>=7)", "sphinx-rtd-theme", "sphinx-autodoc-typehints (>=1.2.0)"] +test = ["anyio", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (>=0.23)"] [[package]] name = "appdirs" @@ -74,27 +76,40 @@ python-dateutil = ">=2.7.0" [[package]] name = "asgiref" -version = "3.6.0" +version = "3.7.2" description = "ASGI specs, helper code, and adapters" category = "main" optional = false python-versions = ">=3.7" +[package.dependencies] +typing-extensions = {version = ">=4", markers = "python_version < \"3.11\""} + [package.extras] tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"] +[[package]] +name = "async-timeout" +version = "4.0.3" +description = "Timeout context manager for asyncio programs" +category = "main" +optional = false +python-versions = ">=3.7" + [[package]] name = "asyncpg" -version = "0.27.0" +version = "0.29.0" description = "An asyncio PostgreSQL driver" category = "main" optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.8.0" + +[package.dependencies] +async-timeout = {version = ">=4.0.3", markers = "python_version < \"3.12.0\""} [package.extras] -dev = ["Cython (>=0.29.24,<0.30.0)", "pytest (>=6.0)", "Sphinx (>=4.1.2,<4.2.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "flake8 (>=5.0.4,<5.1.0)", "uvloop (>=0.15.3)"] -docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)"] -test = ["flake8 (>=5.0.4,<5.1.0)", "uvloop (>=0.15.3)"] +docs = ["Sphinx (>=5.3.0,<5.4.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)", "sphinx-rtd-theme (>=1.2.2)"] +test = ["flake8 (>=6.1,<7.0)", "uvloop (>=0.15.3)"] [[package]] name = "asynctest" @@ -114,7 +129,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "attrs" -version = "23.1.0" +version = "23.2.0" description = "Classes Without Boilerplate" category = "dev" optional = false @@ -125,16 +140,20 @@ cov = ["attrs", "coverage[toml] (>=5.3)"] dev = ["attrs", "pre-commit"] docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] tests = ["attrs", "zope-interface"] -tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest-mypy-plugins", "pytest-xdist", "pytest (>=4.3.0)"] +tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] +tests-no-zope = ["attrs", "cloudpickle", "hypothesis", "pympler", "pytest-xdist", "pytest (>=4.3.0)"] [[package]] name = "babel" -version = "2.12.1" +version = "2.14.0" description = "Internationalization utilities" category = "dev" optional = false python-versions = ">=3.7" +[package.extras] +dev = ["pytest (>=6.0)", "pytest-cov", "freezegun (>=1.0,<2.0)"] + [[package]] name = "beautifulsoup4" version = "4.11.2" @@ -152,7 +171,7 @@ lxml = ["lxml"] [[package]] name = "certifi" -version = "2023.5.7" +version = "2023.11.17" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false @@ -160,7 +179,7 @@ python-versions = ">=3.6" [[package]] name = "charset-normalizer" -version = "3.1.0" +version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "main" optional = false @@ -168,7 +187,7 @@ python-versions = ">=3.7.0" [[package]] name = "click" -version = "8.1.3" +version = "8.1.7" description = "Composable command line interface toolkit" category = "main" optional = false @@ -187,11 +206,11 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7 [[package]] name = "coverage" -version = "7.2.5" +version = "7.4.0" description = "Code coverage measurement for Python" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.dependencies] tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} @@ -247,6 +266,17 @@ toml = ["toml"] vault = ["hvac"] yaml = ["ruamel.yaml"] +[[package]] +name = "exceptiongroup" +version = "1.2.0" +description = "Backport of PEP 654 (exception groups)" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +test = ["pytest (>=6)"] + [[package]] name = "facebook-sdk" version = "3.1.0" @@ -314,7 +344,7 @@ python-versions = ">=3.7" [[package]] name = "httpcore" -version = "0.16.3" +version = "0.17.3" description = "A minimal low-level HTTP client." category = "dev" optional = false @@ -332,7 +362,7 @@ socks = ["socksio (>=1.0.0,<2.0.0)"] [[package]] name = "httpx" -version = "0.23.3" +version = "0.24.1" description = "The next generation HTTP client." category = "dev" optional = false @@ -340,19 +370,19 @@ python-versions = ">=3.7" [package.dependencies] certifi = "*" -httpcore = ">=0.15.0,<0.17.0" -rfc3986 = {version = ">=1.3,<2", extras = ["idna2008"]} +httpcore = ">=0.15.0,<0.18.0" +idna = "*" sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] -cli = ["click (>=8.0.0,<9.0.0)", "pygments (>=2.0.0,<3.0.0)", "rich (>=10,<13)"] +cli = ["click (>=8.0.0,<9.0.0)", "pygments (>=2.0.0,<3.0.0)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (>=1.0.0,<2.0.0)"] [[package]] name = "idna" -version = "3.4" +version = "3.6" description = "Internationalized Domain Names in Applications (IDNA)" category = "main" optional = false @@ -366,22 +396,6 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -[[package]] -name = "importlib-metadata" -version = "6.6.0" -description = "Read metadata from Python packages" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -zipp = ">=0.5" - -[package.extras] -docs = ["sphinx (>=3.5)", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "furo", "sphinx-lint", "jaraco.tidelift (>=1.4)"] -perf = ["ipython"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "pytest-flake8", "importlib-resources (>=1.3)"] - [[package]] name = "iniconfig" version = "2.0.0" @@ -414,7 +428,7 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "lxml" -version = "4.9.2" +version = "5.0.1" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." category = "dev" optional = false @@ -424,11 +438,11 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" cssselect = ["cssselect (>=0.7)"] html5 = ["html5lib"] htmlsoup = ["beautifulsoup4"] -source = ["Cython (>=0.29.7)"] +source = ["Cython (>=3.0.7)"] [[package]] name = "markdownify" -version = "0.10.3" +version = "0.11.6" description = "Convert HTML to markdown." category = "main" optional = false @@ -440,7 +454,7 @@ six = ">=1.15,<2" [[package]] name = "markupsafe" -version = "2.1.2" +version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." category = "main" optional = false @@ -461,7 +475,7 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] [[package]] name = "packaging" -version = "23.1" +version = "23.2" description = "Core utilities for Python packages" category = "dev" optional = false @@ -469,11 +483,11 @@ python-versions = ">=3.7" [[package]] name = "pluggy" -version = "1.0.0" +version = "1.3.0" description = "plugin and hook calling mechanisms for python" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" [package.extras] dev = ["pre-commit", "tox"] @@ -500,7 +514,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "pydantic" -version = "1.10.7" +version = "1.10.13" description = "Data validation and settings management using python type hints" category = "main" optional = false @@ -515,7 +529,7 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pygments" -version = "2.15.1" +version = "2.17.2" description = "Pygments is a syntax highlighting package written in Python." category = "dev" optional = false @@ -523,6 +537,7 @@ python-versions = ">=3.7" [package.extras] plugins = ["importlib-metadata"] +windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pypika-tortoise" @@ -621,7 +636,7 @@ unidecode = ["Unidecode (>=1.1.1)"] [[package]] name = "pytz" -version = "2023.3" +version = "2023.3.post1" description = "World timezone definitions, modern and historical" category = "main" optional = false @@ -662,33 +677,20 @@ rsa = ["oauthlib[signedtoken] (>=3.0.0)"] [[package]] name = "responses" -version = "0.13.4" +version = "0.22.0" description = "A utility library for mocking out the `requests` Python library." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" [package.dependencies] -requests = ">=2.0" -six = "*" +requests = ">=2.22.0,<3.0" +toml = "*" +types-toml = "*" urllib3 = ">=1.25.10" [package.extras] -tests = ["coverage (>=3.7.1,<6.0.0)", "pytest-cov", "pytest-localserver", "flake8", "types-mock", "types-requests", "types-six", "pytest (>=4.6,<5.0)", "pytest (>=4.6)", "mypy"] - -[[package]] -name = "rfc3986" -version = "1.5.0" -description = "Validating URI References per RFC 3986" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -idna = {version = "*", optional = true, markers = "extra == \"idna2008\""} - -[package.extras] -idna2008 = ["idna"] +tests = ["pytest (>=7.0.0)", "coverage (>=6.0.0)", "pytest-cov", "pytest-asyncio", "pytest-httpserver", "flake8", "types-requests", "mypy"] [[package]] name = "six" @@ -716,11 +718,11 @@ python-versions = "*" [[package]] name = "soupsieve" -version = "2.4.1" +version = "2.5" description = "A modern CSS selector implementation for Beautiful Soup." category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [[package]] name = "sphinx" @@ -736,7 +738,6 @@ babel = ">=1.3" colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} docutils = ">=0.14,<0.18" imagesize = "*" -importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} Jinja2 = ">=2.3" packaging = "*" Pygments = ">=2.0" @@ -771,7 +772,7 @@ type_comments = ["typed-ast (>=1.4.0)"] [[package]] name = "sphinx-material" -version = "0.0.35" +version = "0.0.36" description = "Material sphinx theme" category = "dev" optional = false @@ -785,7 +786,7 @@ python-slugify = {version = "*", extras = ["unidecode"]} sphinx = ">=2.0" [package.extras] -dev = ["black (==19.10b0)"] +dev = ["black (==22.12.0)"] [[package]] name = "sphinxcontrib-applehelp" @@ -880,7 +881,6 @@ python-versions = ">=3.7" [package.dependencies] anyio = ">=3.4.0,<5" -typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} [package.extras] full = ["itsdangerous", "jinja2", "python-multipart", "pyyaml", "requests"] @@ -911,7 +911,7 @@ python-versions = ">=3.7" [[package]] name = "tomlkit" -version = "0.11.8" +version = "0.12.3" description = "Style preserving TOML library" category = "main" optional = false @@ -960,17 +960,25 @@ docs = ["myst-parser (==0.15.2)", "readthedocs-sphinx-search (==0.1.1)", "sphinx socks = ["requests[socks] (>=2.27.0,<3)"] test = ["vcrpy (>=1.10.3)"] +[[package]] +name = "types-toml" +version = "0.10.8.7" +description = "Typing stubs for toml" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "typing-extensions" -version = "4.5.0" -description = "Backported and Experimental Type Hints for Python 3.7+" +version = "4.9.0" +description = "Backported and Experimental Type Hints for Python 3.8+" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [[package]] name = "unidecode" -version = "1.3.6" +version = "1.3.7" description = "ASCII transliterations of Unicode text" category = "dev" optional = false @@ -978,14 +986,14 @@ python-versions = ">=3.5" [[package]] name = "urllib3" -version = "1.26.15" +version = "1.26.18" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" [package.extras] -brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] +brotli = ["brotlicffi (>=0.8.0)", "brotli (==1.0.9)", "brotlipy (>=0.6.0)", "brotli (>=1.0.9)"] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "urllib3-secure-extra", "ipaddress"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] @@ -1005,22 +1013,10 @@ h11 = ">=0.8" [package.extras] standard = ["websockets (>=10.0)", "httptools (>=0.4.0)", "watchgod (>=0.6)", "python-dotenv (>=0.13)", "PyYAML (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "colorama (>=0.4)"] -[[package]] -name = "zipp" -version = "3.15.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -docs = ["sphinx (>=3.5)", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "furo", "sphinx-lint", "jaraco.tidelift (>=1.4)"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "jaraco.functools", "more-itertools", "big-o", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "pytest-flake8"] - [metadata] lock-version = "1.1" -python-versions = "^3.9" -content-hash = "bfc1512cd6f94fdc013dbebcf70c0077093b2bc3126c8573c35a3569445f948d" +python-versions = "^3.10" +content-hash = "b758bdb597165ad8f0fc61bce99bb9f7d83c13788ca20ff3c78ae3a574aed11a" [metadata.files] aerich = [] @@ -1030,6 +1026,7 @@ anyio = [] appdirs = [] arrow = [] asgiref = [] +async-timeout = [] asyncpg = [] asynctest = [] atomicwrites = [] @@ -1045,6 +1042,7 @@ css-html-js-minify = [] dictdiffer = [] docutils = [] dynaconf = [] +exceptiongroup = [] facebook-sdk = [] fastapi = [] fastapi-pagination = [] @@ -1053,7 +1051,6 @@ httpcore = [] httpx = [] idna = [] imagesize = [] -importlib-metadata = [] iniconfig = [] iso8601 = [] jinja2 = [] @@ -1078,7 +1075,6 @@ pytz = [] requests = [] requests-oauthlib = [] responses = [] -rfc3986 = [] six = [] sniffio = [] snowballstemmer = [] @@ -1100,8 +1096,8 @@ tomli = [] tomlkit = [] tortoise-orm = [] tweepy = [] +types-toml = [] typing-extensions = [] unidecode = [] urllib3 = [] uvicorn = [] -zipp = [] diff --git a/pyproject.toml b/pyproject.toml index 51f22eb..a34c52b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ authors = ["Simone Robutti "] license = "Coopyleft" [tool.poetry.dependencies] -python = "^3.9" +python = "^3.10" dynaconf = "~3.1" tortoise-orm = {extras = ["asyncpg"], version = "~0.19"} aiosqlite = "~0.17" @@ -18,17 +18,17 @@ requests = "~2.28" arrow = "~1.1" click = "~8.1" beautifulsoup4 = "~4.11" -markdownify = "~0.10" +markdownify = "~0.11" appdirs = "~1.4" tweepy = "~4.13" facebook-sdk = "~3.1" aerich = "~0.6" fastapi = "~0.85" uvicorn = "~0.17" -fastapi-pagination = "^0.11.0" +fastapi-pagination = "~0.11" [tool.poetry.dev-dependencies] -responses = "~0.13" +responses = "~0.22" pytest-asyncio = "~0.15" asynctest = "~0.13" pytest = "~6.2" @@ -38,7 +38,7 @@ Sphinx = "~4.4" sphinxcontrib-napoleon = "~0.7" sphinx-material = "~0.0" sphinx-autodoc-typehints = "~1.17" -httpx = "~0.23" +httpx = "~0.24"