mirror of
https://github.com/beetbox/beets.git
synced 2026-02-23 07:44:38 +01:00
Define MusicBrainzAPI class with rate limiting
This commit is contained in:
parent
fda3bbaea5
commit
a866347345
3 changed files with 56 additions and 2 deletions
|
|
@ -26,6 +26,7 @@ from urllib.parse import urljoin
|
|||
|
||||
import musicbrainzngs
|
||||
from confuse.exceptions import NotFoundError
|
||||
from requests_ratelimiter import LimiterMixin
|
||||
|
||||
import beets
|
||||
import beets.autotag.hooks
|
||||
|
|
@ -34,6 +35,8 @@ from beets.metadata_plugins import MetadataSourcePlugin
|
|||
from beets.util.deprecation import deprecate_for_user
|
||||
from beets.util.id_extractors import extract_release_id
|
||||
|
||||
from ._utils.requests import TimeoutSession
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Iterable, Sequence
|
||||
from typing import Literal
|
||||
|
|
@ -57,6 +60,11 @@ FIELDS_TO_MB_KEYS = {
|
|||
"year": "date",
|
||||
}
|
||||
|
||||
|
||||
class LimiterTimeoutSession(LimiterMixin, TimeoutSession):
|
||||
pass
|
||||
|
||||
|
||||
musicbrainzngs.set_useragent("beets", beets.__version__, "https://beets.io/")
|
||||
|
||||
|
||||
|
|
@ -121,12 +129,24 @@ BROWSE_CHUNKSIZE = 100
|
|||
BROWSE_MAXTRACKS = 500
|
||||
|
||||
|
||||
class MusicBrainzAPI:
|
||||
api_url = "https://musicbrainz.org/ws/2/"
|
||||
|
||||
@cached_property
|
||||
def session(self) -> LimiterTimeoutSession:
|
||||
return LimiterTimeoutSession(per_second=1)
|
||||
|
||||
def _get(self, entity: str, **kwargs) -> JSONDict:
|
||||
return self.session.get(
|
||||
f"{self.api_url}/{entity}", params={**kwargs, "fmt": "json"}
|
||||
).json()
|
||||
|
||||
|
||||
def _preferred_alias(
|
||||
aliases: list[JSONDict], languages: list[str] | None = None
|
||||
) -> JSONDict | None:
|
||||
"""Given a list of alias structures for an artist credit, select
|
||||
and return the user's preferred alias or None if no matching
|
||||
alias is found.
|
||||
"""
|
||||
if not aliases:
|
||||
return None
|
||||
|
|
|
|||
35
poetry.lock
generated
35
poetry.lock
generated
|
|
@ -2683,6 +2683,21 @@ docs = ["sphinx", "sphinx_rtd_theme"]
|
|||
fuzzer = ["atheris", "hypothesis"]
|
||||
test = ["coverage[toml] (>=5.2)", "hypothesis", "pytest (>=6.0)", "pytest-benchmark", "pytest-cov", "pytest-timeout"]
|
||||
|
||||
[[package]]
|
||||
name = "pyrate-limiter"
|
||||
version = "2.10.0"
|
||||
description = "Python Rate-Limiter using Leaky-Bucket Algorithm"
|
||||
optional = false
|
||||
python-versions = ">=3.7,<4.0"
|
||||
files = [
|
||||
{file = "pyrate_limiter-2.10.0-py3-none-any.whl", hash = "sha256:a99e52159f5ed5eb58118bed8c645e30818e7c0e0d127a0585c8277c776b0f7f"},
|
||||
{file = "pyrate_limiter-2.10.0.tar.gz", hash = "sha256:98cc52cdbe058458e945ae87d4fd5a73186497ffa545ee6e98372f8599a5bd34"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
all = ["filelock (>=3.0)", "redis (>=3.3,<4.0)", "redis-py-cluster (>=2.1.3,<3.0.0)"]
|
||||
docs = ["furo (>=2022.3.4,<2023.0.0)", "myst-parser (>=0.17)", "sphinx (>=4.3.0,<5.0.0)", "sphinx-autodoc-typehints (>=1.17,<2.0)", "sphinx-copybutton (>=0.5)", "sphinxcontrib-apidoc (>=0.3,<0.4)"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "8.4.2"
|
||||
|
|
@ -3236,6 +3251,24 @@ requests = ">=2.0.0"
|
|||
[package.extras]
|
||||
rsa = ["oauthlib[signedtoken] (>=3.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "requests-ratelimiter"
|
||||
version = "0.7.0"
|
||||
description = "Rate-limiting for the requests library"
|
||||
optional = false
|
||||
python-versions = "<4.0,>=3.7"
|
||||
files = [
|
||||
{file = "requests_ratelimiter-0.7.0-py3-none-any.whl", hash = "sha256:1a7ef2faaa790272722db8539728690046237766fcc479f85b9591e5356a8185"},
|
||||
{file = "requests_ratelimiter-0.7.0.tar.gz", hash = "sha256:a070c8a359a6f3a001b0ccb08f17228b7ae0a6e21d8df5b6f6bd58389cddde45"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
pyrate-limiter = "<3.0"
|
||||
requests = ">=2.20"
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo (>=2023.3,<2024.0)", "myst-parser (>=1.0)", "sphinx (>=5.2,<6.0)", "sphinx-autodoc-typehints (>=1.22,<2.0)", "sphinx-copybutton (>=0.5)"]
|
||||
|
||||
[[package]]
|
||||
name = "resampy"
|
||||
version = "0.4.3"
|
||||
|
|
@ -4189,4 +4222,4 @@ web = ["flask", "flask-cors"]
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = ">=3.10,<4"
|
||||
content-hash = "9e154214b2f404415ef17df83f926a326ffb62a83b3901a404946110354d4067"
|
||||
content-hash = "1b69db4cdc3908316b2e18a5620916aa55235ded58b275c4433819ffa4ed660b"
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ numpy = [
|
|||
]
|
||||
platformdirs = ">=3.5.0"
|
||||
pyyaml = "*"
|
||||
requests-ratelimiter = ">=0.7.0"
|
||||
typing_extensions = "*"
|
||||
unidecode = ">=1.3.6"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue