Unofficial Qwen API Client, Chat Wrapper, and LlamaIndex adapter
Project description
qwen-chat 🚀
An unofficial, feature-rich Python SDK and client wrapper for the Qwen AI Web API. Enjoy seamless access to advanced models like qwen3.6-plus with support for streaming, multi-turn conversations, system prompts, web search, deep reasoning, automatic local image uploads, and LlamaIndex integration.
✨ Features
-
🧠 Complete Model Support
Interact with Qwen's latest web models includingqwen3.6-plus,qwen-max-latest,qwq-32b,qwen2.5-omni-7b, and specialized vision/coder versions. -
💬 Multi-turn Chat Sessions
Have back-and-forth conversations that maintain context across messages — just like chatting in the Qwen web UI. Build interactive terminal chatbots or conversational agents easily. -
⚡ Synchronous & Asynchronous Clients
Whether you're building a script or a highly concurrent async web server,qwen-chathas you covered with nativecreate()andacreate()workflows. -
🌊 Real-time SSE Streaming (On/Off)
Togglestream=Trueorstream=Falseper request. Stream token-by-token responses directly to your UI or console, or get the full response at once. -
🎭 System & Assistant Roles
Usesystemrole messages to define the AI's personality, behavior, and instructions. Chainassistantanduserroles for few-shot prompting and context injection. -
📸 Automatic Local Image Uploads
Pass a local file path or raw bytes to anImageBlock. The client automatically fetches STS tokens and uploads the image to Alibaba Cloud OSS under the hood — no boilerplate required! -
🔍 Integrated Web Search
Toggle real-time search on or off per message to query live web data and receive detailed citations alongside responses. -
💡 Thinking & Reasoning Controls
Adjust thinking budget settings to enable advanced reasoning capabilities on complex tasks. -
🦙 LlamaIndex Adapter
Use Qwen directly inside LlamaIndex withQwenLlamaIndexfrom the sameqwen_chatpackage. No separateqwen-apiorqwen-llamaindexpackage is required.
📦 Installation
Install qwen-chat via pip:
pip install qwen-chat
⚙️ Environment Setup
To authenticate requests, extract your Authorization bearer token from the Qwen Web UI:
- Go to https://chat.qwen.ai and log in.
- Open developer tools (
F12orCtrl+Shift+I/Cmd+Option+I) and navigate to the Network tab. - Send any message in the chat interface.
- Locate the
completionsrequest (filter by Fetch/XHR). - Click on the request and go to the Headers tab. Copy the value of the
Authorizationheader without the word "Bearer " (just copy the token starting witheyJ...). - Save this value in a
.envfile in the root of your project:
QWEN_AUTH_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Note: You do not need to set up cookies. The package handles cookies automatically.
🚀 Usage Examples
1. Basic Text Completion
The simplest way to get a response from Qwen:
from qwen_chat import Qwen
from qwen_chat.core.types.chat import ChatMessage
client = Qwen()
messages = [
ChatMessage(role="user", content="What is Python?")
]
response = client.chat.create(messages=messages, model="qwen3.6-plus")
print("🤖", response.choices.message.content)
LlamaIndex Usage
Use Qwen as a LlamaIndex LLM from the same qwen-chat package:
from qwen_chat import QwenLlamaIndex
llm = QwenLlamaIndex(model="qwen3.6-plus")
response = llm.complete("Reply with only: ok")
print(response.text)
Chat example:
from llama_index.core.base.llms.types import ChatMessage
from qwen_chat import QwenLlamaIndex
llm = QwenLlamaIndex(model="qwen3.6-plus")
response = llm.chat([
ChatMessage(role="user", content="What is LlamaIndex?")
])
print(response.message.content)
Streaming example:
from qwen_chat import QwenLlamaIndex
llm = QwenLlamaIndex(model="qwen3.6-plus")
for chunk in llm.stream_complete("Write one sentence about Python."):
print(chunk.delta, end="", flush=True)
2. Streaming On / Off
Stream OFF (get full response at once):
from qwen_chat import Qwen
from qwen_chat.core.types.chat import ChatMessage
client = Qwen()
messages = [ChatMessage(role="user", content="Tell me a short joke.")]
# stream=False (default) — returns complete response
response = client.chat.create(messages=messages, model="qwen3.6-plus", stream=False)
print("🤖", response.choices.message.content)
Stream ON (token-by-token output):
from qwen_chat import Qwen
from qwen_chat.core.types.chat import ChatMessage
client = Qwen()
messages = [ChatMessage(role="user", content="Write a poem about the ocean.")]
# stream=True — yields chunks in real-time
stream = client.chat.create(messages=messages, model="qwen3.6-plus", stream=True)
print("🤖 ", end="")
for chunk in stream:
print(chunk.choices[0].delta.content, end="", flush=True)
print()
3. System Role & Assistant Role (Custom Personality)
Use the system role to define how the AI behaves. Use assistant role for few-shot examples:
from qwen_chat import Qwen
from qwen_chat.core.types.chat import ChatMessage
client = Qwen()
messages = [
# System prompt — defines AI personality and behavior
ChatMessage(
role="system",
content="You are a friendly pirate captain. Always respond in pirate speak with lots of 'Arrr!' and nautical references."
),
# User message
ChatMessage(
role="user",
content="What's the weather like today?"
)
]
response = client.chat.create(messages=messages, model="qwen3.6-plus")
print("🏴☠️", response.choices.message.content)
Few-shot prompting with assistant role:
from qwen_chat import Qwen
from qwen_chat.core.types.chat import ChatMessage
client = Qwen()
messages = [
ChatMessage(role="system", content="You are a helpful translator. Translate English to Bengali."),
# Few-shot example
ChatMessage(role="user", content="Hello"),
ChatMessage(role="assistant", content="হ্যালো"),
ChatMessage(role="user", content="How are you?"),
ChatMessage(role="assistant", content="আপনি কেমন আছেন?"),
# Actual request
ChatMessage(role="user", content="I love programming")
]
response = client.chat.create(messages=messages, model="qwen3.6-plus")
print("🤖", response.choices.message.content)
4. Interactive Terminal Chat (Multi-turn Conversation)
Build a fully interactive terminal chatbot that maintains conversation context across multiple turns — just like the Qwen web UI.
How it works: The Qwen API remembers your conversation server-side via
chat_idandparent_id. You only need to send the new message each turn — the AI already knows the full conversation history.
from qwen_chat import Qwen
from qwen_chat.core.types.chat import ChatMessage
def main():
client = Qwen()
print("💬 Qwen Chat Terminal")
print("Type 'exit' to quit\n")
# Optional: send a system prompt as the very first message
system_msg = [
ChatMessage(
role="system",
content="You are a helpful and friendly AI assistant."
)
]
client.chat.create(messages=system_msg, model="qwen3.6-plus")
while True:
try:
user_input = input("🧑 You: ").strip()
except (EOFError, KeyboardInterrupt):
print("\nBye! 👋")
break
if not user_input or user_input.lower() == "exit":
print("Bye! 👋")
break
# Send only the new user message — the API remembers the conversation
messages = [ChatMessage(role="user", content=user_input)]
response = client.chat.create(
messages=messages,
model="qwen3.6-plus",
temperature=0.7
)
print(f"🤖 AI: {response.choices.message.content}\n")
if __name__ == "__main__":
main()
Interactive chat with streaming output:
from qwen_chat import Qwen
from qwen_chat.core.types.chat import ChatMessage
def main():
client = Qwen()
print("💬 Qwen Streaming Chat")
print("Type 'exit' to quit\n")
while True:
try:
user_input = input("🧑 You: ").strip()
except (EOFError, KeyboardInterrupt):
print("\nBye! 👋")
break
if not user_input or user_input.lower() == "exit":
print("Bye! 👋")
break
# Send only the new message each turn
messages = [ChatMessage(role="user", content=user_input)]
stream = client.chat.create(
messages=messages,
model="qwen3.6-plus",
stream=True
)
print("🤖 AI: ", end="")
for chunk in stream:
text = chunk.choices[0].delta.content
print(text, end="", flush=True)
print("\n")
if __name__ == "__main__":
main()
5. Web Search with Citations
from qwen_chat import Qwen
from qwen_chat.core.types.chat import ChatMessage
client = Qwen()
messages = [
ChatMessage(
role="user",
content="What are the latest developments in AI?",
web_search=True
)
]
stream = client.chat.create(messages=messages, model="qwen3.6-plus", stream=True)
for chunk in stream:
delta = chunk.choices[0].delta
if delta.extra and delta.extra.web_search_info:
print("\n🔍 Sources:")
for source in delta.extra.web_search_info:
print(f" • {source.title}: {source.url}")
print()
print(delta.content, end="", flush=True)
print()
6. Automatic Local Image Upload (Vision)
Just pass your local image path directly inside ImageBlock. The client handles the secure upload automatically:
from qwen_chat import Qwen
from qwen_chat.core.types.chat import ChatMessage, TextBlock, ImageBlock
client = Qwen()
messages = [
ChatMessage(
role="user",
blocks=[
TextBlock(text="What's in this image? Describe it in detail."),
ImageBlock(path="photo.jpg") # Auto-uploaded to Alibaba OSS!
]
)
]
response = client.chat.create(messages=messages, model="qwen3.6-plus")
print("🤖", response.choices.message.content)
7. Async Usage
import asyncio
from qwen_chat import Qwen
from qwen_chat.core.types.chat import ChatMessage
async def main():
client = Qwen()
messages = [ChatMessage(role="user", content="Explain quantum computing in one sentence.")]
response = await client.chat.acreate(messages=messages, model="qwen3.6-plus")
print("🤖", response.choices.message.content)
asyncio.run(main())
8. Thinking & Reasoning Mode
Enable deep thinking for complex tasks:
from qwen_chat import Qwen
from qwen_chat.core.types.chat import ChatMessage
client = Qwen()
messages = [
ChatMessage(
role="user",
content="Solve this step by step: If a train travels 120km in 2 hours, then stops for 30 minutes, then travels 90km in 1.5 hours, what is the average speed for the entire journey?",
thinking=True,
thinking_budget=4096
)
]
response = client.chat.create(messages=messages, model="qwen3.6-plus")
print("🤖", response.choices.message.content)
🙋♂️ Contributing
Contributions are welcome! Here's how:
- Fork the project
- Create your feature branch (
git checkout -b feature/awesome-feature) - Commit your changes (
git commit -m 'Add awesome feature') - Push to the branch (
git push origin feature/awesome-feature) - Open a Pull Request
📃 License
This project is licensed under the MIT License.
📞 Contact & Support
For queries, support, or custom integrations, feel free to reach out!
Made with ❤️ by Shahadat Hassan
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file qwen_chat-1.0.6.tar.gz.
File metadata
- Download URL: qwen_chat-1.0.6.tar.gz
- Upload date:
- Size: 36.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a750d5f7119798e342de58d17e6f81fa801d3d3a2100a276dc12c56a5534dde2
|
|
| MD5 |
7a0340d5dda0351916d19cf6c7ecd395
|
|
| BLAKE2b-256 |
39c2bd46b97652a4eb510277ffc5603be71a23177c8f094cfbb0a67fc432120a
|
File details
Details for the file qwen_chat-1.0.6-py3-none-any.whl.
File metadata
- Download URL: qwen_chat-1.0.6-py3-none-any.whl
- Upload date:
- Size: 37.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac71e6f5184e4f2f845b5aeb53037df5710001afb2eb3b18298b72b50ff517a1
|
|
| MD5 |
7892787f612f9b6c2f35e2fe6479e388
|
|
| BLAKE2b-256 |
2116777e39f4f620430d769511988516fbcc01a662d401006b148cd51acf531f
|