Skip to main content

Lightweight GitHub Copilot client with device login

Project description

Copilot Python Client

Synchronous GitHub Copilot client and CLI with device flow auth, token exchange, model management, and streaming chat.

Package/CLI version: 1.0.0

Installation

  • Python 3.10+
  • From PyPI (recommended):
    pip install copilot-client
    
  • From GitHub:
    pip install "git+https://github.com/AlpMeteSenel/copilot-python-client.git"
    

CLI (copilot-client)

The CLI is installed as copilot-client (same version as the package). Credentials live in ~/.copilot_client/config.json and are reused across commands.

  • Authenticate via device flow or paste a token: copilot-client auth
  • List available models: copilot-client models
  • Interactive chat: copilot-client chat --model gpt-5-mini --system "Be concise"

Quickstart (programmatic)

import os
from copilot_client import CopilotClient

# Use an existing Copilot access token or fetch one via device flow (see below)
client = CopilotClient(copilot_access_token=os.environ["COPILOT_TOKEN"])
print(client.get_user())
print(client.chat([{ "role": "user", "content": "Say hi" }]))

Auth options

  • Device flow:
    code = CopilotClient.start_device_flow()
    print(f"Open {code.verification_uri} and enter {code.user_code}")
    github_token = CopilotClient.poll_device_flow(code.device_code, poll_interval=code.interval)
    client = CopilotClient(copilot_access_token=github_token)
    print("Copilot token:", client.copilot_token)
    
  • Existing Copilot access token:
    client = CopilotClient(copilot_access_token=os.environ["COPILOT_TOKEN"])
    

End-to-end walkthrough

from pathlib import Path
import base64
from copilot_client import CopilotClient

# Start device flow and exchange for a Copilot token
code = CopilotClient.start_device_flow()
print(f"Open {code.verification_uri} and enter {code.user_code}")
token = CopilotClient.poll_device_flow(code.device_code, poll_interval=code.interval)
client = CopilotClient(copilot_access_token=token)

print("copilot_token", client.copilot_token)
print("user", client.get_user())

models = client.list_models()
print([[m["id"], (m.get("policy", {}).get("state", "no policy"))] for m in models])

if models:
    try:
        print("enable_model", client.enable_model(models[0]["id"]))
    except Exception as exc:
        print("enable_model skipped", exc)

reply = client.chat([{"role": "user", "content": "Summarize GitHub in 2 bullets"}], system_message="Be concise")
print("chat", reply)

print("chat_stream", end=" ")
for chunk in client.chat_stream([{ "role": "user", "content": "Name two Python async primitives"}], model="copilot-nes-xtab"):
    if chunk["type"] == "text-delta":
        print(chunk["text"], end="")
print()

image_path = Path("husky.jpg")  # replace with your image path
image_base64 = base64.b64encode(image_path.read_bytes()).decode("ascii")
vision_message = [{
    "role": "user",
    "content": [
        {"type": "text", "text": "What is on this image?"},
        {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{image_base64}", "detail": "high"}},
    ],
}]

for chunk in client.chat_stream(vision_message, model="gpt-5-mini", vision=True):
    if chunk["type"] == "text-delta":
        print(chunk["text"], end="")
print()

Core usage

  • Models: list with client.list_models(); enable those needing consent via client.enable_model(model_id).
  • Chat (non-streaming): client.chat([...], model="gpt-5-mini", system_message="Be concise", max_output_tokens=200).
  • Chat (streaming): iterate over client.chat_stream([...], model="copilot-nes-xtab") and print chunk["text"] when chunk["type"] == "text-delta".
  • User info: client.get_user().

enable_model only activates models that require explicit consent; many will already be enabled.

Errors

All methods raise CopilotError on non-2xx responses. Auth issues raise CopilotAuthError; rate limits raise CopilotRateLimitError.

Tips

  • chat_stream(..., vision=True) forwards the Copilot vision header when prompts include images.
  • Copilot access tokens are exchanged automatically for Copilot bearer tokens and refreshed every 30 minutes.

Credits

Built by Alp Mete Senel. Contributions and issues are welcome.

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

copilot_client-1.0.0.tar.gz (10.9 kB view details)

Uploaded Source

Built Distribution

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

copilot_client-1.0.0-py3-none-any.whl (9.8 kB view details)

Uploaded Python 3

File details

Details for the file copilot_client-1.0.0.tar.gz.

File metadata

  • Download URL: copilot_client-1.0.0.tar.gz
  • Upload date:
  • Size: 10.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for copilot_client-1.0.0.tar.gz
Algorithm Hash digest
SHA256 67c388605960bd26af80232963d51b328d38e367d97996a79a91c2a30e6c967b
MD5 4e6981bd8f10f65966a9720ffff68c97
BLAKE2b-256 9e3d930b2aae353ceac02d064184b4a4a93874bdca012c6df1cb76f10bd9c5f7

See more details on using hashes here.

File details

Details for the file copilot_client-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: copilot_client-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 9.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for copilot_client-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9cd6e82462c52b7fcf58641d80bacc5cd0871e43dbea8e2690b46414c5fbd5bc
MD5 3bcc755e0f3aaba2794393214f0885d8
BLAKE2b-256 7090207dae176fb03769a9f9de4e6cd4f72dc18be5c082d88c6a8305800f48b6

See more details on using hashes here.

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