Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking β€œSign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

πŸ› Fixes duplicates in tags listings and new priority to enforce order #6479

Merged
merged 17 commits into from
Oct 3, 2024
Prev Previous commit
Next Next commit
new api
pcrespov committed Oct 3, 2024

Verified

This commit was signed with the committer’s verified signature.
Mamaduka George Mamadashvili
commit 9df3396e1b2dfae52a0a10bb94c0807441a4544b
58 changes: 58 additions & 0 deletions services/web/server/src/simcore_service_webserver/tags/_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
""" _api: implements `tags` plugin **service layer**
"""

from aiohttp import web
from models_library.basic_types import IdInt
from models_library.users import UserID
from servicelib.aiohttp.db_asyncpg_engine import get_async_engine
from simcore_postgres_database.utils_tags import TagsRepo
from sqlalchemy.ext.asyncio import AsyncEngine

from .schemas import TagCreate, TagGet, TagUpdate


async def create_tag(
app: web.Application, user_id: UserID, new_tag: TagCreate
) -> TagGet:
engine: AsyncEngine = get_async_engine(app)

repo = TagsRepo(engine)
tag = await repo.create(
user_id=user_id,
read=True,
write=True,
delete=True,
**new_tag.dict(exclude_unset=True),
)
return TagGet.from_db(tag)


async def list_tags(
app: web.Application,
user_id: UserID,
) -> list[TagGet]:
engine: AsyncEngine = get_async_engine(app)
repo = TagsRepo(engine)
tags = await repo.list_all(user_id=user_id)
return [TagGet.from_db(t) for t in tags]


async def update_tag(
app: web.Application, user_id: UserID, tag_id: IdInt, tag_updates: TagUpdate
) -> TagGet:
engine: AsyncEngine = get_async_engine(app)

repo = TagsRepo(engine)
tag = await repo.update(
user_id=user_id,
tag_id=tag_id,
**tag_updates.dict(exclude_unset=True),
)
return TagGet.from_db(tag)


async def delete_tag(app: web.Application, user_id: UserID, tag_id: IdInt):
engine: AsyncEngine = get_async_engine(app)

repo = TagsRepo(engine)
await repo.delete(user_id=user_id, tag_id=tag_id)
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import functools

from aiohttp import web
from aiopg.sa.engine import Engine
from pydantic import parse_obj_as
from servicelib.aiohttp.requests_validation import (
parse_request_body_as,
@@ -12,17 +11,15 @@
from simcore_postgres_database.utils_tags import (
TagNotFoundError,
TagOperationNotAllowedError,
TagsRepo,
)

from .._meta import API_VTAG as VTAG
from ..db.plugin import get_database_engine
from ..login.decorators import login_required
from ..security.decorators import permission_required
from ..utils_aiohttp import envelope_json_response
from . import _api
from .schemas import (
TagCreate,
TagGet,
TagGroupCreate,
TagGroupGet,
TagGroupPathParams,
@@ -55,70 +52,56 @@ async def wrapper(request: web.Request) -> web.StreamResponse:
@permission_required("tag.crud.*")
@_handle_tags_exceptions
async def create_tag(request: web.Request):
engine: Engine = get_database_engine(request.app)
assert request.app # nosec
req_ctx = TagRequestContext.parse_obj(request)
new_tag = await parse_request_body_as(TagCreate, request)

repo = TagsRepo(user_id=req_ctx.user_id)
async with engine.acquire() as conn:
tag = await repo.create(
conn,
read=True,
write=True,
delete=True,
**new_tag.dict(exclude_unset=True),
)
model = TagGet.from_db(tag)
return envelope_json_response(model)
created = await _api.create_tag(
request.app, user_id=req_ctx.user_id, new_tag=new_tag
)
return envelope_json_response(created)


@routes.get(f"/{VTAG}/tags", name="list_tags")
@login_required
@permission_required("tag.crud.*")
@_handle_tags_exceptions
async def list_tags(request: web.Request):
engine: Engine = get_database_engine(request.app)
req_ctx = TagRequestContext.parse_obj(request)

repo = TagsRepo(user_id=req_ctx.user_id)
async with engine.acquire() as conn:
tags = await repo.list_all(conn)
return envelope_json_response(
[TagGet.from_db(t).dict(by_alias=True) for t in tags]
)
req_ctx = TagRequestContext.parse_obj(request)
got = await _api.list_tags(request.app, user_id=req_ctx.user_id)
return envelope_json_response(got)


@routes.patch(f"/{VTAG}/tags/{{tag_id}}", name="update_tag")
@login_required
@permission_required("tag.crud.*")
@_handle_tags_exceptions
async def update_tag(request: web.Request):
engine: Engine = get_database_engine(request.app)
req_ctx = TagRequestContext.parse_obj(request)
path_params = parse_request_path_parameters_as(TagPathParams, request)
tag_updates = await parse_request_body_as(TagUpdate, request)

repo = TagsRepo(user_id=req_ctx.user_id)
async with engine.acquire() as conn:
tag = await repo.update(
conn, path_params.tag_id, **tag_updates.dict(exclude_unset=True)
)
model = TagGet.from_db(tag)
return envelope_json_response(model)
updated = await _api.update_tag(
request.app,
user_id=req_ctx.user_id,
tag_id=path_params.tag_id,
tag_updates=tag_updates,
)
return envelope_json_response(updated)


@routes.delete(f"/{VTAG}/tags/{{tag_id}}", name="delete_tag")
@login_required
@permission_required("tag.crud.*")
@_handle_tags_exceptions
async def delete_tag(request: web.Request):
engine: Engine = get_database_engine(request.app)
req_ctx = TagRequestContext.parse_obj(request)
path_params = parse_request_path_parameters_as(TagPathParams, request)

repo = TagsRepo(user_id=req_ctx.user_id)
async with engine.acquire() as conn:
await repo.delete(conn, tag_id=path_params.tag_id)
await _api.delete_tag(
request.app, user_id=req_ctx.user_id, tag_id=path_params.tag_id
)

raise web.HTTPNoContent(content_type=MIMETYPE_APPLICATION_JSON)