Sydney.py
Python Client for Copilot (formerly named Bing Chat), also known as Sydney.
Install / Use
/learn @vsakkas/Sydney.pyQuality Score
Category
Development & EngineeringSupported Platforms
README
<img src="https://raw.githubusercontent.com/vsakkas/sydney.py/master/images/logo.svg" width="28px" /> Sydney.py
Python Client for Copilot (formerly named Bing Chat), also known as Sydney.
[!NOTE] This is an unofficial client.
Features
- Connect to Copilot, Microsoft's AI-powered personal assistant.
- Ask questions and have a conversation in various conversation styles.
- Compose content in various formats and tones.
- Stream response tokens for real-time communication.
- Retrieve citations and suggested user responses.
- Enhance your prompts with images for an enriched experience.
- Customize your experience using any of the supported personas.
- Use asyncio for efficient and non-blocking I/O operations.
Requirements
- Python 3.9 or newer
- Microsoft account with access to Copilot (optional)
Installation
To install Sydney.py, run the following command:
pip install sydney-py
or, if you use poetry:
poetry add sydney-py
[!TIP] Make sure you're using the latest version of Sydney.py to ensure best compatibility with Copilot.
Usage
Prerequisites
To use Sydney.py, you first need to extract all the cookies from the Copilot web page. These cookies are used to authenticate your requests to the Copilot API.
To get the cookies, follow these steps on Microsoft Edge:
- Go to the Copilot web page.
- Open the developer tools in your browser (usually by pressing
F12or right-clicking on the chat dialog and selectingInspect). - Select the
Networktab to view all requests sent to Copilot. - Write a message on the chat dialog that appears on the web page.
- Find a request named
create?bundleVersion=XYZand click on it. - Scroll down to the requests headers section and copy the entire value after the
Cookie:field.
Then, set it as an environment variable in your shell:
export BING_COOKIES=<your-cookies>
or, in your Python code:
os.environ["BING_COOKIES"] = "<your-cookies>"
[!TIP] In some regions, using cookies is not required, in which case the above instructions can be skipped.
[!TIP] It is also possible to use the
Cookie-Editorextension, export the cookies inHeader Stringformat and set them the same way.
[!IMPORTANT] For regions where a cookie is required, it is recommended to manually write messages to Copilot until a box containing a
Verifyingmessage appears, which should then switch to aSuccess!message. Without this step, it is possible that Sydney.py will fail with aCaptchaChallengeerror.
[!IMPORTANT] Copilot has been redesigned with a new, non-compatible API. Sydney currently uses https://edgeservices.bing.com/edgesvc/chat instead of https://copilot.microsoft.com as a workaround.
Example
You can use Sydney.py to easily create a CLI client for Copilot:
import asyncio
from sydney import SydneyClient
async def main() -> None:
async with SydneyClient() as sydney:
while True:
prompt = input("You: ")
if prompt == "!reset":
await sydney.reset_conversation()
continue
elif prompt == "!exit":
break
print("Sydney: ", end="", flush=True)
async for response in sydney.ask_stream(prompt):
print(response, end="", flush=True)
print("\n")
if __name__ == "__main__":
asyncio.run(main())
Sydney Client
You can create a Sydney Client and initialize a connection with Copilot which starts a conversation:
sydney = SydneyClient()
await sydney.start_conversation()
# Conversation
await sydney.close_conversation()
Alternatively, you can use the async with statement to keep the code compact:
async with SydneyClient() as sydney:
# Conversation
Conversation Style
You can set the conversation style when creating a Sydney Client:
sydney = SydneyClient(style="creative")
The available options are creative, balanced and precise.
Reset Conversation
You can reset the conversation in order to make the client forget the previous conversation. You can also change the conversation style without creating a new client:
async with SydneyClient() as sydney:
# Conversation
await sydney.reset_conversation(style="creative")
Ask
You can ask Copilot questions and (optionally) include citations in the results:
async with SydneyClient() as sydney:
response = await sydney.ask("When was Bing Chat released?", citations=True)
print(response)
You can also stream the response tokens:
async with SydneyClient() as sydney:
async for response in sydney.ask_stream("When was Bing Chat released?", citations=True):
print(response, end="", flush=True)
Both versions of the ask method support the same parameters.
Attachment
It is also possible to provide a URL to an image or a local image file path as an attachment, which will be used as input together with the prompt:
async with SydneyClient() as sydney:
response = await sydney.ask("What does this picture show?", attachment="<image-url-or-path>")
print(response)
Web Context
You can also provide the contents of a web page as additional context to be used along with the prompt:
async with SydneyClient() as sydney:
response = await sydney.ask("Describe the webpage", context="<web-page-source>")
print(response)
Web Search
It is possible to determine if Copilot can search the web for information to use in the results:
async with SydneyClient() as sydney:
response = await sydney.ask("When was Bing Chat released?", search=False)
print(response)
Searching the web is enabled by default.
[!NOTE] Web search cannot be disabled when the response is streamed.
Personas
It is possible to use specialized versions of Copilot, suitable for specific tasks or conversations:
async with SydneyClient(persona="travel") as sydney:
response = await sydney.ask("Tourist attractions in Sydney")
print(response)
The available options for the persona parameter are:
copilottravelcookingfitness
By default, Sydney.py will use the copilot persona.
Compose
You can ask Copilot to compose different types of content, such emails, articles, ideas and more:
async with SydneyClient() as sydney:
response = await sydney.compose("Why Python is a great language", format="ideas")
print(response)
You can also stream the response tokens:
async with SydneyClient() as sydney:
async for response in sydney.compose_stream("Why Python is a great language", format="ideas"):
print(response, end="", flush=True)
The default available options for the tone parameter are:
professionalcasualenthusiasticinformationalfunny
It is also possible to provide any other value for the tone parameter.
The available options for the format parameter are:
paragraphemailblogpostideas
The available options for the length parameter are:
shortmediumlong
Both versions of the compose method support the same parameters.
Suggested Responses
You can also receive the suggested user responses as generated by Copilot along with the text answer. Both ask, ask_stream support this feature:
async with SydneyClient() as sydney:
response, suggested_responses = await sydney.ask("When was Bing Chat released?", suggestions=True)
if suggested_responses:
print("Suggestions:")
for suggestion in suggested_responses:
print(suggestion)
And also compose and compose_stream:
async with SydneyClient() as sydney:
response, suggested_responses = await sydney.compose(
"Why Python is a great language", format="ideas", suggestions=True
)
if suggested_responses:
print("Suggestions:")
for suggestion in suggested_responses:
print(suggestion)
[!NOTE] The suggested user responses are returned only if the suggestions parameter is true. Otherwise, all
askandcomposemethods return only the response.
[!NOTE] When using the
ask_streamorcompose_streammethod with the suggestions parameter, only the lastly returned suggested user responses may contain a value. For all previous iterations, the suggested user responses will beNone.
Compose using Suggestions
You can also improve or alter the results of compose by using either the suggested responses or any other prompt:
async with SydneyClient() as sydney:
response, suggested_responses = await sydney.compose(
prompt="Why Python is a great language", format="ideas", suggestions=True,
)
response, suggested_responses = await sydney.compose(
prompt=suggested_responses[0], format="ideas", suggestions=True
)
print(response)
Raw Response
You can also receive the raw JSON response that comes from Copilot instead of a text answer. Both ask and compose support this feature:
async with SydneyClient() as sydney:
response = await sydney.ask("When was Bing Chat released?", raw=True)
print(response)
Conversations
You can a
Related Skills
node-connect
346.4kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
claude-opus-4-5-migration
107.2kMigrate prompts and code from Claude Sonnet 4.0, Sonnet 4.5, or Opus 4.1 to Opus 4.5
frontend-design
107.2kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
model-usage
346.4kUse CodexBar CLI local cost usage to summarize per-model usage for Codex or Claude, including the current (most recent) model or a full model breakdown. Trigger when asked for model-level usage/cost data from codexbar, or when you need a scriptable per-model summary from codexbar cost JSON.
