Skip to main content

Cross-platform clipboard access with zero external dependencies. No xclip or xsel needed on Linux.

Project description

pyxclip

PyPI version Python versions Downloads

Cross-platform clipboard access with zero external dependencies. No xclip or xsel needed on Linux. Built with Rust (PyO3 + arboard) for speed and reliability.

Installation

pip install pyxclip

Works with Python 3.8 through 3.14. No C compiler or system packages required.

Quick Start

import pyxclip

pyxclip.copy("Hello, world!")
text = pyxclip.paste()
print(text)  # Hello, world!

That's the whole API. Three functions: copy(), paste(), and clear(). Copy figures out what to do based on the type you pass. Paste returns whatever is on the clipboard.

Text Operations

Copy and paste strings, unicode, multiline text, even empty strings.

import pyxclip

# Basic text
pyxclip.copy("Hello, world!")
print(pyxclip.paste())  # Hello, world!

# Unicode and emoji
pyxclip.copy("cafe\u0301, na\u00efvet\u00e9, \U0001f600")
print(pyxclip.paste())  # cafe, naiveté, 😀

# Multiline text
blocks = """First line
Second line
Third line"""
pyxclip.copy(blocks)
print(pyxclip.paste())
# First line
# Second line
# Third line

# Empty string clears to empty text
pyxclip.copy("")
print(pyxclip.paste())  # (empty string)

Clear the Clipboard

Pass None to copy() or call clear().

import pyxclip

# Either way works
pyxclip.copy(None)
pyxclip.clear()

# Pasting after clearing raises ClipboardError
try:
    pyxclip.paste()
except pyxclip.ClipboardError:
    print("Clipboard is empty")

Image Operations

Copy images by passing a (width, height, pixels) tuple where pixels is raw RGBA data, 4 bytes per pixel, row-major order. Paste returns a dict with "width", "height", and "bytes" keys.

import pyxclip

# Create a 4x4 red square
width, height = 4, 4
pixels = b"\xff\x00\x00\xff" * (width * height)  # RGBA: red, fully opaque
pyxclip.copy((width, height, pixels))

# Paste the image back
result = pyxclip.paste()
print(type(result))        # <class 'dict'>
print(result["width"])     # 4
print(result["height"])    # 4
print(len(result["bytes"]))  # 64 (4 * 4 * 4 bytes)

# Save pasted image to a PNG file
from PIL import Image

result = pyxclip.paste()
img = Image.frombytes("RGBA", (result["width"], result["height"]), result["bytes"])
img.save("screenshot.png")

File Operations

Copy file paths to the clipboard as a single Path or a list. Paste returns a list of strings.

import pyxclip
from pathlib import Path

# Single file
pyxclip.copy(Path("/tmp/report.pdf"))

# Multiple files
files = [Path("/tmp/report.pdf"), Path.home() / "photos" / "vacation.jpg"]
pyxclip.copy(files)

# Paste returns a list
pasted = pyxclip.paste()
print(type(pasted))  # <class 'list'>
print(pasted)        # ['/tmp/report.pdf', '/home/user/photos/vacation.jpg']

str vs Path — why it matters

str is always treated as text, never as a file path. This is intentional:

import pyxclip
from pathlib import Path

pyxclip.copy("/some/path.txt")
print(pyxclip.paste())  # "/some/path.txt" — copied as text

pyxclip.copy(Path("/some/path.txt"))
# — copied as file reference (if file exists)

If you have a string that represents a file path, wrap it in Path:

pyxclip.copy(Path(my_string_path))

Error messages

File copy errors are specific about what went wrong:

import pyxclip
from pathlib import Path

try:
    pyxclip.copy(Path("/does/not/exist.txt"))
except pyxclip.ClipboardError as e:
    print(e)
    # "Failed to copy file paths to clipboard: one or more files may not exist
    #  or are inaccessible. All paths must point to existing files or directories."

File path copy succeeds on all desktop platforms (Windows, macOS, Linux). However, pasting files into a file manager depends on your desktop environment. pyxclip writes the standard text/uri-list format — whether the receiving app reads it is up to that app.

If copy() succeeds but pasting into a specific app doesn't work, the issue is with that app's clipboard support — not pyxclip.

Error Handling

All clipboard failures raise ClipboardError, a subclass of RuntimeError.

import pyxclip

# Catch any clipboard failure
try:
    pyxclip.paste()
except pyxclip.ClipboardError as e:
    print(f"Failed: {e}")

# Detect headless environments before trying
import os

def clipboard_available() -> bool:
    if os.environ.get("DISPLAY") or os.environ.get("WAYLAND_DISPLAY"):
        return True
    if os.name == "nt" or sys.platform == "darwin":
        return True
    return False

if clipboard_available():
    pyxclip.copy("works!")
else:
    print("No clipboard in this environment")

Common errors:

  • "No display server available (headless?)" -- no display set on Linux
  • "Clipboard is empty or contains incompatible data" -- nothing readable
  • "Clipboard is held by another process; retry later" -- transient lock

Practical Examples

Copy the result of a script to clipboard

import pyxclip
import json

data = {"status": "ok", "items": [1, 2, 3]}
pyxclip.copy(json.dumps(data, indent=2))
# Now Ctrl+V in any editor pastes formatted JSON

Pipe data through the clipboard in shell scripts

# Sort lines from clipboard and put them back
python3 -c "
import pyxclip
lines = pyxclip.paste().strip().split('\n')
pyxclip.copy('\n'.join(sorted(set(lines))))
"

# Reverse the clipboard content
python3 -c "
import pyxclip
t = pyxclip.paste()
pyxclip.copy(t[::-1])
"

Clipboard-based communication between scripts

# producer.py
import pyxclip
import time

for i in range(5):
    pyxclip.copy(f"task-{i}")
    time.sleep(1)

# consumer.py
import pyxclip

last = None
while True:
    current = pyxclip.paste()
    if current != last:
        print(f"New item: {current}")
        last = current

Paste clipboard content into a file

import pyxclip

content = pyxclip.paste()
with open("clipboard_dump.txt", "w") as f:
    f.write(content)
print(f"Saved {len(content)} characters")

Copy an API response to clipboard

import pyxclip
import urllib.request

resp = urllib.request.urlopen("https://httpbin.org/get")
data = resp.read().decode()
pyxclip.copy(data)
print("API response copied to clipboard")

Quick notes manager

import pyxclip
from datetime import datetime

# Append a timestamped note
note = pyxclip.paste()
with open("notes.txt", "a") as f:
    f.write(f"[{datetime.now():%Y-%m-%d %H:%M}] {note}\n")
print("Note saved")

Copy a URL from a script

import pyxclip

url = "https://github.com/abbazs/pyxclip"
pyxclip.copy(url)
print(f"Copied: {url} -- paste in browser")

Copy source code to clipboard

import pyxclip

code = '''
def fibonacci(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a
'''
pyxclip.copy(code.strip())

Grab and re-copy clipboard text with modifications

import pyxclip

text = pyxclip.paste()
pyxclip.copy(text.upper())  # or .lower(), .strip(), .replace(...)
print("Text transformed in clipboard")

Type Signatures

def copy(data: None | str | tuple[int, int, bytes] | os.PathLike[str] | os.PathLike[bytes] | list[os.PathLike[str] | str], /) -> None: ...
def paste() -> str | dict[str, object] | list[str]: ...
def clear() -> None: ...

class ClipboardError(RuntimeError): ...

Platform Support

Platform Backend Notes
Linux X11 / Wayland No xclip/xsel. Wayland uses wayland-data-control.
macOS NSPasteboard System framework.
Windows Win32 System API.

On headless Linux (no DISPLAY, no WAYLAND_DISPLAY), all operations raise ClipboardError.

How It Works

A single Rust extension module compiled with PyO3, using arboard for native clipboard access. No Python dependencies beyond the compiled wheel.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyxclip-0.2.3.tar.gz (17.9 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pyxclip-0.2.3-cp313-abi3-win_amd64.whl (292.2 kB view details)

Uploaded CPython 3.13+Windows x86-64

pyxclip-0.2.3-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (705.8 kB view details)

Uploaded CPython 3.13+manylinux: glibc 2.17+ ARM64

pyxclip-0.2.3-cp313-abi3-macosx_11_0_arm64.whl (382.8 kB view details)

Uploaded CPython 3.13+macOS 11.0+ ARM64

pyxclip-0.2.3-cp313-abi3-macosx_10_12_x86_64.whl (402.0 kB view details)

Uploaded CPython 3.13+macOS 10.12+ x86-64

pyxclip-0.2.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (715.8 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

File details

Details for the file pyxclip-0.2.3.tar.gz.

File metadata

  • Download URL: pyxclip-0.2.3.tar.gz
  • Upload date:
  • Size: 17.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyxclip-0.2.3.tar.gz
Algorithm Hash digest
SHA256 3fbb12b9e33c46c143d5a19312599f635b1db97e828ea3174934ebbfb3acb557
MD5 39566c8d3e391b479ff156d4ff31e5fd
BLAKE2b-256 967337811428a0762c97c688864f1115fb83c4428a725308c83b0f48f3912570

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyxclip-0.2.3.tar.gz:

Publisher: publish.yml on abbazs/pyxclip

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyxclip-0.2.3-cp313-abi3-win_amd64.whl.

File metadata

  • Download URL: pyxclip-0.2.3-cp313-abi3-win_amd64.whl
  • Upload date:
  • Size: 292.2 kB
  • Tags: CPython 3.13+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyxclip-0.2.3-cp313-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 7fe21acafdb3425feaf9f4d55ea54a464ebad67ae9eee4311ea5604641ba2c09
MD5 a345e499bef37f661e2898bf960bbac4
BLAKE2b-256 ac4a2f1ba1573cda6d47197658b917c043aad576f60a0af45ab3979ca7595ff9

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyxclip-0.2.3-cp313-abi3-win_amd64.whl:

Publisher: publish.yml on abbazs/pyxclip

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyxclip-0.2.3-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for pyxclip-0.2.3-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 a3b38b03a41145d532d28f34ef8959abaddf06edbc2ca1913824e9b2f171cc75
MD5 f8a2fdc8135105067c45156ab3a02283
BLAKE2b-256 68c9f55c237935a418dab196394a807ffe3a5dd849949c8aa269fdb94f0f83b2

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyxclip-0.2.3-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish.yml on abbazs/pyxclip

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyxclip-0.2.3-cp313-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pyxclip-0.2.3-cp313-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5532effc21de6999e543eae825398be9c99f8443d396dee58c1a7784e23e1b43
MD5 0dac4dd8ae0df34221912265ca242fa9
BLAKE2b-256 d8a627dfd81625606a5e3f5003b8b4ef22122358cd6a4111172a1df1da0d2224

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyxclip-0.2.3-cp313-abi3-macosx_11_0_arm64.whl:

Publisher: publish.yml on abbazs/pyxclip

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyxclip-0.2.3-cp313-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for pyxclip-0.2.3-cp313-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 c859fa34d05ab463a9e5a872a8b3308a8f352824c1ff9815eb41f244e460d57e
MD5 c9a8aefcabebec08a20f3a48428f58d0
BLAKE2b-256 c69c652271f602703c810870ccf9d643a3d8879761291a84d2ec9ed3d76684c6

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyxclip-0.2.3-cp313-abi3-macosx_10_12_x86_64.whl:

Publisher: publish.yml on abbazs/pyxclip

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyxclip-0.2.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyxclip-0.2.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 892d99a582496bd3bcf4fe1ccba8f8b4bfff86c4c642a9a220cb0b5e4c0ab862
MD5 f1ff82f7815408892f555af803e6efe3
BLAKE2b-256 51458fafd22234c3087151461c8cfd889a30c775fb6c266d01f17024ecc25c4b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyxclip-0.2.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on abbazs/pyxclip

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page