asgi-user-agents


Nameasgi-user-agents JSON
Version 0.2.0 PyPI version JSON
download
home_pageNone
SummaryUser Agent integration for ASGI applications.
upload_time2024-05-26 14:24:11
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseNone
keywords asgi fastapi litestar quart starlette
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # asgi-user-agents

[![CI](https://github.com/hasansezertasan/asgi-user-agents/actions/workflows/ci.yml/badge.svg)](https://github.com/hasansezertasan/asgi-user-agents/actions?query=event%3Apush+branch%3Amain+workflow%3ACI)
[![Coverage](https://img.shields.io/codecov/c/github/hasansezertasan/asgi-user-agents)](https://codecov.io/gh/hasansezertasan/asgi-user-agents)
[![PyPI - Version](https://img.shields.io/pypi/v/asgi-user-agents.svg)](https://pypi.org/project/asgi-user-agents)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/asgi-user-agents.svg)](https://pypi.org/project/asgi-user-agents)
[![License](https://img.shields.io/github/license/hasansezertasan/asgi-user-agents.svg)](https://github.com/hasansezertasan/asgi-user-agents/blob/main/LICENSE)
[![Latest Commit](https://img.shields.io/github/last-commit/hasansezertasan/asgi-user-agents)](https://github.com/hasansezertasan/asgi-user-agents)

[![Downloads](https://pepy.tech/badge/asgi-user-agents)](https://pepy.tech/project/asgi-user-agents)
[![Downloads/Month](https://pepy.tech/badge/asgi-user-agents/month)](https://pepy.tech/project/asgi-user-agents)
[![Downloads/Week](https://pepy.tech/badge/asgi-user-agents/week)](https://pepy.tech/project/asgi-user-agents)

[User Agents][python-user-agents] integration for [ASGI](https://asgi.readthedocs.io/en/latest/) applications. Works with Starlette, FastAPI, Quart, Litestar -- or any other web framework supporting ASGI that exposes the ASGI `scope`.

-----

## Table of Contents

- [asgi-user-agents](#asgi-user-agents)
  - [Table of Contents](#table-of-contents)
  - [Installation](#installation)
  - [How does it work?](#how-does-it-work)
  - [Usage](#usage)
  - [API Reference](#api-reference)
    - [`UAMiddleware`](#uamiddleware)
    - [`UADetails`](#uadetails)
    - [`UARequest`](#uarequest)
  - [Development](#development)
  - [Author](#author)
  - [Credits](#credits)
  - [Analysis](#analysis)
  - [License](#license)

## Installation

**NOTE**: This is alpha software. Please be sure to pin your dependencies.

> Latest Release

```bash
pip install asgi-user-agents
```

> Development Version

```bash
pip install git+https://github.com/hasansezertasan/asgi-user-agents.git
```

## How does it work?

It simply adds a `ua` attribute to the request scope. This attribute is an instance of the `UADetails` class which abstracts the `UserAgent` class from the `user-agents` package ๐Ÿ“„.

## Usage

It's pretty simple. Just add the middleware to your ASGI application and access the `ua` attribute from the request scope.

```python
from asgi_user_agents import UAMiddleware
from asgi_user_agents import UARequest as Request
from fastapi.applications import FastAPI
from starlette.middleware import Middleware
from starlette.responses import JSONResponse, Response


app = FastAPI(middleware=[Middleware(UAMiddleware)])


@app.get("/")
async def index(request: Request) -> Response:
    ua = request.scope["ua"]
    data = {
        "ua_string": ua.ua_string,
        "os": ua.os,
        "os.family": ua.os.family,
        "os.version": ua.os.version,
        "os.version_string": ua.os.version_string,
        "browser": ua.browser,
        "browser.family": ua.ua.browser.family,
        "browser.version": ua.ua.browser.version,
        "browser.version_string": ua.ua.browser.version_string,
        "device": ua.device,
        "device.family": ua.device.family,
        "device.brand": ua.device.brand,
        "device.model": ua.device.model,
        "is_provided": ua.is_provided,
        "is_tablet": ua.is_tablet,
        "is_mobile": ua.is_mobile,
        "is_touch_capable": ua.is_touch_capable,
        "is_pc": ua.is_pc,
        "is_bot": ua.is_bot,
        "is_email_client": ua.is_email_client,
    }
    return JSONResponse(data)

```

## API Reference

### `UAMiddleware`

An ASGI middleware that sets `scope["ua"]` to an instance of [`UADetails`](#uadetails) (`scope` refers to the ASGI scope).

```python
app = UAMiddleware(app)
```

### `UADetails`

A helper that provides shortcuts for accessing [`User-Agent` request header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent).

```python
ua = UADetails(scope)
```

- `ua: UserAgent` - The `UserAgent` instance from the `user-agents` package.
- `ua_string: str` - The user agent string.
- `is_provided: bool` - `True` if the user agent string is provided.
- `os: OperatingSystem` - The operating system details of the user agent. It's a named tuple with the following fields:
  - `family: str` - The family of the operating system.
  - `version: str` - The version of the operating system.
  - `version_string: str` - The version of the operating system as a string.
- `browser: Browser` - The browser details of the user agent. It's a named tuple with the following fields:
  - `family: str` - The family of the browser.
  - `version: str` - The version of the browser.
  - `version_string: str` - The version of the browser as a string.
- `device: Device` - The device details of the user agent. It's a named tuple with the following fields:
  - `family: str` - The family of the device.
  - `brand: str` - The brand of the device.
  - `model: str` - The model of the device.
- `is_tablet: bool` - `True` if the request was made by a tablet.
- `is_mobile: bool` - `True` if the request was made by a mobile device.
- `is_touch_capable: bool` - `True` if the request was made by a touch-capable device.
- `is_pc: bool` - `True` if the request was made by a PC.
- `is_bot: bool` - `True` if the request was made by a bot.
- `is_email_client: bool` - `True` if the request was made by an email client.

### `UARequest`

For Starlette-based frameworks, use this instead of the standard `starlette.requests.Request` so that code editors understand that `request.scope["ua"]` contains an `UADetails` instance:

```python
from asgi_user_agents import UARequest as Request

async def home(request: Request):
    reveal_type(request.scope["ua"])  # Revealed type is 'UADetails'
```

## Development

Clone the repository and cd into the project directory:

```bash
git clone https://github.com/hasansezertasan/asgi-user-agents
cd asgi-user-agents
```

Install hatch, you can follow the instructions [here](https://hatch.pypa.io/latest/install/), or simply run the following command:

```bash
pipx install hatch
```

Initialize the environment and install the dependencies:

```bash
hatch shell
```

Initialize pre-commit hooks by running the following command:

```bash
pre-commit install
```

Make your changes on a new branch and run the tests:

```bash
hatch test -a
```

Make sure that the code is typed, linted, and formatted correctly:

```bash
hatch run types:all
```

Stage your changes and commit them:

```bash
git add .
git commit -m "Your message"
```

Push your changes to the repository:

```bash
git push
```

Create a pull request and wait for the review ๐Ÿค“.

## Author

- [Hasan Sezer TaลŸan](https://www.github.com/hasansezertasan), It's me ๐Ÿ‘‹.

## Credits

- This project wouldn't be possible without the [user-agents][python-user-agents] package ๐Ÿ™.
- The project structure is inspired by the [asgi-htmx](https://github.com/florimondmanca/asgi-htmx) ๐Ÿš€ package and contains some code snippets from it ๐Ÿ˜… (even this file).

## Analysis

- [Snyk Python Package Health Analysis](https://snyk.io/advisor/python/asgi-user-agents)
- [Libraries.io - PyPI](https://libraries.io/pypi/asgi-user-agents)
- [Safety DB](https://data.safetycli.com/packages/pypi/asgi-user-agents)
- [PePy Download Stats](https://www.pepy.tech/projects/asgi-user-agents)
- [PyPI Download Stats](https://pypistats.org/packages/asgi-user-agents)
- [Pip Trends Download Stats](https://piptrends.com/package/asgi-user-agents)

## License

`asgi-user-agents` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.

<!-- Links -->
[python-user-agents]: https://github.com/selwin/python-user-agents

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "asgi-user-agents",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "Hasan Sezer Ta\u015fan <hasansezertasan@gmail.com>",
    "keywords": "asgi, fastapi, litestar, quart, starlette",
    "author": null,
    "author_email": "Hasan Sezer Ta\u015fan <hasansezertasan@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/a5/e4/e84ee84d50379c313b6ae16aa8ef484da482559033476a6b3de7f22c991c/asgi_user_agents-0.2.0.tar.gz",
    "platform": null,
    "description": "# asgi-user-agents\n\n[![CI](https://github.com/hasansezertasan/asgi-user-agents/actions/workflows/ci.yml/badge.svg)](https://github.com/hasansezertasan/asgi-user-agents/actions?query=event%3Apush+branch%3Amain+workflow%3ACI)\n[![Coverage](https://img.shields.io/codecov/c/github/hasansezertasan/asgi-user-agents)](https://codecov.io/gh/hasansezertasan/asgi-user-agents)\n[![PyPI - Version](https://img.shields.io/pypi/v/asgi-user-agents.svg)](https://pypi.org/project/asgi-user-agents)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/asgi-user-agents.svg)](https://pypi.org/project/asgi-user-agents)\n[![License](https://img.shields.io/github/license/hasansezertasan/asgi-user-agents.svg)](https://github.com/hasansezertasan/asgi-user-agents/blob/main/LICENSE)\n[![Latest Commit](https://img.shields.io/github/last-commit/hasansezertasan/asgi-user-agents)](https://github.com/hasansezertasan/asgi-user-agents)\n\n[![Downloads](https://pepy.tech/badge/asgi-user-agents)](https://pepy.tech/project/asgi-user-agents)\n[![Downloads/Month](https://pepy.tech/badge/asgi-user-agents/month)](https://pepy.tech/project/asgi-user-agents)\n[![Downloads/Week](https://pepy.tech/badge/asgi-user-agents/week)](https://pepy.tech/project/asgi-user-agents)\n\n[User Agents][python-user-agents] integration for [ASGI](https://asgi.readthedocs.io/en/latest/) applications. Works with Starlette, FastAPI, Quart, Litestar -- or any other web framework supporting ASGI that exposes the ASGI `scope`.\n\n-----\n\n## Table of Contents\n\n- [asgi-user-agents](#asgi-user-agents)\n  - [Table of Contents](#table-of-contents)\n  - [Installation](#installation)\n  - [How does it work?](#how-does-it-work)\n  - [Usage](#usage)\n  - [API Reference](#api-reference)\n    - [`UAMiddleware`](#uamiddleware)\n    - [`UADetails`](#uadetails)\n    - [`UARequest`](#uarequest)\n  - [Development](#development)\n  - [Author](#author)\n  - [Credits](#credits)\n  - [Analysis](#analysis)\n  - [License](#license)\n\n## Installation\n\n**NOTE**: This is alpha software. Please be sure to pin your dependencies.\n\n> Latest Release\n\n```bash\npip install asgi-user-agents\n```\n\n> Development Version\n\n```bash\npip install git+https://github.com/hasansezertasan/asgi-user-agents.git\n```\n\n## How does it work?\n\nIt simply adds a `ua` attribute to the request scope. This attribute is an instance of the `UADetails` class which abstracts the `UserAgent` class from the `user-agents` package \ud83d\udcc4.\n\n## Usage\n\nIt's pretty simple. Just add the middleware to your ASGI application and access the `ua` attribute from the request scope.\n\n```python\nfrom asgi_user_agents import UAMiddleware\nfrom asgi_user_agents import UARequest as Request\nfrom fastapi.applications import FastAPI\nfrom starlette.middleware import Middleware\nfrom starlette.responses import JSONResponse, Response\n\n\napp = FastAPI(middleware=[Middleware(UAMiddleware)])\n\n\n@app.get(\"/\")\nasync def index(request: Request) -> Response:\n    ua = request.scope[\"ua\"]\n    data = {\n        \"ua_string\": ua.ua_string,\n        \"os\": ua.os,\n        \"os.family\": ua.os.family,\n        \"os.version\": ua.os.version,\n        \"os.version_string\": ua.os.version_string,\n        \"browser\": ua.browser,\n        \"browser.family\": ua.ua.browser.family,\n        \"browser.version\": ua.ua.browser.version,\n        \"browser.version_string\": ua.ua.browser.version_string,\n        \"device\": ua.device,\n        \"device.family\": ua.device.family,\n        \"device.brand\": ua.device.brand,\n        \"device.model\": ua.device.model,\n        \"is_provided\": ua.is_provided,\n        \"is_tablet\": ua.is_tablet,\n        \"is_mobile\": ua.is_mobile,\n        \"is_touch_capable\": ua.is_touch_capable,\n        \"is_pc\": ua.is_pc,\n        \"is_bot\": ua.is_bot,\n        \"is_email_client\": ua.is_email_client,\n    }\n    return JSONResponse(data)\n\n```\n\n## API Reference\n\n### `UAMiddleware`\n\nAn ASGI middleware that sets `scope[\"ua\"]` to an instance of [`UADetails`](#uadetails) (`scope` refers to the ASGI scope).\n\n```python\napp = UAMiddleware(app)\n```\n\n### `UADetails`\n\nA helper that provides shortcuts for accessing [`User-Agent` request header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent).\n\n```python\nua = UADetails(scope)\n```\n\n- `ua: UserAgent` - The `UserAgent` instance from the `user-agents` package.\n- `ua_string: str` - The user agent string.\n- `is_provided: bool` - `True` if the user agent string is provided.\n- `os: OperatingSystem` - The operating system details of the user agent. It's a named tuple with the following fields:\n  - `family: str` - The family of the operating system.\n  - `version: str` - The version of the operating system.\n  - `version_string: str` - The version of the operating system as a string.\n- `browser: Browser` - The browser details of the user agent. It's a named tuple with the following fields:\n  - `family: str` - The family of the browser.\n  - `version: str` - The version of the browser.\n  - `version_string: str` - The version of the browser as a string.\n- `device: Device` - The device details of the user agent. It's a named tuple with the following fields:\n  - `family: str` - The family of the device.\n  - `brand: str` - The brand of the device.\n  - `model: str` - The model of the device.\n- `is_tablet: bool` - `True` if the request was made by a tablet.\n- `is_mobile: bool` - `True` if the request was made by a mobile device.\n- `is_touch_capable: bool` - `True` if the request was made by a touch-capable device.\n- `is_pc: bool` - `True` if the request was made by a PC.\n- `is_bot: bool` - `True` if the request was made by a bot.\n- `is_email_client: bool` - `True` if the request was made by an email client.\n\n### `UARequest`\n\nFor Starlette-based frameworks, use this instead of the standard `starlette.requests.Request` so that code editors understand that `request.scope[\"ua\"]` contains an `UADetails` instance:\n\n```python\nfrom asgi_user_agents import UARequest as Request\n\nasync def home(request: Request):\n    reveal_type(request.scope[\"ua\"])  # Revealed type is 'UADetails'\n```\n\n## Development\n\nClone the repository and cd into the project directory:\n\n```bash\ngit clone https://github.com/hasansezertasan/asgi-user-agents\ncd asgi-user-agents\n```\n\nInstall hatch, you can follow the instructions [here](https://hatch.pypa.io/latest/install/), or simply run the following command:\n\n```bash\npipx install hatch\n```\n\nInitialize the environment and install the dependencies:\n\n```bash\nhatch shell\n```\n\nInitialize pre-commit hooks by running the following command:\n\n```bash\npre-commit install\n```\n\nMake your changes on a new branch and run the tests:\n\n```bash\nhatch test -a\n```\n\nMake sure that the code is typed, linted, and formatted correctly:\n\n```bash\nhatch run types:all\n```\n\nStage your changes and commit them:\n\n```bash\ngit add .\ngit commit -m \"Your message\"\n```\n\nPush your changes to the repository:\n\n```bash\ngit push\n```\n\nCreate a pull request and wait for the review \ud83e\udd13.\n\n## Author\n\n- [Hasan Sezer Ta\u015fan](https://www.github.com/hasansezertasan), It's me \ud83d\udc4b.\n\n## Credits\n\n- This project wouldn't be possible without the [user-agents][python-user-agents] package \ud83d\ude4f.\n- The project structure is inspired by the [asgi-htmx](https://github.com/florimondmanca/asgi-htmx) \ud83d\ude80 package and contains some code snippets from it \ud83d\ude05 (even this file).\n\n## Analysis\n\n- [Snyk Python Package Health Analysis](https://snyk.io/advisor/python/asgi-user-agents)\n- [Libraries.io - PyPI](https://libraries.io/pypi/asgi-user-agents)\n- [Safety DB](https://data.safetycli.com/packages/pypi/asgi-user-agents)\n- [PePy Download Stats](https://www.pepy.tech/projects/asgi-user-agents)\n- [PyPI Download Stats](https://pypistats.org/packages/asgi-user-agents)\n- [Pip Trends Download Stats](https://piptrends.com/package/asgi-user-agents)\n\n## License\n\n`asgi-user-agents` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.\n\n<!-- Links -->\n[python-user-agents]: https://github.com/selwin/python-user-agents\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "User Agent integration for ASGI applications.",
    "version": "0.2.0",
    "project_urls": {
        "Documentation": "https://github.com/hasansezertasan/asgi-user-agents#readme",
        "Issues": "https://github.com/hasansezertasan/asgi-user-agents/issues",
        "Source": "https://github.com/hasansezertasan/asgi-user-agents"
    },
    "split_keywords": [
        "asgi",
        " fastapi",
        " litestar",
        " quart",
        " starlette"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "4bcf4fc4529bded46a02a636dea1c0e2bf5d51757928dd9b0f21a2d02f1465d8",
                "md5": "e6682f74e0e29841020c5d35a6a11d5e",
                "sha256": "645a8d51eafd22a9844da8b50d8b11c1deb8ca2f0d10e65c300e81466696df9d"
            },
            "downloads": -1,
            "filename": "asgi_user_agents-0.2.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "e6682f74e0e29841020c5d35a6a11d5e",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 7531,
            "upload_time": "2024-05-26T14:24:12",
            "upload_time_iso_8601": "2024-05-26T14:24:12.860902Z",
            "url": "https://files.pythonhosted.org/packages/4b/cf/4fc4529bded46a02a636dea1c0e2bf5d51757928dd9b0f21a2d02f1465d8/asgi_user_agents-0.2.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "a5e4e84ee84d50379c313b6ae16aa8ef484da482559033476a6b3de7f22c991c",
                "md5": "d67a29671e07688f75edf59a6b1e2655",
                "sha256": "6baef3aff9da02019d0bd089dac0360da19dedda6afa917f6f08447a30e7041b"
            },
            "downloads": -1,
            "filename": "asgi_user_agents-0.2.0.tar.gz",
            "has_sig": false,
            "md5_digest": "d67a29671e07688f75edf59a6b1e2655",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 14865,
            "upload_time": "2024-05-26T14:24:11",
            "upload_time_iso_8601": "2024-05-26T14:24:11.340580Z",
            "url": "https://files.pythonhosted.org/packages/a5/e4/e84ee84d50379c313b6ae16aa8ef484da482559033476a6b3de7f22c991c/asgi_user_agents-0.2.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-05-26 14:24:11",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "hasansezertasan",
    "github_project": "asgi-user-agents#readme",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "asgi-user-agents"
}
        
Elapsed time: 0.24408s