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