{"id":37228823,"url":"https://github.com/iamdual/ua-generator","last_synced_at":"2026-06-15T01:01:55.029Z","repository":{"id":40262860,"uuid":"471395718","full_name":"iamdual/ua-generator","owner":"iamdual","description":"💻 A random user-agent generator.","archived":false,"fork":false,"pushed_at":"2026-06-07T00:47:09.000Z","size":320,"stargazers_count":164,"open_issues_count":2,"forks_count":19,"subscribers_count":5,"default_branch":"master","last_synced_at":"2026-06-07T03:34:15.848Z","etag":null,"topics":["client-hints","fake-user-agent","generator","random-user-agent","user-agent","user-agent-generator","useragent-generator"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/ua-generator/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/iamdual.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-03-18T14:17:00.000Z","updated_at":"2026-06-07T00:47:12.000Z","dependencies_parsed_at":"2023-09-23T02:56:14.955Z","dependency_job_id":"58f70b2e-0eef-4267-818a-8cb892ac9ac0","html_url":"https://github.com/iamdual/ua-generator","commit_stats":{"total_commits":27,"total_committers":1,"mean_commits":27.0,"dds":0.0,"last_synced_commit":"bca04c25a3f54918af55e6a8065740fa481d7166"},"previous_names":[],"tags_count":57,"template":false,"template_full_name":null,"purl":"pkg:github/iamdual/ua-generator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iamdual%2Fua-generator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iamdual%2Fua-generator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iamdual%2Fua-generator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iamdual%2Fua-generator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iamdual","download_url":"https://codeload.github.com/iamdual/ua-generator/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iamdual%2Fua-generator/sbom","scorecard":{"id":368837,"data":{"date":"2025-08-11","repo":{"name":"github.com/iamdual/ua-generator","commit":"e49b21aafd1a42844e2ac01b7900bf7f9d225819"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.7,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/15 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":10,"reason":"30 commit(s) and 3 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/lint.yml:1","Warn: no topLevel permission defined: .github/workflows/release.yml:1","Warn: no topLevel permission defined: .github/workflows/unittest.yml:1","Warn: no topLevel permission defined: .github/workflows/update-bot.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/iamdual/ua-generator/lint.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/iamdual/ua-generator/lint.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/iamdual/ua-generator/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/iamdual/ua-generator/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/iamdual/ua-generator/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:39: update your workflow using https://app.stepsecurity.io/secureworkflow/iamdual/ua-generator/release.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:45: update your workflow using https://app.stepsecurity.io/secureworkflow/iamdual/ua-generator/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/unittest.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/iamdual/ua-generator/unittest.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/unittest.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/iamdual/ua-generator/unittest.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/update-bot.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/iamdual/ua-generator/update-bot.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/update-bot.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/iamdual/ua-generator/update-bot.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/update-bot.yml:50: update your workflow using https://app.stepsecurity.io/secureworkflow/iamdual/ua-generator/update-bot.yml/master?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/lint.yml:20","Warn: pipCommand not pinned by hash: .github/workflows/lint.yml:21","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:20","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:21","Warn: pipCommand not pinned by hash: .github/workflows/unittest.yml:25","Warn: pipCommand not pinned by hash: .github/workflows/update-bot.yml:25","Warn: pipCommand not pinned by hash: .github/workflows/update-bot.yml:26","Info:   0 out of  10 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned","Info:   0 out of   7 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/release.yml:30"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 17 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T12:30:30.680Z","repository_id":40262860,"created_at":"2025-08-18T12:30:30.680Z","updated_at":"2025-08-18T12:30:30.680Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34216356,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-11T02:00:06.485Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["client-hints","fake-user-agent","generator","random-user-agent","user-agent","user-agent-generator","useragent-generator"],"created_at":"2026-01-15T03:29:36.948Z","updated_at":"2026-06-15T01:01:54.998Z","avatar_url":"https://github.com/iamdual.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ua-generator\n\nA random user-agent generator for Python \u003e= 3.9\n\n# Features\n\n- No dependency.\n- No external user-agent list, no downloads.\n- User-agent versions are hardcoded into the code.\n- Platform and browser versions are based on real releases.\n- Client Hints (Sec-CH-UA fields).\n- Easy to integrate into HTTP libraries.\n\n# Install \u0026 upgrade\n\n```bash\npip install -U ua-generator\n```\n_Note: Upgrade ua-generator periodically to keep user-agent versions up to date._\n\n# Basic usage\n\n```python\nimport ua_generator\n\nua = ua_generator.generate()\nprint(ua) # Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/15.2 Safari/604.1.38\n```\n\n# Customization\n\n**It takes three different parameters to customize the user-agent.**\n\n```python\ndevice = ['desktop', 'mobile']\nplatform = ['windows', 'macos', 'ios', 'linux', 'android']\nbrowser = ['chrome', 'edge', 'firefox', 'safari']\n```\n_Note: All parameters are optional and multiple types can be specified using a list (or tuple)._\n## Customized user-agent generation:\n\n```python\nimport ua_generator\n\n# Example 1:\nua = ua_generator.generate(device='desktop', browser=['chrome', 'edge'])\nprint(ua.text) # Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36\nprint(ua.platform) # windows\nprint(ua.browser) # chrome\nprint(ua.ch.brands) # \"Not A(Brand\";v=\"99\", \"Chromium\";v=\"129\", \"Google Chrome\";v=\"129\"\nprint(ua.ch.brands_full_version_list) # \"Not A(Brand\";v=\"99.0.0.0\", \"Chromium\";v=\"129.0.6668.116\", \"Google Chrome\";v=\"129.0.6668.116\"\nprint(ua.ch.mobile) # ?0\nprint(ua.ch.platform) # \"Windows\"\nprint(ua.ch.platform_version) # \"13.0.0\"\nprint(ua.ch.browser_version) # \"129\"\nprint(ua.ch.browser_full_version) # \"129.0.6668.116\"\nprint(ua.ch.bitness) # \"64\"\nprint(ua.ch.architecture) # \"x86\"\nprint(ua.ch.wow64) # \"?1\"\n\n# Example 2:\nua = ua_generator.generate(platform=['ios', 'macos'], browser='edge')\nprint(ua.text) # Mozilla/5.0 (iPhone; CPU iPhone OS 18_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/117.0.2045.73 Version/18.0 Mobile/15E148 Safari/604.1\nprint(ua.platform) # ios\nprint(ua.browser) # edge\nprint(ua.ch.brands) # \"Not A(Brand\";v=\"99\", \"Chromium\";v=\"117\", \"Microsoft Edge\";v=\"117\"\nprint(ua.ch.brands_full_version_list) # \"Not A(Brand\";v=\"99.0.0.0\", \"Chromium\";v=\"117.0.2045.73\", \"Microsoft Edge\";v=\"117.0.2045.73\"\nprint(ua.ch.mobile) # ?1\nprint(ua.ch.platform) # \"iOS\"\nprint(ua.ch.platform_version) # \"18.6.1\"\nprint(ua.ch.browser_version) # \"117\"\nprint(ua.ch.browser_full_version) # \"117.0.2045.73\"\nprint(ua.ch.bitness) # \"64\"\nprint(ua.ch.architecture) # arm\nprint(ua.ch.wow64) # ?0\n```\n\n# Headers\n\n```python\nua = ua_generator.generate(browser=['chrome', 'edge'])\n\n# This will return a dictionary containing the generated user-agent:\nprint(ua.headers.get())\n{\n    'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.43 Safari/537.36',\n    'sec-ch-ua': '\"Not A(Brand\";v=\"99\", \"Chromium\";v=\"103\", \"Google Chrome\";v=\"103\"',\n    'sec-ch-ua-mobile': '?0',\n    'sec-ch-ua-platform': '\"macOS\"'\n}\n\n# Extending the \"Client Hints\" by a value of the \"Accept-CH\" header:\nua.headers.accept_ch('Sec-CH-UA-Platform-Version, Sec-CH-UA-Full-Version-List')\nprint(ua.headers.get())\n{\n    'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.94 Safari/537.36',\n    'sec-ch-ua': '\"Not A(Brand\";v=\"99\", \"Chromium\";v=\"122\", \"Google Chrome\";v=\"122\"',\n    'sec-ch-ua-mobile': '?0',\n    'sec-ch-ua-platform': '\"macOS\"',\n    'sec-ch-ua-platform-version': '\"14.1.0\"',\n    'sec-ch-ua-full-version-list': '\"Not A(Brand\";v=\"99.0.0.0\", \"Chromium\";v=\"122.0.6261.94\", \"Google Chrome\";v=\"122.0.6261.94\"'\n}\n```\n\n## Integrating into the [requests](https://pypi.org/project/requests/):\n\n```python\nimport requests\nimport ua_generator\n\nua = ua_generator.generate(browser=['chrome', 'edge'])\nr = requests.get('https://httpbin.org/get', headers=ua.headers.get())\n```\n\n## Integrating into the [httpx](https://pypi.org/project/httpx/):\n\n```python\nimport httpx\nimport ua_generator\n\nua = ua_generator.generate(browser=['chrome', 'edge'])\nr = httpx.get('https://httpbin.org/get', headers=ua.headers.get())\n```\n\n## Integrating into the [urllib](https://docs.python.org/3/library/urllib.request.html):\n\n```python\nimport urllib.request\nimport ua_generator\n\nua = ua_generator.generate(browser=['chrome', 'edge'])\nrequest = urllib.request.Request('https://httpbin.org/get', headers=ua.headers.get())\nhandler = urllib.request.urlopen(request)\nresponse = handler.read().decode('utf-8')\n```\n\n## Integrating into the [Selenium](https://selenium-python.readthedocs.io/):\n```python\nimport time\nfrom selenium import webdriver\nimport ua_generator\n\nua = ua_generator.generate(browser=['chrome', 'edge'], device=['desktop'])\ndriver = webdriver.Chrome()\ndriver.execute_cdp_cmd('Network.setExtraHTTPHeaders', {'headers': ua.headers.get()})\ndriver.execute_cdp_cmd('Network.setUserAgentOverride', {\n    'userAgent': ua.text,\n    'userAgentMetadata': ua.navigator.get()\n})\ndriver.get('https://browserleaks.com/client-hints')\ntime.sleep(1000)\n```\n\n# Options\n\nYou can define options using the \"options\" parameter for further customization.\n\n## weighted_versions\nTo increase the probability of the latest versions being chosen. Default is `False`.\n\n```python\nimport ua_generator\nfrom ua_generator.options import Options\n\n# Enabling weighted versions\noptions = Options()\noptions.weighted_versions = True\nua = ua_generator.generate(browser=['chrome', 'edge'], options=options)\n```\n\n## version_ranges\nTo choose only versions within specified ranges. Default is `None`.\n\n```python\nimport ua_generator\nfrom ua_generator.options import Options\nfrom ua_generator.data.version import Version, VersionRange\n\n# Choosing only versions within specified ranges\noptions = Options()\noptions.version_ranges = {\n    'chrome': VersionRange(125, 129),  # Choose version between 125 and 129\n    'edge': VersionRange(min_version=120),  # Choose version 120 minimum\n    'macos': VersionRange(max_version=Version(10, 15, 7)),  # Choose macOS 10.15.7 maximum\n}\nua = ua_generator.generate(browser='chrome', options=options)\n```\n\n_Note: If there is no valid version within the range you set, the filter will just skip it and return a random valid version instead._\n\n## latest_versions\nTo choose only the latest version, or one of the latest `N` versions for specified browsers or platforms. Default is `False`.\n\n```python\nimport ua_generator\nfrom ua_generator.options import Options\n\n# Choose only the latest version for every browser and platform\noptions = Options()\noptions.latest_versions = True\nua = ua_generator.generate(options=options)\n\n# Choose one of the latest N versions for specified browsers and platforms\noptions = Options()\noptions.latest_versions = {\n    'chrome': 3,\n    'firefox': 1,\n    'ios': 3,\n    'macos': 1,\n}\nua = ua_generator.generate(browser='chrome', platform='ios', options=options)\n```\n\n## tied_safari_version\nTo make Safari version tied to macOS/iOS version. Default is `False`.\n\n# Issues\n\nYou can create an issue [from here](https://github.com/iamdual/ua-generator/issues) if you are experiencing a problem.\n\n# Contributing\n\nPull requests are welcome. Don't forget to run tests.\n\n# Contributors\n\nEkin Karadeniz ([@iamdual](https://github.com/iamdual)) and [the GitHub community](https://github.com/iamdual/ua-generator/graphs/contributors).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiamdual%2Fua-generator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fiamdual%2Fua-generator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiamdual%2Fua-generator/lists"}