utils.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. """General utils for the fake_useragent package."""
  2. import json
  3. import sys
  4. from typing import TypedDict, Union
  5. # We need files() from Python 3.10 or higher
  6. if sys.version_info >= (3, 10):
  7. import importlib.resources as ilr
  8. else:
  9. import importlib_resources as ilr # noqa: F401
  10. from pathlib import Path
  11. from fake_useragent.errors import FakeUserAgentError
  12. from fake_useragent.log import logger
  13. class BrowserUserAgentData(TypedDict):
  14. """The schema for the browser user agent data that the `browsers.jsonl` file must follow."""
  15. useragent: str
  16. """The user agent string."""
  17. percent: float
  18. """The usage percentage of the user agent."""
  19. type: str
  20. """The device type for this user agent (eg. mobile or desktop)."""
  21. device_brand: Union[str, None]
  22. """Brand name for the device (eg. Generic_Android)."""
  23. browser: Union[str, None]
  24. """Browser name for the user agent (eg. Chrome Mobile)."""
  25. browser_version: str
  26. """Version of the browser (eg. "100.0.4896.60")."""
  27. browser_version_major_minor: float
  28. """Major and minor version of the browser (eg. 100.0)."""
  29. os: Union[str, None]
  30. """OS name for the user agent (eg. Android)."""
  31. os_version: Union[str, None]
  32. """OS version (eg. 10)."""
  33. platform: str
  34. """Platform for the user agent (eg. Linux armv81)."""
  35. def find_browser_json_path() -> Path:
  36. """Find the path to the browsers.json file.
  37. Returns:
  38. Path: Path to the browsers.json file.
  39. Raises:
  40. FakeUserAgentError: If unable to find the file.
  41. """
  42. try:
  43. file_path = ilr.files("fake_useragent.data").joinpath("browsers.jsonl")
  44. return Path(str(file_path))
  45. except Exception as exc:
  46. logger.warning(
  47. "Unable to find local data/jsonl file using importlib-resources.",
  48. exc_info=exc,
  49. )
  50. raise FakeUserAgentError("Could not locate browsers.jsonl file") from exc
  51. def load() -> list[BrowserUserAgentData]:
  52. """Load the included `browser.json` file into memory.
  53. Raises:
  54. FakeUserAgentError: If unable to load or parse the data.
  55. Returns:
  56. list[BrowserUserAgentData]: The list of browser user agent data, following the
  57. `BrowserUserAgentData` schema.
  58. """
  59. data = []
  60. try:
  61. json_path = find_browser_json_path()
  62. for line in json_path.read_text().splitlines():
  63. data.append(json.loads(line))
  64. except Exception as exc:
  65. raise FakeUserAgentError("Failed to load or parse browsers.json") from exc
  66. if not data:
  67. raise FakeUserAgentError("Data list is empty", data)
  68. if not isinstance(data, list):
  69. raise FakeUserAgentError("Data is not a list", data)
  70. return data