python-user-agents

Detects mobile, tablet, and PC devices — and their touch, bot, and browser capabilities — by parsing HTTP user agent strings.

Library
PyPI
v2.2.0
1,513stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
47/100Fair
Development Activity0
Maintenance20
Community80
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
56/100Fair
Architecture62
Code Quality55
Innovation70
Learning Curve35

user-agents is a small Python library for identifying the device, operating system, and browser behind an HTTP user agent string. It wraps the regex-based ua-parser database in a single UserAgent object with attribute-style access to browser, os, and device details, plus derived boolean properties like is_mobile, is_tablet, is_pc, is_touch_capable, and is_bot.

The library targets the common server-side need of branching behavior — serving a different template, redirecting to an app store, or filtering bot traffic — based on the requesting device, without pulling in a full client-detection service.

What You Get

  • A single parse(ua_string) entry point returning a UserAgent object with .browser, .os, and .device namedtuples
  • Boolean device-classification properties: is_mobile, is_tablet, is_pc, is_touch_capable, is_bot, is_email_client
  • Family-membership rule tables (mobile/tablet device families, touch-capable OS families, email client browsers) covering phones, tablets, e-readers, and PCs
  • A pretty-printable __str__ output combining device, OS, and browser into one human-readable string
  • Built on the actively maintained ua-parser regex database rather than a hand-rolled parser

Common Use Cases

  • Serving a mobile-optimized template or redirecting to a native app link based on is_mobile/is_tablet
  • Excluding bot traffic (is_bot) from analytics or A/B test buckets
  • Gating touch-specific UI hints or interaction affordances behind is_touch_capable
  • Filtering out email-client user agents (is_email_client) from web-analytics pageview counts

Under The Hood

Architecture The library is deliberately flat: user_agents/parsers.py defines a set of family-membership tuples (MOBILE_DEVICE_FAMILIES, TABLET_DEVICE_FAMILIES, TOUCH_CAPABLE_OS_FAMILIES, EMAIL_PROGRAM_FAMILIES, and others) alongside a single UserAgent class that wraps the dict returned by ua_parser.user_agent_parser.Parse() into three namedtuples (Browser, OperatingSystem, Device), then exposes is_mobile/is_tablet/is_pc/is_touch_capable/is_bot/is_email_client as properties implementing a cascading chain of membership checks and string-matching heuristics against those tuples. There is no layering beyond parsers.py plus a two-line compat.py Python 2/3 shim and an __init__.py that re-exports parse(); all classification logic lives in one module, so any change to the core UserAgent.__init__ parsing call ripples through every derived property.

Tech Stack A pure Python 2/3-compatible library with a single runtime dependency, ua-parser>=0.10.0, which supplies the regex-based device/OS/browser database that does the actual string matching; compat.py exists solely to normalize string_types across Python versions. Packaging is plain setuptools via setup.py with no build step, and the only CI configuration is a legacy .travis.yml. A devices.json file ships inside the package but is not referenced by parsers.py, suggesting it’s a vestige from before the library delegated detection to ua-parser.

Code Quality user_agents/tests.py exercises the library against an extensive set of real-world user agent string fixtures — iPhone, iPad, Galaxy Tab and S3, Kindle Fire, multiple BlackBerry models, Windows Phone, Windows RT, J2ME/Opera Mini, Nokia Symbian, Firefox Aurora on Android, Thunderbird, Outlook, and Chromebook — run through Python’s standard unittest module via python -m unittest discover. There is no linter, formatter, or type-checking configuration in the repo, and CI is limited to the now-legacy Travis config, so correctness relies on the breadth of hardcoded UA fixtures rather than static enforcement.

API Design The public surface is a single function, parse(user_agent_string), returning an object with intuitive attribute access (.browser.family, .os.version_string, .device.model) and self-explanatory boolean properties — there is no configuration object, no setup step, and no boilerplate required to get a first result. The tradeoff is rigidity: the family-membership tuples that drive every classification decision are hardcoded module-level constants with no override or extension hook exposed through the public API.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search