|
This repository contains a full-stack application designed to be deployed in a Hugging Face Space. |
|
|
|
## backend/ |
|
|
|
The backend/ folder contains the API server, implemented in Python using FastAPI. Project is built using uv. |
|
Main commands in that folder are: |
|
- `make dev` to run a local dev server |
|
- `make style` to apply code formatting |
|
- `make quality` to check code format |
|
- `make test` to run tests |
|
- `uv add ...` to add a new dependency |
|
|
|
When working in the `backend/` folder, please keep these instructions in mind: |
|
- 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. |
|
- You can define as many new endpoints as you need. Follow the FastAPI best practices. All routes should be defined under `/api` prefix. |
|
- 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`. |
|
- 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. |
|
- The FastAPI server and Database are configured in `backend/src/app_factory.py`. DO NOT UPDATE this file. |
|
- 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. |
|
- 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. |
|
|
|
### OAuthInfo definition |
|
|
|
Here is how `OAuthInfo` dataclass is defined in Python. Useful when a user is authenticated. |
|
|
|
```py |
|
@dataclass |
|
class OAuthUserInfo: |
|
sub: str |
|
name: str |
|
preferred_username: str |
|
email_verified: Optional[bool] |
|
email: Optional[str] |
|
picture: str |
|
profile: str |
|
website: Optional[str] |
|
is_pro: bool |
|
can_pay: Optional[bool] |
|
orgs: Optional[List[OAuthOrgInfo]] |
|
|
|
|
|
@dataclass |
|
class OAuthInfo: |
|
access_token: str |
|
access_token_expires_at: datetime.datetime |
|
user_info: OAuthUserInfo |
|
state: Optional[str] |
|
scope: str |
|
``` |
|
|
|
## frontend/ |
|
|
|
The frontend/ folder contains the UI implemented in TS with React and Tailwind. Project is built using vite. |
|
Main commands in that folder are: |
|
- `pnpm install` to install packages |
|
- `pnpm dev` to run a local dev environment |
|
- `pnpm style` to apply code formatting |
|
- `pnpm quality` to check code format |
|
- `pnpm add (-D) ...` to add a new package |
|
|
|
When working in the `frontend/` folder, please keep these instructions in mind: |
|
- UI is a single-page application. It doesn't use any router. You must keep this structure. |
|
- Main app is located in `frontend/src/App.tsx`. |
|
- Components are defined in `frontend/src/components`. |
|
- 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. |
|
- Authentication has to be done using the `OAuthButton` defined in `frontend/src/components/OAuthButton.tsx`. DO NOT UPDATE this file. |
|
- The `BackendHealthCheck` component in `frontend/src/components/BackendHealthCheck.tsx` is made for dev purpose only. DO NOT UPDATE this file except if requested specifically. |
|
- 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. |
|
- You can define as many new components as you want. Make each component self contained. Define new components in `frontend/src/components/`. |
|
- 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. |
|
- 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. |
|
- 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. |
|
- DO NOT MODIFY `frontend/src/index.css` (which imports tailwind) and `frontend/src/main.tsx` (main imports). |
|
|
|
|
|
## How to add a new feature? |
|
|
|
- add new API routes in `backend/src/app.py`. If needed, add a new schema in `backend/src/schemas.py`. Use authentication if required. |
|
- add a new component in `frontend/src/components` and update `frontend/src/App.tsx` to include it. |
|
- let the user run `cd frontend && pnpm dev` and `cd backend && make dev` in 2 terminals to try it out |
|
- once tested, commit the changes and push to remote branch |