From 7a68954f6edab387f01897867f6792fa18d9229d Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 4 Feb 2024 12:11:44 -0700 Subject: [PATCH] upgrade the wiki2/installation chapter --- docs/tutorials/wiki2/installation.rst | 60 +++++++++--------- .../wiki2/src/installation/.coveragerc | 2 - .../wiki2/src/installation/CHANGES.txt | 4 -- .../wiki2/src/installation/MANIFEST.in | 2 +- .../wiki2/src/installation/README.md | 60 ++++++++++++++++++ .../wiki2/src/installation/README.txt | 44 ------------- .../wiki2/src/installation/development.ini | 8 +-- .../wiki2/src/installation/production.ini | 8 +-- .../wiki2/src/installation/pyproject.toml | 58 ++++++++++++++++++ .../wiki2/src/installation/pytest.ini | 6 -- .../tutorials/wiki2/src/installation/setup.py | 61 ------------------- .../wiki2/src/installation/testing.ini | 8 +-- .../src/installation/tutorial/models/meta.py | 24 +++----- .../installation/tutorial/models/mymodel.py | 15 ++--- .../installation/tutorial/views/default.py | 8 +-- 15 files changed, 179 insertions(+), 189 deletions(-) delete mode 100644 docs/tutorials/wiki2/src/installation/.coveragerc delete mode 100644 docs/tutorials/wiki2/src/installation/CHANGES.txt create mode 100644 docs/tutorials/wiki2/src/installation/README.md delete mode 100644 docs/tutorials/wiki2/src/installation/README.txt create mode 100644 docs/tutorials/wiki2/src/installation/pyproject.toml delete mode 100644 docs/tutorials/wiki2/src/installation/pytest.ini delete mode 100644 docs/tutorials/wiki2/src/installation/setup.py diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst index 844d11ca00..707a6a1091 100644 --- a/docs/tutorials/wiki2/installation.rst +++ b/docs/tutorials/wiki2/installation.rst @@ -177,19 +177,14 @@ The console will show ``pip`` checking for packages and installing missing packa .. code-block:: bash - Successfully installed Jinja2-2.11.2 Mako-1.1.3 MarkupSafe-1.1.1 PasteDeploy-2.1.1 Pygments-2.7.3 SQLAlchemy-1.3.22 WebTest-2.0.35 alembic-1.4.3 attrs-20.3.0 beautifulsoup4-4.9.3 coverage-5.3.1 hupper-1.10.2 iniconfig-1.1.1 packaging-20.8 plaster-1.0 plaster-pastedeploy-0.7 pluggy-0.13.1 py-1.10.0 pyparsing-2.4.7 pyramid-1.10.5 pyramid-debugtoolbar-4.9 pyramid-jinja2-2.8 pyramid-mako-1.1.0 pyramid-retry-2.1.1 pyramid-tm-2.4 pytest-6.2.1 pytest-cov-2.10.1 python-dateutil-2.8.1 python-editor-1.0.4 repoze.lru-0.7 six-1.15.0 soupsieve-2.1 toml-0.10.2 transaction-3.0.1 translationstring-1.4 tutorial venusian-3.0.0 waitress-1.4.4 webob-1.8.6 zope.deprecation-4.4.0 zope.interface-5.2.0 zope.sqlalchemy-1.3 + Successfully installed Mako-1.3.2 PasteDeploy-3.1.0 Pygments-2.17.2 SQLAlchemy-2.0.25 WebTest-3.0.0 alembic-1.13.1 beautifulsoup4-4.12.3 coverage-7.4.1 greenlet-3.0.3 hupper-1.12.1 iniconfig-2.0.0 jinja2-3.1.3 markupsafe-2.1.5 packaging-23.2 plaster-1.1.2 plaster-pastedeploy-1.0.1 pluggy-1.4.0 pyramid-2.0.2 pyramid-debugtoolbar-4.12 pyramid-jinja2-2.10 pyramid-mako-1.1.0 pyramid-retry-2.1.1 pyramid-tm-2.5 pytest-8.0.0 pytest-cov-4.1.0 soupsieve-2.5 transaction-4.0 translationstring-1.4 tutorial-0.0 typing-extensions-4.9.0 venusian-3.1.0 waitress-2.1.2 webob-1.8.7 zope.deprecation-5.0 zope.interface-6.1 zope.sqlalchemy-3.1 -Testing requirements are defined in our project's ``setup.py`` file, in the ``tests_require`` and ``extras_require`` stanzas. +Testing requirements are defined in our project's ``pyproject.toml`` file in a ``testing`` optional dependency. -.. literalinclude:: src/installation/setup.py +.. literalinclude:: src/installation/pyproject.toml :language: python :lineno-match: - :lines: 25-29 - -.. literalinclude:: src/installation/setup.py - :language: python - :lineno-match: - :lines: 49-51 + :lines: 34-39 .. _initialize_db_wiki2: @@ -219,11 +214,11 @@ The output to your console should be something like this: .. code-block:: text - 2021-01-07 05:15:57,709 INFO [alembic.runtime.migration:155][MainThread] Context impl SQLiteImpl. - 2021-01-07 05:15:57,709 INFO [alembic.runtime.migration:162][MainThread] Will assume non-transactional DDL. - 2021-01-07 05:15:57,712 INFO [alembic.autogenerate.compare:134][MainThread] Detected added table 'models' - 2021-01-07 05:15:57,712 INFO [alembic.autogenerate.compare:588][MainThread] Detected added index 'my_index' on '['name']' - Generating /tutorial/tutorial/alembic/versions/20210107_d7ab09c3fdec.py ... done + 2024-02-04 12:02:28,828 INFO [alembic.runtime.migration:216][MainThread] Context impl SQLiteImpl. + 2024-02-04 12:02:28,828 INFO [alembic.runtime.migration:219][MainThread] Will assume non-transactional DDL. + 2024-02-04 12:02:28,832 INFO [alembic.autogenerate.compare:189][MainThread] Detected added table 'models' + 2024-02-04 12:02:28,832 INFO [alembic.autogenerate.compare:633][MainThread] Detected added index ''my_index'' on '('name',)' + Generating /Users/michael/work/oss/pyramid/tutorial/tutorial/alembic/versions/20240204_4b6614165904.py ... done Upgrade to that revision. @@ -245,9 +240,9 @@ The output to your console should be something like this: .. code-block:: text - 2021-01-07 05:16:21,558 INFO [alembic.runtime.migration:155][MainThread] Context impl SQLiteImpl. - 2021-01-07 05:16:21,558 INFO [alembic.runtime.migration:162][MainThread] Will assume non-transactional DDL. - 2021-01-07 05:16:21,560 INFO [alembic.runtime.migration:517][MainThread] Running upgrade -> d7ab09c3fdec, init + 2024-02-04 12:03:04,738 INFO [alembic.runtime.migration:216][MainThread] Context impl SQLiteImpl. + 2024-02-04 12:03:04,738 INFO [alembic.runtime.migration:219][MainThread] Will assume non-transactional DDL. + 2024-02-04 12:03:04,739 INFO [alembic.runtime.migration:622][MainThread] Running upgrade -> 4b6614165904, init .. _load_data_wiki2: @@ -337,24 +332,26 @@ If successful, you will see output something like this: .. code-block:: bash - ======================== test session starts ======================== - platform darwin -- Python 3.9.0, pytest-6.2.1, py-1.10.0, pluggy-0.13.1 - rootdir: /tutorial, inifile: pytest.ini, testpaths: tutorial, tests - plugins: cov-2.10.1 + ====================================== test session starts ====================================== + platform darwin -- Python 3.11.7, pytest-8.0.0, pluggy-1.4.0 + rootdir: /Users/michael/work/oss/pyramid/tutorial + configfile: pyproject.toml + testpaths: tutorial, tests + plugins: cov-4.1.0 collected 5 items - tests/test_functional.py .. [ 40%] - tests/test_views.py ... [100%] - - ---------- coverage: platform darwin, python 3.9.0-final-0 ----------- + tests/test_functional.py .. [ 40%] + tests/test_views.py ... [100%] + + ---------- coverage: platform darwin, python 3.11.7-final-0 ---------- Name Stmts Miss Cover Missing ---------------------------------------------------------------------------------- tutorial/__init__.py 8 0 100% tutorial/alembic/env.py 23 4 83% 28-30, 56 - tutorial/alembic/versions/20200106_8c274fe5f3c4.py 12 2 83% 31-32 - tutorial/models/__init__.py 32 2 94% 71, 82 - tutorial/models/meta.py 5 0 100% - tutorial/models/mymodel.py 8 0 100% + tutorial/alembic/versions/20240204_4b6614165904.py 12 2 83% 31-32 + tutorial/models/__init__.py 32 2 94% 111, 122 + tutorial/models/meta.py 4 0 100% + tutorial/models/mymodel.py 10 0 100% tutorial/pshell.py 7 5 29% 5-13 tutorial/routes.py 3 0 100% tutorial/scripts/__init__.py 0 0 100% @@ -363,13 +360,12 @@ If successful, you will see output something like this: tutorial/views/default.py 13 0 100% tutorial/views/notfound.py 5 0 100% ---------------------------------------------------------------------------------- - TOTAL 138 27 80% + TOTAL 139 27 81% - ===================== 5 passed in 0.77 seconds ====================== + ================================= 5 passed, 6 warnings in 0.54s ================================= Our package doesn't quite have 100% test coverage. - .. _test_and_coverage_cookiecutter_defaults_sql: Test and coverage cookiecutter defaults diff --git a/docs/tutorials/wiki2/src/installation/.coveragerc b/docs/tutorials/wiki2/src/installation/.coveragerc deleted file mode 100644 index 5db0e79cff..0000000000 --- a/docs/tutorials/wiki2/src/installation/.coveragerc +++ /dev/null @@ -1,2 +0,0 @@ -[run] -source = tutorial diff --git a/docs/tutorials/wiki2/src/installation/CHANGES.txt b/docs/tutorials/wiki2/src/installation/CHANGES.txt deleted file mode 100644 index 14b902fd10..0000000000 --- a/docs/tutorials/wiki2/src/installation/CHANGES.txt +++ /dev/null @@ -1,4 +0,0 @@ -0.0 ---- - -- Initial version. diff --git a/docs/tutorials/wiki2/src/installation/MANIFEST.in b/docs/tutorials/wiki2/src/installation/MANIFEST.in index b4624fd1ca..201692c1bc 100644 --- a/docs/tutorials/wiki2/src/installation/MANIFEST.in +++ b/docs/tutorials/wiki2/src/installation/MANIFEST.in @@ -1,4 +1,4 @@ -include *.txt *.ini *.cfg *.rst +include *.txt *.ini *.cfg *.rst *.toml recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 recursive-include tests * recursive-exclude * __pycache__ diff --git a/docs/tutorials/wiki2/src/installation/README.md b/docs/tutorials/wiki2/src/installation/README.md new file mode 100644 index 0000000000..5ac1209d01 --- /dev/null +++ b/docs/tutorials/wiki2/src/installation/README.md @@ -0,0 +1,60 @@ +# myproj + +## Getting Started + +- Change directory into your newly created project if not already there. Your + current directory should be the same as this `README.md` file and `pyproject.toml`. + + ``` + cd tutorial + ``` + +- Create a Python virtual environment, if not already created. + + ``` + python3 -m venv env + ``` + +- Upgrade packaging tools, if necessary. + + ``` + env/bin/pip install --upgrade pip + ``` + +- Install the project in editable mode with its testing requirements. + + ``` + env/bin/pip install -e ".[testing]" + ``` + +- Initialize and upgrade the database using Alembic. + + - Generate your first revision. + + ``` + env/bin/alembic -c development.ini revision --autogenerate -m "init" + ``` + + - Upgrade to that revision. + + ``` + env/bin/alembic -c development.ini upgrade head + ``` + +- Load default data into the database using a script. + + ``` + env/bin/initialize_tutorial_db development.ini + ``` + +- Run your project's tests. + + ``` + env/bin/pytest + ``` + +- Run your project. + + ``` + env/bin/pserve development.ini + ``` diff --git a/docs/tutorials/wiki2/src/installation/README.txt b/docs/tutorials/wiki2/src/installation/README.txt deleted file mode 100644 index ed6b88b49e..0000000000 --- a/docs/tutorials/wiki2/src/installation/README.txt +++ /dev/null @@ -1,44 +0,0 @@ -myproj -====== - -Getting Started ---------------- - -- Change directory into your newly created project if not already there. Your - current directory should be the same as this README.txt file and setup.py. - - cd tutorial - -- Create a Python virtual environment, if not already created. - - python3 -m venv env - -- Upgrade packaging tools, if necessary. - - env/bin/pip install --upgrade pip setuptools - -- Install the project in editable mode with its testing requirements. - - env/bin/pip install -e ".[testing]" - -- Initialize and upgrade the database using Alembic. - - - Generate your first revision. - - env/bin/alembic -c development.ini revision --autogenerate -m "init" - - - Upgrade to that revision. - - env/bin/alembic -c development.ini upgrade head - -- Load default data into the database using a script. - - env/bin/initialize_tutorial_db development.ini - -- Run your project's tests. - - env/bin/pytest - -- Run your project. - - env/bin/pserve development.ini diff --git a/docs/tutorials/wiki2/src/installation/development.ini b/docs/tutorials/wiki2/src/installation/development.ini index f02c4b1b6d..e7baeed371 100644 --- a/docs/tutorials/wiki2/src/installation/development.ini +++ b/docs/tutorials/wiki2/src/installation/development.ini @@ -25,16 +25,16 @@ retry.attempts = 3 [pshell] setup = tutorial.pshell.setup -### -# wsgi server configuration -### - [alembic] # path to migration scripts script_location = tutorial/alembic file_template = %%(year)d%%(month).2d%%(day).2d_%%(rev)s # file_template = %%(rev)s_%%(slug)s +### +# wsgi server configuration +### + [server:main] use = egg:waitress#main listen = localhost:6543 diff --git a/docs/tutorials/wiki2/src/installation/production.ini b/docs/tutorials/wiki2/src/installation/production.ini index f8e83f21f2..f636aaba31 100644 --- a/docs/tutorials/wiki2/src/installation/production.ini +++ b/docs/tutorials/wiki2/src/installation/production.ini @@ -19,16 +19,16 @@ retry.attempts = 3 [pshell] setup = tutorial.pshell.setup -### -# wsgi server configuration -### - [alembic] # path to migration scripts script_location = tutorial/alembic file_template = %%(year)d%%(month).2d%%(day).2d_%%(rev)s # file_template = %%(rev)s_%%(slug)s +### +# wsgi server configuration +### + [server:main] use = egg:waitress#main listen = *:6543 diff --git a/docs/tutorials/wiki2/src/installation/pyproject.toml b/docs/tutorials/wiki2/src/installation/pyproject.toml new file mode 100644 index 0000000000..d03ba48820 --- /dev/null +++ b/docs/tutorials/wiki2/src/installation/pyproject.toml @@ -0,0 +1,58 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +version = "0.0" +name = "tutorial" +authors = [] +description = "myproj" +readme = "README.md" +keywords = ["web", "pyramid", "pylons"] +classifiers = [ + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Framework :: Pyramid", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", +] +requires-python = ">=3.8" +dependencies = [ + "plaster_pastedeploy", + "pyramid", + "pyramid_jinja2", + "pyramid_debugtoolbar", + "waitress", + "alembic", + "pyramid_retry", + "pyramid_tm", + "SQLAlchemy", + "transaction", + "zope.sqlalchemy", +] + +[project.optional-dependencies] +testing = [ + "WebTest", + "pytest", + "pytest-cov", +] + +[project.scripts] +initialize_tutorial_db = "tutorial.scripts.initialize_db:main" + +[project.entry-points."paste.app_factory"] +main = "tutorial:main" + +[tool.setuptools.packages.find] +exclude = ["tests"] + +[tool.coverage.run] +source = "tutorial" + +[tool.pytest.ini_options] +addopts = "--strict-markers" +testpaths = [ + "tutorial", + "tests", +] diff --git a/docs/tutorials/wiki2/src/installation/pytest.ini b/docs/tutorials/wiki2/src/installation/pytest.ini deleted file mode 100644 index 3df78fe9dd..0000000000 --- a/docs/tutorials/wiki2/src/installation/pytest.ini +++ /dev/null @@ -1,6 +0,0 @@ -[pytest] -addopts = --strict-markers - -testpaths = - tutorial - tests diff --git a/docs/tutorials/wiki2/src/installation/setup.py b/docs/tutorials/wiki2/src/installation/setup.py deleted file mode 100644 index 5e7a0111dd..0000000000 --- a/docs/tutorials/wiki2/src/installation/setup.py +++ /dev/null @@ -1,61 +0,0 @@ -import os - -from setuptools import setup, find_packages - -here = os.path.abspath(os.path.dirname(__file__)) -with open(os.path.join(here, 'README.txt')) as f: - README = f.read() -with open(os.path.join(here, 'CHANGES.txt')) as f: - CHANGES = f.read() - -requires = [ - 'plaster_pastedeploy', - 'pyramid', - 'pyramid_jinja2', - 'pyramid_debugtoolbar', - 'waitress', - 'alembic', - 'pyramid_retry', - 'pyramid_tm', - 'SQLAlchemy', - 'transaction', - 'zope.sqlalchemy', -] - -tests_require = [ - 'WebTest', - 'pytest', - 'pytest-cov', -] - -setup( - name='tutorial', - version='0.0', - description='myproj', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - 'Programming Language :: Python', - 'Framework :: Pyramid', - 'Topic :: Internet :: WWW/HTTP', - 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', - ], - author='', - author_email='', - url='', - keywords='web pyramid pylons', - packages=find_packages(exclude=['tests']), - include_package_data=True, - zip_safe=False, - extras_require={ - 'testing': tests_require, - }, - install_requires=requires, - entry_points={ - 'paste.app_factory': [ - 'main = tutorial:main', - ], - 'console_scripts': [ - 'initialize_tutorial_db=tutorial.scripts.initialize_db:main', - ], - }, -) diff --git a/docs/tutorials/wiki2/src/installation/testing.ini b/docs/tutorials/wiki2/src/installation/testing.ini index 5caa1a8dc2..503cf30188 100644 --- a/docs/tutorials/wiki2/src/installation/testing.ini +++ b/docs/tutorials/wiki2/src/installation/testing.ini @@ -19,16 +19,16 @@ retry.attempts = 3 [pshell] setup = tutorial.pshell.setup -### -# wsgi server configuration -### - [alembic] # path to migration scripts script_location = tutorial/alembic file_template = %%(year)d%%(month).2d%%(day).2d_%%(rev)s # file_template = %%(rev)s_%%(slug)s +### +# wsgi server configuration +### + [server:main] use = egg:waitress#main listen = localhost:6543 diff --git a/docs/tutorials/wiki2/src/installation/tutorial/models/meta.py b/docs/tutorials/wiki2/src/installation/tutorial/models/meta.py index d659c78573..62d52fcf3e 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/models/meta.py +++ b/docs/tutorials/wiki2/src/installation/tutorial/models/meta.py @@ -1,16 +1,12 @@ -from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy.schema import MetaData +from sqlalchemy import MetaData +from sqlalchemy.orm import DeclarativeBase -# Recommended naming convention used by Alembic, as various different database -# providers will autogenerate vastly different names making migrations more -# difficult. See: https://alembic.sqlalchemy.org/en/latest/naming.html -NAMING_CONVENTION = { - "ix": "ix_%(column_0_label)s", - "uq": "uq_%(table_name)s_%(column_0_name)s", - "ck": "ck_%(table_name)s_%(constraint_name)s", - "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s", - "pk": "pk_%(table_name)s" -} -metadata = MetaData(naming_convention=NAMING_CONVENTION) -Base = declarative_base(metadata=metadata) +class Base(DeclarativeBase): + metadata = MetaData(naming_convention={ + "ix": "ix_%(column_0_label)s", + "uq": "uq_%(table_name)s_%(column_0_name)s", + "ck": "ck_%(table_name)s_`%(constraint_name)s`", + "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s", + "pk": "pk_%(table_name)s" + }) diff --git a/docs/tutorials/wiki2/src/installation/tutorial/models/mymodel.py b/docs/tutorials/wiki2/src/installation/tutorial/models/mymodel.py index d65a01a422..947c7b65f0 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/models/mymodel.py +++ b/docs/tutorials/wiki2/src/installation/tutorial/models/mymodel.py @@ -1,18 +1,15 @@ -from sqlalchemy import ( - Column, - Index, - Integer, - Text, -) +from sqlalchemy import Index, Integer, Text +from sqlalchemy.orm import Mapped, mapped_column +from typing import Optional from .meta import Base class MyModel(Base): __tablename__ = 'models' - id = Column(Integer, primary_key=True) - name = Column(Text) - value = Column(Integer) + id: Mapped[int] = mapped_column(primary_key=True) + name: Mapped[Optional[str]] + value: Mapped[Optional[int]] Index('my_index', MyModel.name, unique=True, mysql_length=255) diff --git a/docs/tutorials/wiki2/src/installation/tutorial/views/default.py b/docs/tutorials/wiki2/src/installation/tutorial/views/default.py index a0f654d385..3eeb7f26de 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/views/default.py +++ b/docs/tutorials/wiki2/src/installation/tutorial/views/default.py @@ -1,6 +1,6 @@ from pyramid.view import view_config from pyramid.response import Response -from sqlalchemy.exc import SQLAlchemyError +import sqlalchemy as sa from .. import models @@ -8,9 +8,9 @@ @view_config(route_name='home', renderer='tutorial:templates/mytemplate.jinja2') def my_view(request): try: - query = request.dbsession.query(models.MyModel) - one = query.filter(models.MyModel.name == 'one').one() - except SQLAlchemyError: + query = sa.select(models.MyModel).where(models.MyModel.name == 'one') + one = request.dbsession.execute(query).scalar_one() + except sa.exc.SQLAlchemyError: return Response(db_err_msg, content_type='text/plain', status=500) return {'one': one, 'project': 'myproj'}