Wauplin HF Staff commited on
Commit
830bf88
·
verified ·
1 Parent(s): 21a86d3
PROMPT.md ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ This repository contains a full-stack application designed to be deployed in a Hugging Face Space.
2
+
3
+ ## backend/
4
+
5
+ The backend/ folder contains the API server, implemented in Python using FastAPI. Project is built using uv.
6
+ Main commands in that folder are:
7
+ - `make dev` to run a local dev server
8
+ - `make style` to apply code formatting
9
+ - `make quality` to check code format
10
+ - `make test` to run tests
11
+ - `uv add ...` to add a new dependency
12
+
13
+ When working in the `backend/` folder, please keep these instructions in mind:
14
+ - API is defined in `backend/src/app.py` using FastAPI. For now it contains an health check endpoint and endpoints to deal with the counter.
15
+ - You can define as many new endpoints as you need. Follow the FastAPI best practices. All routes should be defined under `/api` prefix.
16
+ - OAuth is already baked in. If an endpoint requires the user to be authenticated, pass `oauth_info: RequiredOAuth` as argument. If authentication is optional, pass `oauth_info: OptionalOAuth`. If you don't need authentication, no need for that arg. `RequiredOAuth` is a dataclass of type `OAuthInfo` (see below). `OptionalOAuth` is of type `OAuthInfo | None`.
17
+ - schemas are defined in `backend/src/schemas.py`. We use [SQLModel](https://sqlmodel.tiangolo.com/) to define them which is a wrapper on top of Pydantic and SQLAlchemy. Any object defined in this module with `table=True` will result in a table in the database. Since all models are Pydantic object, you can use them seamlessly with FastAPI. See examples in `backend/src/app.py` on how to load an object from database and how to insert one.
18
+ - The FastAPI server and Database are configured in `backend/src/app_factory.py`. DO NOT UPDATE this file.
19
+ - If the `BACKUP_DATASET_ID` and `HF_TOKEN` env variables are defined, the database will be regularly exported as parquet files in a dataset on the Hub. This is useful to have persistent storage in a Space. Export is done once every 5 minutes in an optimized way (only new data is upload). All of the logic is defined in `backend/src/app_factory.py` and `backend/src/parquet.py`. DO NOT UPDATE these files.
20
+ - App config and constants are defined in `backend/src/constants.py`. You can add new config value if required. Do not update existing ones unless explicitly requested.
21
+
22
+ ### OAuthInfo definition
23
+
24
+ Here is how `OAuthInfo` dataclass is defined in Python. Useful when a user is authenticated.
25
+
26
+ ```py
27
+ @dataclass
28
+ class OAuthUserInfo:
29
+ sub: str
30
+ name: str
31
+ preferred_username: str
32
+ email_verified: Optional[bool]
33
+ email: Optional[str]
34
+ picture: str
35
+ profile: str
36
+ website: Optional[str]
37
+ is_pro: bool
38
+ can_pay: Optional[bool]
39
+ orgs: Optional[List[OAuthOrgInfo]]
40
+
41
+
42
+ @dataclass
43
+ class OAuthInfo:
44
+ access_token: str
45
+ access_token_expires_at: datetime.datetime
46
+ user_info: OAuthUserInfo
47
+ state: Optional[str]
48
+ scope: str
49
+ ```
50
+
51
+ ## frontend/
52
+
53
+ The frontend/ folder contains the UI implemented in TS with React and Tailwind. Project is built using vite.
54
+ Main commands in that folder are:
55
+ - `pnpm install` to install packages
56
+ - `pnpm dev` to run a local dev environment
57
+ - `pnpm style` to apply code formatting
58
+ - `pnpm quality` to check code format
59
+ - `pnpm add (-D) ...` to add a new package
60
+
61
+ When working in the `frontend/` folder, please keep these instructions in mind:
62
+ - UI is a single-page application. It doesn't use any router. You must keep this structure.
63
+ - Main app is located in `frontend/src/App.tsx`.
64
+ - Components are defined in `frontend/src/components`.
65
+ - To make request to the backend, use `apiFetch` from `frontend/src/utils/apiFetch.ts`. It is a wrapper around `fetch` with a predefined backend url and authenticated calls.
66
+ - Authentication has to be done using the `OAuthButton` defined in `frontend/src/components/OAuthButton.tsx`. DO NOT UPDATE this file.
67
+ - The `BackendHealthCheck` component in `frontend/src/components/BackendHealthCheck.tsx` is made for dev purpose only. DO NOT UPDATE this file except if requested specifically.
68
+ - The `Counter` component in `frontend/src/components/Counter.tsx` is a good example on how to define a component making calls to the backend. You can remove / update it if necessary.
69
+ - You can define as many new components as you want. Make each component self contained. Define new components in `frontend/src/components/`.
70
+ - App config and constants are defined in `frontend/src/constants.ts` (backend url, health check interval, etc.). You can add new config value if required.
71
+ - Assets (images, etc.) should be added to the `frontend/src/assets` folder. There is a `frontend/src/assets/huggingface.svg` in it (Hugging Face logo). DO NOT REMOVE it. You can reuse it if you want and/or add any assets you want.
72
+ - Config files (`frontend/vite.config.ts`, `frontend/tsconfig.json`, `frontend/tsconfig.node.json`, `frontend/eslint.config.js`, `frontend/src/vite-env.d.ts`) should not be updated expect if explicitly requested by user.
73
+ - DO NOT MODIFY `frontend/src/index.css` (which imports tailwind) and `frontend/src/main.tsx` (main imports).
74
+
75
+
76
+ ## How to add a new feature?
77
+
78
+ - add new API routes in `backend/src/app.py`. If needed, add a new schema in `backend/src/schemas.py`. Use authentication if required.
79
+ - add a new component in `frontend/src/components` and update `frontend/src/App.tsx` to include it.
80
+ - let the user run `cd frontend && pnpm dev` and `cd backend && make dev` in 2 terminals to try it out
81
+ - once tested, commit the changes and push to remote branch
README.md CHANGED
@@ -17,7 +17,24 @@ This repo is a template to run a FastAPI server hosting a React+Tailwind app in
17
 
18
  Spaces are very well suited to vibe-code demos using Cursor, Lovable, Claude Code, etc. The hardest past is often to correctly configure the tooltip to make it work in the first place. This repo is intended to solve that.
19
 
20
- ## Getting started
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
  The backend (Python + FastAPI) and the frontend (TS + React + Tailwind) are located respectively in the `backend/` and `frontend/` folder.
23
 
 
17
 
18
  Spaces are very well suited to vibe-code demos using Cursor, Lovable, Claude Code, etc. The hardest past is often to correctly configure the tooltip to make it work in the first place. This repo is intended to solve that.
19
 
20
+ ## Main features
21
+
22
+ - 🚀 Built for HF Spaces
23
+ - ✨ Vibe-coding ready (see [PROMPT.md](./PROMPT.md))
24
+ - 🤗 Support OAuth (Sign in with Hugging Face)
25
+ - ⚡ FastAPI for the API²
26
+ - 🎨 React + Tailwind for the UI
27
+ - 💾 local SQLLite database + regular backups as HF dataset
28
+
29
+ ## Quick start
30
+
31
+ 1. Duplicate the Space.
32
+ 2. Set an `HF_TOKEN` as Space secret and `BACKUP_DATASET_ID` as Space variable. These will be used to make regular backups of the database.
33
+ 3. At this stage, Space should be running correctly on the Hub with a demo.
34
+ 4. For local development, follow the dev instructions below.
35
+ 5. Once server is running locally, you can start to edit it. All instructions are located in `PROMPT.md`. Inject that file in the vibe coding tool of your choice and start building!
36
+
37
+ ## Instructions
38
 
39
  The backend (Python + FastAPI) and the frontend (TS + React + Tailwind) are located respectively in the `backend/` and `frontend/` folder.
40
 
backend/Makefile CHANGED
@@ -1,4 +1,4 @@
1
- .PHONY: quality style
2
 
3
  dev:
4
  HF_HUB_DISABLE_EXPERIMENTAL_WARNING=1 uv run uvicorn src.app:app --reload
 
1
+ .PHONY: quality style dev preview test
2
 
3
  dev:
4
  HF_HUB_DISABLE_EXPERIMENTAL_WARNING=1 uv run uvicorn src.app:app --reload
frontend/src/App.tsx CHANGED
@@ -78,16 +78,18 @@ function App() {
78
 
79
  <div className="bg-gray-800/30 backdrop-blur-sm rounded-xl p-6 border border-gray-700/30">
80
  <div className="text-cyan-400 text-2xl mb-3">💾</div>
81
- <h3 className="text-lg font-semibold mb-2">SQLite Database</h3>
 
 
82
  <p className="text-gray-300 text-sm">
83
- (semi-)persistent data storage
84
  </p>
85
  </div>
86
  </div>
87
 
88
  <div className="bg-gray-800/20 backdrop-blur-sm rounded-xl p-6 border border-gray-700/20 mb-8">
89
  <h3 className="text-xl font-semibold mb-4 text-center">
90
- Duplicate this Space, open the README, and make it yours.
91
  </h3>
92
  </div>
93
  </div>
 
78
 
79
  <div className="bg-gray-800/30 backdrop-blur-sm rounded-xl p-6 border border-gray-700/30">
80
  <div className="text-cyan-400 text-2xl mb-3">💾</div>
81
+ <h3 className="text-lg font-semibold mb-2">
82
+ SQLite + Parquet backups
83
+ </h3>
84
  <p className="text-gray-300 text-sm">
85
+ Work with SQLite locally, but persist data in a HF dataset as parquet
86
  </p>
87
  </div>
88
  </div>
89
 
90
  <div className="bg-gray-800/20 backdrop-blur-sm rounded-xl p-6 border border-gray-700/20 mb-8">
91
  <h3 className="text-xl font-semibold mb-4 text-center">
92
+ Duplicate this Space to start building!
93
  </h3>
94
  </div>
95
  </div>
frontend/src/components/BackendHealthCheck.tsx CHANGED
@@ -1,5 +1,5 @@
1
  import { useState, useEffect } from "react";
2
- import { BACKEND_URL, APP_CONFIG } from "../config/constants";
3
 
4
  interface BackendHealthCheckProps {
5
  checkInterval?: number;
 
1
  import { useState, useEffect } from "react";
2
+ import { BACKEND_URL, APP_CONFIG } from "../constants";
3
 
4
  interface BackendHealthCheckProps {
5
  checkInterval?: number;
frontend/src/components/OAuthButton.tsx CHANGED
@@ -1,5 +1,5 @@
1
  import React, { useState, useEffect } from "react";
2
- import { BACKEND_URL } from "../config/constants";
3
  import { apiFetch } from "../utils/apiFetch";
4
 
5
  interface UserInfo {
 
1
  import React, { useState, useEffect } from "react";
2
+ import { BACKEND_URL } from "../constants";
3
  import { apiFetch } from "../utils/apiFetch";
4
 
5
  interface UserInfo {
frontend/src/{config/constants.ts → constants.ts} RENAMED
File without changes
frontend/src/utils/apiFetch.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { BACKEND_URL } from "../config/constants";
2
 
3
  export async function apiFetch(
4
  endpoint: string,
 
1
+ import { BACKEND_URL } from "../constants";
2
 
3
  export async function apiFetch(
4
  endpoint: string,