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 devto run a local dev servermake styleto apply code formattingmake qualityto check code formatmake testto run testsuv 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.pyusing 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
/apiprefix. - OAuth is already baked in. If an endpoint requires the user to be authenticated, pass
oauth_info: RequiredOAuthas argument. If authentication is optional, passoauth_info: OptionalOAuth. If you don't need authentication, no need for that arg.RequiredOAuthis a dataclass of typeOAuthInfo(see below).OptionalOAuthis of typeOAuthInfo | None. - schemas are defined in
backend/src/schemas.py. We use SQLModel to define them which is a wrapper on top of Pydantic and SQLAlchemy. Any object defined in this module withtable=Truewill result in a table in the database. Since all models are Pydantic object, you can use them seamlessly with FastAPI. See examples inbackend/src/app.pyon 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_IDandHF_TOKENenv 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 inbackend/src/app_factory.pyandbackend/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.
@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 installto install packagespnpm devto run a local dev environmentpnpm styleto apply code formattingpnpm qualityto check code formatpnpm 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
apiFetchfromfrontend/src/utils/apiFetch.ts. It is a wrapper aroundfetchwith a predefined backend url and authenticated calls. - Authentication has to be done using the
OAuthButtondefined infrontend/src/components/OAuthButton.tsx. DO NOT UPDATE this file. - The
BackendHealthCheckcomponent infrontend/src/components/BackendHealthCheck.tsxis made for dev purpose only. DO NOT UPDATE this file except if requested specifically. - The
Countercomponent infrontend/src/components/Counter.tsxis 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/assetsfolder. There is afrontend/src/assets/huggingface.svgin 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) andfrontend/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 inbackend/src/schemas.py. Use authentication if required. - add a new component in
frontend/src/componentsand updatefrontend/src/App.tsxto include it. - let the user run
cd frontend && pnpm devandcd backend && make devin 2 terminals to try it out - once tested, commit the changes and push to remote branch