Skip to content

Commit

Permalink
✨ Is765/extends products plugin (⚠️ devops) (#3540)
Browse files Browse the repository at this point in the history
  • Loading branch information
pcrespov authored Nov 14, 2022
1 parent 8532cf0 commit a028fcd
Show file tree
Hide file tree
Showing 19 changed files with 749 additions and 245 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
"""new products table
Revision ID: 2ca532b0831f
Revises: 90c92dae8fc9
Create Date: 2022-11-11 10:54:13.921120+00:00
"""
import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = "2ca532b0831f"
down_revision = "90c92dae8fc9"
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column(
"products",
sa.Column("vendor", postgresql.JSONB(astext_type=sa.Text()), nullable=True),
)
op.add_column(
"products",
sa.Column("issues", postgresql.JSONB(astext_type=sa.Text()), nullable=True),
)
op.add_column(
"products",
sa.Column("manuals", postgresql.JSONB(astext_type=sa.Text()), nullable=True),
)
op.add_column(
"products",
sa.Column("support", postgresql.JSONB(astext_type=sa.Text()), nullable=True),
)
op.drop_column("products", "feedback_form_url")
op.drop_column("products", "manual_extra_url")
op.drop_column("products", "issues_new_url")
op.drop_column("products", "manual_url")
op.drop_column("products", "issues_login_url")
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column(
"products",
sa.Column(
"issues_login_url",
sa.VARCHAR(),
server_default=sa.text(
"'https://github.com/ITISFoundation/osparc-simcore/issues'::character varying"
),
autoincrement=False,
nullable=True,
),
)
op.add_column(
"products",
sa.Column(
"manual_url",
sa.VARCHAR(),
server_default=sa.text(
"'https://itisfoundation.github.io/osparc-manual/'::character varying"
),
autoincrement=False,
nullable=False,
),
)
op.add_column(
"products",
sa.Column(
"issues_new_url",
sa.VARCHAR(),
server_default=sa.text(
"'https://github.com/ITISFoundation/osparc-simcore/issues/new'::character varying"
),
autoincrement=False,
nullable=True,
),
)
op.add_column(
"products",
sa.Column(
"manual_extra_url",
sa.VARCHAR(),
server_default=sa.text(
"'https://itisfoundation.github.io/osparc-manual-z43/'::character varying"
),
autoincrement=False,
nullable=True,
),
)
op.add_column(
"products",
sa.Column(
"feedback_form_url", sa.VARCHAR(), autoincrement=False, nullable=True
),
)
op.drop_column("products", "support")
op.drop_column("products", "manuals")
op.drop_column("products", "issues")
op.drop_column("products", "vendor")
# ### end Alembic commands ###
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,76 @@
- Every product has a front-end with exactly the same name
"""

from typing import Literal, TypedDict

import sqlalchemy as sa
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.sql import func

from .base import metadata
from .jinja2_templates import jinja2_templates


#
# Layout of the data in the JSONB columns
#
class Vendor(TypedDict, total=True):
"""
Brand information about the vendor
E.g. company name, address, copyright, etc.
"""

name: str
copyright: str
url: str


class IssueTracker(TypedDict, total=True):
"""Link to actions in an online issue tracker (e.g. in fogbugz, github, gitlab ...)
e.g. URL to create a new issue for this product
new_url=https://github.com/ITISFoundation/osparc-simcore/issues/new/choose
"""

label: str
login_url: str
new_url: str


class Manual(TypedDict, total=True):
label: str
url: str


class WebFeedback(TypedDict, total=True):
"""URL to a feedback form (e.g. google forms etc)"""

kind: Literal["web"]
label: str
url: str


class EmailFeedback(TypedDict, total=True):
"""Give feedback via email"""

kind: Literal["email"]
label: str
email: str


class Forum(TypedDict, total=True):
"""Link to a forum"""

kind: Literal["forum"]
label: str
url: str


#
# Table
#

products = sa.Table(
"products",
metadata,
Expand Down Expand Up @@ -58,41 +122,19 @@
"The SID of the Messaging Service you want to associate with the message."
"When set to None, this feature is disabled.",
),
sa.Column("vendor", JSONB, nullable=True, doc="Info about the Vendor"),
sa.Column("issues", JSONB, nullable=True, doc="Issue trackers: list[IssueTracker]"),
sa.Column(
"manual_url",
sa.String,
nullable=False,
server_default="https://itisfoundation.github.io/osparc-manual/",
doc="URL to main product's manual",
),
sa.Column(
"manual_extra_url",
sa.String,
nullable=True,
server_default="https://itisfoundation.github.io/osparc-manual-z43/",
doc="URL to extra product's manual",
),
sa.Column(
"issues_login_url",
sa.String,
"manuals",
JSONB,
nullable=True,
server_default="https://github.com/ITISFoundation/osparc-simcore/issues",
doc="URL to login in the issue tracker site"
"NOTE: Set nullable because some POs consider that issue tracking is optional in some products.",
doc="User manuals: list[Manual]",
),
sa.Column(
"issues_new_url",
sa.String,
nullable=True,
server_default="https://github.com/ITISFoundation/osparc-simcore/issues/new",
doc="URL to create a new issue for this product (e.g. fogbugz new case, github new issues)"
"NOTE: Set nullable because some POs consider that issue tracking is optional in some products.",
),
sa.Column(
"feedback_form_url",
sa.String,
"support",
JSONB,
nullable=True,
doc="URL to a feedback form (e.g. google forms etc)",
doc="User support: list[Forum | EmailFeedback | WebFeedback ]",
),
sa.Column(
"registration_email_template",
Expand Down
85 changes: 79 additions & 6 deletions packages/postgres-database/tests/test_models_products.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
# pylint: disable=unused-argument


import json
from pathlib import Path
from pprint import pprint
from typing import Callable

import pytest
Expand All @@ -13,11 +15,19 @@
from aiopg.sa.exc import ResourceClosedError
from aiopg.sa.result import ResultProxy, RowProxy
from simcore_postgres_database.models.jinja2_templates import jinja2_templates
from simcore_postgres_database.models.products import (
EmailFeedback,
Forum,
IssueTracker,
Manual,
Vendor,
WebFeedback,
)
from simcore_postgres_database.webserver_models import products


@pytest.fixture
def product_sample() -> dict:
def products_regex() -> dict:
return {
"osparc": r"^osparc.",
"s4l": r"(^s4l[\.-])|(^sim4life\.)",
Expand All @@ -27,10 +37,10 @@ def product_sample() -> dict:

@pytest.fixture
def make_products_table(
product_sample: dict,
products_regex: dict,
) -> Callable:
async def _make(conn) -> None:
for name, regex in product_sample.items():
for name, regex in products_regex.items():
result = await conn.execute(
products.insert().values(name=name, host_regex=regex)
)
Expand All @@ -44,7 +54,7 @@ async def _make(conn) -> None:


async def test_load_products(
pg_engine: Engine, make_products_table: Callable, product_sample: dict
pg_engine: Engine, make_products_table: Callable, products_regex: dict
):
exclude = {
products.c.created,
Expand All @@ -63,7 +73,7 @@ async def test_load_products(

assert {
row[products.c.name]: row[products.c.host_regex] for row in rows
} == product_sample
} == products_regex


async def test_jinja2_templates_table(
Expand Down Expand Up @@ -123,8 +133,8 @@ async def test_jinja2_templates_table(
result: ResultProxy = await conn.execute(stmt)
assert result.rowcount == 2
assert await result.fetchall() == [
("s4l", "registration_email.jinja2", "s4l web"),
("osparc", "registration_email.jinja2", "osparc"),
("s4l", "registration_email.jinja2", "s4l web"),
]

assert (
Expand All @@ -144,3 +154,66 @@ async def test_jinja2_templates_table(
)
is None
)


async def test_insert_select_product(
pg_engine: Engine,
):
osparc_product = {
"name": "osparc",
"display_name": "o²S²PARC",
"short_name": "osparc",
"host_regex": r"([\.-]{0,1}osparc[\.-])",
"support_email": "[email protected]",
"twilio_messaging_sid": None,
"vendor": Vendor(
name="ACME",
copyright="© ACME correcaminos",
url="https://acme.com",
),
"issues": [
IssueTracker(
label="github",
login_url="https://github.com/ITISFoundation/osparc-simcore",
new_url="https://github.com/ITISFoundation/osparc-simcore/issues/new/choose",
),
IssueTracker(
label="fogbugz",
login_url="https://fogbugz.com/login",
new_url="https://fogbugz.com/new?project=123",
),
],
"manuals": [
Manual(label="main", url="doc.acme.com"),
Manual(label="z43", url="yet-another-manual.acme.com"),
],
"support": [
Forum(label="forum", kind="forum", url="forum.acme.com"),
EmailFeedback(label="email", kind="email", email="[email protected]"),
WebFeedback(label="web-form", kind="web", url="support.acme.com"),
],
}

print(json.dumps(osparc_product))

async with pg_engine.acquire() as conn:
# writes
stmt = products.insert().values(**osparc_product).returning(products.c.name)
name = await conn.scalar(stmt)

# reads
stmt = sa.select(products).where(products.c.name == name)
row = await (await conn.execute(stmt)).fetchone()
print(row)
assert row

pprint(dict(**row))

assert row.manuals
assert row.manuals == osparc_product["manuals"]

assert row.vendor == {
"url": "https://acme.com",
"name": "ACME",
"copyright": "© ACME correcaminos",
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from models_library.basic_types import BootModeEnum, LogLevel
from pydantic import AnyHttpUrl, Field, SecretStr
from pydantic.class_validators import validator
from servicelib.statics_constants import FRONTEND_APP_DEFAULT
from settings_library.base import BaseCustomSettings
from settings_library.catalog import CatalogSettings
from settings_library.postgres import PostgresSettings
Expand Down Expand Up @@ -112,7 +113,7 @@ class ApplicationSettings(BasicSettings):
auto_default_from_env=True
)
API_SERVER_DEFAULT_PRODUCT_NAME: str = Field(
default="osparc", description="The API-server default product name"
default=FRONTEND_APP_DEFAULT, description="The API-server default product name"
)

# DIAGNOSTICS
Expand Down
Loading

0 comments on commit a028fcd

Please sign in to comment.