API¶
Global Helpers¶
- ua_parser.parse(ua: str) Result[source]¶
Parses the
UserAgent,OS, andDeviceinformation using theglobal parser.Equivalent to calling each of
parse_user_agent(),parse_os(), andparse_device()but may be more efficient than calling them separately depending on the underlying parser.Even in the best case, prefer the domain-specific helpers if you’re not going to use all of them.
- ua_parser.parse_user_agent(ua: str) UserAgent | None[source]¶
Parses the
browserinformation using theglobal parser.
- ua_parser.parse_device(ua: str) Device | None[source]¶
Parses the
Deviceinformation using theglobal parser.
- ua_parser.parser: Parser = <ua_parser.Parser object>¶
Global
Parser, lazy-initialised on first access, used by the global helper functions.Can be set to configure a customised global parser.
Accessing the parser explicitely can be used eagerly force its initialisation, rather than pay for it at first call.
Core Types¶
- class ua_parser.Resolver[source]¶
The resolver is the thin central abstraction of ua-parser, and used to compose various objects into the resolution stack which best fits the system’s needs.
A resolver is any callable which takes a string
uaand aDomain, and returns aPartialResultwith at least the requested domains marked as resolved (whether successfully or not).A resolver may resolve more domains than requested, but it needs to resolve at least the requested domains.
See
PartialResultfor more information about its working.- abstractmethod __call__(ua: str, domain: Domain, /) PartialResult[source]¶
Resolves the
ua.
- class ua_parser.Domain(*values)[source]¶
Hint for selecting which domains are requested when asking for a
PartialResult.- USER_AGENT = 1¶
browser (user agent) domain
- OS = 2¶
os domain
- DEVICE = 4¶
device domain
- ALL = 7¶
shortcut for all three domains
Data Types¶
These are the various types produced by successfully resolving a user agent string. They are guaranteed to be dataclasses, and using dataclass utility functions is officially supported.
- class ua_parser.PartialResult(domains: Domain, user_agent: UserAgent | None, os: OS | None, device: Device | None, string: str)[source]¶
Potentially partial (incomplete) result.
Domain fields (
user_agent,os, anddevice) can be:unset if not parsed yet
set to a parsing failure
set to a parsing success
The
domainsflags specify which is which: if aDomainflag is set, the corresponding attribute was looked up and is eitherNonefor a resolution failure (no match was found) or a value for a parsing success.If the flag is unset, the field has not been looked up yet, in which case it can be anything (but should usually be
None).- complete() Result[source]¶
Requires that the result be fully resolved (every attribute is set, even if to a lookup failure).
- Raises:
ValueError – if the result is not fully resolved
- class ua_parser.Result(user_agent: UserAgent | None, os: OS | None, device: Device | None, string: str)[source]¶
Complete result.
For each attribute (and domain), either the resolution was a success (a match was found) and the corresponding data is set, or it was a failure and the value is None.
- with_defaults() DefaultedResult[source]¶
Replaces every failed domain by its default value.
Roughly matches pre-1.0 semantics, and can allow for more uniform handling by the client if they don’t want or need the lookup failure information.
- class ua_parser.UserAgent(family: str = 'Other', major: str | None = None, minor: str | None = None, patch: str | None = None, patch_minor: str | None = None)[source]¶
Browser (“user agent” aka the software responsible for the request) information parsed from the user agent string.
- class ua_parser.OS(family: str = 'Other', major: str | None = None, minor: str | None = None, patch: str | None = None, patch_minor: str | None = None)[source]¶
OS information parsed from the user agent string.
Base Resolvers¶
Base resolvers take sets of Matchers
generated by loaders, and use them to extract data
from user agent strings.
- class ua_parser.basic.Resolver(Matchers)[source]¶
A simple pure-python resolver based around trying a number of regular expressions in sequence for each domain, and returning a result when one matches.
- class ua_parser.re2.Resolver(Matchers)¶
An advanced resolver based around
google-re2’sFilteredRE2feature, which efficiently prunes the number of possibly matching matchers before actually running them.Sufficiently fast that a cache may not be necessary, and may even be detrimental at smaller cache sizes
Warning
Only available if
google-re2is installed.
- class ua_parser.regex.Resolver(Matchers)¶
An advanced resolver based on Rust’s regex and a bespoke implementation of regex prefiltering, by the sibling project uap-rust.
Sufficiently fast that a cache may not be necessary, and may even be detrimental at smaller cache sizes
Warning
Only available if ua-parser-rs <https://pypi.org/project/ua-parser-rs/>_ is installed.
Eager Matchers¶
- class ua_parser.matchers.DeviceMatcher(regex: str, regex_flag: Literal['i'] | None = None, family: str | None = None, brand: str | None = None, model: str | None = None)[source]¶
-
Eager device matcher, compiles the input
regexat initialisation.- property flags: int¶
Returns the matcher’s pattern flags (only
re.IGNORECASEis supported, and only forMatcher[Device])
- class ua_parser.matchers.OSMatcher(regex: str, family: str | None = None, major: str | None = None, minor: str | None = None, patch: str | None = None, patch_minor: str | None = None)[source]¶
-
Eager OS matcher, compiles the input
regexat initialisation.
Lazy Matchers¶
These matchers will lazily compile their
pattern to an re.Pattern.
While this saves CPU upfront, this is most useful with resolvers which
likely will not need to apply most of them, like
ua_parser.re2.Resolver. If the resolver will very likely need
to apply (and thus compile) every pattern like
ua_parser.basic.Resolver, then lazy compilation has a higher
overhead.
- class ua_parser.lazy.DeviceMatcher(regex: str, regex_flag: Literal['i'] | None = None, family: str | None = None, brand: str | None = None, model: str | None = None)[source]¶
-
Lazy device matcher, compiles the input
regexon first use.Requires slightly more memory as it needs to reference both the pattern string and the compiled pattern.
- property flags: int¶
Returns the matcher’s pattern flags (only
re.IGNORECASEis supported, and only forMatcher[Device])
- class ua_parser.lazy.OSMatcher(regex: str, family: str | None = None, major: str | None = None, minor: str | None = None, patch: str | None = None, patch_minor: str | None = None)[source]¶
-
Lazy OS matcher, compiles the input
regexon first use.Requires slightly more memory as it needs to reference both the pattern string and the compiled pattern.
- class ua_parser.lazy.UserAgentMatcher(regex: str, family: str | None = None, major: str | None = None, minor: str | None = None, patch: str | None = None, patch_minor: str | None = None)[source]¶
-
Lazy user agent matcher, compiles the input
regexon first use.Requires slightly more memory as it needs to reference both the pattern string and the compiled pattern.
Caching¶
Web clients commonly have multiple interactions with a given system,
leading to significant repetition in user agents encountered. A cache
allows making use of that to avoid redundant parses, at the cost of
memory. This is most useful for slow base resolvers like the
basic resolver.
- class ua_parser.caching.Cache[source]¶
Cache abstract protocol. The
CachingResolverwill look values up, merge what was returned (possibly nothing) with what it got from its actual parser, and re-set the result.- abstractmethod __getitem__(key: str) PartialResult | None[source]¶
Returns a partial result for
keyif there is any.
- abstractmethod __setitem__(key: str, value: PartialResult) None[source]¶
Adds or replace
valueto the cache at keykey.
- class ua_parser.CachingResolver(resolver: Resolver, cache: Cache)[source]¶
A wrapper resolver which takes an underlying concrete
Cachefor the actual caching and cache strategy.This resolver only interacts with the
Cacheand delegates to the wrapped resolver in case of lookup failure.CachingParserwill set entries back in the cache when filling them up, it does not update results in place (and can’t really, they’re immutable).
- class ua_parser.caching.S3Fifo(maxsize: int)[source]¶
FIFO-based quick-demotion lazy-promotion cache [S3-FIFO].
Experimentally provides excellent hit rate at lower cache sizes, for a relatively simple and efficient implementation. Notably excellent at handling “one hit wonders”, aka entries seen only once during a work-set (or reasonable work window).
- class ua_parser.caching.Sieve(maxsize: int)[source]¶
FIFO-based quick-demotion cache [SIEVE].
Simpler FIFO-based cache, cousin of
S3Fifo. Experimentally slightly lower hit rates thanS3Fifo(if way superior to LRU still), but much more compact (~50% lower memory overhead at larger cache sizes, up to 100% at very small cache sizes).Can be an interesting candidate when trying to save on memory, although the contained entries will generally be much larger than the cache itself.
- class ua_parser.caching.Lru(maxsize: int)[source]¶
Cache following a least-recently used replacement policy: when there is no more room in the cache, whichever entry was last seen the least recently is removed.
Simple LRUs are generally outdated and to avoid as they have relatively low hit rates for modern caches (at lower sizes). The main use case here is if the workload can lead to the cache being full of popular items then all of them being replaced at once:
S3FifoandSieveare FIFO-based caches and have worst-case O(n) eviction.
- class ua_parser.caching.Local(factory: Callable[[], Cache])[source]¶
Thread local cache decorator. Takes a cache factory and lazily instantiates a cache for each thread it’s accessed from.
This means the cache capacity and memory consumption is figuratively multiplied by however many threads the cache is used from, but those threads don’t share their caching, and thus don’t contend on cache use.
Loading¶
- ua_parser.core.Matchers¶
alias of
Tuple[List[Matcher[UserAgent]],List[Matcher[OS]],List[Matcher[Device]]]
- class ua_parser.core.Matcher[source]¶
A matcher is an individual pattern-rule, able to match a user agent string and in case of success extract the relevant data.
Matchers need to expose their pattern for bulk resolvers.
- property flags: int¶
Returns the matcher’s pattern flags (only
re.IGNORECASEis supported, and only forMatcher[Device])
- ua_parser.load_builtins() Matchers[source]¶
Loads the pre-compiled matcher data into eager matchers.
The matchers data is imported lazily, and cached after imports, further imports simply reference the existing datas.
- ua_parser.load_lazy_builtins() Matchers[source]¶
Loads the pre-compiled matcher data into lazy matchers.
The matchers data is imported lazily, and cached after imports, further imports simply reference the existing datas.
Custom regexes.yaml data¶
- ua_parser.loaders.load_data(MatchersData) Matchers[source]¶
Loads the input data set into eager matchers.
- ua_parser.loaders.load_lazy(MatchersData) Matchers[source]¶
Loads the input data set into lazy matchers.
- ua_parser.loaders.load_json(f: PathOrFile, loader: DataLoader = <function load_data>) Matchers[source]¶
Loads JSON data following the
regexes.yamlstructure.The
loaderparameter customises which matcher variant is generated, by defaultload_data()is used to generate eager matchers,load_lazy()can be used to generate lazy matchers instead.
- ua_parser.loaders.load_yaml(f: PathOrFile, loader: DataLoader = load_data) Matchers[source]¶
Loads YAML data following the
regexes.yamlstructure.The
loaderparameter customises which matcher variant is generated, by defaultload_data()is used to generate eager matchers,load_lazy()can be used to generate lazy matchers instead.Warning
Only available if
PyYamlis installed.