Skip to main content

Complete Python implementation of LastPass CLI with API

Project description

lastpass-py

Coverage Python License

A complete Python implementation of the LastPass CLI with a friendly API for programmatic access to your LastPass vault.

Features

  • ๐Ÿ” Secure - AES-256 encryption, PBKDF2 key derivation
  • ๐Ÿ Pure Python - No binary dependencies, works everywhere
  • ๐Ÿš€ Complete CLI - All major LastPass commands implemented
  • ๐Ÿ“š Python API - Clean interface for scripts and automation
  • ๐Ÿงช Well Tested - 331+ tests with 95% code coverage
  • ๐ŸŒ Cross-Platform - Linux, macOS, and Windows

Table of Contents

Installation

From PyPI

pip install lastpass-py

From Source

git clone https://github.com/dynacylabs/lastpass-py.git
cd lastpass-py
pip install -e .

Development Install

pip install -e ".[dev]"

This installs additional tools: pytest, pytest-cov, pytest-mock, responses

Optional: Clipboard Support

pip install pyperclip

Quick Start

Command Line

# Login
lpass login user@example.com

# List accounts
lpass ls

# Show account details  
lpass show github --password

# Generate password
lpass generate 20

# Logout
lpass logout

Python API

from lastpass import LastPassClient

# Login
client = LastPassClient()
client.login("user@example.com", "password")

# Get accounts
accounts = client.get_accounts()
for account in accounts:
    print(f"{account.name}: {account.username}")

# Find specific account
github = client.find_account("github")
print(github.password)

# Generate password
password = client.generate_password(length=20)

# Logout
client.logout()

CLI Reference

Commands

Command Description
lpass login [USERNAME] Login to LastPass
lpass logout Logout and clear session
lpass status Show login status
lpass show [QUERY] Display account details
lpass ls [GROUP] List accounts
lpass generate [LENGTH] Generate password
lpass sync Sync vault from server
lpass add [NAME] Add new account
lpass edit [QUERY] Edit existing account
lpass rm [QUERY] Remove account
lpass duplicate [QUERY] Duplicate account
lpass mv [QUERY] [GROUP] Move account to group

Common Options

login

lpass login user@example.com --trust --otp 123456
  • --trust - Trust this device
  • --otp CODE - One-time password for 2FA
  • --force - Force new login

show

lpass show github --password --clip
  • --password - Show only password
  • --username - Show only username
  • --url - Show only URL
  • --notes - Show only notes
  • --field NAME - Show specific field
  • --json - Output as JSON
  • --clip - Copy to clipboard

ls

lpass ls Work --long --json
  • --long - Long listing format
  • --json - Output as JSON

generate

lpass generate 24 --no-symbols --clip
  • --no-symbols - Exclude special characters
  • --clip - Copy to clipboard

add

lpass add "GitHub" --username user@example.com --url https://github.com
  • --username - Account username
  • --password - Account password (prompts if not provided)
  • --url - Website URL
  • --notes - Account notes
  • --group - Group/folder name
  • --generate LENGTH - Generate password of specified length

edit

lpass edit "GitHub" --password --url https://github.com/login
  • --name - Update account name
  • --username - Update username
  • --password - Update password (prompts if flag provided without value)
  • --url - Update URL
  • --notes - Update notes
  • --group - Move to different group

rm

lpass rm "Old Account" --force
  • --force - Skip confirmation prompt

duplicate

lpass duplicate "GitHub" --name "GitHub Backup"
  • --name - Name for duplicate (defaults to "Copy of [original]")

mv

lpass mv "GitHub" "Work/Development"
  • Moves account to specified group/folder

API Reference

LastPassClient

from lastpass import LastPassClient

client = LastPassClient(server="lastpass.com", config_dir=None)

Authentication

login(username, password=None, trust=False, otp=None, force=False)

Login to LastPass. Returns Session object.

client.login("user@example.com", "password", otp="123456")

logout(force=False)

Logout and clear session data.

client.logout()

is_logged_in()

Check if currently logged in. Returns bool.

if client.is_logged_in():
    print("Logged in!")

Vault Operations

get_accounts(sync=True)

Get all accounts. Returns List[Account].

accounts = client.get_accounts()

find_account(query, sync=True)

Find account by name, ID, or URL. Returns Account or None.

account = client.find_account("github")

search_accounts(query, sync=True, group=None)

Search accounts by keyword. Returns List[Account].

matches = client.search_accounts("google")

list_groups(sync=True)

Get all group/folder names. Returns List[str].

groups = client.list_groups()

sync(force=False)

Sync vault from server.

client.sync(force=True)

Utilities

generate_password(length=16, symbols=True)

Generate random password. Returns str.

password = client.generate_password(length=20, symbols=False)

get_password(query, sync=True)

Get password for account. Returns str or None.

password = client.get_password("github")

get_username(query, sync=True)

Get username for account. Returns str or None.

get_notes(query, sync=True)

Get notes for account. Returns str or None.

Write Operations

add_account(name, username="", password="", url="", notes="", group="", fields=None)

Add new account to vault. Returns account ID as str.

account_id = client.add_account(
    name="GitHub",
    username="user@example.com",
    password="secret123",
    url="https://github.com",
    group="Work"
)

update_account(query, name=None, username=None, password=None, url=None, notes=None, group=None)

Update existing account. Only provided fields are updated.

client.update_account("GitHub", password="newsecret", url="https://github.com/login")

delete_account(query)

Delete account from vault.

client.delete_account("Old Account")

duplicate_account(query, new_name=None)

Duplicate an account. Returns new account ID as str.

new_id = client.duplicate_account("GitHub", "GitHub Backup")

move_account(query, new_group)

Move account to different group/folder.

client.move_account("GitHub", "Work/Development")

Data Models

Account

@dataclass
class Account:
    id: str
    name: str
    username: str
    password: str
    url: str
    group: str
    notes: str
    fullname: str
    fields: List[Field]
    attachments: List[Attachment]
    share: Optional[Share]
    
    def to_dict(self) -> Dict
    def get_field(self, name: str) -> Optional[Field]
    def is_secure_note(self) -> bool

Field

@dataclass
class Field:
    name: str
    value: str
    type: str
    checked: bool

Share

@dataclass
class Share:
    id: str
    name: str
    readonly: bool

Exceptions

All exceptions inherit from LastPassException:

  • LoginFailedException - Authentication failed
  • InvalidSessionException - Session expired
  • NetworkException - Network/HTTP error
  • DecryptionException - Decryption failed
  • AccountNotFoundException - Account not found
  • InvalidPasswordException - Invalid password
from lastpass import LastPassClient, LoginFailedException

try:
    client.login("user@example.com", "wrong")
except LoginFailedException:
    print("Invalid credentials")
  1. Make your changes
  2. Add tests if applicable
  3. Submit a pull request

License

This project is licensed under the GNU General Public License v2.0 or later (GPLv2+), the same license as the original LastPass CLI.

Disclaimer

This is an independent implementation. It is not officially supported by LastPass/LogMeIn. Use at your own risk.

Implementation Details

Core Features Implemented

โœ… Cryptography

  • AES-256-CBC encryption/decryption
  • PBKDF2-HMAC-SHA256 key derivation
  • RSA encryption for shared folders
  • Base64 encoding/decoding
  • SHA256 hashing

โœ… Authentication

  • Username/password login
  • Two-factor authentication (OTP)
  • Session management
  • Encrypted session storage
  • Logout functionality

โœ… Vault Operations

  • Download and parse encrypted blob
  • Account listing and filtering
  • Account search (by name, username, URL, ID)
  • Group/folder listing
  • Custom field support
  • Shared folder support

โœ… CLI Commands

  • login - Login to LastPass
  • logout - Logout from LastPass
  • status - Show login status
  • show - Display account details
  • ls - List accounts
  • generate - Generate random password
  • sync - Sync vault from server

โœ… Python API

Complete programmatic access to LastPass functionality:

  • LastPassClient - Main client class
  • login() / logout() - Authentication
  • get_accounts() - Get all accounts
  • find_account() - Find specific account
  • search_accounts() - Search vault
  • list_groups() - Get folder list
  • generate_password() - Generate password
  • get_password() / get_username() / get_notes() - Convenience methods

Comparison with C CLI

This Python implementation provides:

โœ… All core functionality of the C-based CLI โœ… Python API for programmatic access โœ… No compilation required โœ… Easier to modify and extend โœ… Better error messages and debugging

Some differences:

  • Clipboard support requires pyperclip or system tools
  • Agent/daemon not implemented (use session-based auth)
  • Some advanced features (shares management, etc.) are simplified

Security Notes

  • Master Password: Never stored, only used for key derivation
  • Encryption: AES-256-CBC with unique IVs
  • Key Derivation: PBKDF2-HMAC-SHA256
  • Session Storage: Encrypted with derived key, mode 0600
  • Memory: Sensitive data cleared when possible

Configuration

Configuration is stored in:

  • Linux/macOS: ~/.config/lpass/
  • Windows: %APPDATA%\lpass\

Files:

  • session: Encrypted session data

Testing

Running Tests

Quick start:

# Install dev dependencies
pip install -e ".[dev]"

# Run all tests
pytest

# With coverage
pytest --cov=lastpass --cov-report=term-missing

Test Modes

1. Mock Tests (Default)

Fast, offline tests using mocked API responses. No credentials needed.

pytest                    # Run all mock tests
pytest -v                 # Verbose output
pytest tests/test_client.py  # Specific test file

2. Live API Tests

Tests against real LastPass API. Use a test account!

pytest --live --username test@example.com --password testpass

If email verification is required:

pytest --live --username test@example.com --password testpass --otp 123456

3. Complete Test Suite

Run both mock and live tests for full coverage:

pytest tests/ --live --username test@example.com --password testpass --cov=lastpass

Expected: 331+ tests passed, 95% coverage

Test Structure

  • tests/test_cli.py - CLI interface (87 tests)
  • tests/test_client.py - Client API (42 tests)
  • tests/test_cipher.py - Cryptography (26 tests)
  • tests/test_models.py - Data models (16 tests)
  • tests/test_http.py - HTTP client (26 tests)
  • And 8 more test files...

Coverage Report

Current coverage: 95%

Module                Coverage
--------------------------------
lastpass/__init__.py   100%
lastpass/cli.py         99%
lastpass/http.py        96%
lastpass/cipher.py      96%
lastpass/models.py      95%
lastpass/client.py      93%
lastpass/session.py     93%
lastpass/blob.py        89%
--------------------------------
TOTAL                   95%

Contributing

We welcome contributions! Here's how to get started:

Development Setup

  1. Fork and clone

    git clone https://github.com/YOUR_USERNAME/lastpass-py.git
    cd lastpass-py
    
  2. Install dev dependencies

    pip install -e ".[dev]"
    
  3. Create a branch

    git checkout -b feature/your-feature-name
    

Guidelines

Code Quality

  • Follow PEP 8 style guidelines
  • Add type hints to new functions
  • Document public APIs with docstrings
  • Keep functions focused and testable

Testing Requirements โš ๏ธ

  • All tests must pass - Run pytest before submitting
  • Maintain 95% coverage - Add tests for new code
  • Include both unit and integration tests when applicable
# Verify before submitting
pytest --cov=lastpass --cov-report=term-missing

# Expected output:
# ========== 279 passed in X.XXs ==========
# TOTAL coverage: 95%

Commit Messages

  • Use clear, descriptive commit messages
  • Reference issue numbers when applicable
  • Example: fix: handle rate limiting in HTTP client (#123)

Submitting Changes

  1. Run tests

    pytest --cov=lastpass
    

    Ensure: โœ… All tests pass โœ… Coverage โ‰ฅ 95%

  2. Push your branch

    git push origin feature/your-feature-name
    
  3. Open a Pull Request

    • Describe your changes clearly
    • Reference any related issues
    • Include test results/coverage report

Areas for Contribution

  • ๐Ÿ› Bug fixes and improvements
  • ๐Ÿ“ Documentation enhancements
  • ๐Ÿงช Additional test coverage
  • โœจ New features (discuss in an issue first)
  • ๐Ÿ”ง Code refactoring
  • ๐ŸŒ Platform compatibility

Getting Help

  • ๐Ÿ“– Check existing documentation
  • ๐Ÿ’ฌ Open an issue for discussion
  • ๐Ÿ” Search closed issues for similar problems

Code of Conduct

  • Be respectful and inclusive
  • Welcome newcomers
  • Focus on constructive feedback
  • Assume good intentions

Comparison with LastPass CLI (C Implementation)

โœ… Implemented Features

This Python implementation now covers all major operations from the C CLI:

Feature C CLI Python Status
Authentication
Login with username/password โœ… โœ… Full support
Two-factor auth (OTP) โœ… โœ… Full support
Trust device โœ… โœ… Full support
Logout โœ… โœ… Full support
Session management โœ… โœ… Full support
Vault Operations
List accounts (ls) โœ… โœ… Full support
Show account (show) โœ… โœ… Full support
Search/filter accounts โœ… โœ… Full support
Sync vault โœ… โœ… Full support
Password generation (generate) โœ… โœ… Full support
Status check โœ… โœ… Full support
Write Operations
Add account (add) โœ… โœ… Full support
Edit account (edit) โœ… โœ… Full support
Delete account (rm) โœ… โœ… Full support
Move account (mv) โœ… โœ… Full support
Duplicate account (duplicate) โœ… โœ… Full support
Data Access
Account fields โœ… โœ… Full support
Custom fields โœ… โœ… Full support
Secure notes โœ… โœ… Full support
Shared folders โœ… โœ… Full support
Groups/folders โœ… โœ… Full support
Cryptography
AES-256-CBC encryption โœ… โœ… Full support
PBKDF2 key derivation โœ… โœ… Full support
RSA for shared folders โœ… โœ… Full support
Output Formats
Standard text output โœ… โœ… Full support
Long listing format โœ… โœ… Full support
JSON output โœ… โœ… Full support
Clipboard support โœ… โœ… Full support

โŒ Not Implemented

The following advanced features from the C CLI are not implemented:

Feature C CLI Python Notes
Change master password (passwd) โœ… โŒ High risk operation
Share management โœ… โŒ Complex, requires share API
Import accounts โœ… โŒ CSV import not implemented
Export accounts โœ… โœ… Partial (JSON only, no CSV)
Attachments download โœ… โŒ API exists, not in CLI
Agent/daemon mode โœ… โŒ Not planned

๐ŸŽฏ Design Philosophy

Python Implementation Focus:

  • โœ… Complete CRUD operations - Create, Read, Update, Delete accounts
  • โœ… Safe vault management - All standard operations supported
  • โœ… Automation-friendly - Clean Python API for scripts
  • โœ… Cross-platform - Pure Python, no compilation needed
  • โœ… Well-tested - Comprehensive test coverage

Excluded Operations:

  • Master password changes (use web app for security)
  • Advanced share management (complex API)
  • CSV import/export (JSON supported)
  • Agent mode (session-based auth is simpler)

๐Ÿ“Š Feature Coverage Summary

Core Functionality:     100% โœ…
Read Operations:        100% โœ…  
Write Operations:       100% โœ… (add, edit, delete, move, duplicate)
Advanced Features:       30% โš ๏ธ  (passwd, shares, import not implemented)
Cryptography:           100% โœ…
Authentication:         100% โœ…
Session Management:     100% โœ…
Test Coverage:           95% โœ…

๐Ÿš€ Python-Specific Advantages

Features only in the Python implementation:

  • ๐Ÿ Native Python API - Use as a library in your Python projects
  • ๐Ÿ“ฆ No compilation - pip install and you're ready
  • ๐Ÿ”ง Easy to extend - Pure Python, modify for your needs
  • ๐Ÿงช Comprehensive tests - 331+ tests vs minimal C tests
  • ๐Ÿ“š Better documentation - Docstrings, type hints, examples
  • ๐ŸŒ Modern architecture - Uses requests, dataclasses, type hints

๐Ÿ’ก Use Cases

Perfect for:

  • โœ… Retrieving passwords in automation scripts
  • โœ… Integration with deployment pipelines
  • โœ… Password lookups in Python applications
  • โœ… Auditing vault contents
  • โœ… Bulk password exports
  • โœ… Cross-platform password access

Not suitable for:

  • โŒ Creating/modifying vault entries (use web app)
  • โŒ Account management workflows
  • โŒ Complex share management
  • โŒ Import/migration operations

๐Ÿ”ฎ Future Considerations

If there's demand, write operations could be added:

  • add - Create new accounts
  • edit - Modify existing accounts
  • rm - Delete accounts
  • import - Import from CSV

However, the current focus is on rock-solid read operations with excellent test coverage.

License

This project is licensed under the GNU General Public License v2.0 or later (GPLv2+).

See LICENSE for full details.

Security

  • Master Password: Never stored or logged
  • Encryption: AES-256-CBC with PBKDF2-SHA256
  • Session Data: Encrypted at rest (mode 0600)
  • Memory Safety: Sensitive data cleared when possible

Acknowledgments

  • Original LastPass CLI by LastPass
  • Python implementation by the community

Disclaimer

This is an independent implementation and is not officially supported by LastPass/LogMeIn. Use at your own risk.

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

lastpass_py-1.0.1.tar.gz (76.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lastpass_py-1.0.1-py3-none-any.whl (70.8 kB view details)

Uploaded Python 3

File details

Details for the file lastpass_py-1.0.1.tar.gz.

File metadata

  • Download URL: lastpass_py-1.0.1.tar.gz
  • Upload date:
  • Size: 76.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for lastpass_py-1.0.1.tar.gz
Algorithm Hash digest
SHA256 b7160a0a752401f682ee9919ede50e185b4c348c3a9002dba8696b5099501ba6
MD5 8038a6cd3cb6839ca6b8b6b6f47a5851
BLAKE2b-256 0aac78dda384f1cdedc0005a3241d5e6e9c5f2eb139fc3c707760ad53ff83f73

See more details on using hashes here.

Provenance

The following attestation bundles were made for lastpass_py-1.0.1.tar.gz:

Publisher: publish-to-pypi.yml on dynacylabs/lastpass-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file lastpass_py-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: lastpass_py-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 70.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for lastpass_py-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a5cc531177db95e1ee6dc5446fa73c55f6821f55418774bdecc0d2c3f40e3b05
MD5 60814d6b9401caf19d8e2fcac19c8979
BLAKE2b-256 33d25ac383b9afbf7980fc71c86a2ca1023d1b8274a0b4f4eca784e8eeed1bdb

See more details on using hashes here.

Provenance

The following attestation bundles were made for lastpass_py-1.0.1-py3-none-any.whl:

Publisher: publish-to-pypi.yml on dynacylabs/lastpass-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page