NERDDISCO commited on
Commit
d378496
β€’
1 Parent(s): 41d4a1f

feat: added base components, updated the readme, extended summarization

Browse files
.env.local.example ADDED
@@ -0,0 +1 @@
 
 
1
+ HF_EXAMPLE_SECRET=thisisjustanexample
.gitignore CHANGED
@@ -32,4 +32,7 @@ yarn-error.log*
32
 
33
  # typescript
34
  *.tsbuildinfo
35
- next-env.d.ts
 
 
 
 
32
 
33
  # typescript
34
  *.tsbuildinfo
35
+ next-env.d.ts
36
+
37
+ # Docker secrets used for local dev
38
+ .secrets
Dockerfile CHANGED
@@ -15,6 +15,10 @@ RUN \
15
  else echo "Lockfile not found." && exit 1; \
16
  fi
17
 
 
 
 
 
18
 
19
  # Rebuild the source code only when needed
20
  FROM base AS builder
 
15
  else echo "Lockfile not found." && exit 1; \
16
  fi
17
 
18
+ # Uncomment the following lines if you want to use a secret at buildtime,
19
+ # for example to access your private npm packages
20
+ # RUN --mount=type=secret,id=HF_EXAMPLE_SECRET,mode=0444,required=true \
21
+ # $(cat /run/secrets/HF_EXAMPLE_SECRET)
22
 
23
  # Rebuild the source code only when needed
24
  FROM base AS builder
README.md CHANGED
@@ -1,6 +1,6 @@
1
  ---
2
  title: "Next.js on \U0001F917 Spaces"
3
- emoji: "πŸ³πŸ€—"
4
  colorFrom: blue
5
  colorTo: yellow
6
  sdk: docker
@@ -10,14 +10,25 @@ app_port: 3000
10
  ---
11
  <h1 align="center">Next.js on πŸ€— Spaces</h1>
12
 
13
- This starter can be used to run [Next.js](https://nextjs.org/) using [Docker](https://huggingface.co/docs/hub/spaces-sdks-docker) on πŸ€— [Spaces](https://huggingface.co/spaces).
 
 
 
 
 
 
14
 
15
  <!-- toc -->
16
 
17
  - [Local development](#local-development)
18
- - [Use the Docker container locally](#use-the-docker-container-locally)
 
 
 
19
  - [Dockerize an existing project](#dockerize-an-existing-project)
20
- - [Manage your πŸ€— Space via GitHub](#manage-your-%F0%9F%A4%97-space-via-github)
 
 
21
 
22
  <!-- tocstop -->
23
 
@@ -29,16 +40,68 @@ This starter can be used to run [Next.js](https://nextjs.org/) using [Docker](ht
29
  2. Start the local dev-server: `npm run dev`
30
  3. Open the app via [localhost:3000](http://localhost:3000)
31
 
32
- ## Use the Docker container locally
 
 
33
 
34
  To make sure that everything is working out, you can run your container locally:
35
 
36
  1. [Install Docker](https://docs.docker.com/get-docker/) on your machine
37
  2. Go into the `nextjs-hf-spaces` folder
38
- 3. Build your Docker image: `docker build -t nextjs-hf-spaces .`.
39
  4. Run your Docker container: `docker run -p 3000:3000 nextjs-hf-spaces`.
40
  5. Open the app via [localhost:3000](http://localhost:3000)
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  ## Dockerize an existing project
43
 
44
  To add support for Docker to an existing project, just copy the `Dockerfile` into the root of the project and add the following to the `next.config.js` file:
@@ -53,9 +116,9 @@ module.exports = {
53
 
54
  This will build the project as a standalone app inside the Docker image.
55
 
56
- ## Manage your πŸ€— Space via GitHub
57
 
58
- If you want to use all the features for collaborative development on GitHub, but keep your demo on Spaces, then you can set up a GitHub action that will automatically push changes from GitHub into Spaces.
59
 
60
  > ℹ️ Git-LFS is required for files bigger than 10MB
61
 
@@ -71,3 +134,42 @@ This should force push changes in the **main** branch from GitHub into your πŸ€—
71
  For further information, you can check out the [guide on Hugging Face](https://huggingface.co/docs/hub/spaces-github-actions).
72
 
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  title: "Next.js on \U0001F917 Spaces"
3
+ emoji: "\U0001F433\U0001F917"
4
  colorFrom: blue
5
  colorTo: yellow
6
  sdk: docker
 
10
  ---
11
  <h1 align="center">Next.js on πŸ€— Spaces</h1>
12
 
13
+ <p align="center">
14
+ Run your ML demo with ease in a <a href="https://nextjs.org">Next.js</a> environment
15
+ </p>
16
+
17
+ At failfast, we're passionate about crafting demos with TypeScript, Next.js, and MUI. Inspired by the ease-of-use of Gradio and Streamlit within Hugging Face Spaces, we aim to deliver a similar developer experience to JavaScript enthusiasts. Our toolkit includes predefined MUI components, empowering you to build intuitive UIs for your ML demos.
18
+
19
+ ---
20
 
21
  <!-- toc -->
22
 
23
  - [Local development](#local-development)
24
+ * [Use the Docker container locally](#use-the-docker-container-locally)
25
+ - [Secret Management](#secret-management)
26
+ * [Build-time](#build-time)
27
+ * [Runtime](#runtime)
28
  - [Dockerize an existing project](#dockerize-an-existing-project)
29
+ - [Sync your GitHub repository with your πŸ€— Space](#sync-your-github-repository-with-your-%F0%9F%A4%97-space)
30
+ - [Cleanup your πŸ€— Space](#cleanup-your-%F0%9F%A4%97-space)
31
+ - [Development Roadmap](#development-roadmap)
32
 
33
  <!-- tocstop -->
34
 
 
40
  2. Start the local dev-server: `npm run dev`
41
  3. Open the app via [localhost:3000](http://localhost:3000)
42
 
43
+ ### Use the Docker container locally
44
+
45
+ > ℹ️ In order for the commands to work, you need at least Docker >= 20.10, as we use env-variables as secrets
46
 
47
  To make sure that everything is working out, you can run your container locally:
48
 
49
  1. [Install Docker](https://docs.docker.com/get-docker/) on your machine
50
  2. Go into the `nextjs-hf-spaces` folder
51
+ 3. Build your Docker image: `docker build -t nextjs-hf-spaces .`
52
  4. Run your Docker container: `docker run -p 3000:3000 nextjs-hf-spaces`.
53
  5. Open the app via [localhost:3000](http://localhost:3000)
54
 
55
+ If you also have a secret that needs to be passed into the container, you can do this:
56
+
57
+ 1. Create a copy of `.env.local.example` and rename it to `.env.local` (it contains the secret `HF_EXAMPLE_SECRET`)
58
+ 2. Run your Docker container and specify the env-file: `docker run -p 3000:3000 --env-file .env.local nextjs-hf-spaces`
59
+ 3. Open the example API via [localhost:3000/api/env](http://localhost:3000/api/env) and see that the value of our secret `HF_EXAMPLE_SECRET` is shown
60
+
61
+ ## Secret Management
62
+
63
+ To not expose your secrets to end users, you can add them directly in **Settings** of your πŸ€— Space.
64
+
65
+ 1. Open your space and navigate to the **Settings**
66
+ 2. Find **Repository secrets** & click on **New secret**
67
+
68
+ That's it, you can now access your secret.
69
+
70
+ ### Build-time
71
+
72
+ If you need to have a secret during build-time (e.g. you want to install private npm packages), then you can add this directly into the `Dockerfile`:
73
+
74
+ ```dockerfile
75
+ # Uncomment the following lines if you want to use a secret at buildtime,
76
+ # for example to access your private npm packages
77
+ RUN --mount=type=secret,id=HF_EXAMPLE_SECRET,mode=0444,required=true \
78
+ $(cat /run/secrets/HF_EXAMPLE_SECRET)
79
+ ```
80
+
81
+ In this case, we mount the secret `HF_EXAMPLE_SECRET` (using [Docker secrets](https://docs.docker.com/engine/swarm/secrets/)) inside and can use it.
82
+
83
+ ### Runtime
84
+
85
+ When your πŸ€— Space is running and you want to use a secret (e.g. access an API that requires authentication) without exposing it to the user, you can use it as an environment variable via `process.env`.
86
+
87
+ ```typescript
88
+ import process from "node:process";
89
+ import { NextApiRequest, NextApiResponse } from "next";
90
+
91
+ export default async function handler(
92
+ request: NextApiRequest,
93
+ response: NextApiResponse
94
+ ) {
95
+ const exampleSecret = process.env.HF_EXAMPLE_SECRET;
96
+
97
+ // Your logic to access an API that requires authentication
98
+
99
+ return response.status(200).json("We have access to an external API");
100
+ }
101
+ ```
102
+
103
+ A simple example can be found at [nextjs-hf-spaces/api/env](https://huggingface.co/spaces/failfast/nextjs-hf-spaces/api/env). This will return the secret to see that it's working, but you wouldn't do this in your space, as you don't want to expose the secret to an end user.
104
+
105
  ## Dockerize an existing project
106
 
107
  To add support for Docker to an existing project, just copy the `Dockerfile` into the root of the project and add the following to the `next.config.js` file:
 
116
 
117
  This will build the project as a standalone app inside the Docker image.
118
 
119
+ ## Sync your GitHub repository with your πŸ€— Space
120
 
121
+ If you want to use all the features for collaborative development on GitHub, but keep your demo on πŸ€— Spaces, then you can set up a GitHub action that will automatically push changes from GitHub into Spaces.
122
 
123
  > ℹ️ Git-LFS is required for files bigger than 10MB
124
 
 
134
  For further information, you can check out the [guide on Hugging Face](https://huggingface.co/docs/hub/spaces-github-actions).
135
 
136
 
137
+ ## Cleanup your πŸ€— Space
138
+
139
+ You don't need all the demo content and examples? Then you can delete these resources to get a clean πŸ€— Space:
140
+
141
+ * `src/pages/api/env.ts`
142
+ * `src/components/example-components.tsx`
143
+ * `src/components/getting-started.tsx`
144
+ * `src/components/under-construction.tsx`
145
+ * `src/components/title.tsx`
146
+ * `src/components/huggingface/huggingface.tsx`
147
+
148
+ Update the `src/components/index.tsx` and remove:
149
+
150
+ ```jsx
151
+ <Title />
152
+
153
+ <GettingStarted />
154
+
155
+ <DividerBox />
156
+
157
+ <ExampleComponents />
158
+ ```
159
+
160
+ > i Got an idea how this could be better? Please let us know!
161
+
162
+ ## Development Roadmap
163
+
164
+ The next milestones in no particular order are:
165
+
166
+ * Components for all [`@huggingface/inference`](https://huggingface.co/docs/huggingface.js/inference/README) methods (WIP)
167
+ * Components to use [langchain.js](https://js.langchain.com/docs)
168
+ * Components to use [hyv](https://github.com/failfa-st/hyv)
169
+ * Publish components on npm to make them usable outside of [nextjs-hf-spaces](https://github.com/failfa-st/nextjs-hf-spaces)
170
+ * Provide templates for different use-cases, that are too complex for single components
171
+ * Docs on how to use the components with all available options
172
+
173
+ > i Anything missing? Please let us know!
174
+
175
+
package-lock.json CHANGED
@@ -7,7 +7,7 @@
7
  "": {
8
  "name": "nextjs-docker-starter",
9
  "version": "1.0.0",
10
- "license": "AGPL",
11
  "dependencies": {
12
  "@emotion/cache": "11.10.7",
13
  "@emotion/react": "11.10.6",
 
7
  "": {
8
  "name": "nextjs-docker-starter",
9
  "version": "1.0.0",
10
+ "license": "MIT",
11
  "dependencies": {
12
  "@emotion/cache": "11.10.7",
13
  "@emotion/react": "11.10.6",
package.json CHANGED
@@ -1,12 +1,13 @@
1
  {
2
- "name": "nextjs-docker-starter",
3
- "version": "1.0.0",
4
- "description": "Run your ML demo app using Next.js on πŸ€— Spaces",
5
  "keywords": [
6
  "nextjs",
7
  "artificial intelligence",
8
  "javascript",
9
- "hugging face spaces",
 
10
  "machine learning"
11
  ],
12
  "license": "MIT",
@@ -15,11 +16,11 @@
15
  "url": "https://github.com/TimPietrusky"
16
  },
17
  "scripts": {
18
- "dev": "next dev",
19
  "build": "next build",
20
- "start": "next start",
21
  "lint": "next lint",
22
  "spj": "npx sort-package-json",
 
23
  "toc": "npx markdown-toc README.md -i"
24
  },
25
  "dependencies": {
 
1
  {
2
+ "name": "nextjs-hf-spaces",
3
+ "version": "0.0.1",
4
+ "description": "Run your ML demo with ease in a Next.js environment",
5
  "keywords": [
6
  "nextjs",
7
  "artificial intelligence",
8
  "javascript",
9
+ "typescript",
10
+ "hugging face",
11
  "machine learning"
12
  ],
13
  "license": "MIT",
 
16
  "url": "https://github.com/TimPietrusky"
17
  },
18
  "scripts": {
 
19
  "build": "next build",
20
+ "dev": "next dev",
21
  "lint": "next lint",
22
  "spj": "npx sort-package-json",
23
+ "start": "next start",
24
  "toc": "npx markdown-toc README.md -i"
25
  },
26
  "dependencies": {
src/components/{boxes.tsx β†’ base/boxes.tsx} RENAMED
@@ -3,12 +3,11 @@ import { styled } from "@mui/material/styles";
3
 
4
  export const SectionBox = styled(Paper)<PaperProps>(({ theme }) => ({
5
  display: "flex",
6
- alignItems: "center",
7
- justifyContent: "center",
8
  padding: 15,
9
- border: `5px solid transparent`,
10
- borderImage: `linear-gradient(to bottom right, #b827fc 0%, #2c90fc 25%, #b8fd33 50%, #fec837 75%, #fd1892 100%)`,
11
- borderImageSlice: 1,
 
12
  }));
13
 
14
  export const HighlightBox = styled(Paper)<PaperProps>(({ theme }) => ({
 
3
 
4
  export const SectionBox = styled(Paper)<PaperProps>(({ theme }) => ({
5
  display: "flex",
 
 
6
  padding: 15,
7
+ paddingTop: 30,
8
+ paddingBottom: 30,
9
+ marginBottom: 20,
10
+ background: `linear-gradient(to bottom right, ${theme.palette.primary.main} 0%, ${theme.palette.secondary.main} 100%)`,
11
  }));
12
 
13
  export const HighlightBox = styled(Paper)<PaperProps>(({ theme }) => ({
src/components/base/code.tsx ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { styled } from "@mui/material/styles";
2
+ import { Paper, PaperProps } from "@mui/material";
3
+
4
+ type CodeProps = {
5
+ children: string;
6
+ };
7
+
8
+ const CodeBox = styled(Paper)<PaperProps>(({ theme }) => ({
9
+ fontFamily: "monospace",
10
+ padding: 8,
11
+ borderTop: `2px solid ${theme.palette.secondary.dark}`,
12
+ borderBottom: `2px solid ${theme.palette.secondary.dark}`,
13
+ }));
14
+
15
+ export default function Code(props: CodeProps) {
16
+ const { children } = props;
17
+
18
+ return <CodeBox>{children}</CodeBox>;
19
+ }
src/components/base/example-button.tsx ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Button, Typography } from "@mui/material";
2
+ import { MouseEventHandler } from "react";
3
+
4
+ interface ExampleButtonProps {
5
+ text: string;
6
+ displayLength?: number;
7
+ onClick?: (text: string) => void;
8
+ }
9
+
10
+ /**
11
+ *
12
+ * A button that hosts an example "text" that can be used as the input
13
+ * to anything to get an inspiration on how to get started.
14
+ *
15
+ * @param props ExampleButtonProps
16
+ * @returns
17
+ */
18
+ export default function ExampleButton(props: ExampleButtonProps) {
19
+ const { text, displayLength = 50, onClick } = props;
20
+
21
+ const displayText =
22
+ text.slice(0, displayLength) + (text.length > displayLength ? "..." : "");
23
+
24
+ const handleClick: MouseEventHandler = event => {
25
+ event.preventDefault();
26
+
27
+ if (onClick) {
28
+ onClick(text);
29
+ }
30
+ };
31
+
32
+ return (
33
+ <Button
34
+ onClick={handleClick}
35
+ sx={{ textTransform: "none" }}
36
+ variant="outlined"
37
+ >
38
+ <Typography>{displayText}</Typography>
39
+ </Button>
40
+ );
41
+ }
src/components/base/options.tsx ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { KeyboardArrowDown, KeyboardArrowUp } from "@mui/icons-material";
2
+ import {
3
+ Card,
4
+ CardContent,
5
+ CardHeader,
6
+ Collapse,
7
+ IconButton,
8
+ Stack,
9
+ } from "@mui/material";
10
+ import { ReactElement, useState } from "react";
11
+
12
+ type OptionsProps = {
13
+ children: ReactElement | ReactElement[];
14
+ opened?: boolean;
15
+ };
16
+
17
+ /**
18
+ * Define options that are hidden by default
19
+ *
20
+ * @param props OptionsProps
21
+ * @param props.opened boolean - Are the options visible or not (default)
22
+ *
23
+ * @returns Options
24
+ */
25
+ export default function Options(props: OptionsProps) {
26
+ const { children, opened = false } = props;
27
+
28
+ const [showOptions, setShowOptions] = useState(opened);
29
+
30
+ const handleShowOptions = () => setShowOptions(!showOptions);
31
+
32
+ return (
33
+ <>
34
+ <Card>
35
+ <CardHeader
36
+ title="Options"
37
+ onClick={handleShowOptions}
38
+ action={
39
+ <IconButton aria-label="expand" size="small">
40
+ {showOptions ? <KeyboardArrowUp /> : <KeyboardArrowDown />}
41
+ </IconButton>
42
+ }
43
+ sx={{
44
+ cursor: "pointer",
45
+ }}
46
+ titleTypographyProps={{ variant: "h6", sx: { fontSize: "1em" } }}
47
+ />
48
+ <Collapse in={showOptions}>
49
+ <CardContent>
50
+ <Stack spacing={2}>{children}</Stack>
51
+ </CardContent>
52
+ </Collapse>
53
+ </Card>
54
+ </>
55
+ );
56
+ }
src/components/base/slider-with-label.tsx ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ Box,
3
+ FormControlLabel,
4
+ Slider,
5
+ SliderProps,
6
+ Typography,
7
+ } from "@mui/material";
8
+
9
+ type SliderWithLabelProps = SliderProps & {
10
+ label?: string;
11
+ };
12
+
13
+ export default function SliderWithLabel(props: SliderWithLabelProps) {
14
+ const { label = "", valueLabelDisplay = "auto" } = props;
15
+
16
+ return (
17
+ <Box>
18
+ <Typography variant="subtitle1">{label}</Typography>
19
+ <Slider {...props} valueLabelDisplay={valueLabelDisplay} />
20
+ </Box>
21
+ );
22
+ }
src/components/example-components.tsx CHANGED
@@ -1,24 +1,35 @@
1
- import { Stack, Typography } from "@mui/material";
2
  import Huggingface from "./huggingface/huggingface";
3
- import { SectionBox } from "./boxes";
 
4
 
5
  export default function ExampleComponents() {
6
  return (
7
  <>
8
  <SectionBox>
9
  <Stack spacing={2}>
10
- <Typography component="h2" variant="h3" sx={{ textAlign: "center" }}>
11
  Components
12
  </Typography>
13
 
14
  <Typography variant="body1">
15
- Unsure where to begin? Our pre-built components are at your service,
16
- offering a jumpstart for your ML demo.
17
  </Typography>
18
  </Stack>
19
  </SectionBox>
20
 
21
  <Huggingface />
 
 
 
 
 
 
 
 
 
 
22
  </>
23
  );
24
  }
 
1
+ import { Box, Stack, Typography } from "@mui/material";
2
  import Huggingface from "./huggingface/huggingface";
3
+ import { DividerBox, HighlightBox, SectionBox } from "./base/boxes";
4
+ import { UnderConstruction } from "./under-construction";
5
 
6
  export default function ExampleComponents() {
7
  return (
8
  <>
9
  <SectionBox>
10
  <Stack spacing={2}>
11
+ <Typography component="h2" variant="h3">
12
  Components
13
  </Typography>
14
 
15
  <Typography variant="body1">
16
+ Unsure where to begin? Our pre-built components offer a jumpstart
17
+ for your ML demo πŸš€
18
  </Typography>
19
  </Stack>
20
  </SectionBox>
21
 
22
  <Huggingface />
23
+
24
+ <DividerBox />
25
+
26
+ <Stack spacing={4}>
27
+ <HighlightBox>
28
+ <Typography variant="h4">More comming soon!</Typography>
29
+ </HighlightBox>
30
+
31
+ <UnderConstruction />
32
+ </Stack>
33
  </>
34
  );
35
  }
src/components/getting-started.tsx CHANGED
@@ -19,7 +19,7 @@ import SentimentVerySatisfiedIcon from "@mui/icons-material/SentimentVerySatisfi
19
  import ContentCopyIcon from "@mui/icons-material/ContentCopy";
20
  import LinkIcon from "@mui/icons-material/Link";
21
  import SyncIcon from "@mui/icons-material/Sync";
22
- import { HighlightBox } from "./boxes";
23
 
24
  export default function GettingStarted() {
25
  return (
@@ -28,7 +28,7 @@ export default function GettingStarted() {
28
  <Grid item sm={8} lg={6} sx={{ justifyContent: "center" }}>
29
  <Paper sx={{ p: 2 }}>
30
  <List disablePadding>
31
- <ListSubheader>Features</ListSubheader>
32
 
33
  <ListItem>
34
  <ListItemIcon>
@@ -58,7 +58,15 @@ export default function GettingStarted() {
58
  >
59
  langchain.js
60
  </Link>{" "}
61
- components (WIP)
 
 
 
 
 
 
 
 
62
  </ListItemText>
63
  </ListItem>
64
 
@@ -107,7 +115,7 @@ export default function GettingStarted() {
107
  <Stack gap={2}>
108
  <Paper sx={{ p: 2 }}>
109
  <Typography variant="body1">
110
- Explore our{" "}
111
  <Link
112
  href="https://huggingface.co/spaces/failfast/nextjs-docker-starter/blob/main/README.md"
113
  target="_blank"
@@ -122,14 +130,16 @@ export default function GettingStarted() {
122
 
123
  <Paper sx={{ p: 2 }}>
124
  <Typography variant="body1">
125
- Something missing?{" "}
126
  <Link
127
  href="https://huggingface.co/spaces/failfast/nextjs-docker-starter/discussions"
128
  target="_blank"
129
  rel="noopener"
130
  >
131
- Please let us know!
132
- </Link>
 
 
133
  </Typography>
134
  </Paper>
135
  </Stack>
 
19
  import ContentCopyIcon from "@mui/icons-material/ContentCopy";
20
  import LinkIcon from "@mui/icons-material/Link";
21
  import SyncIcon from "@mui/icons-material/Sync";
22
+ import { HighlightBox } from "./base/boxes";
23
 
24
  export default function GettingStarted() {
25
  return (
 
28
  <Grid item sm={8} lg={6} sx={{ justifyContent: "center" }}>
29
  <Paper sx={{ p: 2 }}>
30
  <List disablePadding>
31
+ <ListSubheader sx={{ fontSize: "1.5em" }}>Features</ListSubheader>
32
 
33
  <ListItem>
34
  <ListItemIcon>
 
58
  >
59
  langchain.js
60
  </Link>{" "}
61
+ and{" "}
62
+ <Link
63
+ href="https://github.com/failfa-st/hyv"
64
+ target="_blank"
65
+ rel="noopener"
66
+ >
67
+ hyv
68
+ </Link>{" "}
69
+ components (comming soon)
70
  </ListItemText>
71
  </ListItem>
72
 
 
115
  <Stack gap={2}>
116
  <Paper sx={{ p: 2 }}>
117
  <Typography variant="body1">
118
+ Explore the{" "}
119
  <Link
120
  href="https://huggingface.co/spaces/failfast/nextjs-docker-starter/blob/main/README.md"
121
  target="_blank"
 
130
 
131
  <Paper sx={{ p: 2 }}>
132
  <Typography variant="body1">
133
+ Have feedback or ideas?{" "}
134
  <Link
135
  href="https://huggingface.co/spaces/failfast/nextjs-docker-starter/discussions"
136
  target="_blank"
137
  rel="noopener"
138
  >
139
+ We&apos;re eager to hear from you!
140
+ </Link>{" "}
141
+ As an open-source project in its early stages, your input can
142
+ significantly shape our development.
143
  </Typography>
144
  </Paper>
145
  </Stack>
src/components/huggingface/huggingface.tsx CHANGED
@@ -1,7 +1,9 @@
1
- import { Typography } from "@mui/material";
2
  import { HfInference } from "@huggingface/inference";
3
  import { useEffect } from "react";
4
  import Summarization from "./inference/summarization";
 
 
5
 
6
  export type InferenceProps = {
7
  token?: string;
@@ -11,14 +13,52 @@ export type InferenceProps = {
11
  export default function Huggingface() {
12
  return (
13
  <>
14
- <Typography component="h4" variant="h4">
15
- huggingface.js
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  </Typography>
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  <Typography component="h5" variant="h5">
19
  Summarization
20
  </Typography>
21
- <Summarization model="facebook/bart-large-cnn" />
 
 
 
22
  </>
23
  );
24
  }
 
1
+ import { Alert, Link, Typography } from "@mui/material";
2
  import { HfInference } from "@huggingface/inference";
3
  import { useEffect } from "react";
4
  import Summarization from "./inference/summarization";
5
+ import { HighlightBox } from "../base/boxes";
6
+ import Code from "../base/code";
7
 
8
  export type InferenceProps = {
9
  token?: string;
 
13
  export default function Huggingface() {
14
  return (
15
  <>
16
+ <HighlightBox>
17
+ <Typography component="h4" variant="h4">
18
+ huggingface.js
19
+ </Typography>
20
+ </HighlightBox>
21
+
22
+ <Typography variant="body1">
23
+ <Link
24
+ href="https://huggingface.co/docs/huggingface.js/index"
25
+ target="_blank"
26
+ rel="noopener"
27
+ >
28
+ huggingface.js
29
+ </Link>{" "}
30
+ is a suite of JavaScript libraries that interact with the Hugging Face
31
+ API. It enables the use of over 100,000 ML models or your own via the{" "}
32
+ <Link
33
+ href="https://huggingface.co/docs/inference-endpoints/index"
34
+ target="_blank"
35
+ rel="noopener"
36
+ >
37
+ Inference API
38
+ </Link>
39
+ , and supports managing Hugging Face repositories.
40
  </Typography>
41
 
42
+ <Alert severity="info">
43
+ When you run into rate limits while using the components, make sure to
44
+ add your πŸ€— access token (optained via your{" "}
45
+ <Link
46
+ href="https://huggingface.co/settings/tokens"
47
+ target="_blank"
48
+ rel="noopener"
49
+ >
50
+ account settings
51
+ </Link>
52
+ ) into `HF Access Token` under &quot;Options&quot;.
53
+ </Alert>
54
+
55
  <Typography component="h5" variant="h5">
56
  Summarization
57
  </Typography>
58
+
59
+ <Code>{`<Summarization model="facebook/bart-large-cnn" maxLength={100} />`}</Code>
60
+
61
+ <Summarization model="facebook/bart-large-cnn" maxLength={100} />
62
  </>
63
  );
64
  }
src/components/huggingface/inference/summarization.tsx CHANGED
@@ -1,24 +1,73 @@
1
  import {
2
  Alert,
 
3
  Button,
 
4
  IconButton,
5
  InputAdornment,
6
  Paper,
 
7
  Stack,
8
  TextField,
 
9
  } from "@mui/material";
10
  import { useEffect, useRef, useState } from "react";
11
- import { HfInference } from "@huggingface/inference";
12
  import { Visibility, VisibilityOff } from "@mui/icons-material";
13
  import { InferenceProps } from "../huggingface";
 
 
 
14
 
15
- export default function Summarization(props: InferenceProps) {
16
- const { model } = props;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
  const [token, setToken] = useState<string>("");
 
19
  const [summary, setSummary] = useState<string>("");
20
  const [error, setError] = useState<string>("");
21
  const [showToken, setShowToken] = useState(false);
 
22
 
23
  const inference = useRef<HfInference | null>(null);
24
 
@@ -26,6 +75,7 @@ export default function Summarization(props: InferenceProps) {
26
  inference.current = new HfInference(token);
27
  }, [token]);
28
 
 
29
  const handleSubmit = (event: any) => {
30
  event.preventDefault();
31
  const data = new FormData(event.currentTarget);
@@ -33,20 +83,26 @@ export default function Summarization(props: InferenceProps) {
33
  setToken(data.get("token") as string);
34
 
35
  const text = data.get("text") as string;
 
36
 
37
- call(text);
38
  };
39
 
40
  const handleShowToken = () => setShowToken(!showToken);
41
 
42
- const call = async (inputs: string) => {
 
 
 
 
 
43
  try {
 
 
44
  const response = await inference.current?.summarization({
45
  model,
46
  inputs,
47
- parameters: {
48
- max_length: 100,
49
- },
50
  });
51
 
52
  setSummary(response?.summary_text as string);
@@ -58,27 +114,14 @@ export default function Summarization(props: InferenceProps) {
58
  setError("An unknown error occurred");
59
  }
60
  }
 
 
61
  };
62
 
63
  return (
64
  <>
65
  <Paper component="form" onSubmit={handleSubmit} sx={{ padding: "1em" }}>
66
  <Stack spacing={2}>
67
- <TextField
68
- variant="filled"
69
- label="HF Token"
70
- name="token"
71
- type={showToken ? "text" : "password"}
72
- InputProps={{
73
- endAdornment: (
74
- <InputAdornment position="end">
75
- <IconButton onClick={handleShowToken}>
76
- {showToken ? <Visibility /> : <VisibilityOff />}
77
- </IconButton>
78
- </InputAdornment>
79
- ),
80
- }}
81
- />
82
  <TextField
83
  variant="filled"
84
  label="Text to summarize"
@@ -86,9 +129,24 @@ export default function Summarization(props: InferenceProps) {
86
  required
87
  minRows={4}
88
  name="text"
 
 
89
  />
90
- <Button type="submit" variant="contained">
91
- Run
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  </Button>
93
 
94
  {error && <Alert severity="error">{error}</Alert>}
@@ -101,6 +159,49 @@ export default function Summarization(props: InferenceProps) {
101
  name="text"
102
  value={summary}
103
  />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  </Stack>
105
  </Paper>
106
  </>
 
1
  import {
2
  Alert,
3
+ Box,
4
  Button,
5
+ CircularProgress,
6
  IconButton,
7
  InputAdornment,
8
  Paper,
9
+ Slider,
10
  Stack,
11
  TextField,
12
+ Typography,
13
  } from "@mui/material";
14
  import { useEffect, useRef, useState } from "react";
15
+ import { HfInference, SummarizationArgs } from "@huggingface/inference";
16
  import { Visibility, VisibilityOff } from "@mui/icons-material";
17
  import { InferenceProps } from "../huggingface";
18
+ import Options from "@/components/base/options";
19
+ import SliderWithLabel from "@/components/base/slider-with-label";
20
+ import ExampleButton from "@/components/base/example-button";
21
 
22
+ type SummarizationProps = InferenceProps & {
23
+ /**
24
+ * (Default: None). Integer to define the maximum length in tokens of the output summary.
25
+ */
26
+ maxLength?: number;
27
+ /**
28
+ * (Default: None). Float (0-120.0). The amount of time in seconds that the query should take maximum. Network can cause some overhead so it will be a soft limit.
29
+ */
30
+ maxTime?: number;
31
+ /**
32
+ * (Default: None). Integer to define the minimum length in tokens of the output summary.
33
+ */
34
+ minLength?: number;
35
+ /**
36
+ * (Default: None). Float (0.0-100.0). The more a token is used within generation the more it is penalized to not be picked in successive generation passes.
37
+ */
38
+ repetitionPenalty?: number;
39
+ /**
40
+ * (Default: 1.0). Float (0.0-100.0). The temperature of the sampling operation. 1 means regular sampling, 0 means always take the highest score, 100.0 is getting closer to uniform probability.
41
+ */
42
+ temperature?: number;
43
+ /**
44
+ * (Default: None). Integer to define the top tokens considered within the sample operation to create new text.
45
+ */
46
+ topK?: number;
47
+ /**
48
+ * (Default: None). Float to define the tokens that are within the sample operation of text generation. Add tokens in the sample for more probable to least probable until the sum of the probabilities is greater than top_p.
49
+ */
50
+ topP?: number;
51
+ };
52
+
53
+ export default function Summarization(props: SummarizationProps) {
54
+ const {
55
+ model,
56
+ maxLength,
57
+ maxTime,
58
+ minLength,
59
+ repetitionPenalty,
60
+ temperature,
61
+ topK,
62
+ topP,
63
+ } = props;
64
 
65
  const [token, setToken] = useState<string>("");
66
+ const [inputText, setInputText] = useState<string>("");
67
  const [summary, setSummary] = useState<string>("");
68
  const [error, setError] = useState<string>("");
69
  const [showToken, setShowToken] = useState(false);
70
+ const [loading, setLoading] = useState(false);
71
 
72
  const inference = useRef<HfInference | null>(null);
73
 
 
75
  inference.current = new HfInference(token);
76
  }, [token]);
77
 
78
+ // Parse the data of the form and trigger "call"
79
  const handleSubmit = (event: any) => {
80
  event.preventDefault();
81
  const data = new FormData(event.currentTarget);
 
83
  setToken(data.get("token") as string);
84
 
85
  const text = data.get("text") as string;
86
+ const max_length = Number(data.get("maxLength") as string);
87
 
88
+ call({ model, inputs: text, parameters: { max_length } });
89
  };
90
 
91
  const handleShowToken = () => setShowToken(!showToken);
92
 
93
+ /**
94
+ * Call the inference API using args
95
+ */
96
+ const call = async (args: SummarizationArgs) => {
97
+ const { inputs, parameters } = args;
98
+
99
  try {
100
+ setLoading(true);
101
+
102
  const response = await inference.current?.summarization({
103
  model,
104
  inputs,
105
+ parameters,
 
 
106
  });
107
 
108
  setSummary(response?.summary_text as string);
 
114
  setError("An unknown error occurred");
115
  }
116
  }
117
+
118
+ setLoading(false);
119
  };
120
 
121
  return (
122
  <>
123
  <Paper component="form" onSubmit={handleSubmit} sx={{ padding: "1em" }}>
124
  <Stack spacing={2}>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  <TextField
126
  variant="filled"
127
  label="Text to summarize"
 
129
  required
130
  minRows={4}
131
  name="text"
132
+ value={inputText}
133
+ onChange={e => setInputText(e.target.value)}
134
  />
135
+
136
+ <Button type="submit" variant="contained" disabled={loading}>
137
+ Run{" "}
138
+ {loading && (
139
+ <CircularProgress
140
+ size={24}
141
+ sx={{
142
+ position: "absolute",
143
+ top: "50%",
144
+ left: "50%",
145
+ marginTop: "-12px",
146
+ marginLeft: "-12px",
147
+ }}
148
+ />
149
+ )}
150
  </Button>
151
 
152
  {error && <Alert severity="error">{error}</Alert>}
 
159
  name="text"
160
  value={summary}
161
  />
162
+
163
+ <Options>
164
+ <TextField
165
+ variant="filled"
166
+ label="HF Access Token"
167
+ name="token"
168
+ type={showToken ? "text" : "password"}
169
+ InputProps={{
170
+ endAdornment: (
171
+ <InputAdornment position="end">
172
+ <IconButton onClick={handleShowToken}>
173
+ {showToken ? <Visibility /> : <VisibilityOff />}
174
+ </IconButton>
175
+ </InputAdornment>
176
+ ),
177
+ }}
178
+ />
179
+
180
+ <SliderWithLabel
181
+ label="max_length"
182
+ name="maxLength"
183
+ aria-label="max length"
184
+ defaultValue={maxLength}
185
+ step={1}
186
+ min={56}
187
+ max={256}
188
+ />
189
+ </Options>
190
+
191
+ <Typography variant="h6" sx={{ fontSize: "1em" }}>
192
+ Examples
193
+ </Typography>
194
+ <Stack direction="row" spacing={2}>
195
+ <ExampleButton
196
+ text="The tower is 324 metres (1,063 ft) tall, about the same height as an 81-storey building, and the tallest structure in Paris. Its base is square, measuring 125 metres (410 ft) on each side. During its construction, the Eiffel Tower surpassed the Washington Monument to become the tallest man-made structure in the world, a title it held for 41 years until the Chrysler Building in New York City was finished in 1930. It was the first structure to reach a height of 300 metres. Due to the addition of a broadcasting aerial at the top of the tower in 1957, it is now taller than the Chrysler Building by 5.2 metres (17 ft). Excluding transmitters, the Eiffel Tower is the second tallest free-standing structure in France after the Millau Viaduct."
197
+ onClick={setInputText}
198
+ />
199
+
200
+ <ExampleButton
201
+ text="Machine learning (ML) is a field devoted to understanding and building methods that let machines 'learn' – that is, methods that leverage data to improve computer performance on some set of tasks. Machine learning algorithms build a model based on sample data, known as training data, in order to make predictions or decisions without being explicitly programmed to do so. Machine learning algorithms are used in a wide variety of applications, such as in medicine, email filtering, speech recognition, agriculture, and computer vision, where it is difficult or unfeasible to develop conventional algorithms to perform the needed tasks."
202
+ onClick={setInputText}
203
+ />
204
+ </Stack>
205
  </Stack>
206
  </Paper>
207
  </>
src/components/title.tsx CHANGED
@@ -1,5 +1,5 @@
1
  import { Button, Link, Paper, Stack, Typography } from "@mui/material";
2
- import { HighlightBox } from "./boxes";
3
  import ContentCopyIcon from "@mui/icons-material/ContentCopy";
4
 
5
  export default function Title() {
@@ -33,7 +33,7 @@ export default function Title() {
33
 
34
  <HighlightBox>
35
  <Typography variant="h5" component="p">
36
- Run your ML demo with ease in a Next.js/React environment
37
  </Typography>
38
  </HighlightBox>
39
 
 
1
  import { Button, Link, Paper, Stack, Typography } from "@mui/material";
2
+ import { HighlightBox } from "./base/boxes";
3
  import ContentCopyIcon from "@mui/icons-material/ContentCopy";
4
 
5
  export default function Title() {
 
33
 
34
  <HighlightBox>
35
  <Typography variant="h5" component="p">
36
+ Run your ML demo with ease in a Next.js environment
37
  </Typography>
38
  </HighlightBox>
39
 
src/components/under-construction.tsx ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ import { styled } from "@mui/material/styles";
2
+
3
+ export const UnderConstruction = styled("div")({
4
+ width: "100%",
5
+ height: "266px",
6
+ backgroundRepeat: "round",
7
+ backgroundImage: `url("data:image/gif;base64,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")`,
8
+ });
src/lib/theme.ts CHANGED
@@ -21,10 +21,10 @@ const theme = extendTheme({
21
  light: {
22
  palette: {
23
  primary: {
24
- main: "#40088d",
25
  },
26
  secondary: {
27
- main: "#038225",
28
  },
29
  },
30
  },
 
21
  light: {
22
  palette: {
23
  primary: {
24
+ main: "#2c90fc",
25
  },
26
  secondary: {
27
+ main: "#b827fc",
28
  },
29
  },
30
  },
src/pages/api/env.ts ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import process from "node:process";
2
+ import { NextApiRequest, NextApiResponse } from "next";
3
+
4
+ export default async function handler(
5
+ request: NextApiRequest,
6
+ response: NextApiResponse
7
+ ) {
8
+ const exampleSecret = process.env.HF_EXAMPLE_SECRET;
9
+
10
+ return response.status(200).json({ HF_EXAMPLE_SECRET: exampleSecret });
11
+ }
src/pages/index.tsx CHANGED
@@ -6,7 +6,7 @@ import Huggingface from "@/components/huggingface/huggingface";
6
  import GettingStarted from "@/components/getting-started";
7
  import ExampleComponents from "@/components/example-components";
8
  import { Stack } from "@mui/material";
9
- import { DividerBox } from "@/components/boxes"
10
 
11
  export default function Home() {
12
  return (
 
6
  import GettingStarted from "@/components/getting-started";
7
  import ExampleComponents from "@/components/example-components";
8
  import { Stack } from "@mui/material";
9
+ import { DividerBox } from "@/components/base/boxes";
10
 
11
  export default function Home() {
12
  return (