# larkpy larkpy is a comprehensive Python SDK for the Lark (Feishu) Open Platform, providing complete API wrappers for bot messaging, document operations, multi-dimensional tables (Bitable), instant messaging, and calendar management. The SDK simplifies integration with Lark's enterprise collaboration platform by offering intuitive classes for each major functionality area. The library supports two authentication methods: webhook-based messaging for simple bot notifications and OAuth-based API access for full platform capabilities. It includes support for sending text messages, rich text posts, interactive cards, images, and files. Advanced features include Bitable data manipulation with pandas DataFrame integration, document block operations, calendar event management, and browser-based requests using cookies for accessing authenticated endpoints. ## Installation ```bash pip install larkpy ``` ## LarkWebhook - Bot Webhook Messaging The LarkWebhook class enables sending messages to Lark group chats via webhook URLs. It supports plain text, rich text posts, and interactive cards with customizable templates and buttons. ```python from larkpy import LarkWebhook # Initialize with webhook URL webhook_url = "https://open.feishu.cn/open-apis/bot/v2/hook/your-webhook-id" webhook = LarkWebhook(webhook_url) # Send plain text message response = webhook.send_text("Hello, World!") print(response.json()) # Output: {"code": 0, "msg": "success", "data": {}} # Send rich text post with links payload = [ {"tag": "text", "text": "Project update notification\n"}, {"tag": "a", "text": "View details", "href": "https://github.com/example"} ] response = webhook.send_payload(payload, title="Project Update") # Send interactive card with markdown content response = webhook.send_card( content="**Status**: Deployment completed\n- Environment: Production\n- Version: 1.2.3", title="Deployment Notification", subtitle="Auto-deploy pipeline", template="green", buttons=[ {"content": "View Logs", "url": "https://logs.example.com"}, {"content": "Dashboard", "url": "https://dashboard.example.com"} ] ) # Create collapsible panel in card panel = LarkWebhook.gen_collapsible_panel( content="Detailed error stack trace here...", title="Error Details", expanded=False, background_color="red", border=True ) webhook.send_card(content=panel, title="Error Report") ``` ## WebhookConfig - Webhook Configuration Management The WebhookConfig class provides persistent storage for multiple webhook configurations, allowing you to manage different bots across projects. ```python from larkpy import WebhookConfig # Initialize config manager (defaults to ~/.larkpy/webhook_config.json) config = WebhookConfig() # Save webhook configurations config.save_config('alerts-bot', 'https://open.feishu.cn/open-apis/bot/v2/hook/abc123') config.save_config('deploy-bot', 'https://open.feishu.cn/open-apis/bot/v2/hook/xyz789') # Retrieve stored webhook URL alerts_url = config.get_config('alerts-bot') print(alerts_url) # Output: https://open.feishu.cn/open-apis/bot/v2/hook/abc123 # Use custom config file path custom_config = WebhookConfig(config_file='/path/to/custom/config.json') ``` ## LarkAPI - Base API Client The LarkAPI class is the foundation for all OAuth-based API interactions, providing authentication and request handling. It's used as a base class for specialized clients. ```python from larkpy import LarkAPI # Initialize with app credentials api = LarkAPI( app_id="cli_your_app_id", app_secret="your_app_secret", user_id_type="open_id" # Options: 'open_id', 'user_id', 'union_id' ) # Get wiki node information node = api.get_node(token="wikcnXXXXXXXXXXXXX") print(node) # Output: {'obj_token': 'doccnXXXXXX', 'obj_type': 'docx', 'parent_node_token': '...', ...} # Access the document token for further operations doc_token = node['obj_token'] # Download file from message file_content = api.download_file(file_key="file_v2_xxxx") with open("downloaded_file.pdf", "wb") as f: f.write(file_content) # Make custom API request response = api.request( method="GET", url="https://open.feishu.cn/open-apis/wiki/v2/spaces", params={"page_size": 50} ) print(response.json()) ``` ## LarkMessage - Instant Messaging The LarkMessage class provides comprehensive instant messaging capabilities including sending text, images, files, interactive cards, and managing message reactions. ```python from larkpy import LarkMessage from pathlib import Path # Initialize IM client im = LarkMessage( app_id="cli_your_app_id", app_secret="your_app_secret", receive_id="ou_xxxxxxxxxxxxx", # Default recipient (open_id) log_level="INFO" ) # Smart send - automatically detects content type im.send("Hello, this is a text message") im.send(Path("/path/to/image.png")) # Sends as image im.send(Path("/path/to/document.pdf")) # Sends as file # Send to specific recipients (auto-detects ID type) im.messages("Hello!", receive_id="ou_xxxxx") # open_id im.messages("Hello!", receive_id="oc_xxxxx") # chat_id (group) im.messages("Hello!", receive_id="user@company.com") # email # Send image image_key = im.upload_image("/path/to/screenshot.png") im.send_image("/path/to/chart.png", receive_id="oc_group_chat_id") # Send file (supports pandas DataFrame) import pandas as pd df = pd.DataFrame({"Name": ["Alice", "Bob"], "Score": [95, 87]}) im.send_file(df, receive_id="ou_xxxxx", file_name="scores.xlsx") # Send interactive card card_content = { "header": { "template": "blue", "title": {"content": "Task Completed", "tag": "plain_text"} }, "elements": [ {"tag": "div", "text": {"content": "Build #123 succeeded", "tag": "lark_md"}}, {"tag": "hr"}, {"tag": "note", "elements": [{"tag": "plain_text", "content": "Click to view details"}]} ] } message_id = im.send_interactive_card(card_content, receive_id="oc_xxxxx") # Reply to a message im.reply_to_message(message_id="om_xxxxx", content="Thanks for the update!") # Add emoji reaction to message im.add_reaction(message_id="om_xxxxx", emoji_type="THUMBSUP") # Get message reactions reactions = im.get_message_reactions(message_id="om_xxxxx") status = im.check_reaction_status(reactions) # Returns True/False/None # Fetch group chat messages with pagination messages = im.fetch_chat_messages( chat_id="oc_xxxxx", start_time="2024-01-01 00:00:00", page_size=50, max_pages=5 ) # Format messages for display formatted = im.format_messages_for_display( messages, resolve_user_names=True, time_format="%Y-%m-%d %H:%M" ) print(formatted) # Get group chat list chats = im.get_group_chat_list(sort_type="ByActiveTimeDesc", page_size=20) # Recall message im.recall(message_id="om_xxxxx") im.recall_all() # Recall all messages sent in this session ``` ## LarkBitTable - Multi-dimensional Table Operations The LarkBitTable class enables CRUD operations on Lark Bitable (multi-dimensional tables) with pandas DataFrame integration for data analysis. ```python from larkpy import LarkBitTable import pandas as pd # Initialize Bitable client bitable = LarkBitTable( app_id="cli_your_app_id", app_secret="your_app_secret", wiki_token="wikcnXXXXXXXXXXXX", table_id="tblXXXXXXXXXXXX", view_id="vewXXXXXXXXXX" # Optional: default view ) # Search records with filter conditions result = bitable.search( fields=["Name", "Status", "Created"], filter={ "conjunction": "and", "conditions": [ bitable._cond("Status", "is", "Active"), bitable._cond("Priority", "is", ["High", "Medium"]) ] }, order=[{"field_name": "Created", "desc": True}], page_size=100 ) print(result) # Output: {'code': 0, 'data': {'items': [...], 'has_more': False, 'total': 42}} # Get results as pandas DataFrame df = bitable.search( filter={ "conjunction": "or", "conditions": [ bitable._cond("Category", "contains", "Bug"), bitable._cond("Category", "contains", "Feature") ] }, out=pd.DataFrame ) print(df.head()) # Name Status Priority # 0 Task1 Active High # 1 Task2 Pending Low # Convert existing data to DataFrame table_data = bitable.search() df = bitable.to_frame(table_data, columns=["Name", "Status"]) # Update single record bitable.update( record_id="recXXXXXXXX", fields={"Status": "Completed", "Updated": "2024-01-15"} ) # Batch update multiple records records = [ {"record_id": "recAAA", "fields": {"Status": "Done"}}, {"record_id": "recBBB", "fields": {"Status": "Done"}}, ] bitable.batch_update(records) ``` ## LarkDocx - Document Operations The LarkDocx class provides block-level operations for Lark documents, supporting creation and deletion of various content blocks. ```python from larkpy.docx import LarkDocx, BlockType # Initialize document client docx = LarkDocx( app_id="cli_your_app_id", app_secret="your_app_secret", document_id="doccnXXXXXXXXXXXX" ) # Create text block at document root result = docx.create_block( block_children={ "block_type": BlockType.text.value, "text": { "elements": [{"text_run": {"content": "Hello, World!"}}] } }, index=0 # Insert at beginning, -1 for end ) print(result) # Output: {'code': 0, 'data': {'children': [{'block_id': 'doxcnXXX', ...}]}} # Create heading block docx.create_block({ "block_type": BlockType.heading1.value, "heading1": { "elements": [{"text_run": {"content": "Section Title"}}] } }) # Create bullet list docx.create_block({ "block_type": BlockType.bullet.value, "bullet": { "elements": [{"text_run": {"content": "First item"}}] } }) # Create code block docx.create_block({ "block_type": BlockType.code.value, "code": { "elements": [{"text_run": {"content": "print('Hello')"}}], "language": 49 # Python } }) # Create multiple blocks at once blocks = [ {"block_type": BlockType.text.value, "text": {"elements": [{"text_run": {"content": "Line 1"}}]}}, {"block_type": BlockType.text.value, "text": {"elements": [{"text_run": {"content": "Line 2"}}]}} ] docx.create_block(blocks, index=-1) # Delete blocks by index range docx.delete_block( start_index=5, end_index=10, block_id="doxcnXXXXXXX" # Parent block ID ) ``` ## LarkCalendar - Calendar Event Management The LarkCalendar class enables creating, searching, and querying calendar events with full timezone support. ```python from larkpy import LarkCalendar import datetime # Initialize calendar client calendar = LarkCalendar( app_id="cli_your_app_id", app_secret="your_app_secret", calendar_id="feishu.cn_XXXXX@group.calendar.feishu.cn" ) # Query available calendars calendars = calendar.query_calendar_list() for cal in calendars: print(f"{cal['calendar_id']}: {cal['summary']}") # Create a new event start = datetime.datetime(2024, 3, 15, 14, 0) end = datetime.datetime(2024, 3, 15, 15, 30) response = calendar.create_event( start_time=start, end_time=end, summary="Team Meeting", description="Weekly sync meeting\n- Review progress\n- Plan next sprint", visibility="default", free_busy_status="busy", location={"name": "Conference Room A", "address": "Building 1, Floor 3"}, reminders=[{"minutes": 15}, {"minutes": 5}], timezone="Asia/Shanghai" ) print(response.json()) # Output: {'code': 0, 'data': {'event': {'event_id': 'XXXXX', ...}}} # Create all-day event calendar.create_event( start_time=datetime.datetime(2024, 3, 20), end_time=datetime.datetime(2024, 3, 21), summary="Company Holiday", whole_day=True ) # Create recurring event calendar.create_event( start_time=start, end_time=end, summary="Daily Standup", recurrence="FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR" ) # Search events by time range response = calendar.search_event( start_time=datetime.datetime(2024, 3, 1), end_time=datetime.datetime(2024, 3, 31), page_size=50 ) events = response.json()['data']['items'] # Query events with keyword search response = calendar.query_event( query="meeting", start_time=datetime.datetime(2024, 3, 1), end_time=datetime.datetime(2024, 3, 31), timezone="Asia/Shanghai" ) ``` ## LarkRequests - Browser-based Requests The LarkRequests class enables accessing Lark endpoints that require browser authentication using cookies, useful for personal workspace operations. ```python from larkpy import LarkRequests # Initialize with browser cookie cookie = "session=xxx; _csrf_token=xxx; ..." lark_req = LarkRequests(cookie=cookie) # Get recent files from Lark space response = lark_req.space_recent( length=20, obj_types=[2, 22, 44, 3, 30, 8, 11, 12, 84] # Different doc types ) data = response.json() if data['code'] == 0: node_list = data['data']['node_list'] nodes = data['data']['entities']['nodes'] for node_id in node_list[:5]: node_info = nodes[node_id] print(f"Name: {node_info['name']}") print(f"Type: {node_info['type']}") print(f"URL: {node_info['url']}") print(f"Last opened: {node_info['open_time']}") print("---") # Output: # Name: Project Roadmap # Type: 22 # URL: https://xxx.feishu.cn/docx/xxx # Last opened: 1710234567 # --- ``` ## CardElementGenerator - Card Element Builder The CardElementGenerator class provides utility methods for building Lark card elements, including markdown, tables, buttons, and images. ```python from larkpy import CardElementGenerator, LarkWebhook import pandas as pd # Create markdown element md_element = CardElementGenerator.markdown( "**Status**: Online\n*Last updated*: 2024-03-15" ) # Create horizontal rule hr = CardElementGenerator.hr() # Create button button = CardElementGenerator.button( text="View Details", url="https://example.com/details" ) # Create image element image = CardElementGenerator.image( image_key="img_v2_xxxxx", alt="Chart preview", width="300px", height="200px" ) # Create table from DataFrame df = pd.DataFrame({ "Task": ["Build", "Test", "Deploy"], "Status": ["Done", "Running", "Pending"], "Duration": [120, 45, 0] }) table_element = CardElementGenerator.table_card( df, page_size=5, row_height="low", freeze_first_column=True, header_style={ "text_align": "center", "bold": True, "background_style": "grey" } ) # Combine elements into a card webhook = LarkWebhook("https://open.feishu.cn/open-apis/bot/v2/hook/xxx") webhook.send_card( content=[md_element, hr, table_element, button], title="Build Pipeline Status", template="blue" ) ``` ## Summary larkpy provides a complete toolkit for integrating Python applications with the Lark/Feishu platform. The webhook-based messaging enables quick setup for bot notifications and alerts, while the OAuth-based API clients offer full access to documents, tables, calendars, and instant messaging. The pandas DataFrame integration with Bitable makes it particularly useful for data-driven applications and automated reporting workflows. Common integration patterns include: automated deployment notifications using LarkWebhook, data synchronization between external systems and Bitable using LarkBitTable, document automation with LarkDocx for generating reports, calendar integration for scheduling and event management, and building interactive bot experiences with LarkMessage's card and reaction features. The SDK's modular design allows developers to use only the components they need while maintaining consistent authentication and request handling across all services.