Skip to content

Commit

Permalink
♻️ Preparation of tags for both services and projects 🗃️ (#6092)
Browse files Browse the repository at this point in the history
  • Loading branch information
pcrespov authored Aug 27, 2024
1 parent 8cfffaa commit 2e2993c
Show file tree
Hide file tree
Showing 20 changed files with 724 additions and 275 deletions.
19 changes: 14 additions & 5 deletions api/specs/web-server/_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@
# pylint: disable=too-many-arguments


from fastapi import APIRouter, status
from typing import Annotated

from fastapi import APIRouter, Depends, status
from models_library.generics import Envelope
from simcore_service_webserver._meta import API_VTAG
from simcore_service_webserver.tags._handlers import TagCreate, TagGet, TagUpdate
from simcore_service_webserver.tags._handlers import (
TagCreate,
TagGet,
TagPathParams,
TagUpdate,
)

router = APIRouter(prefix=f"/{API_VTAG}", tags=["tags"])

Expand All @@ -16,7 +23,7 @@
"/tags",
response_model=Envelope[TagGet],
)
async def create_tag(create: TagCreate):
async def create_tag(_body: TagCreate):
...


Expand All @@ -32,13 +39,15 @@ async def list_tags():
"/tags/{tag_id}",
response_model=Envelope[TagGet],
)
async def update_tag(tag_id: int, update: TagUpdate):
async def update_tag(
_path_params: Annotated[TagPathParams, Depends()], _body: TagUpdate
):
...


@router.delete(
"/tags/{tag_id}",
status_code=status.HTTP_204_NO_CONTENT,
)
async def delete_tag(tag_id: int):
async def delete_tag(_path_params: Annotated[TagPathParams, Depends()]):
...
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""renamed study_tags table
Revision ID: 7604e65e2f83
Revises: 617e0ecaf602
Create Date: 2024-08-23 12:03:59.328670+00:00
"""
from alembic import op

# revision identifiers, used by Alembic.
revision = "7604e65e2f83"
down_revision = "617e0ecaf602"
branch_labels = None
depends_on = None


def upgrade():
op.rename_table("study_tags", "projects_tags")

# Rename the column from study_id to project_id in the renamed table
op.alter_column("projects_tags", "study_id", new_column_name="project_id")


def downgrade():
# Reverse the column rename from project_id to study_id
op.alter_column("projects_tags", "project_id", new_column_name="study_id")

# Reverse the table rename from projects_tags to study_tags
op.rename_table("projects_tags", "study_tags")
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""new services_tags table
Revision ID: e8057a4a7bb0
Revises: 7604e65e2f83
Create Date: 2024-08-23 12:12:32.883771+00:00
"""
import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "e8057a4a7bb0"
down_revision = "7604e65e2f83"
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"services_tags",
sa.Column("service_key", sa.String(), nullable=False),
sa.Column("service_version", sa.String(), nullable=False),
sa.Column("tag_id", sa.BigInteger(), nullable=False),
sa.ForeignKeyConstraint(
["service_key", "service_version"],
["services_meta_data.key", "services_meta_data.version"],
onupdate="CASCADE",
ondelete="CASCADE",
),
sa.ForeignKeyConstraint(
["tag_id"], ["tags.id"], onupdate="CASCADE", ondelete="CASCADE"
),
sa.UniqueConstraint(
"service_key", "service_version", "tag_id", name="services_tags_uc"
),
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("services_tags")
# ### end Alembic commands ###
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""rename tags_to_groups
Revision ID: feca36c8e18f
Revises: e8057a4a7bb0
Create Date: 2024-08-23 12:30:56.650085+00:00
"""
from alembic import op

# revision identifiers, used by Alembic.
revision = "feca36c8e18f"
down_revision = "e8057a4a7bb0"
branch_labels = None
depends_on = None


def upgrade():
op.rename_table("tags_to_groups", "tags_access_rights")


def downgrade():
# Reverse the table rename from projects_tags to study_tags
op.rename_table("tags_access_rights", "tags_to_groups")
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import sqlalchemy as sa

from .base import metadata
from .projects import projects
from .tags import tags

projects_tags = sa.Table(
#
# Tags associated to a project (many-to-many relation)
#
"projects_tags",
metadata,
sa.Column(
"project_id",
sa.BigInteger,
sa.ForeignKey(projects.c.id, onupdate="CASCADE", ondelete="CASCADE"),
nullable=False,
doc="NOTE that project.c.id != project.c.uuid",
),
sa.Column(
"tag_id",
sa.BigInteger,
sa.ForeignKey(tags.c.id, onupdate="CASCADE", ondelete="CASCADE"),
nullable=False,
),
sa.UniqueConstraint("project_id", "tag_id"),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import sqlalchemy as sa

from .base import metadata
from .tags import tags

services_tags = sa.Table(
#
# Tags assigned to a service (many-to-many relation)
#
"services_tags",
metadata,
# Service
sa.Column(
"service_key",
sa.String,
nullable=False,
doc="Service Key Identifier",
),
sa.Column(
"service_version",
sa.String,
nullable=False,
doc="Service version",
),
# Tag
sa.Column(
"tag_id",
sa.BigInteger,
sa.ForeignKey(tags.c.id, onupdate="CASCADE", ondelete="CASCADE"),
nullable=False,
),
# Constraints
sa.ForeignKeyConstraint(
["service_key", "service_version"],
["services_meta_data.key", "services_meta_data.version"],
onupdate="CASCADE",
ondelete="CASCADE",
),
sa.UniqueConstraint(
"service_key", "service_version", "tag_id", name="services_tags_uc"
),
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import sqlalchemy as sa

from ._common import column_created_datetime, column_modified_datetime
from .base import metadata

#
Expand Down Expand Up @@ -35,86 +34,3 @@
doc="Hex color (see https://www.color-hex.com/)",
),
)


#
# tags_to_groups: Maps tags with groups to define the level of access
# of a group (group_id) for the corresponding tag (tag_id)
#
tags_to_groups = sa.Table(
"tags_to_groups",
metadata,
sa.Column(
"tag_id",
sa.BigInteger(),
sa.ForeignKey(
tags.c.id,
onupdate="CASCADE",
ondelete="CASCADE",
name="fk_tag_to_group_tag_id",
),
nullable=False,
doc="Tag unique ID",
),
sa.Column(
"group_id",
sa.BigInteger,
sa.ForeignKey(
"groups.gid",
onupdate="CASCADE",
ondelete="CASCADE",
name="fk_tag_to_group_group_id",
),
nullable=False,
doc="Group unique ID",
),
# ACCESS RIGHTS ---
sa.Column(
"read",
sa.Boolean(),
nullable=False,
server_default=sa.sql.expression.true(),
doc="If true, group can *read* a tag."
"This column can be used to set the tag invisible",
),
sa.Column(
"write",
sa.Boolean(),
nullable=False,
server_default=sa.sql.expression.false(),
doc="If true, group can *create* and *update* a tag",
),
sa.Column(
"delete",
sa.Boolean(),
nullable=False,
server_default=sa.sql.expression.false(),
doc="If true, group can *delete* the tag",
),
# TIME STAMPS ----
column_created_datetime(timezone=False),
column_modified_datetime(timezone=False),
sa.UniqueConstraint("tag_id", "group_id"),
)


#
# study_tags: projects marked with tags
#
study_tags = sa.Table(
"study_tags",
metadata,
sa.Column(
"study_id",
sa.BigInteger,
sa.ForeignKey("projects.id", onupdate="CASCADE", ondelete="CASCADE"),
nullable=False,
),
sa.Column(
"tag_id",
sa.BigInteger,
sa.ForeignKey("tags.id", onupdate="CASCADE", ondelete="CASCADE"),
nullable=False,
),
sa.UniqueConstraint("study_id", "tag_id"),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import sqlalchemy as sa

from ._common import column_created_datetime, column_modified_datetime
from .base import metadata
from .groups import groups
from .tags import tags

tags_access_rights = sa.Table(
#
# Maps tags with groups to define the level of access rights
# of a group (group_id) for the corresponding tag (tag_id)
#
"tags_access_rights",
metadata,
sa.Column(
"tag_id",
sa.BigInteger(),
sa.ForeignKey(
tags.c.id,
onupdate="CASCADE",
ondelete="CASCADE",
name="fk_tag_to_group_tag_id",
),
nullable=False,
doc="Tag unique ID",
),
sa.Column(
"group_id",
sa.BigInteger,
sa.ForeignKey(
groups.c.gid,
onupdate="CASCADE",
ondelete="CASCADE",
name="fk_tag_to_group_group_id",
),
nullable=False,
doc="Group unique ID",
),
# ACCESS RIGHTS ---
sa.Column(
"read",
sa.Boolean(),
nullable=False,
server_default=sa.sql.expression.true(),
doc="If true, group can *read* a tag."
"This column can be used to set the tag invisible",
),
sa.Column(
"write",
sa.Boolean(),
nullable=False,
server_default=sa.sql.expression.false(),
doc="If true, group can *create* and *update* a tag",
),
sa.Column(
"delete",
sa.Boolean(),
nullable=False,
server_default=sa.sql.expression.false(),
doc="If true, group can *delete* the tag",
),
# TIME STAMPS ----
column_created_datetime(timezone=False),
column_modified_datetime(timezone=False),
sa.UniqueConstraint("tag_id", "group_id"),
)
Loading

0 comments on commit 2e2993c

Please sign in to comment.