Files
2026-11-08 05:38:19 +00:00

108 lines
4.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Dify Backend API
## Setup and Run
[`uv`](https://docs.astral.sh/uv/), Docker Compose, and the Node.js and pnpm versions pinned in the root `package.json` are required. Run the commands below from the repository root, with each long-running service in its own terminal.
### Using scripts (recommended)
1. Run setup for a new checkout (copies env files and installs dependencies). This overwrites `api/.env`, `web/.env.local`, and `docker/middleware.env`; preserve existing configuration before rerunning it.
```bash
./dev/setup
```
1. Review `api/.env`, `web/.env.local`, and `docker/middleware.env` values (see the `SECRET_KEY` note below).
1. Start middleware (PostgreSQL/Redis/Weaviate).
```bash
./dev/start-docker-compose
```
1. Start backend (runs migrations first).
```bash
./dev/start-api
```
1. Start Dify [web](../web) service.
```bash
./dev/start-web
```
`./dev/setup` and `./dev/start-web` install JavaScript dependencies through the repository root workspace, so you do not need a separate `cd web && pnpm install` step.
1. Set up your application by visiting `http://localhost:3000`.
1. Start the worker service (executes queued async tasks).
```bash
./dev/start-worker
```
1. Start Celery Beat when scheduled tasks are needed. This is required when
`KNOWLEDGE_FS_LIFECYCLE_WORKER_ENABLED=true` so provisioning and deletion
outbox commands are dispatched to the lifecycle worker.
```bash
./dev/start-beat
```
### Environment notes
> [!IMPORTANT]
>
> When the frontend and backend run on different subdomains, set COOKIE_DOMAIN to the site’s top-level domain (e.g., `example.com`). The frontend and backend must be under the same top-level domain in order to share authentication cookies.
Leave `SECRET_KEY` empty to let Dify generate a persistent key in the storage directory. To manage it explicitly, generate a value with `openssl rand -base64 42` and set `SECRET_KEY` in `api/.env`.
### Timezones and local-time conversion
The backend uses `zoneinfo` with the system IANA timezone database, falling back to the explicitly required `tzdata` package. `LOG_TZ` is validated when configuration loads. Valid names and aliases are accepted, and differently cased names such as `utc` and `asia/shanghai` are resolved to their canonical spelling when needed. Unknown nonempty values are rejected; they never silently fall back to UTC. Explicit `None` and empty-string values retain their existing unset behavior.
When parsing a local time without an explicit UTC offset, `parse_time_range` and the Time conversion tools apply these rules:
- A repeated time resolves to its **later occurrence**.
- A nonexistent time shifts **forward by the actual size of the timezone transition**, preserving its position within the gap. The returned local time is normalized to a real wall-clock time.
The `pytz` migration intentionally changes the repeated-hour choice in `Europe/Dublin`: `2024-10-27 01:30` now resolves to `01:30Z` (`01:30+00:00`), whereas the previous `is_dst=False` policy selected `00:30Z` (`01:30+01:00`). Both instants exist; the new policy consistently chooses by chronological order rather than by the timezone database's DST label. New York's existing later-occurrence behavior is preserved.
## Testing
Test real production behavior with real objects. Do not use mocks, `SimpleNamespace`, or other shortcuts that bypass real testing.
Backend unit-test directories must exactly mirror the production code's relative directory structure, and filenames must match the production filenames with a `test_` prefix. For example, `api/libs/schedule_utils.py` maps to `api/tests/unit_tests/libs/test_schedule_utils.py`.
Apply the same rule to provider-local suites: `<provider>/src/<package>/module.py` maps to `<provider>/tests/unit_tests/src/<package>/test_module.py`.
Run from the repository root:
```bash
uv sync --project api --group dev
make test
make test TARGET_TESTS=./api/tests/unit_tests/<path>
make lint
make type-check
```
`make test` includes provider unit tests and runs controller tests separately. Integration suites are CI-only and are not expected to run locally. Test environment defaults live in `api/pyproject.toml` under `tool.pytest_env`; see the backend [agent guide](AGENTS.md) for package conventions.
## API contracts
The [API schema guide](controllers/API_SCHEMA_GUIDE.md) owns schema changes and verification. Generate the OpenAPI specifications and TypeScript/Zod contracts through the workspace script:
```bash
pnpm -C packages/contracts gen-api-contract
```
Refresh the checked-in Markdown reference with:
```bash
uv run --project api python api/dev/generate_swagger_markdown_docs.py \
--swagger-dir packages/contracts/openapi --markdown-dir api/openapi/markdown --keep-swagger-json
```
Update the backend schema owner and regenerate contracts instead of converting types manually or editing generated files.