Skip to content

Commit

Permalink
Feature/implement feather client (#5)
Browse files Browse the repository at this point in the history
* add builders

* add feathers client and socket io connection

* Update Notebook.js

* Update gatsby-node.js

* Update NotebookCard.js

* Update UserArea.js
  • Loading branch information
danieleguido authored Jun 19, 2024
1 parent 5121f02 commit 448f38f
Show file tree
Hide file tree
Showing 13 changed files with 566 additions and 86 deletions.
42 changes: 42 additions & 0 deletions .github/workflows/docker-build-latest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Build and publish latest Docker image
on:
# Trigger the workflow on push or pull request,
# for the develop branch and all new tags
push:
branches:
- master
workflow_dispatch:
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: get env variables for GIT related info
run: |
echo "GIT_COMMIT_SHA=$(echo $GITHUB_SHA | cut -c1-7)" >> $GITHUB_ENV
echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
echo "GIT_BRANCH=$(echo $GITHUB_REF | sed 's/refs\/heads\///')" >> $GITHUB_ENV
echo "GIT_REMOTE=$(git config --get remote.origin.url)" >> $GITHUB_ENV
echo "GIT_TAG=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: impresso/impresso-datalab:latest
build-args: |
VERSION=latest
GIT_COMMIT_SHA=${{ env.GIT_COMMIT_SHA }}
BUILD_DATE=${{ env.BUILD_DATE }}
GIT_BRANCH=${{ env.GIT_BRANCH }}
GIT_REMOTE=${{ env.GIT_REMOTE }}
GIT_TAG=${{ env.GIT_TAG }}
17 changes: 6 additions & 11 deletions .github/workflows/updateNotebooks.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
name: Update Notebooks if needed
on:
schedule:
- cron: "0 0 * * *"
workflow_dispatch:

jobs:
updateNotebooks:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v2
uses: actions/checkout@v4
- name: Setup Nodejs
uses: actions/setup-node@v4
with:
python-version: "3.x"
node-version: 22
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
run: yarn
- name: Update Notebooks
run: |
python updateNotebooks.py
run: node updateNotebooks.py
55 changes: 55 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
FROM node:22.2.0-alpine3.20 AS gatsby

# docker build --no-cache --progress=plain -t impresso/impresso-datalab:${BUILD_TAG} \
# --build-arg GIT_REVISION=$(shell git rev-parse --short HEAD) \
# --build-arg GIT_TAG=$(shell git describe --tags --abbrev=0 HEAD) \
# --build-arg GIT_BUILD_TAG=${BUILD_TAG} \
# --build-arg GIT_BRANCH=$(shell git rev-parse --abbrev-ref HEAD) \
# --build-arg BUILD_DATE=$(shell date -u +'%Y-%m-%dT%H:%M:%SZ') \
# --build-arg GIT_REPO=$(shell git config --get remote.origin.url) .

ARG GIT_REVISION
ARG GIT_TAG
ARG GIT_BUILD_TAG
ARG GIT_BRANCH
ARG BUILD_DATE
ARG GIT_REPO

WORKDIR /app

COPY package.json .
COPY yarn.lock .

RUN yarn install

COPY src /app/src
COPY static /app/static
COPY utils /app/utils

COPY createfontscss.js /app/createfontscss.js
COPY updatenotebooks.js /app/updatenotebooks.js
COPY gatsby-config.js /app/gatsby-config.js
COPY gatsby-node.js /app/gatsby-node.js
COPY gatsby-ssr.js /app/gatsby-ssr.js
COPY gatsby-browser.js /app/gatsby-browser.js

ENV GIT_REVISION=${GIT_REVISION}
ENV GIT_TAG=${GIT_TAG}
ENV GIT_BUILD_TAG=${GIT_BUILD_TAG}
ENV GIT_BRANCH=${GIT_BRANCH}
ENV BUILD_DATE=${BUILD_DATE}
ENV GIT_REPO=${GIT_REPO}
ENV GATSBY_PATH_PREFIX="/datalab"
ENV GATSBY_IMPRESSO_API_URL="/api"

RUN yarn build

# Install and run pagefind
RUN npx [email protected] --site /app/public --verbose

# copy all files built by gatsy to busybox
FROM busybox:stable
WORKDIR /app
COPY --from=gatsby /app/public .

RUN ls -la
23 changes: 22 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,25 @@ run-dev:
PREFIX_PATHS=true \
GATSBY_PATH_PREFIX="" \
GATSBY_IMPRESSO_API_URL="https://impresso-project.ch/api" \
yarn start
yarn start

build-dev:
GIT_TAG=$(shell git describe --tags --abbrev=0 HEAD) \
GIT_BUILD_TAG=${BUILD_TAG} \
GIT_BRANCH=$(shell git rev-parse --abbrev-ref HEAD) \
GIT_REVISION=$(shell git rev-parse --short HEAD) \
GIT_REPO=$(shell git config --get remote.origin.url) \
PATH_PREFIX=/datalab \
PREFIX_PATHS=true \
GATSBY_PATH_PREFIX="/datalab" \
GATSBY_IMPRESSO_API_URL="https://impresso-project.ch/api" \
yarn build

build:
docker build --no-cache --progress=plain -t impresso/impresso-datalab:${BUILD_TAG} \
--build-arg GIT_REVISION=$(shell git rev-parse --short HEAD) \
--build-arg GIT_TAG=$(shell git describe --tags --abbrev=0 HEAD) \
--build-arg GIT_BUILD_TAG=${BUILD_TAG} \
--build-arg GIT_BRANCH=$(shell git rev-parse --abbrev-ref HEAD) \
--build-arg BUILD_DATE=$(shell date -u +'%Y-%m-%dT%H:%M:%SZ') \
--build-arg GIT_REPO=$(shell git config --get remote.origin.url) .
19 changes: 18 additions & 1 deletion gatsby-browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import PrefetchData from "./src/components/PrefetchData"
import PageLayout from "./src/components/PageLayout"
import { useBrowserStore } from "./src/store"
import { versionService } from "./src/services"

// Logs when the client route changes
export function onRouteUpdate({ location, prevLocation }) {
Expand All @@ -23,7 +24,16 @@ export function onRouteUpdate({ location, prevLocation }) {
}

// Create a client
const queryClient = new QueryClient()
const queryClient = new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
retry: false,
// Add a timeout of 10 seconds
staleTime: 10000,
},
},
})
console.info(
"Impresso datalab",
"\n - PATH_PREFIX:",
Expand All @@ -32,6 +42,13 @@ console.info(
process.env.GATSBY_PATH_PREFIX
)

setTimeout(() => {
console.info("[gatsby-browser] load version...")
versionService.find().then((data) => {
console.info("[gatsby-browser] use version:", data)
})
}, 3000)

// Wraps every page in a component
export function wrapRootElement({ element, props }) {
console.log("[gatsby-browser]@wrapRootElement")
Expand Down
9 changes: 4 additions & 5 deletions gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* @type {import('gatsby').GatsbyConfig}
*/
const { createProxyMiddleware } = require("http-proxy-middleware")

require("dotenv").config({
path: [`.env.${process.env.NODE_ENV}`, ".env"],
})
Expand Down Expand Up @@ -32,13 +33,11 @@ module.exports = {
pathPrefix: process.env.PATH_PREFIX || "/",
developMiddleware: (app) => {
app.use(
"/api",
"/api/socket.io",
createProxyMiddleware({
target: ApiHost,
target: "https://dev.impresso-project.ch",
ws: true,
changeOrigin: true,
pathRewrite: {
"^/api": "/api",
},
})
)
},
Expand Down
6 changes: 6 additions & 0 deletions gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ exports.createPages = async function ({ actions, graphql }) {
frontmatter {
title
binderUrl
googleColabUrl
githubUrl
sha
authors
tags
}
Expand All @@ -91,6 +94,9 @@ exports.createPages = async function ({ actions, graphql }) {
tags: node.childMdx.frontmatter.tags || [],
excerpt: node.childMdx.excerpt,
binderUrl: node.childMdx.frontmatter.binderUrl,
googleColabUrl: node.childMdx.frontmatter.googleColabUrl,
githubUrl: node.childMdx.frontmatter.githubUrl,
sha: node.childMdx.frontmatter.sha,
authors: node.childMdx.frontmatter.authors || [],
collections: [],
}
Expand Down
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
},
"dependencies": {
"@codemirror/lang-python": "^6.1.4",
"@feathersjs/authentication-client": "^5.0.26",
"@feathersjs/socketio-client": "^5.0.26",
"@mdx-js/react": "^3.0.0",
"@react-spring/web": "^9.7.3",
"@tanstack/react-query": "^5.25.0",
Expand All @@ -39,10 +41,13 @@
"react": "^18.2.0",
"react-bootstrap": "^2.10.0",
"react-dom": "^18.2.0",
"socket.io-client": "^4.7.5",
"yaml": "^2.4.5",
"zustand": "^4.5.2"
},
"devDependencies": {
"http-proxy-middleware": "^2.0.6"
"cors": "^2.8.5",
"express": "^4.19.2",
"http-proxy-middleware": "^3.0.0"
}
}
4 changes: 1 addition & 3 deletions src/components/NotebookCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ const NotebookCard = ({ name }) => {
<h3 className="m-0">{notebook?.title}</h3>
<ol className="NotebookCard__authors">
{notebook?.authors.map((name) => (
<Link key={name} to={`/`}>
<AuthorCard name={name} />
</Link>
<AuthorCard key={name} name={name} />
))}
</ol>
</div>
Expand Down
43 changes: 14 additions & 29 deletions src/components/UserArea.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,28 @@
import { useQuery } from "@tanstack/react-query"
import axios from "axios"
import React from "react"
import React, { useEffect, useState } from "react"
import { Button } from "react-bootstrap"
import { ModalLoginView, useBrowserStore, usePersistentStore } from "../store"
import UserCard from "./UserCard"
import { versionService } from "../services"
import { use } from "marked"

const UserArea = () => {
const [view, setView] = useBrowserStore((state) => [
state.view,
state.setView,
])
const [user, token, resetUser, patchUser] = usePersistentStore((state) => [
state.user,
state.token,
state.resetUser,
])
const { status, data, error } = useQuery({
queryKey: ["me"],
queryFn: () =>
axios
.get("/api/me", {
headers: {
Authorization: `Bearer ${token}`,
},
})
.then((res) => res.data),
retry: false,
refetchOnMount: false,
refetchOnReconnect: false,
enabled: user === null && token !== null,
})
if (status === "error" && error.response?.status === 401) {
console.warn("[UserArea] token is incorrect. ", error.response.data)
// clean up the token(s) and user(s) from the store
resetUser()
} else if (status === "success") {
patchUser(data)
}
console.info("[UserArea] user", user, "status", status)
useEffect(() => {
versionService.find().then((data) => {
console.info("[UserArea] version", data)
})
}, [])
// userService.find().then((data) => {
// console.info("[UserArea] data", data)
// return data
// })
// }, [])
const user = usePersistentStore((state) => state.user)
return (
<div className="UserArea me-3 d-flex">
{user !== null ? (
Expand Down
48 changes: 48 additions & 0 deletions src/services.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { feathers } from "@feathersjs/feathers"
import socketio from "@feathersjs/socketio-client"
import auth from "@feathersjs/authentication-client"
import io from "socket.io-client"
import { usePersistentStore } from "./store"
const setAuthenticatedUser = usePersistentStore.getState().setAuthenticatedUser

const socket = io("", {
path: "/api/socket.io/",
forceNew: true,
transports: ["websocket"],
})
// print ut socket version
const app = feathers()
app.configure(
auth({
storage: window.localStorage,
})
)
app.configure(
socketio(socket, {
timeout: 20000,
})
)
socket.on("connect_error", (err) => {
console.error("[services] ocket.io connection error:", err)
// reconnnect using transports
socket.disconnect()
})
socket.on("connect_timeout", (timeout) => {
console.error("[services] socket.io connection timeout:", timeout)
})
socket.on("connect", async () => {
console.info("[services] socket.io connection established")

await app
.reAuthenticate()
.then((data) => {
console.info("[services] reAuthenticate", Object.keys(data))
setAuthenticatedUser(data.user, data.accessToken)
})
.catch((err) => {
console.error("[services] reAuthenticate", err)
})
})

export const versionService = app.service("version")
// export const userService = app.service("me")
Loading

0 comments on commit 448f38f

Please sign in to comment.