# X-AnyLabeling-Server, where requirements.txt and pyproject.toml disagree

> X-AnyLabeling-Server is a small FastAPI inference service that sits behind the X-AnyLabeling annotation tool and lets custom models be plugged in without touching framework code. The interesting parts of the repository are in the packaging: two dependency files that do not describe the same install, extras named after model families, one pin that constrains transformers for everybody else, and a licence field written as free text.

**CVHub520/X-AnyLabeling-Server** — A Simple, Lightweight, and Extensible Serving Framework for X-AnyLabeling

- Repository: https://github.com/CVHub520/X-AnyLabeling-Server
- Website: https://xanylabeling.com
- Stars: 319 · Forks: 57
- Language: Python
- License: AGPL-3.0
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/cvhub520-x-anylabeling-server

## The two dependency files describe two different installations

pyproject.toml and requirements.txt list overlapping packages in different shapes, and the difference decides what you end up installing.

pyproject.toml puts ten names in the core dependency list and moves model families and tooling into optional extras. requirements.txt is a flat file with section comments, and two of those sections are the dev tools and the model runners.

The practical effect is that pip install -r requirements.txt gives you black and flake8 on a production machine, plus ultralytics, lapx, transformers, and accelerate whether or not you use those models. Installing the extras instead gives you none of them by default and lets you add one family at a time. For a service whose selling point is being lightweight, that is the difference between a small image and a large one, decided entirely by which file you point pip at.

The build system is setuptools with a requirement of 70.0.0 or newer, and the wheel backend is the standard setuptools.build_meta.

## zai-sdk and packaging exist in only one of the two files

Two packages appear in pyproject.toml and nowhere in requirements.txt.

The first is packaging, with a floor of 23.2. The second is zai-sdk, which carries no version constraint at all. Both sit in the core dependency list alongside fastapi[standard] at 0.115.0 or newer, pydantic at 2.12.0 or newer, openai at 1.99.1 or newer, requests, opencv-python-headless, loguru, numpy, and pillow.

So an environment built from requirements.txt is not the same environment pyproject.toml describes. If anything in the service imports zai-sdk at runtime, the requirements.txt install fails at the point of use rather than at install time, which is the least convenient way to find out. If you are pinning for a deployment, treat pyproject.toml as the source of truth and requirements.txt as a convenience file that has drifted from it.

The opencv-python-headless choice is the one deliberate signal in the core list. The headless build avoids pulling GUI libraries into what is meant to be a server, which is consistent with the framework being described as lightweight.

## The extras are named after model families, not after capabilities

Optional dependencies are organised by which model you intend to run, and there are four of them.

The ultralytics extra brings ultralytics and lapx. The transformers extra brings transformers, accelerate, and qwen_vl_utils. The locateanything extra brings a version-constrained transformers, accelerate, peft, and torchvision. The sam3 extra brings decord, einops, a pinned ftfy, huggingface_hub, and hydra-core with a floor of 1.3.2. The dev extra is black and flake8.

Naming extras after model families rather than after features is the right shape for this project, because the pluggable architecture claim only means something if a new model arrives with its own dependency needs. The cost is that the extras do not describe what you get, only which weights you can load, and a service running two families installs both sets with no way to tell from the command line which one is in use.

## One extra caps transformers for everybody else

A single version constraint in one extra reaches outside that extra.

The locateanything group asks for transformers>=4.50,<5, while the plain transformers group asks for transformers with no bound at all, and requirements.txt asks for it again with no bound. pip resolves the intersection, so an environment that installs the locateanything extra silently caps transformers below version 5 for every other component in the same environment.

The sam3 extra is stricter in a different way. ftfy is pinned to exactly 6.1.1, a single-version equality rather than a range, so anything else in the environment that wants a different ftfy will conflict outright. Two of the four extras therefore impose constraints well beyond their own scope, and neither pyproject.toml nor requirements.txt says so in prose.

The practical advice is to run one model family per environment until you have checked the resolved versions yourself.

## The licence is AGPL-3.0 but the metadata field says AGPLv3

The repository licence and the packaging metadata do not use the same vocabulary.

The repository is AGPL-3.0, and the classifier line reads GNU Affero General Public License v3, which is the correct classifier. The licence field, however, is written as free text, AGPLv3, rather than as a standard licence expression. That form is deprecated in modern packaging metadata because tools cannot reliably match a free-text value against a known licence, and some build backends warn on it.

The practical effect is small but annoying: automated licence scanners that read package metadata rather than the LICENSE file will see a string they have to guess at, while scanners that read the repository see the real thing. If you are adding this service as a dependency, read the LICENSE file rather than the metadata.

The rest of the project metadata is conventional: dynamic version, readme from README.md, Python 3.10 or newer with no upper bound, one author and one maintainer, and a keyword list that runs from computer-vision through to x-anylabeling-server.

## Production ready names four capabilities and configures none

The feature list asserts a production posture in one line, and the rest of the repository does not expand on it.

That line names structured logging, error handling, concurrency control, and security authentication as included. None of the four appears as a configuration key in the visible metadata, and the README itself is 188 words long and contains no deployment section at all. Everything operational is delegated to five links: installation and setup, a configuration guide, custom model integration, an API guide, and an OpenAPI schema.

The OpenAPI schema is the most concrete of the five, and it matters, because it means the HTTP surface is described by a machine-readable document rather than by hand-written prose. The API guide and the router documentation sit beside it.

The four claims are not unreasonable for a FastAPI service built on pydantic, since both handle validation and structured errors out of the box. What is missing is the evidence, and the README is not where a sceptical reader would find it.

## Version 0.0.12, and the last push landed three days later

The release line is a sequence of 0.0.x tags, and the version number is computed rather than written down.

The recent tags are v0.0.10 on 25 April 2026, v0.0.11 on 6 June 2026, and v0.0.12 on 5 August 2026. The repository is not archived, and the last push to main is 8 August 2026, three days after the newest tag. pyproject.toml marks the version as dynamic, so the number in the built artefact comes from somewhere at build time rather than from the file you can read.

Two months between patch tags is a slow cadence for a service other systems call into, and 0.0.x signals that the interfaces may still move. A CHANGELOG.md sits at the root for anyone who needs to know what changed between them.

The repository layout is otherwise plain: app/ for the service, configs/ for configuration, scripts/, tests/, assets/, and docs/ with the English pages plus openapi.json. A .flake8 file at the root pairs with black as a dev dependency, which is two tools with overlapping opinions about line length and no shared configuration visible in the metadata.

## Conclusion

X-AnyLabeling-Server fits a team that annotates with X-AnyLabeling and wants model inference to live on a machine other than the annotation desktop, especially if the models come from one of the four named families. Check three things first. Which dependency file you actually install from, because requirements.txt pulls development and model packages that pyproject.toml keeps behind extras. Whether you are willing to work under AGPL-3.0, which is the repository licence even though the metadata field holds a free-text label. And whether the version your deployment pins is a tag or whatever the build computed, since the version is marked dynamic and the release line is still at 0.0.12.

## FAQ

### What is x-AnyLabeling?

It is the annotation tool this serving framework is built for, linked from the README as a separate repository. X-AnyLabeling-Server describes itself as an AI model inference service for it, and its keyword list covers object detection, instance and rotated object detection, pose estimation, vision-language, and segment-anything work.

### How do I install X-AnyLabeling-Server?

The README links to an installation and setup page, a configuration guide, a custom model integration guide, an API guide, and an OpenAPI schema, all under docs/. The package builds with setuptools 70.0.0 or newer, requires Python 3.10 or newer, and is published under the name x-anylabeling-server.

### Which model families can X-AnyLabeling-Server serve?

The optional extras are ultralytics, transformers, locateanything, and sam3. The locateanything extra pins transformers to 4.50 and above but below 5, and the sam3 extra pins ftfy to exactly 6.1.1.

### What version of X-AnyLabeling-Server is current?

Recent tags are v0.0.10 on 25 April 2026, v0.0.11 on 6 June 2026, and v0.0.12 on 5 August 2026, and the repository is not archived. The version is marked dynamic in pyproject.toml rather than written there, and the last push to main is 8 August 2026.

## Sources

- [CVHub520/X-AnyLabeling-Server on GitHub](https://github.com/CVHub520/X-AnyLabeling-Server)
- [License: AGPL-3.0](https://github.com/CVHub520/X-AnyLabeling-Server/blob/main/LICENSE)
- [Project website](https://xanylabeling.com)
- [README](https://github.com/CVHub520/X-AnyLabeling-Server/blob/main/README.md)
- [Releases](https://github.com/CVHub520/X-AnyLabeling-Server/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/cvhub520-x-anylabeling-server
