askp - Perplexity CLI (Python)
A tiny command-line tool to query Perplexity’s API with optional search filters and structured/text output.
Modes
askp supports two main modes:
-
Interactive mode:
Start a conversational REPL for multi-turn chat and advanced features. Just runaskpwith no arguments. -
Single-shot mode:
Ask a single question and get a response immediately. Runaskp "your question"with optional flags for output format, filters, and model selection. Defaults to raw json to work with other model as a researcher.
If you only want to run it, install to PATH and simply run askp "your question" after setting your API key.
Features
- Interactive chat mode (REPL) with slash commands for advanced control
- Single-shot mode for quick answers or scripting
- Simple one-file CLI in Python, no build step required
- Search filters:
- Academic-only search:
-a/--academic - Restrict to a domain:
-d/--domain - Recency filter:
--recency {day|week|month}
- Academic-only search:
- Output modes:
- Raw JSON (default, great for piping to
jq) - Text-only output:
-t/--text - Structured JSON with
--json-schema - Optional
--usageand--citationssummaries
- Raw JSON (default, great for piping to
- Model selection with validation:
-m/--model {sonar, sonar-pro, sonar-reasoning, sonar-reasoning-pro} - Async API support for long-running jobs (
--async,/async) - File and directory attachment in chat (
/attach,/ocr), including OCR for images - Slash commands for model switching, system prompts, filters, pruning, and more
- Piping and scripting: designed for shell integration and automation
- Verbose logging with
-v/--verbosefor debugging - Cross-platform: works on macOS, Linux, and Windows
- Easy install: venv, pipx, or single-line user install
- API key fallback: supports both
PPLX_API_KEYandPERPLEXITY_API_KEY - Extensible: supports additional Python packages for enhanced features (e.g., BeautifulSoup for HTML, pytesseract for OCR)
Requirements
- Python 3.8+
requestsPython package
Install dependencies one of two ways:
-
With a venv and requirements.txt:
python -m venv .venv source .venv/bin/activate pip install -r requirements.txt
Install
Recommended: Install from PyPI
pip install askp-cli
After installation, you can use the askp command directly:
askp --help
Alternative: Install with pipx (isolated environment)
pipx install askp-cli
Development: Install from source
If you want to contribute or use the latest development version:
git clone https://github.com/LienSimen/perplexity-cli.git
cd perplexity-cli
pip install -e .
Or install directly from Git with pipx:
pipx install git+https://github.com/LienSimen/perplexity-cli.git
Get an API key
- You need a Perplexity API key. See Perplexity’s docs/pricing for obtaining an API key.
Configure your API key (PPLX_API_KEY with fallback)
askp.py checks these environment variables in order:
PPLX_API_KEY(preferred)PERPLEXITY_API_KEY(fallback)
Below are platform-specific instructions to set environment variables.
macOS and Linux (bash/zsh)
-
Current shell only:
export PPLX_API_KEY="your_api_key_here"
-
Persist for future shells (append to your shell profile):
- For bash:
echo 'export PPLX_API_KEY="your_api_key_here"' >> ~/.bashrc - For zsh:
echo 'export PPLX_API_KEY="your_api_key_here"' >> ~/.zshrc - Then reload:
source ~/.bashrcorsource ~/.zshrc
- For bash:
-
fish shell (universal variable):
set -Ux PPLX_API_KEY "your_api_key_here"
-
System-wide (Debian/Ubuntu):
echo 'PPLX_API_KEY="your_api_key_here"' | sudo tee -a /etc/environment # log out and back in for changes to take effect
Windows (PowerShell)
-
Current session only:
$env:PPLX_API_KEY = "your_api_key_here"
-
Persist for your user profile:
setx PPLX_API_KEY "your_api_key_here" # Restart your shell to see the change
-
GUI method:
- Start > search "Environment Variables" > Edit the system environment variables
- Click "Environment Variables…"
- Under "User variables", New…
- Name:
PPLX_API_KEY, Value: your key, OK
If you already have PERPLEXITY_API_KEY set, that works too -- no changes needed.
Usage
To start interactive mode:
askp
Basic (raw JSON by default):
askp "What are the key differences between SQL and NoSQL?"
Text-only output:
askp -t "Explain RAG in simple terms"
Academic-only search:
askp -a -t "Latest research on diffusion models vs transformers"
Restrict to a domain:
askp -t -d arxiv.org "Chain of thought prompting"
Recency filter:
askp -t --recency week "Best LLM fine-tuning guides"
Structured JSON response (example schema for startups):
askp --json-schema "List 5 notable AI infrastructure startups and their focus areas"
Choose a model:
askp -t -m sonar-pro "Summarize latest LLM evals"
# Note: the async API only supports 'sonar-deep-research'; prefer -m sonar-deep-research with --async
Show usage and citations (when available) with text output:
askp -t --usage --citations "Provide sources for your answer on LoRA vs QLoRA"
Piping to jq (optional, when using raw JSON):
askp "Explain vector databases" | jq .
Interactive chat mode
Slash commands overview (type / to see suggestions):
- /help — list commands
/model <name>,/models— change model or list available models/system <text>— set a system prompt; typing/systemand pressing Enter pre-fills it/academic on|off— toggle or set academic search filter/domain [host]— set or clear domain filter/recency day|week|month|off— set or clear recency filter/jsonschema on|off— toggle structured output/citations on|off— toggle citation display (non-stream)/usage on|off— toggle usage display (non-stream)/stream on|off— toggle streaming output/attach [path] [summarize|full|all] [--as-user] [--max-files N] [--pattern ".py,.md"] [--include-hidden]— attach a local file or directory (supports txt, md, pdf, docx, html, images via OCR). Default: summarize. If [path] is omitted, it uses the current directory. Useallto skip selection UI and include all shown./async submit [prompt]|list|get <id>|wait <id>— async helpers for chat sessions/attachlimit <N>— set truncation limit for/attach --as-user(default 8000)- /settings — show current settings
- /prune [N] — summarize the conversation and restart with the summary as system prompt (default N=200 words)
- /clear — clear screen and start new conversation
- /new, /reset — new conversation (preserve /system)
- /exit, /quit — exit chat
Run askp with no arguments to start a conversational REPL:
askp
Attach files in chat (/attach and /ocr)
Attach local files into the chat to provide context:
- Supported: .txt, .md, .pdf, .docx, .html/.htm, .py, .json, .yaml/.yml, .toml, .ini/.cfg, .csv/.tsv, .sh, .ps1, .bat/.cmd, .ipynb
- Images with OCR: .png, .jpg, .jpeg, .tif, .tiff (requires Tesseract OCR installed)
- Default behavior is summarize, which adds a brief summary as a system note.
- Use full to insert the entire text as a user message (only if reasonably small).
- Use --as-user to force inserting as a user message with truncation if very long. Adjust with
/attachlimit <N>or--attach-limit <N>CLI flag.
Examples:
/attach # no path: uses current directory, summarizes supported files
/attach notes.md # summarize by default
/attach report.pdf summarize # explicit summarize
/attach "docs/plan v2.txt" full # include full content if small enough
/attach "huge.pdf" --as-user # attach as user with truncation if long
/attach ./project-notes/ # attach a directory; auto-summarize supported files
/attach ./project-notes/ all # attach all shown files without selection UI
/ocr ./images # OCR images in a directory; interactive selection
/ocr ./images all # OCR all shown images without selection UI
/ocr ./images --pattern ".png" # limit to PNGs
/ocr ./scan.jpg --as-user # OCR a single file and insert as user message
Notes on OCR: pytesseract requires the Tesseract binary.
- macOS (Homebrew): brew install tesseract
- Debian/Ubuntu: sudo apt-get install tesseract-ocr
- Windows: Install from https://github.com/tesseract-ocr/tesseract and ensure it’s on PATH.
Notes on HTML extraction (optional BeautifulSoup):
- If the beautifulsoup4 package is installed, askp uses it for more accurate HTML-to-text extraction (ignores scripts/styles, preserves text order better).
- If not installed, askp falls back to a basic tag-stripper using regular expressions.
- To install: pip install beautifulsoup4
Async usage
askp supports the Perplexity Async API for single-shot requests and within chat. Only the model sonar-deep-research is supported by the async API.
Single-shot (CLI) price around 0.40$:
# Takes 3-5 min, aprox $0.40
askp --async --wait -t -m sonar-deep-research "Survey recent academic literature on applications of large language models in scientific research"
# or fire-and-forget without --wait
askp --async -t -m sonar-deep-research "Outline key strategies for global poverty reduction"
Example cost for above:
"prompt_tokens": 9,
"completion_tokens": 9895,
"total_tokens": 9904,
"search_context_size": null,
"citation_tokens": 8417,
"num_search_queries": 20,
"reasoning_tokens": 62953,
"cost":
"input_tokens_cost": 0.0,
"output_tokens_cost": 0.08,
"reasoning_tokens_cost": 0.19,
"total_cost": 0.38
Tunables available with --async:
- --search-mode {web|none}
- --reasoning-effort {low|medium|high}
- --return-images
- --return-related-questions
In chat, you can use helpers:
/async submit # submit current conversation as async job
/async list # list async jobs
/async get <id> # fetch a job by id
/async wait <id> # poll until completed
Notes:
- In chat mode, replies are printed as plain text. You can pass
--usageand/or--citationsat startup to show those when available. - Startup flags like
-a/--academic,-d/--domain,--recency, and-m/--modelapply to the whole chat session. You can change the model mid-chat using:model.
Command-line flags
--attach-limit <N>: Set truncation limit used by /attach --as-userquery(positional): Your question/prompt-a, --academic: Use academic search filter-d, --domain <host>: Restrict search to a domain (e.g.,arxiv.org)--recency {day|week|month}: Search recency filter--json-schema: Enable structured JSON response for the included schema example-m, --model {sonar, sonar-pro, sonar-reasoning, sonar-reasoning-pro}: Select model (default:sonar)-t, --text: Print only the assistant text (instead of raw JSON)-u, --usage: Show token usage summary if available (only with--text)-c, --citations: Show citations if available (only with--text)--async: Use the async API for single-shot requests--wait: When used with--async, poll for the result and print it when completed--search-mode {web|none}: Search mode (async only)--reasoning-effort {low|medium|high}: Reasoning effort (async only)--return-images: Return images in the async response (async only)--return-related-questions: Return related questions (async only)-v, --verbose: Enable debug logging
Making it a global command (optional)
macOS/Linux
Option A: Shebang + executable + PATH
- Make the script executable:
chmod +x askp.py - Put it somewhere on your PATH, e.g.:
cp askp.py /usr/local/bin/askp - Alternatively, use the included wrapper scripts for Windows/macOS/Linux; once on PATH, invoke
askpeverywhere.
Option B: Use the included wrapper script
- The included
askpbash wrapper uses a relative path to the adjacentaskp.py. Once the wrapper is on your PATH (chmod +x askp), just runaskp.
Option C: Alias
alias askp='python /absolute/path/to/askp.py'
Add that line to your shell profile to persist.
Windows
- If you installed from PyPI (
pip install askp-cli) the installer will place anaskplauncher in your Python Scripts folder (for example,Scriptsunder your virtualenv or%USERPROFILE%\AppData\Roaming\Python\PythonXY\Scripts). Make sure that folder is on your PATH, then run:
askp "your question"
- Alternatively, to run the local copy from this repository you can use the included
askp.bat(it calls theaskp.pynext to it). Add the repository folder to your PATH or copyaskp.batinto a folder already on your PATH.
Troubleshooting
- Error:
Error: API key not found. Set PPLX_API_KEY (preferred) or PERPLEXITY_API_KEY.- Ensure you exported/set the variable and restarted your shell.
- Error:
ModuleNotFoundError: No module named 'requests'- Run
pip install requestsorpip install -r requirements.txtin your virtual environment.
- Run
- HTTP 401 Unauthorized
- Check that your API key is valid and has access.
- Other HTTP errors
- The CLI prints server responses on errors to help diagnose issues (rate limits, malformed payloads, etc.).
Metadata
Release files for askp-cli 1.0.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| askp_cli-1.0.8.tar.gz | 59.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| askp_cli-1.0.8-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 113.3 kB
Release files / askp_cli-1.0.8.tar.gz
| Download URL | askp_cli-1.0.8.tar.gz |
|---|---|
| Size | 59.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2b99acf226ea1b0c6b13ae314dae31118d6dd2036995c17cb7bc9a6bafb8a7f3
|
|
BLAKE2b-256 checksum How to use checksums |
992ee50be7b42ec95d98ce691b68fdf9bf6d2e24d1da0b824d8424e951da911a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.5
|
Release files / askp_cli-1.0.8-py3-none-any.whl
| Download URL | askp_cli-1.0.8-py3-none-any.whl |
|---|---|
| Size | 53.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b15449bf9cb8b44d67108734789fc9d67d3f366af9158d63c496c91d1e89498b
|
|
BLAKE2b-256 checksum How to use checksums |
c1e7888beb41b1cf6db217843ec99a50039755fb9f8a375fb36f74d75b6b7923
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.5
|
Security for askp-cli 1.0.8
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.