From 24c8ff814c988d03ae09b5923d491b0c20f3d90c Mon Sep 17 00:00:00 2001 From: "J. M. F. Tsang" Date: Sun, 18 Feb 2024 16:44:10 +0000 Subject: [PATCH] Deployment on SRCF * Script for deployment on SRCF * Replace T | None with Optional[T] to run on Python 3.8 * Rename a deprecated kwarg, https://github.com/pallets/flask/issues/4753 * Update Flask version * Remove Pandas as a dependency, skip tests if Pandas isn't available --- deploy/srcf.sh | 15 +++++++++++++++ models.py | 18 +++++++++--------- pypew.py | 2 +- requirements.txt | 13 ++++++------- tests/test_pypew.py | 7 +++++++ utils.py | 5 +++-- views/feast_views.py | 2 +- views/pew_sheet_views.py | 2 +- 8 files changed, 43 insertions(+), 21 deletions(-) create mode 100755 deploy/srcf.sh diff --git a/deploy/srcf.sh b/deploy/srcf.sh new file mode 100755 index 0000000..a07dd40 --- /dev/null +++ b/deploy/srcf.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -eux +files="$(dirname $0)" +bindto="unix:web.sock" + +export SERVER_NAME=jmft2.user.srcf.net +export SCRIPT_NAME=/pypew + +. /home/jmft2/venvs/py38/bin/activate + +cd "$(dirname "$files")" +exec gunicorn wsgi:app \ + -w 4 \ + --bind "$bindto" \ + --log-level debug diff --git a/models.py b/models.py index 996c749..8ba9eba 100644 --- a/models.py +++ b/models.py @@ -3,7 +3,7 @@ import re import typing from abc import ABC, abstractmethod -from functools import cache +from functools import lru_cache from pathlib import Path from typing import List, Optional @@ -349,7 +349,7 @@ def collects(self) -> List[str]: # TODO primary or secondary? @property - def introit_proper(self) -> str | None: + def introit_proper(self) -> Optional[str]: return self.primary_feast.introit @property @@ -372,27 +372,27 @@ def gat_propers(self) -> List[str]: return propers @property - def offertory_proper(self) -> str | None: + def offertory_proper(self) -> Optional[str]: return self.primary_feast.offertory @property - def communion_proper(self) -> str | None: + def communion_proper(self) -> Optional[str]: return self.primary_feast.communion @property - def epistle_ref(self) -> str | None: + def epistle_ref(self) -> Optional[str]: return self.primary_feast.epistle_ref @property - def epistle(self) -> str | None: + def epistle(self) -> Optional[str]: return self.primary_feast.epistle @property - def gospel_ref(self) -> str | None: + def gospel_ref(self) -> Optional[str]: return self.primary_feast.gospel_ref @property - def gospel(self) -> str | None: + def gospel(self) -> Optional[str]: return self.primary_feast.gospel @property @@ -478,7 +478,7 @@ def create_docx(self, path): doc.save(path) -@cache +@lru_cache() def _feast_from_yaml(slug: str) -> Feast: with open((DATA_DIR / slug).with_suffix('.yaml')) as f: info = yaml.safe_load(f) diff --git a/pypew.py b/pypew.py index 619cb79..a36cac8 100644 --- a/pypew.py +++ b/pypew.py @@ -84,7 +84,7 @@ def clear_trailing_slashes(): return app -def main(argv: Sequence[str] | None = None) -> None: +def main(argv: Optional[Sequence[str]] = None) -> None: """ Start PyPew. """ diff --git a/requirements.txt b/requirements.txt index 130c8f4..6b00309 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,19 +3,18 @@ attrs~=21.2.0 cattrs~=22.1.0 docxtpl~=0.15.2 dotmap~=1.3.26 -Flask~=1.1.2 -Flask-WTF +Flask~=2.2.2 +Flask-WTF~=1.2.1 gunicorn~=20.1.0 -Jinja2~=2.11.3 -markupsafe==2.0.1 +Jinja2~=3.1.2 +markupsafe==2.1.1 parameterized~=0.8.1 python-dateutil~=2.8.2 python-docx~=0.8.11 -python-dotenv~=0.19.2 +python-dotenv~=0.21.0 python-slugify~=7.0.0 PyYAML~=6.0 WTForms~=3.0.1 setuptools~=50.3.2 openpyxl==3.0.9 -pandas==2.1.0 -Werkzeug~=1.0.1 +Werkzeug~=2.2.2 diff --git a/tests/test_pypew.py b/tests/test_pypew.py index b639361..6ca018e 100644 --- a/tests/test_pypew.py +++ b/tests/test_pypew.py @@ -61,6 +61,13 @@ def test_english_ordinals(self, supplied_date, expected_string): self.assertEqual(english_date(supplied_date), expected_string) +try: + import pandas as pd +except ImportError: + pd = None + + +@unittest.skipIf(pd is None, "Pandas not available") class TestModels(unittest.TestCase): def test_neh_lookup(self): music = Music.get_neh_hymn_by_ref('NEH: 1a') diff --git a/utils.py b/utils.py index bcfc31f..a576dd4 100644 --- a/utils.py +++ b/utils.py @@ -5,7 +5,6 @@ from pathlib import Path from typing import Optional -import pandas as pd from appdirs import AppDirs @@ -31,7 +30,9 @@ def str2date(s: Optional[str]) -> date: @lru_cache() def get_neh_df(): - if pd is None: + try: + import pandas as pd + except ImportError: raise NoPandasError( 'Pandas not available, can\'t load hymn information' ) diff --git a/views/feast_views.py b/views/feast_views.py index 7e2ba09..d812de3 100644 --- a/views/feast_views.py +++ b/views/feast_views.py @@ -94,5 +94,5 @@ def feast_docx_view(slug): temp_docx = os.path.join(cache_dir, f"feast_{str(uuid.uuid4())}.docx") feast.create_docx(path=temp_docx) return send_file( - temp_docx, as_attachment=True, attachment_filename=filename + temp_docx, as_attachment=True, download_name=filename ) diff --git a/views/pew_sheet_views.py b/views/pew_sheet_views.py index bbe0710..c76e8d7 100644 --- a/views/pew_sheet_views.py +++ b/views/pew_sheet_views.py @@ -83,5 +83,5 @@ def pew_sheet_docx_view(): temp_docx = os.path.join(cache_dir, f"pew_sheet_{str(uuid.uuid4())}.docx") service.create_docx(temp_docx) return send_file( - temp_docx, as_attachment=True, attachment_filename=filename + temp_docx, as_attachment=True, download_name=filename )