diff --git a/.github/workflows/test_publish.yml b/.github/workflows/test_publish.yml index dc3f4e92d..df760db24 100644 --- a/.github/workflows/test_publish.yml +++ b/.github/workflows/test_publish.yml @@ -63,53 +63,6 @@ jobs: ${{ steps.docker_image.outputs.image_repository }}:${{ steps.docker_image.outputs.image_tag }} ${{ steps.docker_image.outputs.image_repository }}:${{ env.DEVCONTAINER_IMAGE_TAG_MAIN }} - style-checks: - runs-on: ubuntu-latest - needs: - - build-devcontainer - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Docker image metadata - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.DEVCONTAINER_REGISTRY }}/${{ env.DEVCONTAINER_IMAGE_NAME }} - tags: | - type=ref,event=pr,prefix=cache-pr-,priority=600 - type=ref,event=branch,prefix=cache-,priority=500 - type=ref,event=tag,prefix=cache-,priority=500 - flavor: | - latest=false - - name: Extract Docker image name - id: docker_image - env: - IMAGE_TAGS: ${{ steps.meta.outputs.tags }} - run: | - IMAGE=$(echo "$IMAGE_TAGS" | cut -d" " -f1) - IMAGE_REPOSITORY=$(echo "$IMAGE" | cut -d":" -f1) - IMAGE_TAG=$(echo "$IMAGE" | cut -d":" -f2) - echo "image=$IMAGE" >> "$GITHUB_OUTPUT" - echo "image_repository=$IMAGE_REPOSITORY" >> "$GITHUB_OUTPUT" - echo "image_tag=$IMAGE_TAG" >> "$GITHUB_OUTPUT" - - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Pre-build devcontainer - uses: devcontainers/ci@v0.3 - continue-on-error: true - with: - push: always - skipContainerUserIdUpdate: false - imageName: ${{ steps.docker_image.outputs.image_repository }} - imageTag: ${{ steps.docker_image.outputs.image_tag }} - cacheFrom: | - ${{ steps.docker_image.outputs.image_repository }}:${{ steps.docker_image.outputs.image_tag }} - ${{ steps.docker_image.outputs.image_repository }}:${{ env.DEVCONTAINER_IMAGE_TAG_MAIN }} - style-checks: runs-on: ubuntu-latest needs: @@ -142,6 +95,7 @@ jobs: push: never skipContainerUserIdUpdate: false cacheFrom: ${{ needs.build-devcontainer.outputs.image_repository }}:${{ needs.build-devcontainer.outputs.image_tag }} + test-main: runs-on: ubuntu-latest needs: diff --git a/components/renku_data_services/crc/db.py b/components/renku_data_services/crc/db.py index 13b5e1ea5..b12170ac3 100644 --- a/components/renku_data_services/crc/db.py +++ b/components/renku_data_services/crc/db.py @@ -12,11 +12,10 @@ from functools import wraps from typing import Any, Concatenate, Optional, ParamSpec, TypeVar, cast -from sqlalchemy import NullPool, create_engine, delete, select, true +from sqlalchemy import NullPool, create_engine, delete, false, select, true from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import Session, selectinload, sessionmaker from sqlalchemy.sql import Select, and_, not_, or_ -from sqlalchemy.sql.expression import false, true import renku_data_services.base_models as base_models from renku_data_services import errors diff --git a/components/renku_data_services/notebooks/api/amalthea_patches/init_containers.py b/components/renku_data_services/notebooks/api/amalthea_patches/init_containers.py index 7593e0c00..7b801c462 100644 --- a/components/renku_data_services/notebooks/api/amalthea_patches/init_containers.py +++ b/components/renku_data_services/notebooks/api/amalthea_patches/init_containers.py @@ -15,6 +15,7 @@ # NOTE: If these are directly imported then you get circular imports. from renku_data_services.notebooks.api.classes.server import UserServer + async def git_clone_container_v2(server: "UserServer") -> dict[str, Any] | None: """Returns the specification for the container that clones the user's repositories for new operator.""" amalthea_session_work_volume: str = "amalthea-volume" @@ -104,7 +105,6 @@ async def git_clone_container_v2(server: "UserServer") -> dict[str, Any] | None: }, ) - # Set up git repositories for idx, repo in enumerate(repositories): obj_env = f"{prefix}REPOSITORIES_{idx}_" @@ -153,6 +153,7 @@ async def git_clone_container_v2(server: "UserServer") -> dict[str, Any] | None: "env": env, } + async def git_clone_container(server: "UserServer") -> dict[str, Any] | None: """Returns the specification for the container that clones the user's repositories.""" repositories = await server.repositories() @@ -241,7 +242,6 @@ async def git_clone_container(server: "UserServer") -> dict[str, Any] | None: }, ) - # Set up git repositories for idx, repo in enumerate(repositories): obj_env = f"{prefix}REPOSITORIES_{idx}_" diff --git a/components/renku_data_services/notebooks/api/schemas/server_options.py b/components/renku_data_services/notebooks/api/schemas/server_options.py index 2d6b2064c..1b421c378 100644 --- a/components/renku_data_services/notebooks/api/schemas/server_options.py +++ b/components/renku_data_services/notebooks/api/schemas/server_options.py @@ -6,10 +6,10 @@ from marshmallow import Schema, fields +from renku_data_services.crc.models import ResourceClass from renku_data_services.notebooks.api.schemas.custom_fields import ByteSizeField, CpuField, GpuField from renku_data_services.notebooks.config.dynamic import CPUEnforcement from renku_data_services.notebooks.errors.programming import ProgrammingError -from renku_data_services.crc.models import ResourceClass @dataclass diff --git a/components/renku_data_services/notebooks/api/schemas/servers_get.py b/components/renku_data_services/notebooks/api/schemas/servers_get.py index d1d8f913a..cbe43b3f9 100644 --- a/components/renku_data_services/notebooks/api/schemas/servers_get.py +++ b/components/renku_data_services/notebooks/api/schemas/servers_get.py @@ -6,7 +6,6 @@ from enum import Enum from typing import Any, Union, cast -from kubernetes.utils.quantity import parse_quantity from marshmallow import EXCLUDE, Schema, fields, pre_load, validate from renku_data_services.notebooks.api.classes.server_manifest import UserServerManifest @@ -403,9 +402,7 @@ def get_status(server: UserServerManifest, started: datetime) -> dict[str, dict[ hibernation_date_str = annotations.get("renku.io/hibernationDate") - hibernated_seconds_threshold = ( - server.manifest.spec.culling.hibernatedSecondsThreshold - ) + hibernated_seconds_threshold = server.manifest.spec.culling.hibernatedSecondsThreshold if hibernation_date_str and hibernated_seconds_threshold > 0 and not is_user_anonymous(server): hibernation_date = datetime.fromisoformat(hibernation_date_str) diff --git a/components/renku_data_services/notebooks/apispec.py b/components/renku_data_services/notebooks/apispec.py index 773869ae2..b50197cef 100644 --- a/components/renku_data_services/notebooks/apispec.py +++ b/components/renku_data_services/notebooks/apispec.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: api.spec.yaml -# timestamp: 2024-08-28T09:26:11+00:00 +# timestamp: 2024-08-28T11:41:22+00:00 from __future__ import annotations @@ -341,35 +341,6 @@ class ServerStatus(BaseAPISpec): warnings: Optional[List[ServerStatusWarning]] = None -class SessionPostRequest(BaseAPISpec): - project_id: str = Field( - ..., - description="ULID identifier", - max_length=26, - min_length=26, - pattern="^[A-Z0-9]{26}$", - ) - launcher_id: str = Field( - ..., - description="ULID identifier", - max_length=26, - min_length=26, - pattern="^[A-Z0-9]{26}$", - ) - storage: int = Field( - 1, description="The size of disk storage for the session, in gigabytes" - ) - resource_class_id: Optional[int] = None - - -class SessionStatus(BaseAPISpec): - details: Optional[List[SessionStatusDetail]] = None - message: Optional[str] = None - state: State3 - will_hibernate_at: Optional[datetime] = None - will_delete_at: Optional[datetime] = None - - class SessionResources(BaseAPISpec): requests: Optional[SessionResourcesRequests] = None diff --git a/components/renku_data_services/notebooks/blueprints.py b/components/renku_data_services/notebooks/blueprints.py index 079ae0558..1995dd5a2 100644 --- a/components/renku_data_services/notebooks/blueprints.py +++ b/components/renku_data_services/notebooks/blueprints.py @@ -3,10 +3,10 @@ import base64 import json as json_lib import logging -from math import floor import os from dataclasses import dataclass from datetime import UTC, datetime +from math import floor from pathlib import Path from typing import Any from urllib.parse import urljoin, urlparse @@ -784,15 +784,15 @@ async def _handler( internal_gitlab_user: APIUser, body: apispec.SessionPostRequest, ) -> JSONResponse: + # gitlab_client = NotebooksGitlabClient(self.nb_config.git.url, internal_gitlab_user.access_token) + launcher = await self.session_repo.get_launcher(user, ULID.from_str(body.launcher_id)) + project = await self.project_repo.get_project(user=user, project_id=launcher.project_id) server_name = renku_2_make_server_name( - safe_username=user.id, project_id=body.project_id, launcher_id=body.launcher_id + safe_username=user.id, project_id=str(launcher.project_id), launcher_id=body.launcher_id ) existing_session = await self.nb_config.k8s_v2_client.get_server(server_name, user.id) if existing_session is not None and existing_session.spec is not None: return json(existing_session.as_apispec().model_dump(exclude_none=True, mode="json")) - gitlab_client = NotebooksGitlabClient(self.nb_config.git.url, internal_gitlab_user.access_token) - project = await self.project_repo.get_project(user=user, project_id=ULID.from_str(body.project_id)) - launcher = await self.session_repo.get_launcher(user, ULID.from_str(body.launcher_id)) environment = launcher.environment image = environment.container_image default_resource_class = await self.rp_repo.get_default_resource_class() @@ -800,7 +800,7 @@ async def _handler( raise errors.ProgrammingError(message="The default reosurce class has to have an ID", quiet=True) resource_class_id = body.resource_class_id or default_resource_class.id parsed_server_options = await self.nb_config.crc_validator.validate_class_storage( - user, resource_class_id, body.storage + user, resource_class_id, body.disk_storage ) work_dir = Path("/home/jovyan/work") user_secrets: K8sUserSecrets | None = None @@ -816,7 +816,7 @@ async def _handler( server = Renku2UserServer( user=user, image=image, - project_id=body.project_id, + project_id=str(launcher.project_id), launcher_id=body.launcher_id, server_name=server_name, server_options=parsed_server_options, @@ -857,7 +857,7 @@ async def _handler( parsed_server_url = urlparse(server.server_url) annotations: dict[str, str] = { - "renku.io/project_id": body.project_id, + "renku.io/project_id": str(launcher.project_id), "renku.io/launcher_id": body.launcher_id, "renku.io/resource_class_id": str(body.resource_class_id or default_resource_class.id), } @@ -874,7 +874,7 @@ async def _handler( port=environment.port, storage=Storage( className=self.nb_config.sessions.storage.pvs_storage_class, - size=str(body.storage) + "Gi", + size=str(body.disk_storage) + "G", mountPath=environment.mount_directory.as_posix(), ), workingDir=environment.working_directory.as_posix(), diff --git a/components/renku_data_services/notebooks/config/dynamic.py b/components/renku_data_services/notebooks/config/dynamic.py index 99b6df507..20ddd187d 100644 --- a/components/renku_data_services/notebooks/config/dynamic.py +++ b/components/renku_data_services/notebooks/config/dynamic.py @@ -13,6 +13,7 @@ latest_version: str = "1.25.3" + def _parse_str_as_bool(val: Union[str, bool]) -> bool: if isinstance(val, str): return val.lower() == "true" @@ -409,14 +410,14 @@ def from_env(cls) -> Self: def _for_testing(cls) -> Self: return cls( culling=_SessionCullingConfig.from_env(), - git_proxy=_GitProxyConfig(renku_client_secret="not-defined"), + git_proxy=_GitProxyConfig(renku_client_secret="not-defined"), # nosec B106 git_rpc_server=_GitRpcServerConfig.from_env(), git_clone=_GitCloneConfig.from_env(), ingress=_SessionIngress(host="localhost"), ca_certs=_CustomCaCertsConfig.from_env(), oidc=_SessionOidcConfig( client_id="not-defined", - client_secret="not-defined", + client_secret="not-defined", # nosec B106 token_url="http://not.defined", auth_url="http://not.defined", issuer_url="http://not.defined", diff --git a/components/renku_data_services/notebooks/cr_base.py b/components/renku_data_services/notebooks/cr_base.py index 6722a5aba..ec75db447 100644 --- a/components/renku_data_services/notebooks/cr_base.py +++ b/components/renku_data_services/notebooks/cr_base.py @@ -1,8 +1,6 @@ """Base models for K8s CRD specifications.""" -from pydantic import BaseModel, Field - - +from pydantic import BaseModel class BaseCRD(BaseModel): @@ -12,4 +10,3 @@ class Config: """Do not exclude unknown properties.""" extra = "allow" - diff --git a/components/renku_data_services/notebooks/crs.py b/components/renku_data_services/notebooks/crs.py index f7a6cbff3..6bac792dc 100644 --- a/components/renku_data_services/notebooks/crs.py +++ b/components/renku_data_services/notebooks/crs.py @@ -171,6 +171,14 @@ def as_apispec(self) -> apispec.SessionResponse: url = urljoin(f"{scheme}://{self.spec.ingress.host}", self.spec.session.urlPath) else: url = self.status.url + ready_containers = 0 + total_containers = 0 + if self.status.initContainerCounts is not None: + ready_containers += self.status.initContainerCounts.ready or 0 + total_containers += self.status.initContainerCounts.total or 0 + if self.status.containerCounts is not None: + ready_containers += self.status.containerCounts.ready or 0 + total_containers += self.status.containerCounts.total or 0 return apispec.SessionResponse( image=self.spec.session.image, name=self.metadata.name, @@ -183,8 +191,9 @@ def as_apispec(self) -> apispec.SessionResponse: ), started=self.metadata.creationTimestamp, status=apispec.SessionStatus( - details=[], state=apispec.State3.running, + ready_containers=ready_containers, + total_containers=total_containers, ), url=url, project_id=str(self.project_id), diff --git a/components/renku_data_services/notebooks/models.py b/components/renku_data_services/notebooks/models.py index f5de19a25..fec11eb4b 100644 --- a/components/renku_data_services/notebooks/models.py +++ b/components/renku_data_services/notebooks/models.py @@ -10,12 +10,16 @@ @dataclass class SessionEnvVar: + """Environment variables for an amalthea session.""" + name: str value: str @dataclass class SessionUserSecrets: + """User secret mounted in an amalthea session.""" + mount_path: Path user_secret_ids: list[str] @@ -45,6 +49,8 @@ class Config: class AmaltheaSessionManifest: + """The manifest for an amalthea session.""" + def __init__(self, manifest: AmaltheaSessionV1Alpha1) -> None: self._manifest = manifest self._metadata = _MetadataValidation.model_validate(self._manifest.metadata) @@ -54,6 +60,7 @@ def __repr__(self) -> str: @property def env_vars(self) -> dict[str, SessionEnvVar]: + """Extract the environment variables from a manifest.""" output: dict[str, SessionEnvVar] = {} assert self._manifest.spec for env in self._manifest.spec.session.env or []: @@ -64,5 +71,6 @@ def env_vars(self) -> dict[str, SessionEnvVar]: @property def requested_env_vars(self) -> dict[str, SessionEnvVar]: + """The environment variables requested.""" requested_names = self._metadata.annotations.env_variable_names return {ikey: ival for ikey, ival in self.env_vars.items() if ikey in requested_names} diff --git a/components/renku_data_services/notebooks/util/kubernetes_.py b/components/renku_data_services/notebooks/util/kubernetes_.py index b05dfe013..027f269fe 100644 --- a/components/renku_data_services/notebooks/util/kubernetes_.py +++ b/components/renku_data_services/notebooks/util/kubernetes_.py @@ -18,13 +18,13 @@ from __future__ import annotations -from dataclasses import dataclass from enum import StrEnum from hashlib import md5 -from typing import Any, Self, TypeAlias, cast +from typing import Any, TypeAlias, cast import escapism from kubernetes.client import V1Container + from renku_data_services.notebooks.crs import Patch, PatchType diff --git a/components/renku_data_services/notebooks/util/repository.py b/components/renku_data_services/notebooks/util/repository.py index b9fa975d7..49fa42b82 100644 --- a/components/renku_data_services/notebooks/util/repository.py +++ b/components/renku_data_services/notebooks/util/repository.py @@ -1,6 +1,5 @@ """Repository utilities.""" -import requests from typing import Any, Optional, cast import requests diff --git a/components/renku_data_services/repositories/db.py b/components/renku_data_services/repositories/db.py index 289f60f17..afebc4b5e 100644 --- a/components/renku_data_services/repositories/db.py +++ b/components/renku_data_services/repositories/db.py @@ -1,7 +1,7 @@ """Adapters for repositories database classes.""" -from collections.abc import Callable, Coroutine -from typing import Any, Literal +from collections.abc import Callable +from typing import Literal from urllib.parse import urlparse from httpx import AsyncClient as HttpClient diff --git a/components/renku_data_services/session/apispec_base.py b/components/renku_data_services/session/apispec_base.py index 33d7e7773..d91e73fb9 100644 --- a/components/renku_data_services/session/apispec_base.py +++ b/components/renku_data_services/session/apispec_base.py @@ -26,4 +26,4 @@ def convert_path_to_string(cls, val: str | PurePosixPath) -> str: """Converts the python path to a regular string when pydantic deserializes.""" if isinstance(val, PurePosixPath): return val.as_posix() - return val \ No newline at end of file + return val diff --git a/components/renku_data_services/session/db.py b/components/renku_data_services/session/db.py index c03b07f03..e4b390096 100644 --- a/components/renku_data_services/session/db.py +++ b/components/renku_data_services/session/db.py @@ -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, 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/projects/background_jobs/poetry.lock b/projects/background_jobs/poetry.lock index 9f5bae824..df5c92e02 100644 --- a/projects/background_jobs/poetry.lock +++ b/projects/background_jobs/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "aiofile" @@ -89,6 +89,20 @@ files = [ {file = "appier-1.34.3.tar.gz", hash = "sha256:29e903ee4dee12d7c745a582e4adf7beb98e081c14c2c83534864ffbd4a83cdb"}, ] +[[package]] +name = "asyncache" +version = "0.3.1" +description = "Helpers to use cachetools with async code." +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "asyncache-0.3.1-py3-none-any.whl", hash = "sha256:ef20a1024d265090dd1e0785c961cf98b9c32cc7d9478973dcf25ac1b80011f5"}, + {file = "asyncache-0.3.1.tar.gz", hash = "sha256:9a1e60a75668e794657489bdea6540ee7e3259c483517b934670db7600bf5035"}, +] + +[package.dependencies] +cachetools = ">=5.2.0,<6.0.0" + [[package]] name = "asyncpg" version = "0.29.0" @@ -551,6 +565,17 @@ files = [ dnspython = ">=2.0.0" idna = ">=2.0.0" +[[package]] +name = "escapism" +version = "1.0.1" +description = "Simple, generic API for escaping strings." +optional = false +python-versions = "*" +files = [ + {file = "escapism-1.0.1-py2.py3-none-any.whl", hash = "sha256:d28f19edc3cb1ffc36fa238956ecc068695477e748f57157c6dde00a6b77f229"}, + {file = "escapism-1.0.1.tar.gz", hash = "sha256:73256bdfb4f22230f0428fc6efecee61cdc4fad531b6f98b849cb9c80711e4ec"}, +] + [[package]] name = "factory-boy" version = "3.3.0" @@ -971,6 +996,23 @@ cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] +[[package]] +name = "httpx-ws" +version = "0.6.0" +description = "WebSockets support for HTTPX" +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpx_ws-0.6.0-py3-none-any.whl", hash = "sha256:437cfca94519a4e6ae06eb5573192df6c0da85c22b1a19cc1ea0b02b05a51d25"}, + {file = "httpx_ws-0.6.0.tar.gz", hash = "sha256:60218f531fb474a2143af38568f4b7d94ba356780973443365c8e2c87882bb8c"}, +] + +[package.dependencies] +anyio = ">=4" +httpcore = ">=1.0.4" +httpx = ">=0.23.1" +wsproto = "*" + [[package]] name = "idna" version = "3.7" @@ -1018,6 +1060,31 @@ files = [ {file = "json5-0.9.25.tar.gz", hash = "sha256:548e41b9be043f9426776f05df8635a00fe06104ea51ed24b67f908856e151ae"}, ] +[[package]] +name = "kr8s" +version = "0.17.2" +description = "A Kubernetes API library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "kr8s-0.17.2-py3-none-any.whl", hash = "sha256:5beba0ccf08c7a2305c0fa8f85fa8d2fe7d3f265872f718489e1bea3162fa91b"}, + {file = "kr8s-0.17.2.tar.gz", hash = "sha256:536d08c3f701365e6ac5ce42c0e8313aa6e6740f92b7077f28209e892af046ab"}, +] + +[package.dependencies] +anyio = ">=3.7.0" +asyncache = ">=0.3.1" +cryptography = ">=35" +httpx = ">=0.24.1" +httpx-ws = ">=0.5.2" +python-box = ">=7.0.1" +python-jsonpath = ">=0.7.1" +pyyaml = ">=6.0" + +[package.extras] +docs = ["furo (>=2023.3.27)", "myst-parser (>=1.0.0)", "sphinx (>=5.3.0)", "sphinx-autoapi (>=2.1.0)", "sphinx-autobuild (>=2021.3.14)", "sphinx-copybutton (>=0.5.1)", "sphinx-design (>=0.3.0)", "sphinxcontrib-mermaid (>=0.8.1)"] +test = ["kubernetes (>=26.1.0)", "kubernetes-asyncio (>=24.2.3)", "kubernetes-validate (>=1.28.0)", "lightkube (>=0.13.0)", "pykube-ng (>=23.6.0)", "pytest (>=7.2.2)", "pytest-asyncio (>=0.20.3)", "pytest-cov (>=4.0.0)", "pytest-kind (>=22.11.1)", "pytest-rerunfailures (>=11.1.2)", "pytest-timeout (>=2.1.0)", "trio (>=0.22.0)", "types-pyyaml (>=6.0)"] + [[package]] name = "kubernetes" version = "30.1.0" @@ -1132,6 +1199,25 @@ files = [ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] +[[package]] +name = "marshmallow" +version = "3.22.0" +description = "A lightweight library for converting complex datatypes to and from native Python datatypes." +optional = false +python-versions = ">=3.8" +files = [ + {file = "marshmallow-3.22.0-py3-none-any.whl", hash = "sha256:71a2dce49ef901c3f97ed296ae5051135fd3febd2bf43afe0ae9a82143a494d9"}, + {file = "marshmallow-3.22.0.tar.gz", hash = "sha256:4972f529104a220bb8637d595aa4c9762afbe7f7a77d82dc58c1615d70c5823e"}, +] + +[package.dependencies] +packaging = ">=17.0" + +[package.extras] +dev = ["marshmallow[tests]", "pre-commit (>=3.5,<4.0)", "tox"] +docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.13)", "sphinx (==8.0.2)", "sphinx-issues (==4.1.0)", "sphinx-version-warning (==1.1.2)"] +tests = ["pytest", "pytz", "simplejson"] + [[package]] name = "multidict" version = "6.0.5" @@ -1265,6 +1351,17 @@ rsa = ["cryptography (>=3.0.0)"] signals = ["blinker (>=1.4.0)"] signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] +[[package]] +name = "packaging" +version = "24.1" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, +] + [[package]] name = "prometheus-client" version = "0.7.1" @@ -1612,6 +1709,41 @@ dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pyte docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] +[[package]] +name = "python-box" +version = "7.2.0" +description = "Advanced Python dictionaries with dot notation access" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python_box-7.2.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:6bdeec791e25258351388b3029a3ec5da302bb9ed3be175493c43cdc6c47f5e3"}, + {file = "python_box-7.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c449f7b3756a71479fa9c61a86e344ac00ed782a66d7662590f0afa294249d18"}, + {file = "python_box-7.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:6b0d61f182d394106d963232854e495b51edc178faa5316a797be1178212d7e0"}, + {file = "python_box-7.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e2d752de8c1204255bf7b0c814c59ef48293c187a7e9fdcd2fefa28024b72032"}, + {file = "python_box-7.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8a6c35ea356a386077935958a5debcd5b229b9a1b3b26287a52dfe1a7e65d99"}, + {file = "python_box-7.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:32ed58ec4d9e5475efe69f9c7d773dfea90a6a01979e776da93fd2b0a5d04429"}, + {file = "python_box-7.2.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:2a2d664c6a27f7515469b6f1e461935a2038ee130b7d194b4b4db4e85d363618"}, + {file = "python_box-7.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8a5a7365db1aaf600d3e8a2747fcf6833beb5d45439a54318548f02e302e3ec"}, + {file = "python_box-7.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:739f827056ea148cbea3122d4617c994e829b420b1331183d968b175304e3a4f"}, + {file = "python_box-7.2.0-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:2617ef3c3d199f55f63c908f540a4dc14ced9b18533a879e6171c94a6a436f23"}, + {file = "python_box-7.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffd866bed03087b1d8340014da8c3aaae19135767580641df1b4ae6fff6ac0aa"}, + {file = "python_box-7.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:9681f059e7e92bdf20782cd9ea6e533d4711fc7b8c57a462922a025d46add4d0"}, + {file = "python_box-7.2.0-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:6b59b1e2741c9ceecdf5a5bd9b90502c24650e609cd824d434fed3b6f302b7bb"}, + {file = "python_box-7.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23fae825d809ae7520fdeac88bb52be55a3b63992120a00e381783669edf589"}, + {file = "python_box-7.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:573b1abdcb7bd745fa404444f060ee62fc35a74f067181e55dcb43cfe92f2827"}, + {file = "python_box-7.2.0-py3-none-any.whl", hash = "sha256:a3c90832dd772cb0197fdb5bc06123b6e1b846899a1b53d9c39450d27a584829"}, + {file = "python_box-7.2.0.tar.gz", hash = "sha256:551af20bdab3a60a2a21e3435120453c4ca32f7393787c3a5036e1d9fc6a0ede"}, +] + +[package.extras] +all = ["msgpack", "ruamel.yaml (>=0.17)", "toml"] +msgpack = ["msgpack"] +pyyaml = ["PyYAML"] +ruamel-yaml = ["ruamel.yaml (>=0.17)"] +toml = ["toml"] +tomli = ["tomli", "tomli-w"] +yaml = ["ruamel.yaml (>=0.17)"] + [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -1645,6 +1777,17 @@ requests-toolbelt = ">=1.0.0" autocompletion = ["argcomplete (>=1.10.0,<3)"] yaml = ["PyYaml (>=6.0.1)"] +[[package]] +name = "python-jsonpath" +version = "1.2.0" +description = "JSONPath, JSON Pointer and JSON Patch for Python." +optional = false +python-versions = ">=3.7" +files = [ + {file = "python_jsonpath-1.2.0-py3-none-any.whl", hash = "sha256:3172c7b87098fced1ed84bd3492bd1a19ef1ad41d4f5b8a3e9a147c750ac08b3"}, + {file = "python_jsonpath-1.2.0.tar.gz", hash = "sha256:a29a84ec3ac38e5dcaa62ac2a215de72c4eb60cb1303e10700da980cf7873775"}, +] + [[package]] name = "python-ulid" version = "2.7.0" @@ -2140,6 +2283,17 @@ files = [ doc = ["reno", "sphinx"] test = ["pytest", "tornado (>=4.5)", "typeguard"] +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] + [[package]] name = "tracerite" version = "1.1.1" @@ -2432,7 +2586,38 @@ files = [ {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"}, ] +[[package]] +name = "werkzeug" +version = "3.0.4" +description = "The comprehensive WSGI web application library." +optional = false +python-versions = ">=3.8" +files = [ + {file = "werkzeug-3.0.4-py3-none-any.whl", hash = "sha256:02c9eb92b7d6c06f31a782811505d2157837cea66aaede3e217c7c27c039476c"}, + {file = "werkzeug-3.0.4.tar.gz", hash = "sha256:34f2371506b250df4d4f84bfe7b0921e4762525762bbd936614909fe25cd7306"}, +] + +[package.dependencies] +MarkupSafe = ">=2.1.1" + +[package.extras] +watchdog = ["watchdog (>=2.3)"] + +[[package]] +name = "wsproto" +version = "1.2.0" +description = "WebSockets state-machine based protocol implementation" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "wsproto-1.2.0-py3-none-any.whl", hash = "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736"}, + {file = "wsproto-1.2.0.tar.gz", hash = "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065"}, +] + +[package.dependencies] +h11 = ">=0.9.0,<1" + [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "26c5d2120aaab33aba2ded28a1332a2f35a83b4f85385a4cf14d33dfa3c84aa4" +content-hash = "333b1ecfa2157a45af4fbe6dd1192f0d19cd63bc9d92772f3b3433314c40a80b" diff --git a/projects/background_jobs/pyproject.toml b/projects/background_jobs/pyproject.toml index 6b938d74d..73a1dce2e 100644 --- a/projects/background_jobs/pyproject.toml +++ b/projects/background_jobs/pyproject.toml @@ -63,6 +63,11 @@ sentry-sdk = { version = "^2.6.0", extras = ["sanic"] } # see https://github.com/sanic-org/sanic/issues/2828 for setuptools dependency, remove when not needed anymore setuptools = { version = "^70.0.0" } aiofile = "^3.8.8" +escapism = "^1.0.1" +kr8s = "^0.17.2" +marshmallow = "^3.22.0" +toml = "^0.10.2" +werkzeug = "^3.0.4" [tool.poetry.group.dev.dependencies] pyavro-gen = "^0.3.3" diff --git a/projects/renku_data_service/poetry.lock b/projects/renku_data_service/poetry.lock index 6570372b4..d7671e554 100644 --- a/projects/renku_data_service/poetry.lock +++ b/projects/renku_data_service/poetry.lock @@ -1,21 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. - -[[package]] -name = "aiofile" -version = "3.8.8" -description = "Asynchronous file operations." -optional = false -python-versions = ">=3.7, <4" -files = [ - {file = "aiofile-3.8.8-py3-none-any.whl", hash = "sha256:41e8845cce055779cd77713d949a339deb012eab605b857765e8f8e52a5ed811"}, - {file = "aiofile-3.8.8.tar.gz", hash = "sha256:41f3dc40bd730459d58610476e82e5efb2f84ae6e9fa088a9545385d838b8a43"}, -] - -[package.dependencies] -caio = ">=0.9.0,<0.10.0" - -[package.extras] -develop = ["aiomisc-pytest", "coveralls", "pytest", "pytest-cov", "pytest-rst"] +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "aiofile" @@ -2745,6 +2728,17 @@ files = [ doc = ["reno", "sphinx"] test = ["pytest", "tornado (>=4.5)", "typeguard"] +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] + [[package]] name = "tracerite" version = "1.1.1" @@ -3174,4 +3168,4 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "55f69faac39d2d41374517a5683cff60c0a7a6213d4e1583a23f6f69b9b22834" +content-hash = "9b5baa917b378b47b0bd171aabe6564a6710ca50504f9d9233ea9348ee7f91db" diff --git a/projects/renku_data_service/pyproject.toml b/projects/renku_data_service/pyproject.toml index 5a2025ae1..138f15aba 100644 --- a/projects/renku_data_service/pyproject.toml +++ b/projects/renku_data_service/pyproject.toml @@ -67,6 +67,7 @@ werkzeug = "^3.0.3" # see https://github.com/sanic-org/sanic/issues/2828 for setuptools dependency, remove when not needed anymore setuptools = { version = "^70.0.0" } aiofile = "^3.8.8" +toml = "^0.10.2" [tool.poetry.group.dev.dependencies] pyavro-gen = "^0.3.3" diff --git a/projects/secrets_storage/poetry.lock b/projects/secrets_storage/poetry.lock index 58a9656f5..d21262f6d 100644 --- a/projects/secrets_storage/poetry.lock +++ b/projects/secrets_storage/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "aiofile" @@ -103,6 +103,20 @@ files = [ [package.extras] test = ["coverage", "mypy", "pexpect", "ruff", "wheel"] +[[package]] +name = "asyncache" +version = "0.3.1" +description = "Helpers to use cachetools with async code." +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "asyncache-0.3.1-py3-none-any.whl", hash = "sha256:ef20a1024d265090dd1e0785c961cf98b9c32cc7d9478973dcf25ac1b80011f5"}, + {file = "asyncache-0.3.1.tar.gz", hash = "sha256:9a1e60a75668e794657489bdea6540ee7e3259c483517b934670db7600bf5035"}, +] + +[package.dependencies] +cachetools = ">=5.2.0,<6.0.0" + [[package]] name = "asyncpg" version = "0.29.0" @@ -660,6 +674,17 @@ files = [ dnspython = ">=2.0.0" idna = ">=2.0.0" +[[package]] +name = "escapism" +version = "1.0.1" +description = "Simple, generic API for escaping strings." +optional = false +python-versions = "*" +files = [ + {file = "escapism-1.0.1-py2.py3-none-any.whl", hash = "sha256:d28f19edc3cb1ffc36fa238956ecc068695477e748f57157c6dde00a6b77f229"}, + {file = "escapism-1.0.1.tar.gz", hash = "sha256:73256bdfb4f22230f0428fc6efecee61cdc4fad531b6f98b849cb9c80711e4ec"}, +] + [[package]] name = "factory-boy" version = "3.3.0" @@ -1069,6 +1094,23 @@ cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] +[[package]] +name = "httpx-ws" +version = "0.6.0" +description = "WebSockets support for HTTPX" +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpx_ws-0.6.0-py3-none-any.whl", hash = "sha256:437cfca94519a4e6ae06eb5573192df6c0da85c22b1a19cc1ea0b02b05a51d25"}, + {file = "httpx_ws-0.6.0.tar.gz", hash = "sha256:60218f531fb474a2143af38568f4b7d94ba356780973443365c8e2c87882bb8c"}, +] + +[package.dependencies] +anyio = ">=4" +httpcore = ">=1.0.4" +httpx = ">=0.23.1" +wsproto = "*" + [[package]] name = "idna" version = "3.7" @@ -1137,6 +1179,31 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "kr8s" +version = "0.17.2" +description = "A Kubernetes API library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "kr8s-0.17.2-py3-none-any.whl", hash = "sha256:5beba0ccf08c7a2305c0fa8f85fa8d2fe7d3f265872f718489e1bea3162fa91b"}, + {file = "kr8s-0.17.2.tar.gz", hash = "sha256:536d08c3f701365e6ac5ce42c0e8313aa6e6740f92b7077f28209e892af046ab"}, +] + +[package.dependencies] +anyio = ">=3.7.0" +asyncache = ">=0.3.1" +cryptography = ">=35" +httpx = ">=0.24.1" +httpx-ws = ">=0.5.2" +python-box = ">=7.0.1" +python-jsonpath = ">=0.7.1" +pyyaml = ">=6.0" + +[package.extras] +docs = ["furo (>=2023.3.27)", "myst-parser (>=1.0.0)", "sphinx (>=5.3.0)", "sphinx-autoapi (>=2.1.0)", "sphinx-autobuild (>=2021.3.14)", "sphinx-copybutton (>=0.5.1)", "sphinx-design (>=0.3.0)", "sphinxcontrib-mermaid (>=0.8.1)"] +test = ["kubernetes (>=26.1.0)", "kubernetes-asyncio (>=24.2.3)", "kubernetes-validate (>=1.28.0)", "lightkube (>=0.13.0)", "pykube-ng (>=23.6.0)", "pytest (>=7.2.2)", "pytest-asyncio (>=0.20.3)", "pytest-cov (>=4.0.0)", "pytest-kind (>=22.11.1)", "pytest-rerunfailures (>=11.1.2)", "pytest-timeout (>=2.1.0)", "trio (>=0.22.0)", "types-pyyaml (>=6.0)"] + [[package]] name = "kubernetes" version = "30.1.0" @@ -1251,6 +1318,25 @@ files = [ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] +[[package]] +name = "marshmallow" +version = "3.22.0" +description = "A lightweight library for converting complex datatypes to and from native Python datatypes." +optional = false +python-versions = ">=3.8" +files = [ + {file = "marshmallow-3.22.0-py3-none-any.whl", hash = "sha256:71a2dce49ef901c3f97ed296ae5051135fd3febd2bf43afe0ae9a82143a494d9"}, + {file = "marshmallow-3.22.0.tar.gz", hash = "sha256:4972f529104a220bb8637d595aa4c9762afbe7f7a77d82dc58c1615d70c5823e"}, +] + +[package.dependencies] +packaging = ">=17.0" + +[package.extras] +dev = ["marshmallow[tests]", "pre-commit (>=3.5,<4.0)", "tox"] +docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.13)", "sphinx (==8.0.2)", "sphinx-issues (==4.1.0)", "sphinx-version-warning (==1.1.2)"] +tests = ["pytest", "pytz", "simplejson"] + [[package]] name = "multidict" version = "6.0.5" @@ -1780,6 +1866,41 @@ dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pyte docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] +[[package]] +name = "python-box" +version = "7.2.0" +description = "Advanced Python dictionaries with dot notation access" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python_box-7.2.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:6bdeec791e25258351388b3029a3ec5da302bb9ed3be175493c43cdc6c47f5e3"}, + {file = "python_box-7.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c449f7b3756a71479fa9c61a86e344ac00ed782a66d7662590f0afa294249d18"}, + {file = "python_box-7.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:6b0d61f182d394106d963232854e495b51edc178faa5316a797be1178212d7e0"}, + {file = "python_box-7.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e2d752de8c1204255bf7b0c814c59ef48293c187a7e9fdcd2fefa28024b72032"}, + {file = "python_box-7.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8a6c35ea356a386077935958a5debcd5b229b9a1b3b26287a52dfe1a7e65d99"}, + {file = "python_box-7.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:32ed58ec4d9e5475efe69f9c7d773dfea90a6a01979e776da93fd2b0a5d04429"}, + {file = "python_box-7.2.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:2a2d664c6a27f7515469b6f1e461935a2038ee130b7d194b4b4db4e85d363618"}, + {file = "python_box-7.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8a5a7365db1aaf600d3e8a2747fcf6833beb5d45439a54318548f02e302e3ec"}, + {file = "python_box-7.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:739f827056ea148cbea3122d4617c994e829b420b1331183d968b175304e3a4f"}, + {file = "python_box-7.2.0-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:2617ef3c3d199f55f63c908f540a4dc14ced9b18533a879e6171c94a6a436f23"}, + {file = "python_box-7.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffd866bed03087b1d8340014da8c3aaae19135767580641df1b4ae6fff6ac0aa"}, + {file = "python_box-7.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:9681f059e7e92bdf20782cd9ea6e533d4711fc7b8c57a462922a025d46add4d0"}, + {file = "python_box-7.2.0-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:6b59b1e2741c9ceecdf5a5bd9b90502c24650e609cd824d434fed3b6f302b7bb"}, + {file = "python_box-7.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23fae825d809ae7520fdeac88bb52be55a3b63992120a00e381783669edf589"}, + {file = "python_box-7.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:573b1abdcb7bd745fa404444f060ee62fc35a74f067181e55dcb43cfe92f2827"}, + {file = "python_box-7.2.0-py3-none-any.whl", hash = "sha256:a3c90832dd772cb0197fdb5bc06123b6e1b846899a1b53d9c39450d27a584829"}, + {file = "python_box-7.2.0.tar.gz", hash = "sha256:551af20bdab3a60a2a21e3435120453c4ca32f7393787c3a5036e1d9fc6a0ede"}, +] + +[package.extras] +all = ["msgpack", "ruamel.yaml (>=0.17)", "toml"] +msgpack = ["msgpack"] +pyyaml = ["PyYAML"] +ruamel-yaml = ["ruamel.yaml (>=0.17)"] +toml = ["toml"] +tomli = ["tomli", "tomli-w"] +yaml = ["ruamel.yaml (>=0.17)"] + [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -1813,6 +1934,17 @@ requests-toolbelt = ">=1.0.0" autocompletion = ["argcomplete (>=1.10.0,<3)"] yaml = ["PyYaml (>=6.0.1)"] +[[package]] +name = "python-jsonpath" +version = "1.2.0" +description = "JSONPath, JSON Pointer and JSON Patch for Python." +optional = false +python-versions = ">=3.7" +files = [ + {file = "python_jsonpath-1.2.0-py3-none-any.whl", hash = "sha256:3172c7b87098fced1ed84bd3492bd1a19ef1ad41d4f5b8a3e9a147c750ac08b3"}, + {file = "python_jsonpath-1.2.0.tar.gz", hash = "sha256:a29a84ec3ac38e5dcaa62ac2a215de72c4eb60cb1303e10700da980cf7873775"}, +] + [[package]] name = "python-ulid" version = "2.7.0" @@ -2297,6 +2429,17 @@ files = [ doc = ["reno", "sphinx"] test = ["pytest", "tornado (>=4.5)", "typeguard"] +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] + [[package]] name = "tracerite" version = "1.1.1" @@ -2644,7 +2787,38 @@ files = [ {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"}, ] +[[package]] +name = "werkzeug" +version = "3.0.4" +description = "The comprehensive WSGI web application library." +optional = false +python-versions = ">=3.8" +files = [ + {file = "werkzeug-3.0.4-py3-none-any.whl", hash = "sha256:02c9eb92b7d6c06f31a782811505d2157837cea66aaede3e217c7c27c039476c"}, + {file = "werkzeug-3.0.4.tar.gz", hash = "sha256:34f2371506b250df4d4f84bfe7b0921e4762525762bbd936614909fe25cd7306"}, +] + +[package.dependencies] +MarkupSafe = ">=2.1.1" + +[package.extras] +watchdog = ["watchdog (>=2.3)"] + +[[package]] +name = "wsproto" +version = "1.2.0" +description = "WebSockets state-machine based protocol implementation" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "wsproto-1.2.0-py3-none-any.whl", hash = "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736"}, + {file = "wsproto-1.2.0.tar.gz", hash = "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065"}, +] + +[package.dependencies] +h11 = ">=0.9.0,<1" + [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "65147685c4e6045dfeea89e0f6cab4f2b5dae0ac3b580cb6b3975d46f063de30" +content-hash = "4726232226cd73d84417c572427bca4ad02556ff591d9237c3210449b61ebb69" diff --git a/projects/secrets_storage/pyproject.toml b/projects/secrets_storage/pyproject.toml index a31079d5c..73a292b1a 100644 --- a/projects/secrets_storage/pyproject.toml +++ b/projects/secrets_storage/pyproject.toml @@ -31,6 +31,7 @@ packages = [ { include = "renku_data_services/storage", from = "../../components" }, { include = "renku_data_services/users", from = "../../components" }, { include = "renku_data_services/utils", from = "../../components" }, + { include = "renku_data_services/notebooks", from = "../../components" }, ] [tool.poetry.dependencies] @@ -62,6 +63,11 @@ authzed = "^0.15.0" # see https://github.com/sanic-org/sanic/issues/2828 for setuptools dependency, remove when not needed anymore setuptools = { version = "^70.0.0" } aiofile = "^3.8.8" +escapism = "^1.0.1" +kr8s = "^0.17.2" +marshmallow = "^3.22.0" +toml = "^0.10.2" +werkzeug = "^3.0.4" [tool.poetry.group.dev.dependencies] pyavro-gen = "^0.3.3" diff --git a/pyproject.toml b/pyproject.toml index 2806a8416..11399923f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -156,7 +156,12 @@ convention = "google" [tool.bandit] skips = ["B101", "B603", "B607", "B404"] -exclude_dirs = ["test", ".devcontainer"] +exclude_dirs = [ + "test", + ".devcontainer", + "components/renku_data_services/notebooks/cr_jupyter_server.py", + "components/renku_data_services/notebooks/cr_amalthea_session.py", +] [tool.pytest.ini_options] addopts = "--cov components/ --cov bases/ --cov-report=term-missing -v" diff --git a/session_image/Dockerfile b/session_image/Dockerfile deleted file mode 100644 index 3508e6e21..000000000 --- a/session_image/Dockerfile +++ /dev/null @@ -1,2 +0,0 @@ -FROM renku/renkulab-py:3.10-0.23.0 -COPY jupyter_server_config.py /usr/local/etc/jupyter/ diff --git a/session_image/jupyter_server_config.py b/session_image/jupyter_server_config.py deleted file mode 100644 index 40b5c582e..000000000 --- a/session_image/jupyter_server_config.py +++ /dev/null @@ -1,13 +0,0 @@ -import os -from urllib.parse import urljoin - -c.ServerApp.ip="0.0.0.0" -c.ServerApp.port = 8888 -c.ServerApp.base_url = os.environ.get("RENKU_BASE_URL_PATH", "/") -c.ServerApp.token = "" -c.ServerApp.password = "" -c.ServerApp.allow_remote_access=True -c.ContentsManager.allow_hidden=True -# base_url = os.environ.get("RENKU_BASE_URL", "http://127.0.0.1") -# c.ServerApp.allow_origin = urljoin(base_url, "/").rstrip("/") -c.ServerApp.allow_origin = '*' diff --git a/test/bases/renku_data_services/data_api/test_sessions.py b/test/bases/renku_data_services/data_api/test_sessions.py index 28c38d2c5..0527d546a 100644 --- a/test/bases/renku_data_services/data_api/test_sessions.py +++ b/test/bases/renku_data_services/data_api/test_sessions.py @@ -1,11 +1,9 @@ """Tests for sessions blueprints.""" from asyncio import AbstractEventLoop -from collections.abc import AsyncIterator, Coroutine from typing import Any import pytest -import pytest_asyncio from pytest import FixtureRequest from sanic_testing.testing import SanicASGITestClient, TestingResponse