pxcli 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pxcli-0.3.0/PKG-INFO +746 -0
- pxcli-0.3.0/README.md +707 -0
- pxcli-0.3.0/pyproject.toml +98 -0
- pxcli-0.3.0/setup.cfg +4 -0
- pxcli-0.3.0/src/perplexity_cli/__init__.py +3 -0
- pxcli-0.3.0/src/perplexity_cli/api/__init__.py +15 -0
- pxcli-0.3.0/src/perplexity_cli/api/client.py +182 -0
- pxcli-0.3.0/src/perplexity_cli/api/endpoints.py +176 -0
- pxcli-0.3.0/src/perplexity_cli/api/models.py +181 -0
- pxcli-0.3.0/src/perplexity_cli/auth/__init__.py +15 -0
- pxcli-0.3.0/src/perplexity_cli/auth/oauth_handler.py +299 -0
- pxcli-0.3.0/src/perplexity_cli/auth/token_manager.py +172 -0
- pxcli-0.3.0/src/perplexity_cli/cli.py +861 -0
- pxcli-0.3.0/src/perplexity_cli/formatting/__init__.py +31 -0
- pxcli-0.3.0/src/perplexity_cli/formatting/base.py +69 -0
- pxcli-0.3.0/src/perplexity_cli/formatting/json.py +76 -0
- pxcli-0.3.0/src/perplexity_cli/formatting/markdown.py +89 -0
- pxcli-0.3.0/src/perplexity_cli/formatting/plain.py +127 -0
- pxcli-0.3.0/src/perplexity_cli/formatting/registry.py +83 -0
- pxcli-0.3.0/src/perplexity_cli/formatting/rich.py +221 -0
- pxcli-0.3.0/src/perplexity_cli/resources/skill.md +345 -0
- pxcli-0.3.0/src/perplexity_cli/threads/__init__.py +7 -0
- pxcli-0.3.0/src/perplexity_cli/threads/cache_manager.py +367 -0
- pxcli-0.3.0/src/perplexity_cli/threads/date_parser.py +139 -0
- pxcli-0.3.0/src/perplexity_cli/threads/exporter.py +85 -0
- pxcli-0.3.0/src/perplexity_cli/threads/scraper.py +348 -0
- pxcli-0.3.0/src/perplexity_cli/utils/__init__.py +1 -0
- pxcli-0.3.0/src/perplexity_cli/utils/config.py +303 -0
- pxcli-0.3.0/src/perplexity_cli/utils/encryption.py +94 -0
- pxcli-0.3.0/src/perplexity_cli/utils/logging.py +85 -0
- pxcli-0.3.0/src/perplexity_cli/utils/rate_limiter.py +132 -0
- pxcli-0.3.0/src/perplexity_cli/utils/retry.py +110 -0
- pxcli-0.3.0/src/perplexity_cli/utils/style_manager.py +94 -0
- pxcli-0.3.0/src/perplexity_cli/utils/version.py +72 -0
- pxcli-0.3.0/src/pxcli.egg-info/PKG-INFO +746 -0
- pxcli-0.3.0/src/pxcli.egg-info/SOURCES.txt +57 -0
- pxcli-0.3.0/src/pxcli.egg-info/dependency_links.txt +1 -0
- pxcli-0.3.0/src/pxcli.egg-info/entry_points.txt +3 -0
- pxcli-0.3.0/src/pxcli.egg-info/requires.txt +15 -0
- pxcli-0.3.0/src/pxcli.egg-info/top_level.txt +1 -0
- pxcli-0.3.0/tests/test_api_client.py +277 -0
- pxcli-0.3.0/tests/test_api_integration.py +118 -0
- pxcli-0.3.0/tests/test_auth.py +255 -0
- pxcli-0.3.0/tests/test_auth_integration.py +197 -0
- pxcli-0.3.0/tests/test_chrome_connection.py +85 -0
- pxcli-0.3.0/tests/test_cli.py +376 -0
- pxcli-0.3.0/tests/test_config_improvements.py +109 -0
- pxcli-0.3.0/tests/test_encryption.py +154 -0
- pxcli-0.3.0/tests/test_endpoints.py +188 -0
- pxcli-0.3.0/tests/test_formatters.py +338 -0
- pxcli-0.3.0/tests/test_logging.py +51 -0
- pxcli-0.3.0/tests/test_manual_auth.py +319 -0
- pxcli-0.3.0/tests/test_models.py +204 -0
- pxcli-0.3.0/tests/test_query_realtime.py +64 -0
- pxcli-0.3.0/tests/test_query_simple.py +41 -0
- pxcli-0.3.0/tests/test_retry.py +67 -0
- pxcli-0.3.0/tests/test_style_manager.py +190 -0
- pxcli-0.3.0/tests/test_thread_cache.py +436 -0
- pxcli-0.3.0/tests/test_version.py +29 -0
pxcli-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,746 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pxcli
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: A command-line interface for querying Perplexity.ai with persistent authentication
|
|
5
|
+
Author-email: Jamie Mills <jamie.mills@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/jamiemills/perplexity-cli
|
|
8
|
+
Project-URL: Repository, https://github.com/jamiemills/perplexity-cli
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/jamiemills/perplexity-cli/issues
|
|
10
|
+
Project-URL: Source Code, https://github.com/jamiemills/perplexity-cli
|
|
11
|
+
Keywords: cli,perplexity,ai,query,command-line
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Topic :: Utilities
|
|
23
|
+
Requires-Python: >=3.12
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
Requires-Dist: click>=8.0
|
|
26
|
+
Requires-Dist: cryptography>=41.0
|
|
27
|
+
Requires-Dist: httpx>=0.25
|
|
28
|
+
Requires-Dist: websockets>=12.0
|
|
29
|
+
Requires-Dist: rich>=13.0
|
|
30
|
+
Requires-Dist: tenacity>=8.0
|
|
31
|
+
Requires-Dist: python-dateutil>=2.8.0
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest-mock>=3.0; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest-cov>=7.0; extra == "dev"
|
|
36
|
+
Requires-Dist: pytest-asyncio>=1.2.0; extra == "dev"
|
|
37
|
+
Requires-Dist: ruff>=0.1; extra == "dev"
|
|
38
|
+
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
39
|
+
|
|
40
|
+
# Perplexity CLI
|
|
41
|
+
|
|
42
|
+
A command-line interface for querying Perplexity.ai with persistent authentication and encrypted token storage.
|
|
43
|
+
|
|
44
|
+
[](https://pypi.org/project/pxcli/)
|
|
45
|
+
|
|
46
|
+
## Features
|
|
47
|
+
|
|
48
|
+
- **Persistent authentication** - Token stored securely and reused across invocations
|
|
49
|
+
- **Encrypted tokens** - Tokens encrypted with system-derived keys
|
|
50
|
+
- **Multiple output formats** - Plain text, Markdown, or rich terminal output
|
|
51
|
+
- **Source references** - Web sources extracted and displayed
|
|
52
|
+
- **Thread library export** - Export your entire Perplexity thread history to CSV with timestamps
|
|
53
|
+
- **Date filtering** - Filter exported threads by date range
|
|
54
|
+
- **Configurable URLs** - Base URL and endpoints configurable via JSON or environment variables
|
|
55
|
+
- **Error handling** - Clear error messages with exit codes and automatic retry logic
|
|
56
|
+
- **Server-Sent Events** - Streams responses in real-time
|
|
57
|
+
- **Logging** - Configurable logging with verbose/debug modes and log file support
|
|
58
|
+
- **Streaming output** - Real-time streaming of query responses as they arrive
|
|
59
|
+
|
|
60
|
+
## Installation
|
|
61
|
+
|
|
62
|
+
### Quick Install (Recommended for Users)
|
|
63
|
+
|
|
64
|
+
The easiest way to use pxcli is with `uvx`:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
uvx pxcli auth
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Or install with uv pip:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
uv pip install pxcli
|
|
74
|
+
pxcli auth
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Note: The command can also be run as `perplexity-cli` for convenience.
|
|
78
|
+
|
|
79
|
+
### Development Installation (For Contributors)
|
|
80
|
+
|
|
81
|
+
Clone and set up development environment:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
git clone https://github.com/jamiemills/perplexity-cli.git
|
|
85
|
+
cd perplexity-cli
|
|
86
|
+
uv venv --python=3.12
|
|
87
|
+
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
|
88
|
+
uv pip install -e ".[dev]"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Run tests to verify setup:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
pytest
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Prerequisites
|
|
98
|
+
|
|
99
|
+
- Python 3.12 or higher
|
|
100
|
+
- Google Chrome (for authentication)
|
|
101
|
+
|
|
102
|
+
## Quick Start
|
|
103
|
+
|
|
104
|
+
### Authenticate (One Time)
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
perplexity-cli auth
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
This opens your browser to authenticate with Perplexity.ai. Your token is encrypted and stored locally.
|
|
111
|
+
|
|
112
|
+
### Ask a Question
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
perplexity-cli query "What is Python?"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Check Status
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
perplexity-cli status
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Output Formats
|
|
125
|
+
|
|
126
|
+
Query with JSON output:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
perplexity-cli query "Explain machine learning" --format json
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Verbose Mode
|
|
133
|
+
|
|
134
|
+
Get detailed logging:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
perplexity-cli query "What is AI?" --verbose
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Log Out
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
perplexity-cli logout
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Configuration
|
|
147
|
+
|
|
148
|
+
### Environment Variables
|
|
149
|
+
|
|
150
|
+
Configure perplexity-cli with environment variables:
|
|
151
|
+
|
|
152
|
+
- `PERPLEXITY_BASE_URL`: Custom API base URL (default: https://www.perplexity.ai)
|
|
153
|
+
- `PERPLEXITY_QUERY_ENDPOINT`: Custom query endpoint
|
|
154
|
+
- `PERPLEXITY_LOG_LEVEL`: Logging level - DEBUG, INFO, WARNING, ERROR (default: INFO)
|
|
155
|
+
- `PERPLEXITY_LOG_FILE`: Path to log file (default: ~/.config/perplexity-cli/perplexity-cli.log)
|
|
156
|
+
- `PERPLEXITY_RATE_LIMITING_ENABLED`: Enable/disable rate limiting (default: true)
|
|
157
|
+
- `PERPLEXITY_RATE_LIMITING_RPS`: Requests per period (default: 20)
|
|
158
|
+
- `PERPLEXITY_RATE_LIMITING_PERIOD`: Period in seconds (default: 60)
|
|
159
|
+
|
|
160
|
+
Example:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
export PERPLEXITY_LOG_LEVEL=DEBUG
|
|
164
|
+
perplexity-cli query "test"
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Output Formats
|
|
168
|
+
|
|
169
|
+
Available formats: `plain`, `markdown`, `rich`, `json`
|
|
170
|
+
|
|
171
|
+
Default is `rich` for terminal output with formatting. Use `--format` flag:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
perplexity-cli query "..." --format markdown
|
|
175
|
+
perplexity-cli query "..." --format json
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Token Management
|
|
179
|
+
|
|
180
|
+
Your authentication token is encrypted and stored at:
|
|
181
|
+
- **Linux/macOS**: `~/.config/perplexity-cli/token.json`
|
|
182
|
+
- **Windows**: `%APPDATA%\perplexity-cli\token.json`
|
|
183
|
+
|
|
184
|
+
The token is encrypted using Fernet (AES-128-CBC) with a key derived from your system hostname and OS user. Tokens are not portable between machines.
|
|
185
|
+
|
|
186
|
+
To re-authenticate:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
perplexity-cli logout
|
|
190
|
+
perplexity-cli auth
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Usage
|
|
194
|
+
|
|
195
|
+
### Authentication Setup
|
|
196
|
+
|
|
197
|
+
The first time you use perplexity-cli, you need to authenticate with Perplexity.ai. This is a one-time process that extracts your session token and stores it securely on your machine.
|
|
198
|
+
|
|
199
|
+
#### Step 1: Install Chrome for Testing
|
|
200
|
+
|
|
201
|
+
Download a dedicated Chrome browser for authentication (this keeps testing separate from your main Chrome instance):
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
npx @puppeteer/browsers install chrome@stable
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
This downloads Chrome to `~/.local/bin/chrome/` (the path may change between Chrome versions).
|
|
208
|
+
|
|
209
|
+
#### Step 2: Create a Shell Alias
|
|
210
|
+
|
|
211
|
+
Set up an alias to easily run Chrome with remote debugging enabled:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
# Add this line to your shell config (~/.bashrc, ~/.zshrc, etc.)
|
|
215
|
+
alias chromefortesting='open ~/.local/bin/chrome/mac_arm-*/chrome-mac-arm64/Google\ Chrome\ for\ Testing.app --args "--remote-debugging-port=9222" "about:blank"'
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Note:** The `mac_arm-*` pattern matches the version directory. The exact path varies by Chrome version.
|
|
219
|
+
|
|
220
|
+
#### Step 3: Start Chrome and Authenticate
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
# Terminal 1: Start Chrome with debugging enabled
|
|
224
|
+
chromefortesting
|
|
225
|
+
|
|
226
|
+
# Terminal 2: Run authentication
|
|
227
|
+
perplexity-cli auth
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
The authentication process will:
|
|
231
|
+
1. Connect to Chrome via the remote debugging port
|
|
232
|
+
2. Navigate to Perplexity.ai
|
|
233
|
+
3. Wait for you to log in (you'll see the login page in Chrome)
|
|
234
|
+
4. Extract your session token automatically
|
|
235
|
+
5. Save it encrypted to `~/.config/perplexity-cli/token.json`
|
|
236
|
+
|
|
237
|
+
Once complete, you won't need to authenticate again unless you run `perplexity-cli logout`.
|
|
238
|
+
|
|
239
|
+
#### Custom Port (Optional)
|
|
240
|
+
|
|
241
|
+
If port 9222 is already in use, specify a different port:
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
perplexity-cli auth --port 9223
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Then start Chrome with the matching port:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
alias chromefortesting='open ~/.local/bin/chrome/mac_arm-*/chrome-mac-arm64/Google\ Chrome\ for\ Testing.app --args "--remote-debugging-port=9223" "about:blank"'
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Query Perplexity
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
# Default format (rich terminal output)
|
|
257
|
+
perplexity-cli query "What is machine learning?"
|
|
258
|
+
|
|
259
|
+
# Plain text (for scripts)
|
|
260
|
+
perplexity-cli query --format plain "What is Python?"
|
|
261
|
+
|
|
262
|
+
# Markdown format
|
|
263
|
+
perplexity-cli query --format markdown "Explain quantum computing" > answer.md
|
|
264
|
+
|
|
265
|
+
# JSON format (structured output for programmatic use)
|
|
266
|
+
perplexity-cli query --format json "What is machine learning?" > answer.json
|
|
267
|
+
|
|
268
|
+
# Remove citations and references section
|
|
269
|
+
perplexity-cli query --strip-references "What is Python?"
|
|
270
|
+
|
|
271
|
+
# Stream response in real-time
|
|
272
|
+
perplexity-cli query --stream "What is Python?"
|
|
273
|
+
|
|
274
|
+
# Combine options
|
|
275
|
+
perplexity-cli query --format plain --strip-references "What is 2+2?"
|
|
276
|
+
|
|
277
|
+
# Use in scripts
|
|
278
|
+
ANSWER=$(perplexity-cli query --format plain "What is 2+2?")
|
|
279
|
+
echo "The answer is: $ANSWER"
|
|
280
|
+
|
|
281
|
+
# Enable verbose logging
|
|
282
|
+
perplexity-cli --verbose query "What is Python?"
|
|
283
|
+
|
|
284
|
+
# Enable debug logging with custom log file
|
|
285
|
+
perplexity-cli --debug --log-file /tmp/perplexity.log query "What is Python?"
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Status and Logout
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
# Check authentication status
|
|
292
|
+
perplexity-cli status
|
|
293
|
+
|
|
294
|
+
# Remove stored token
|
|
295
|
+
perplexity-cli logout
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## Commands
|
|
299
|
+
|
|
300
|
+
### `perplexity-cli auth [--port PORT]`
|
|
301
|
+
|
|
302
|
+
Authenticate with Perplexity.ai via Chrome.
|
|
303
|
+
|
|
304
|
+
**Options:**
|
|
305
|
+
- `--port PORT` - Chrome remote debugging port (default: 9222)
|
|
306
|
+
|
|
307
|
+
### `perplexity-cli query QUESTION [OPTIONS]`
|
|
308
|
+
|
|
309
|
+
Submit a query and get an answer with source references.
|
|
310
|
+
|
|
311
|
+
**Arguments:**
|
|
312
|
+
- `QUESTION` - Your question (quoted)
|
|
313
|
+
|
|
314
|
+
**Options:**
|
|
315
|
+
- `--format {plain,markdown,rich,json}` - Output format (default: rich)
|
|
316
|
+
- `plain` - Plain text, suitable for scripts
|
|
317
|
+
- `markdown` - GitHub-flavoured Markdown
|
|
318
|
+
- `rich` - Terminal output with colours and formatting
|
|
319
|
+
- `json` - Structured JSON with answer and references
|
|
320
|
+
- `--strip-references` - Remove citations and references section
|
|
321
|
+
- `--stream` - Stream response in real-time as it arrives (experimental)
|
|
322
|
+
|
|
323
|
+
**Global Options:**
|
|
324
|
+
- `--verbose, -v` - Enable verbose output (INFO level logging)
|
|
325
|
+
- `--debug, -d` - Enable debug output (DEBUG level logging)
|
|
326
|
+
- `--log-file PATH` - Write logs to file (default: ~/.config/perplexity-cli/perplexity-cli.log)
|
|
327
|
+
|
|
328
|
+
**Exit codes:**
|
|
329
|
+
- `0` - Success
|
|
330
|
+
- `1` - Error
|
|
331
|
+
|
|
332
|
+
### `perplexity-cli status`
|
|
333
|
+
|
|
334
|
+
Display authentication status and token information.
|
|
335
|
+
|
|
336
|
+
### `perplexity-cli logout`
|
|
337
|
+
|
|
338
|
+
Remove stored authentication token.
|
|
339
|
+
|
|
340
|
+
### `perplexity-cli configure STYLE`
|
|
341
|
+
|
|
342
|
+
Set a custom style prompt applied to all queries.
|
|
343
|
+
|
|
344
|
+
**Example:**
|
|
345
|
+
```bash
|
|
346
|
+
perplexity-cli configure "be concise"
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### `perplexity-cli view-style`
|
|
350
|
+
|
|
351
|
+
Display currently configured style.
|
|
352
|
+
|
|
353
|
+
### `perplexity-cli clear-style`
|
|
354
|
+
|
|
355
|
+
Remove configured style.
|
|
356
|
+
|
|
357
|
+
### `perplexity-cli export-threads [OPTIONS]`
|
|
358
|
+
|
|
359
|
+
Export your Perplexity.ai thread library to CSV format with creation timestamps.
|
|
360
|
+
|
|
361
|
+
Uses your stored authentication token - no browser required after initial auth setup!
|
|
362
|
+
|
|
363
|
+
**Options:**
|
|
364
|
+
- `--from-date DATE` - Start date for filtering (YYYY-MM-DD format, inclusive)
|
|
365
|
+
- `--to-date DATE` - End date for filtering (YYYY-MM-DD format, inclusive)
|
|
366
|
+
- `--output PATH` - Output CSV file path (default: threads-TIMESTAMP.csv)
|
|
367
|
+
- `--force-refresh` - Ignore local cache and fetch fresh data from Perplexity API
|
|
368
|
+
- `--clear-cache` - Delete local cache file before export
|
|
369
|
+
|
|
370
|
+
**Examples:**
|
|
371
|
+
```bash
|
|
372
|
+
# Export all threads (uses cache if available)
|
|
373
|
+
perplexity-cli export-threads
|
|
374
|
+
|
|
375
|
+
# Export threads from 2025
|
|
376
|
+
perplexity-cli export-threads --from-date 2025-01-01
|
|
377
|
+
|
|
378
|
+
# Export threads from a specific date range
|
|
379
|
+
perplexity-cli export-threads --from-date 2025-01-01 --to-date 2025-12-31
|
|
380
|
+
|
|
381
|
+
# Export to custom file
|
|
382
|
+
perplexity-cli export-threads --output my-threads.csv
|
|
383
|
+
|
|
384
|
+
# Force fresh data from API (bypass cache)
|
|
385
|
+
perplexity-cli export-threads --force-refresh
|
|
386
|
+
|
|
387
|
+
# Clear cache and export fresh
|
|
388
|
+
perplexity-cli export-threads --clear-cache
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
**Setup:**
|
|
392
|
+
Just authenticate once with `perplexity-cli auth` - the export command reuses your stored token. No browser needed!
|
|
393
|
+
|
|
394
|
+
**Output format:**
|
|
395
|
+
```csv
|
|
396
|
+
created_at,title,url
|
|
397
|
+
2025-12-23T23:06:00.525132Z,What is Python?,https://www.perplexity.ai/search/...
|
|
398
|
+
2025-12-22T20:54:36.349239Z,Explain AI,https://www.perplexity.ai/search/...
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
The export includes:
|
|
402
|
+
- **created_at** - ISO 8601 timestamp with timezone (UTC)
|
|
403
|
+
- **title** - Thread question/title
|
|
404
|
+
- **url** - Full URL to the thread
|
|
405
|
+
|
|
406
|
+
**How it works:**
|
|
407
|
+
The command uses your stored authentication token to call the Perplexity.ai API directly. It automatically paginates through your entire library (handles thousands of threads) and exports the results to CSV.
|
|
408
|
+
|
|
409
|
+
**Caching:**
|
|
410
|
+
Thread exports are automatically cached locally to improve performance. On first export, all threads are fetched and cached. On subsequent exports, the cache is used unless:
|
|
411
|
+
- Requested date range extends beyond cached data (smart partial updates only fetch the gap)
|
|
412
|
+
- `--force-refresh` flag is used to bypass cache
|
|
413
|
+
- Cache is cleared with `--clear-cache` flag
|
|
414
|
+
|
|
415
|
+
The cache is encrypted with the same system-derived key as your auth token and stored at `~/.config/perplexity-cli/threads-cache.json`.
|
|
416
|
+
|
|
417
|
+
## Configuration
|
|
418
|
+
|
|
419
|
+
### Token Storage and Encryption
|
|
420
|
+
|
|
421
|
+
Tokens are stored encrypted at `~/.config/perplexity-cli/token.json` (Linux/macOS) or `%APPDATA%\perplexity-cli\token.json` (Windows).
|
|
422
|
+
|
|
423
|
+
**Encryption:**
|
|
424
|
+
- Uses Fernet symmetric encryption (AES-128-CBC)
|
|
425
|
+
- Key derived from system hostname and OS user
|
|
426
|
+
- Tokens not portable between machines
|
|
427
|
+
- No user passwords required
|
|
428
|
+
|
|
429
|
+
**Format:**
|
|
430
|
+
```json
|
|
431
|
+
{
|
|
432
|
+
"version": 1,
|
|
433
|
+
"encrypted": true,
|
|
434
|
+
"token": "encrypted_token_data"
|
|
435
|
+
}
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
**File permissions:** 0600 (owner read/write only)
|
|
439
|
+
|
|
440
|
+
### URL Configuration
|
|
441
|
+
|
|
442
|
+
Perplexity URLs are configured in `~/.config/perplexity-cli/urls.json`.
|
|
443
|
+
|
|
444
|
+
**Default configuration:**
|
|
445
|
+
```json
|
|
446
|
+
{
|
|
447
|
+
"perplexity": {
|
|
448
|
+
"base_url": "https://www.perplexity.ai",
|
|
449
|
+
"query_endpoint": "https://www.perplexity.ai/rest/sse/perplexity_ask"
|
|
450
|
+
},
|
|
451
|
+
"rate_limiting": {
|
|
452
|
+
"enabled": true,
|
|
453
|
+
"requests_per_period": 20,
|
|
454
|
+
"period_seconds": 60,
|
|
455
|
+
"description": "Allow 20 requests per 60 seconds (~3s delay). Override via env vars or edit this file."
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
To use alternative URLs, edit this file. Configuration is automatically created on first run.
|
|
461
|
+
|
|
462
|
+
**Environment Variables:**
|
|
463
|
+
|
|
464
|
+
You can override configuration values using environment variables:
|
|
465
|
+
- `PERPLEXITY_BASE_URL` - Overrides `perplexity.base_url`
|
|
466
|
+
- `PERPLEXITY_QUERY_ENDPOINT` - Overrides `perplexity.query_endpoint`
|
|
467
|
+
|
|
468
|
+
Example:
|
|
469
|
+
```bash
|
|
470
|
+
export PERPLEXITY_BASE_URL="https://custom.example.com"
|
|
471
|
+
perplexity-cli query "What is Python?"
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### Rate Limiting Configuration
|
|
475
|
+
|
|
476
|
+
Thread export operations are rate-limited by default to prevent overwhelming the Perplexity API and encountering 429 (Too Many Requests) errors.
|
|
477
|
+
|
|
478
|
+
**Default Rate Limit:**
|
|
479
|
+
- 20 requests per 60 seconds
|
|
480
|
+
- Approximately 3 second delay between API requests
|
|
481
|
+
- Safe for exporting libraries with thousands of threads
|
|
482
|
+
|
|
483
|
+
**Adjust Rate Limiting:**
|
|
484
|
+
|
|
485
|
+
Edit `~/.config/perplexity-cli/urls.json` and modify the `rate_limiting` section:
|
|
486
|
+
|
|
487
|
+
```json
|
|
488
|
+
{
|
|
489
|
+
"rate_limiting": {
|
|
490
|
+
"enabled": true,
|
|
491
|
+
"requests_per_period": 20,
|
|
492
|
+
"period_seconds": 60
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
**Common Configurations:**
|
|
498
|
+
|
|
499
|
+
```json
|
|
500
|
+
{
|
|
501
|
+
"rate_limiting": {
|
|
502
|
+
"enabled": true,
|
|
503
|
+
"requests_per_period": 10,
|
|
504
|
+
"period_seconds": 60,
|
|
505
|
+
"description": "Conservative: ~6 second delay (10 requests/60s). Use if encountering rate limits."
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
```json
|
|
511
|
+
{
|
|
512
|
+
"rate_limiting": {
|
|
513
|
+
"enabled": true,
|
|
514
|
+
"requests_per_period": 30,
|
|
515
|
+
"period_seconds": 60,
|
|
516
|
+
"description": "Aggressive: ~2 second delay (30 requests/60s). Use for faster exports."
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
```json
|
|
522
|
+
{
|
|
523
|
+
"rate_limiting": {
|
|
524
|
+
"enabled": false,
|
|
525
|
+
"description": "Disabled: No rate limiting (not recommended, may hit API limits)."
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
**Environment Variable Overrides:**
|
|
531
|
+
|
|
532
|
+
You can override rate limiting settings without editing the config file:
|
|
533
|
+
|
|
534
|
+
- `PERPLEXITY_RATE_LIMITING_ENABLED` - Set to "true" or "false"
|
|
535
|
+
- `PERPLEXITY_RATE_LIMITING_RPS` - requests_per_period (e.g., "10")
|
|
536
|
+
- `PERPLEXITY_RATE_LIMITING_PERIOD` - period_seconds (e.g., "60")
|
|
537
|
+
|
|
538
|
+
Example:
|
|
539
|
+
```bash
|
|
540
|
+
# Disable rate limiting for a single export
|
|
541
|
+
export PERPLEXITY_RATE_LIMITING_ENABLED=false
|
|
542
|
+
perplexity-cli export-threads
|
|
543
|
+
|
|
544
|
+
# Use conservative rate limiting (10 requests/minute)
|
|
545
|
+
export PERPLEXITY_RATE_LIMITING_RPS=10
|
|
546
|
+
export PERPLEXITY_RATE_LIMITING_PERIOD=60
|
|
547
|
+
perplexity-cli export-threads
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
## Troubleshooting
|
|
551
|
+
|
|
552
|
+
### "Not authenticated"
|
|
553
|
+
|
|
554
|
+
Run `perplexity-cli auth` to authenticate.
|
|
555
|
+
|
|
556
|
+
### "Failed to decrypt token"
|
|
557
|
+
|
|
558
|
+
Token was encrypted on a different machine or with a different user. Run `perplexity-cli auth` to re-authenticate.
|
|
559
|
+
|
|
560
|
+
### Chrome connection fails
|
|
561
|
+
|
|
562
|
+
Ensure Chrome is running with `--remote-debugging-port=9222`. Verify the port matches the one you specified.
|
|
563
|
+
|
|
564
|
+
### Token file has insecure permissions
|
|
565
|
+
|
|
566
|
+
Token file was modified or has incorrect permissions. Delete the file and re-authenticate:
|
|
567
|
+
```bash
|
|
568
|
+
rm ~/.config/perplexity-cli/token.json
|
|
569
|
+
perplexity-cli auth
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
## Output Formats
|
|
573
|
+
|
|
574
|
+
### Plain
|
|
575
|
+
|
|
576
|
+
Plain text output suitable for scripts and piping.
|
|
577
|
+
|
|
578
|
+
```bash
|
|
579
|
+
perplexity-cli query --format plain "What is Python?"
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
### Markdown
|
|
583
|
+
|
|
584
|
+
GitHub-flavoured Markdown with headers and formatting.
|
|
585
|
+
|
|
586
|
+
```bash
|
|
587
|
+
perplexity-cli query --format markdown "Explain AI" > answer.md
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
### Rich
|
|
591
|
+
|
|
592
|
+
Terminal output with colours, bold text, and formatted tables (default).
|
|
593
|
+
|
|
594
|
+
```bash
|
|
595
|
+
perplexity-cli query "What is Python?"
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
### JSON
|
|
599
|
+
|
|
600
|
+
Structured JSON output suitable for programmatic processing and integration with other tools.
|
|
601
|
+
|
|
602
|
+
```bash
|
|
603
|
+
perplexity-cli query --format json "What is machine learning?"
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
**Output structure:**
|
|
607
|
+
```json
|
|
608
|
+
{
|
|
609
|
+
"format_version": "1.0",
|
|
610
|
+
"answer": "Machine learning is a subfield of artificial intelligence...",
|
|
611
|
+
"references": [
|
|
612
|
+
{
|
|
613
|
+
"index": 1,
|
|
614
|
+
"title": "Machine learning, explained | MIT Sloan",
|
|
615
|
+
"url": "https://mitsloan.mit.edu/ideas-made-to-matter/machine-learning-explained",
|
|
616
|
+
"snippet": "Machine learning is a powerful form of artificial intelligence..."
|
|
617
|
+
}
|
|
618
|
+
]
|
|
619
|
+
}
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
**Use cases:**
|
|
623
|
+
- Parse responses programmatically in scripts or applications
|
|
624
|
+
- Save structured data for later analysis
|
|
625
|
+
- Integrate with data pipelines
|
|
626
|
+
- Extract references for citation management
|
|
627
|
+
- Process answers through additional tools or APIs
|
|
628
|
+
|
|
629
|
+
**Examples:**
|
|
630
|
+
|
|
631
|
+
Save to file:
|
|
632
|
+
```bash
|
|
633
|
+
perplexity-cli query --format json "What is Python?" > python.json
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
Extract and display answer as readable text:
|
|
637
|
+
```bash
|
|
638
|
+
# Use jq -r to render newlines as actual line breaks
|
|
639
|
+
perplexity-cli query --format json "What is Python?" | jq -r '.answer'
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
Extract just the reference URLs:
|
|
643
|
+
```bash
|
|
644
|
+
perplexity-cli query --format json "What is Python?" | jq -r '.references[] | .url'
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
Remove references from JSON output:
|
|
648
|
+
```bash
|
|
649
|
+
perplexity-cli query --format json --strip-references "What is Python?"
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
Count the number of references:
|
|
653
|
+
```bash
|
|
654
|
+
perplexity-cli query --format json "What is Python?" | jq '.references | length'
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
Parse JSON in a script:
|
|
658
|
+
```bash
|
|
659
|
+
python3 << 'EOF'
|
|
660
|
+
import json
|
|
661
|
+
import subprocess
|
|
662
|
+
|
|
663
|
+
result = subprocess.run(
|
|
664
|
+
["perplexity-cli", "query", "--format", "json", "What is Python?"],
|
|
665
|
+
capture_output=True,
|
|
666
|
+
text=True
|
|
667
|
+
)
|
|
668
|
+
data = json.loads(result.stdout)
|
|
669
|
+
print(data["answer"])
|
|
670
|
+
for ref in data["references"]:
|
|
671
|
+
print(f"- {ref['title']}: {ref['url']}")
|
|
672
|
+
EOF
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
**Note:** When viewing JSON output, use `jq -r` (raw output) to properly display newlines in the answer text. Without `-r`, you'll see escape sequences like `\n` instead of actual line breaks.
|
|
676
|
+
|
|
677
|
+
## Development
|
|
678
|
+
|
|
679
|
+
### Setup Development Environment
|
|
680
|
+
|
|
681
|
+
```bash
|
|
682
|
+
git clone https://github.com/jamiemills/perplexity-cli.git
|
|
683
|
+
cd perplexity-cli
|
|
684
|
+
uv venv --python=3.12
|
|
685
|
+
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
|
686
|
+
uv pip install -e ".[dev]"
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
### Run Tests
|
|
690
|
+
|
|
691
|
+
```bash
|
|
692
|
+
pytest
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
### Linting, Formatting, and Type Checking
|
|
696
|
+
|
|
697
|
+
Format code (auto-fix):
|
|
698
|
+
|
|
699
|
+
```bash
|
|
700
|
+
ruff format src/
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
Check for linting issues:
|
|
704
|
+
|
|
705
|
+
```bash
|
|
706
|
+
ruff check src/
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
Type checking:
|
|
710
|
+
|
|
711
|
+
```bash
|
|
712
|
+
mypy src/
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
For more details on development practices, see `.claude/TESTING_GUIDE.md`.
|
|
716
|
+
|
|
717
|
+
## Security
|
|
718
|
+
|
|
719
|
+
- Tokens encrypted at rest using Fernet
|
|
720
|
+
- Encryption key derived from system identifiers
|
|
721
|
+
- File permissions restricted to owner (0600)
|
|
722
|
+
- Tokens validated on each request
|
|
723
|
+
- Token expiration detection (warns if token is >30 days old)
|
|
724
|
+
- Audit logging for token operations
|
|
725
|
+
- No credentials printed to logs
|
|
726
|
+
|
|
727
|
+
## Contributing
|
|
728
|
+
|
|
729
|
+
Contributions are welcome. Please ensure:
|
|
730
|
+
- Code follows PEP 8 standards
|
|
731
|
+
- All tests pass
|
|
732
|
+
- New features include tests
|
|
733
|
+
|
|
734
|
+
## License
|
|
735
|
+
|
|
736
|
+
MIT
|
|
737
|
+
|
|
738
|
+
## Dependencies
|
|
739
|
+
|
|
740
|
+
- click - CLI framework
|
|
741
|
+
- httpx - HTTP client
|
|
742
|
+
- websockets - WebSocket support
|
|
743
|
+
- rich - Terminal formatting
|
|
744
|
+
- cryptography - Token encryption
|
|
745
|
+
- tenacity - Retry logic with exponential backoff
|
|
746
|
+
- python-dateutil - Date parsing for thread exports
|