# Appium Python Client is a Selenium extension, and that shapes everything

> Appium-Python-Client is a Python library that adds WebDriver and Appium commands to the Selenium binding, aimed at mobile test automation teams. Its compatibility matrix, its versioned breaking changes and its dependency on Selenium are the facts a team must plan around before adopting it.

**appium/python-client** — Python language bindings for Appium

- Repository: https://github.com/appium/python-client
- Stars: 1,844 · Forks: 572
- Language: Python
- License: Apache-2.0
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/appium-python-client

## An extension layer on top of the Selenium binding

The README describes the library in one sentence, and that sentence is the whole design. It is an extension library for adding WebDriver Protocol and Appium commands to the Selenium Python language binding, for use with the Appium mobile testing framework. Nothing here talks to a device directly. Your test imports the Selenium webdriver, imports Appium options, and constructs a remote driver whose traffic goes to an Appium server, which is the part that owns the device connection.

That layering is the single most important fact for anyone weighing the library. The Python surface you use is Selenium's, which means the element location, the waits and the driver lifecycle are the ones a Selenium tester already knows. What Appium contributes is the mobile vocabulary on top: platform specific options objects, mobile: extension commands, and the action helpers for touch. The cost of that inheritance is stated in the README as well, that the client depends on the Selenium Python binding and that a Selenium update might affect Appium client behaviour, with some changes in the Selenium binding able to break the Appium client.

For teams already running Selenium, that is a familiar bargain. You get a mature element model and a mobile command set in one import, at the price of a dependency whose release schedule is not yours to control.

## The compatibility matrix is the contract you actually adopt

Because the library wraps Selenium, the versions of both matter, and the README publishes a table that pairs every client line with a Selenium binding range and a minimum Python version. The current row reads `6.0.0`+ with Selenium `4.37.0`+ on Python 3.10+. Below it sit the older pairings: `5.1.1` to `5.3.1` on Selenium `4.26.0` to `4.46.0` with Python 3.9+, `4.5.0` to `5.1.0` on Selenium `4.26.0` to `4.31.0`, and a longer tail down to `0.52` and below on Python 2.7 and 3.4 to 3.7.

This table is more than a compatibility chart, it is a deprecation schedule. Each row corresponds to a set of API changes, and the README then walks through them one major version at a time under quick migration guides. Reading those guides in order tells you what your code will have to look like after each upgrade, which is the information a team needs when deciding whether to jump to 6 or hold on a line that its Selenium version still supports.

The project also asks you to manage dependencies with a version management tool, naming uv specifically, to keep compatible version combinations. That recommendation is not decoration. With a matrix this tight, an unpinned selenium install is a coin toss, and the recommended practice in the README is to pin the combination that the table says works.

## Installing from PyPI, from a tarball or from a clone

Three installation routes are documented, and they differ in what you get. The first is the ordinary one from PyPI, and the package name on the index is Appium-Python-Client:

```bash
    pip install Appium-Python-Client
```

The second route installs from the source tarball, which you download from the same PyPI page and unpack before installing the directory:

```bash
    tar -xvf Appium-Python-Client-X.X.tar.gz
    cd Appium-Python-Client-X.X
    pip install .
```

The third takes the source straight from GitHub:

```bash
    git clone git@github.com:appium/python-client.git
    cd python-client
    pip install .
```

Whichever route you use, the effective requirements are declared in the project metadata rather than in the README, and they are strict. The current release is version 6.0.7, it requires Python 3.10 or newer, and it declares two runtime dependencies, selenium at `>=4.37.0,<5.0` and typing-extensions at `~=4.16`. The classifiers list Python 3.10 through 3.14, which tells you the supported interpreter range for the current line. The build backend is hatchling, and the wheel packages the appium directory.

One consequence of that dependency list deserves emphasis: a Selenium 5 release would not be picked up silently, because the upper bound pins it below 5.0. Your Selenium version is therefore a deliberate choice rather than whatever pip resolves.

## AppiumClientConfig replaced the loose keyword arguments

The single most disruptive change in the client's recent history is the v4 to v5 move, and it only affects you if you pass keep_alive, direct_connection or strict_ssl to webdriver.Remote. The old form passed them as keyword arguments on the driver constructor, and the new form routes them through a dedicated configuration object, AppiumClientConfig, which is passed as the client_config argument:

```python
        from appium.webdriver.client_config import AppiumClientConfig

        client_config = AppiumClientConfig(
            remote_server_addr=SERVER_URL_BASE,
            direct_connection=True,
            keep_alive=False,
            ignore_certificates=True,
        )
        driver = webdriver.Remote(options=UiAutomator2Options().load_capabilities(desired_caps), client_config=client_config)
```

The old strict_ssl argument became ignore_certificates, which is a rename as well as a move, so a mechanical search and replace will not carry a v4 test suite forward. The two argument forms can be mixed, and when they are, the remote_server_addr in AppiumClientConfig takes priority over the url argument of the webdriver.Remote constructor.

The same migration also moved the default server address to `http://127.0.0.1:4723` instead of `http://127.0.0.1:4444/wd/hub`. Any test suite, CI job or docker-compose file that hardcoded the old path with the wd/hub suffix needs to change, and that kind of break tends to surface as a connection error rather than a clear failure.

## Removed helpers are the real upgrade tax

Beyond the constructor change, the older guides record a long list of removals, and these are what a team actually feels when it upgrades. The v3 to v4 guide removes MultiAction and TouchAction outright, pointing to W3C WebDriver actions or mobile: extensions instead, and deprecates AppiumBy.WINDOWS_UI_AUTOMATION as having no usage. The v2 to v3 guide removed the desired_capabilities argument in favour of an options object such as XCUITestOptions, dropped the end_test_coverage method along with the session and all_sessions properties, and replaced several device management methods with mobile: extension commands: start_activity became mobile: startActivity, launch_app, close_app and reset were folded into a single upstream issue, and the IME methods were replaced by mobile: shell. set_value and set_text were replaced by element.send_keys or W3C actions.

The pattern is consistent. Wherever the client had implemented something itself, the migration pushes that behaviour out to the W3C protocol or to a driver side mobile: command, and the client keeps only the plumbing. For a greenfield project that is a good design, because the surface you learn is smaller and the server does the work. For a suite written in the v2 era it is a substantial amount of rewriting, and the upstream Appium issue 15807 is the reference for the application lifecycle changes.

Note also the v1 to v2 note that forceMjsonwp was removed, since Selenium v4 and Appium Python client v2 expect only the W3C WebDriver protocol. The JSON Wire Protocol era is gone from this client and cannot be re-enabled.

## A Makefile built around uv, ruff and mypy

The contributor workflow in this repository is a good indicator of how the project treats its own dependencies, and it is short. The Makefile defines a check-all target that runs the checks and the unit tests, with check itself split into check-lint and check-format. Linting runs ruff over the tree and mypy over the appium package:

```bash
check-lint:
	uv run ruff check .
	uv run mypy appium
```

Formatting has its own target and its own fix variant, and the fix target combines a lint fix and a format pass:

```bash
check-format:
	uv run ruff format --check .
```

```bash
fix-lint:
	uv run ruff check --fix .
```

The unit tests are run through pytest against the test/unit directory, and there is an install-uv target that checks for uv on the path and, if it is missing, fetches the installer from astral.sh before adjusting the PATH for the current shell. The dev dependency group in the project metadata matches that story, with ruff, mypy, pytest, pytest-cov and pytest-xdist alongside the release and documentation tooling, and a uv.lock file at the top level.

Two things follow for a consumer. The project takes its own dependency discipline seriously, which is a fair signal for the library, and the toolchain is uv first, so a contributor without uv will install it before anything else runs.

## Apache-2.0 terms, a steady release line, and a moving Selenium

On the legal side, the project is licensed Apache-2.0, and the metadata names the licence file explicitly with license-files pointing at LICENSE. That is a permissive licence with an express patent grant, and it suits both commercial and academic use without additional obligations beyond preserving notices. The distribution name on the index is Appium-Python-Client while the import package is appium, which trips people up the first time they search for the module.

Activity is steady rather than dramatic. The last push was on 2026-10-19, the repository is not archived, and the recent release line is tight: v6.0.7 on 2026-09-18, v6.0.6 on 2026-09-12 and v6.0.5 on 2026-09-10. Patch releases are frequent, and the breaking changes are concentrated at major version boundaries, which is the friendlier arrangement for a library whose users upgrade on their own schedule.

The real upgrade cost sits in the dependency rather than in this project. The README is explicit that the client depends on the Selenium Python binding, that a Selenium update might affect the Appium client behaviour, and that some changes in the Selenium binding could break the Appium client. A team that lets pip float selenium is choosing to inherit that risk, and the compatibility matrix plus a pinned lock file is the mitigation the documentation actually recommends.

## Conclusion

Appium-Python-Client suits a team already writing Selenium tests that now needs to drive iOS and Android devices through an Appium server, and who can pin Selenium and Python versions deliberately. It is the wrong choice for a project that wants one binding for web and mobile without a separate server, because the client speaks to an Appium server rather than to a browser directly. Before you adopt it, check the compatibility matrix row that matches your Selenium binding, decide whether you are writing new code against the AppiumClientConfig form or carrying code written for v4 and earlier, and confirm the mobile: extension you rely on still exists in the Appium driver you deploy.

## FAQ

### What Python and Selenium versions does Appium-Python-Client 6 need?

The compatibility matrix lists Appium Python Client 6.0.0 and later against Selenium binding 4.37.0 and later on Python 3.10 and up. The project metadata requires Python 3.10 or newer and pins selenium to >=4.37.0,<5.0.

### How do I install the Appium Python client?

The README gives three routes: pip install Appium-Python-Client from PyPI, unpacking the source tarball and running pip install . inside it, or cloning the GitHub repository and running pip install . there.

### What replaced the strict_ssl argument in webdriver.Remote?

Starting with the v5 client, keep_alive, direct_connection and strict_ssl are passed through an AppiumClientConfig object given as the client_config argument. The strict_ssl argument became ignore_certificates, and the remote_server_addr in that config takes priority over the url argument of webdriver.Remote.

### Are MultiAction and TouchAction still available?

No. They were deprecated in v2 and removed in the v4 client. The migration guide points to W3C WebDriver actions and to the mobile: extensions in appium/webdriver/extensions/action_helpers.py instead.

## Sources

- [appium/python-client on GitHub](https://github.com/appium/python-client)
- [Issues](https://github.com/appium/python-client/issues)
- [License: Apache-2.0](https://github.com/appium/python-client/blob/master/LICENSE)
- [README](https://github.com/appium/python-client/blob/master/README.md)
- [Releases](https://github.com/appium/python-client/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/appium-python-client
