a digital person for bluesky
1#!/usr/bin/env python3
2"""
3Centralized script for retrieving Bluesky post threads from URIs.
4Includes YAML-ified string conversion for easy LLM parsing.
5"""
6
7import argparse
8import sys
9import logging
10from typing import Optional, Dict, Any
11import yaml
12from bsky_utils import default_login, thread_to_yaml_string
13
14# Configure logging
15logging.basicConfig(
16 level=logging.INFO,
17 format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
18)
19logger = logging.getLogger("get_thread")
20
21
22def get_thread_from_uri(uri: str) -> Optional[Dict[str, Any]]:
23 """
24 Retrieve a post thread from a Bluesky URI.
25
26 Args:
27 uri: The Bluesky post URI (e.g., at://did:plc:xyz/app.bsky.feed.post/abc123)
28
29 Returns:
30 Thread data or None if retrieval failed
31 """
32 try:
33 client = default_login()
34 logger.info(f"Fetching thread for URI: {uri}")
35
36 thread = client.app.bsky.feed.get_post_thread({'uri': uri, 'parent_height': 80, 'depth': 10})
37 return thread
38
39 except Exception as e:
40 logger.error(f"Error retrieving thread for URI {uri}: {e}")
41 return None
42
43
44# thread_to_yaml_string is now imported from bsky_utils
45
46
47def main():
48 """Main CLI interface for the thread retrieval script."""
49 parser = argparse.ArgumentParser(
50 description="Retrieve and display Bluesky post threads",
51 formatter_class=argparse.RawDescriptionHelpFormatter,
52 epilog="""
53Examples:
54 python get_thread.py at://did:plc:xyz/app.bsky.feed.post/abc123
55 python get_thread.py --raw at://did:plc:xyz/app.bsky.feed.post/abc123
56 python get_thread.py --output thread.yaml at://did:plc:xyz/app.bsky.feed.post/abc123
57 """
58 )
59
60 parser.add_argument(
61 "uri",
62 help="Bluesky post URI to retrieve thread for"
63 )
64
65 parser.add_argument(
66 "--raw",
67 action="store_true",
68 help="Include all metadata fields (don't strip for LLM parsing)"
69 )
70
71 parser.add_argument(
72 "--output", "-o",
73 help="Output file to write YAML to (default: stdout)"
74 )
75
76 parser.add_argument(
77 "--quiet", "-q",
78 action="store_true",
79 help="Suppress info logging"
80 )
81
82 args = parser.parse_args()
83
84 if args.quiet:
85 logging.getLogger().setLevel(logging.ERROR)
86
87 # Retrieve the thread
88 thread = get_thread_from_uri(args.uri)
89
90 if thread is None:
91 logger.error("Failed to retrieve thread")
92 sys.exit(1)
93
94 # Convert to YAML
95 yaml_output = thread_to_yaml_string(thread, strip_metadata=not args.raw)
96
97 # Output the result
98 if args.output:
99 try:
100 with open(args.output, 'w', encoding='utf-8') as f:
101 f.write(yaml_output)
102 logger.info(f"Thread saved to {args.output}")
103 except Exception as e:
104 logger.error(f"Error writing to file {args.output}: {e}")
105 sys.exit(1)
106 else:
107 print(yaml_output)
108
109
110if __name__ == "__main__":
111 main()