A decentralized music tracking and discovery platform built on AT Protocol 🎵
rocksky.app
spotify
atproto
lastfm
musicbrainz
scrobbling
listenbrainz
1[project]
2name = "rocksky"
3version = "0.3.0"
4description = "Python SDK for Rocksky — native bindings to the shared Rust core"
5readme = "README.md"
6license = { text = "MIT" }
7authors = [{ name = "Rocksky" }]
8requires-python = ">=3.10"
9keywords = ["rocksky", "atproto", "bluesky", "scrobble", "lastfm", "music"]
10classifiers = [
11 "Development Status :: 4 - Beta",
12 "Framework :: AsyncIO",
13 "Intended Audience :: Developers",
14 "License :: OSI Approved :: MIT License",
15 "Programming Language :: Python :: 3",
16 "Programming Language :: Python :: 3 :: Only",
17 "Programming Language :: Python :: 3.10",
18 "Programming Language :: Python :: 3.11",
19 "Programming Language :: Python :: 3.12",
20 "Programming Language :: Python :: 3.13",
21 "Topic :: Internet :: WWW/HTTP",
22 "Topic :: Software Development :: Libraries :: Python Modules",
23 "Typing :: Typed",
24]
25dependencies = []
26
27[project.urls]
28Homepage = "https://rocksky.app"
29Documentation = "https://docs.rocksky.app"
30Repository = "https://github.com/tsirysndr/rocksky"
31Issues = "https://github.com/tsirysndr/rocksky/issues"
32
33[build-system]
34requires = ["hatchling"]
35build-backend = "hatchling.build"
36
37[tool.hatch.build.targets.wheel]
38packages = ["src/rocksky"]
39# Ship the native-core download manifest, but NOT the native lib itself — the
40# wheel is pure-Python and fetches the ~14 MB lib on first import (see
41# rocksky/_native.py). A gitignored local dev build must be force-excluded.
42artifacts = ["src/rocksky/manifest.json"]
43exclude = [
44 "src/rocksky/*.so",
45 "src/rocksky/*.dylib",
46 "src/rocksky/*.dll",
47]
48
49[dependency-groups]
50dev = [
51 "pytest>=8.0.0",
52 "pytest-asyncio>=0.23.0",
53 "respx>=0.21.0",
54 "ruff>=0.5.0",
55 "mypy>=1.10.0",
56]
57
58[tool.uv]
59default-groups = ["dev"]
60
61[tool.pytest.ini_options]
62asyncio_mode = "auto"
63testpaths = ["tests"]
64filterwarnings = ["error"]
65
66[tool.ruff]
67line-length = 100
68target-version = "py310"
69
70[tool.ruff.lint]
71select = ["E", "F", "I", "B", "UP", "SIM", "RUF"]
72ignore = ["E501"]
73
74[tool.mypy]
75python_version = "3.10"
76strict = true
77warn_return_any = true
78disallow_untyped_defs = true