WolfDavid commited on
Commit
b0821c5
·
1 Parent(s): 84055d7

chore(01-02): bootstrap Python 3.12 toolchain, Git LFS and package skeleton

Browse files

- Pin Python 3.12.12 (.python-version) to match the ZeroGPU runtime; 3.11 and
3.13 are both invalid there
- Arm Git LFS for .vrm/.vvm/.wav/.onnx before any binary lands in the repo
- Add pyproject.toml with pytest ini options, ruff config and a dev extra
- Create src/japanese_avatar package skeleton (ui, voice, telemetry) and tests/
- Add tests/test_scaffold.py proving interpreter version, importability, config
and LFS arming
- Commit uv.lock so Space rebuilds are reproducible

.gitattributes ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ *.vrm filter=lfs diff=lfs merge=lfs -text
2
+ *.vvm filter=lfs diff=lfs merge=lfs -text
3
+ *.wav filter=lfs diff=lfs merge=lfs -text
4
+ *.onnx filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+ node_modules/
7
+ .env
8
+ voicevox_runtime/
9
+ test-results/
.python-version ADDED
@@ -0,0 +1 @@
 
 
1
+ 3.12.12
pyproject.toml ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [project]
2
+ name = "japanese-learning-avatar"
3
+ version = "0.1.0"
4
+ description = "A lip-synced VRM avatar that speaks and hears Japanese, on a Hugging Face Space"
5
+ requires-python = ">=3.12,<3.13"
6
+ dependencies = [
7
+ "gradio==6.22.0",
8
+ "spaces==0.51.1",
9
+ "huggingface_hub==1.28.0",
10
+ ]
11
+
12
+ [project.optional-dependencies]
13
+ dev = [
14
+ "pytest>=8.0",
15
+ "pytest-playwright>=0.5",
16
+ "playwright>=1.48",
17
+ "ruff>=0.6",
18
+ "numpy>=1.26",
19
+ "requests>=2.32",
20
+ ]
21
+
22
+ [build-system]
23
+ requires = ["hatchling"]
24
+ build-backend = "hatchling.build"
25
+
26
+ [tool.hatch.build.targets.wheel]
27
+ packages = ["src/japanese_avatar"]
28
+
29
+ [tool.pytest.ini_options]
30
+ testpaths = ["tests"]
31
+ pythonpath = ["src", "."]
32
+ addopts = "-q --strict-markers"
33
+ markers = [
34
+ "deployed: requires a live Space; skipped unless --space-url is given",
35
+ "slow: takes more than ~10s",
36
+ ]
37
+
38
+ [tool.ruff]
39
+ line-length = 100
40
+ target-version = "py312"
41
+ # ruff 0.16+ lints and formats Python code blocks embedded in Markdown. Planning docs,
42
+ # research notes and design snippets are prose, not source: excluding *.md keeps the lint
43
+ # gate about shipped Python and stops doc snippets from failing `ruff format --check`.
44
+ extend-exclude = ["avatar/vendor", "*.md"]
45
+
46
+ [tool.ruff.lint]
47
+ select = ["E", "F", "I", "UP", "B", "SIM"]
48
+
49
+ [tool.ruff.format]
50
+ quote-style = "double"
src/japanese_avatar/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ __version__ = "0.1.0"
src/japanese_avatar/telemetry/__init__.py ADDED
File without changes
src/japanese_avatar/ui/__init__.py ADDED
File without changes
src/japanese_avatar/voice/__init__.py ADDED
File without changes
tests/__init__.py ADDED
File without changes
tests/e2e/__init__.py ADDED
File without changes
tests/test_scaffold.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Proves the toolchain works before any real code exists."""
2
+
3
+ import subprocess
4
+ import sys
5
+ from pathlib import Path
6
+
7
+
8
+ def test_python_version_matches_space_runtime():
9
+ assert sys.version_info[:2] == (3, 12), (
10
+ "ZeroGPU provides only Python 3.10.13 and 3.12.12; this project pins 3.12.12"
11
+ )
12
+
13
+
14
+ def test_package_importable():
15
+ import japanese_avatar
16
+
17
+ assert japanese_avatar.__version__
18
+
19
+
20
+ def test_ruff_and_pytest_configured():
21
+ import tomllib
22
+
23
+ cfg = tomllib.loads(Path("pyproject.toml").read_text(encoding="utf-8"))
24
+ assert cfg["tool"]["ruff"]["target-version"] == "py312"
25
+ assert "pytest" in cfg["tool"]
26
+
27
+
28
+ def test_lfs_armed_before_any_binary_lands():
29
+ """Plans 01-01 and 01-04 commit tens of megabytes. A non-LFS push of that size is rejected."""
30
+ for path in ("avatar/assets/tutor.vrm", "voicevox/model/zundamon.vvm", "tests/fixtures/x.wav"):
31
+ out = subprocess.run(
32
+ ["git", "check-attr", "filter", "--", path], capture_output=True, text=True, check=True
33
+ ).stdout
34
+ assert "filter: lfs" in out, f"{path} is not LFS-tracked; see .gitattributes"
uv.lock ADDED
The diff for this file is too large to render. See raw diff