Skip to content

Commit

Permalink
Merge pull request #31 from nebari-dev/thumbnail-support
Browse files Browse the repository at this point in the history
  • Loading branch information
aktech authored Jan 5, 2024
2 parents 2631b81 + 0029f8c commit 3a70e8c
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 20 deletions.
3 changes: 2 additions & 1 deletion jhub_apps/service/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from datetime import datetime
from typing import Any, Dict, List, Optional


from pydantic import BaseModel


Expand Down Expand Up @@ -51,7 +52,7 @@ class UserOptions(BaseModel):
jhub_app: bool
display_name: str
description: str
thumbnail: typing.Optional[str] = str()
thumbnail: str = None
filepath: typing.Optional[str] = str()
framework: str = "panel"
custom_command: typing.Optional[str] = str()
Expand Down
32 changes: 28 additions & 4 deletions jhub_apps/service/service.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import typing
import dataclasses
import os
from datetime import timedelta

from fastapi import APIRouter, Depends, status, Request
from fastapi import APIRouter, Depends, status, Request, File, UploadFile, Form, HTTPException
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel, ValidationError
from starlette.responses import RedirectResponse

from jhub_apps.service.auth import create_access_token
Expand All @@ -14,7 +17,8 @@
from fastapi.templating import Jinja2Templates

from jhub_apps.hub_client.hub_client import HubClient
from jhub_apps.service.utils import get_conda_envs, get_jupyterhub_config, get_spawner_profiles
from jhub_apps.service.utils import get_conda_envs, get_jupyterhub_config, get_spawner_profiles, \
encode_file_to_data_url
from jhub_apps.spawner.types import FRAMEWORKS

app = FastAPI()
Expand Down Expand Up @@ -62,6 +66,7 @@ async def login(request: Request):
authorization_url = os.environ["PUBLIC_HOST"] + "/hub/api/oauth2/authorize?response_type=code&client_id=service-japps"
return RedirectResponse(authorization_url, status_code=302)


@router.get("/server/", description="Get all servers")
@router.get("/server/{server_name}", description="Get a server by server name")
async def get_server(user: User = Depends(get_current_user), server_name=None):
Expand All @@ -81,12 +86,31 @@ async def get_server(user: User = Depends(get_current_user), server_name=None):
return user_servers


class Checker:
def __init__(self, model: BaseModel):
self.model = model

def __call__(self, data: str = Form(...)):
try:
return self.model.model_validate_json(data)
except ValidationError as e:
raise HTTPException(
detail=jsonable_encoder(e.errors()),
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
)


@router.post("/server/")
async def create_server(
# request: Request,
server: ServerCreation,
server: ServerCreation = Depends(Checker(ServerCreation)),
thumbnail: typing.Optional[UploadFile] = File(None),
user: User = Depends(get_current_user),
):
if thumbnail:
thumbnail_contents = await thumbnail.read()
server.user_options.thumbnail = encode_file_to_data_url(
thumbnail.filename, thumbnail_contents
)
hub_client = HubClient()
return hub_client.create_server(
username=user.name,
Expand Down
12 changes: 12 additions & 0 deletions jhub_apps/service/utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import base64
import os

from jupyterhub.app import JupyterHub
Expand Down Expand Up @@ -44,3 +45,14 @@ def get_spawner_profiles(config):
raise ValueError(
f"Invalid value for config.KubeSpawner.profile_list: {profile_list}"
)


def encode_file_to_data_url(filename, file_contents):
"""Converts image file to data url to display in browser."""
base64_encoded = base64.b64encode(file_contents)
filename_ = filename.lower()
mime_type = "image/png"
if filename_.endswith(".jpg") or filename_.endswith(".jpeg"):
mime_type = "image/jpeg"
data_url = f"data:{mime_type};base64,{base64_encoded.decode('utf-8')}"
return data_url
Loading

0 comments on commit 3a70e8c

Please sign in to comment.