File size: 5,470 Bytes
830bf88 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
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 |