Wauplin's picture
Wauplin HF Staff
final?
830bf88 verified

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 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.

@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