From 03223a7e480b5692c59ab9f16cfc3c71fd7039f5 Mon Sep 17 00:00:00 2001 From: Tasko Olevski Date: Tue, 27 Aug 2024 23:15:37 +0200 Subject: [PATCH] chore: use PurePosixPath type in sqlalchemy --- ..._expand_and_separate_environments_from_.py | 2 +- components/renku_data_services/session/db.py | 8 +++----- components/renku_data_services/session/orm.py | 10 +++++----- .../renku_data_services/utils/sqlalchemy.py | 20 +++++++++++++++++++ .../data_api/test_migrations.py | 14 ++++++------- 5 files changed, 36 insertions(+), 18 deletions(-) diff --git a/components/renku_data_services/migrations/versions/584598f3b769_expand_and_separate_environments_from_.py b/components/renku_data_services/migrations/versions/584598f3b769_expand_and_separate_environments_from_.py index b85fff125..6973937d6 100644 --- a/components/renku_data_services/migrations/versions/584598f3b769_expand_and_separate_environments_from_.py +++ b/components/renku_data_services/migrations/versions/584598f3b769_expand_and_separate_environments_from_.py @@ -21,7 +21,7 @@ mount_dir: str = "/home/jovyan/work" uid: int = 1000 gid: int = 1000 -port: int = 4180 +port: int = 8888 def upgrade() -> None: diff --git a/components/renku_data_services/session/db.py b/components/renku_data_services/session/db.py index 5d182c2e9..e4b390096 100644 --- a/components/renku_data_services/session/db.py +++ b/components/renku_data_services/session/db.py @@ -74,8 +74,8 @@ async def __insert_environment( container_image=new_environment.container_image, default_url=new_environment.default_url, port=new_environment.port, - working_directory=new_environment.working_directory.as_posix(), - mount_directory=new_environment.mount_directory.as_posix(), + working_directory=new_environment.working_directory, + mount_directory=new_environment.mount_directory, uid=new_environment.uid, gid=new_environment.gid, environment_kind=new_environment.environment_kind, @@ -229,9 +229,7 @@ async def insert_launcher( raise errors.UnauthorizedError(message="You do not have the required permissions for this operation.") project_id = new_launcher.project_id - authorized = await self.project_authz.has_permission( - user, ResourceType.project, ULID.from_str(project_id), Scope.WRITE - ) + authorized = await self.project_authz.has_permission(user, ResourceType.project, project_id, Scope.WRITE) if not authorized: raise errors.MissingResourceError( message=f"Project with id '{project_id}' does not exist or you do not have access to it." diff --git a/components/renku_data_services/session/orm.py b/components/renku_data_services/session/orm.py index e99f238ce..12217cc39 100644 --- a/components/renku_data_services/session/orm.py +++ b/components/renku_data_services/session/orm.py @@ -12,7 +12,7 @@ from renku_data_services.crc.orm import ResourceClassORM from renku_data_services.project.orm import ProjectORM from renku_data_services.session import models -from renku_data_services.utils.sqlalchemy import ULIDType +from renku_data_services.utils.sqlalchemy import PurePosixPathType, ULIDType metadata_obj = MetaData(schema="sessions") # Has to match alembic ini section name JSONVariant = JSON().with_variant(JSONB(), "postgresql") @@ -51,8 +51,8 @@ class EnvironmentORM(BaseORM): """Default URL path to open in a session.""" port: Mapped[int] = mapped_column("port") - working_directory: Mapped[str] = mapped_column("working_directory", String()) - mount_directory: Mapped[str] = mapped_column("mount_directory", String()) + working_directory: Mapped[PurePosixPath] = mapped_column("working_directory", PurePosixPathType) + mount_directory: Mapped[PurePosixPath] = mapped_column("mount_directory", PurePosixPathType) uid: Mapped[int] = mapped_column("uid") gid: Mapped[int] = mapped_column("gid") environment_kind: Mapped[models.EnvironmentKind] = mapped_column("environment_kind") @@ -72,8 +72,8 @@ def dump(self) -> models.Environment: gid=self.gid, uid=self.uid, environment_kind=self.environment_kind, - mount_directory=PurePosixPath(self.mount_directory), - working_directory=PurePosixPath(self.working_directory), + mount_directory=self.mount_directory, + working_directory=self.working_directory, port=self.port, args=self.args, command=self.command, diff --git a/components/renku_data_services/utils/sqlalchemy.py b/components/renku_data_services/utils/sqlalchemy.py index f1cd59c9b..82bcfb9db 100644 --- a/components/renku_data_services/utils/sqlalchemy.py +++ b/components/renku_data_services/utils/sqlalchemy.py @@ -1,5 +1,6 @@ """Utilities for SQLAlchemy.""" +from pathlib import PurePosixPath from typing import cast from sqlalchemy import Dialect, types @@ -23,3 +24,22 @@ def process_result_value(self, value: str | None, dialect: Dialect) -> ULID | No if value is None: return None return cast(ULID, ULID.from_str(value)) # cast because mypy doesn't understand ULID type annotations + + +class PurePosixPathType(types.TypeDecorator): + """Wrapper type for Path <--> str conversion.""" + + impl = types.String + cache_ok = True + + def process_bind_param(self, value: PurePosixPath | None, dialect: Dialect) -> str | None: + """Transform value for storing in the database.""" + if value is None: + return None + return value.as_posix() + + def process_result_value(self, value: str | None, dialect: Dialect) -> PurePosixPath | None: + """Transform string from database into PosixPath.""" + if value is None: + return None + return PurePosixPath(value) diff --git a/test/bases/renku_data_services/data_api/test_migrations.py b/test/bases/renku_data_services/data_api/test_migrations.py index ec45a911c..e1b4e3274 100644 --- a/test/bases/renku_data_services/data_api/test_migrations.py +++ b/test/bases/renku_data_services/data_api/test_migrations.py @@ -100,9 +100,8 @@ async def test_migration_to_f34b87ddd954( @pytest.mark.asyncio -async def test_migration_to_584598f3b769(sanic_client_no_migrations: SanicASGITestClient, app_config: Config) -> None: +async def test_migration_to_584598f3b769(app_config: Config) -> None: run_migrations_for_app("common", "dcc1c1ee662f") - sanic_client = sanic_client_no_migrations await app_config.kc_user_repo.initialize(app_config.kc_api) await app_config.group_repo.generate_user_namespaces() env_id = str(ULID()) @@ -122,14 +121,15 @@ async def test_migration_to_584598f3b769(sanic_client_no_migrations: SanicASGITe ) ) run_migrations_for_app("common", "584598f3b769") - _, response = await sanic_client.get("/api/data/environments") - assert response.status_code == 200, response.text - assert len(response.json) == 1 - env = response.json[0] + async with app_config.db.async_session_maker() as session, session.begin(): + res = await session.execute(sa.text("SELECT * FROM sessions.environments")) + data = res.all() + assert len(data) == 1 + env = data[0]._mapping assert env["id"] == env_id assert env["name"] == "test" assert env["container_image"] == "test" assert env["default_url"] == "/test" - assert env["port"] == 4180 + assert env["port"] == 8888 assert env["uid"] == 1000 assert env["gid"] == 1000