Full-featured interactive IPython console for Odoo development, replicating PyCharm Console functionality with enhanced Odoo-specific features.
- PyCharm-like REPL - Full interactive shell with automatic result display
 - Multiline Editing - Smart auto-indent for code blocks
 - Persistent History - Command history saved between sessions
 - Syntax Highlighting - Monokai theme with Pygments integration
 - Enhanced Autocompletion - Jedi-powered with Odoo model awareness
 
- Preloaded Environment - 
envready for immediate ORM operations - Smart Model Completion - Tab-complete model names, fields, domains
 - Domain Builder Assistance - Autocomplete operators and field values
 - Selection Values - Auto-suggest selection field options
 - Many2one Samples - Cached record suggestions for relation fields
 - Transaction Control - Visual feedback for commit/rollback
 
- Variable Inspector - 
lsvars()shows all workspace variables (like PyCharm Variables panel) - Object Inspector - 
inspect_obj()provides deep introspection with docs - Performance Profiler - 
profile_query()for execution analysis - Debug Mode - Built-in pdb integration with 
%pdb on - Safe Output - Automatic truncation and binary field handling
 
- 
Install dependencies:
pip install -r requirements.txt
 - 
Ensure Odoo is installed:
pip install odoo>=16.0 - 
Configure paths:
- Place your 
odoo.confinodoo_configs/directory - Or specify custom path with 
--configflag 
 - Place your 
 
python3 odoo_ipython_console.py -d your_database_name# Custom config file
python3 odoo_ipython_console.py -d mydb -c /path/to/odoo.conf
# Disable autocompletion
python3 odoo_ipython_console.py -d mydb --no-autocomplete
# Safe mode (restrict write operations)
python3 odoo_ipython_console.py -d mydb --safe-mode
# Disable syntax highlighting
python3 odoo_ipython_console.py -d mydb --no-syntax-highlight
# Custom autocomplete value limit
python3 odoo_ipython_console.py -d mydb --fetch-values-limit 10| Command | Description | Example | 
|---|---|---|
env | 
Odoo ORM environment | env['res.partner'].search([], limit=5) | 
show(record, fields=None) | 
Pretty-print records with grid formatting | show(env['res.partner'].browse(1)) | 
lsmodels(page=1, per_page=20) | 
List all models with descriptions | lsmodels() | 
lsfields(model, page, per_page) | 
List model fields with types | lsfields('res.partner') | 
lsallfields(model, page, per_page) | 
Fields with sample values | lsallfields('res.partner') | 
lsvars() | 
List all workspace variables | lsvars() | 
inspect_obj(obj) | 
Deep object inspection | inspect_obj(env['res.partner']) | 
profile_query(func, *args) | 
Profile function performance | profile_query(env['res.partner'].search, []) | 
q(model, domain, limit) | 
Quick search with domain | q('res.partner', [('active','=',True)], 5) | 
commit() | 
Commit transaction with timestamp | commit() | 
rollback() | 
Rollback transaction with feedback | rollback() | 
special_vars() | 
Show all helpers | special_vars() | 
loop | 
Asyncio event loop | Available for async operations | 
| Command | Description | Example | 
|---|---|---|
%reload_env | 
Reload Odoo environment cache | %reload_env | 
%pdb on/off | 
Toggle debugger on exceptions | %pdb on | 
%hist | 
Show command history | %hist -n 20 | 
%who | 
List variables (short) | %who | 
%whos | 
List variables (detailed) | %whos | 
%timeit | 
Time statement execution | %timeit env['res.partner'].search([]) | 
%debug | 
Enter debugger after exception | %debug | 
# Search and display records
partners = env['res.partner'].search([('customer_rank', '>', 0)], limit=5)
show(partners)
# Quick search
q('res.partner', [('is_company', '=', True)], limit=10)
# Create and commit
new_partner = env['res.partner'].create({'name': 'Test Company'})
commit()# List all models
lsmodels()
# Explore model fields
lsfields('sale.order')
# See fields with example data
lsallfields('sale.order', per_page=30)
# Inspect workspace
lsvars()
# Deep object inspection
inspect_obj(env['res.partner'])# Profile performance
def heavy_search():
    return env['res.partner'].search([('active', '=', True)])
result = profile_query(heavy_search)
# Async operations
await loop.run_in_executor(None, lambda: env['res.partner'].search_count([]))
# Debug on errors
%pdb on
env['nonexistent.model'].search([])  # Will drop into debugger# Tab-complete models
env['res.p<TAB>  # → res.partner, res.partner.bank, etc.
# Field completion in domains
q('res.partner', [('cu<TAB>  # → customer_rank, currency_id, etc.
# Operator suggestions
q('res.partner', [('name', 'l<TAB>  # → like, ilike
# Selection value hints (if field is selection type)
q('res.partner', [('type', '=', <TAB>  # → contact, invoice, delivery, etc.# Create some variables
partners = env['res.partner'].search([], limit=5)
orders = env['sale.order'].search([], limit=3)
total = len(partners) + len(orders)
# View all variables with types and values
lsvars()
# Output:
# ╔═══════════╦═══════════════╦═══════════════════════════════════╗
# ║ Name      ║ Type          ║ Value                            ║
# ╠═══════════╬═══════════════╬═══════════════════════════════════╣
# ║ orders    ║ sale.order    ║ sale.order(1, 2, 3)              ║
# ║ partners  ║ res.partner   ║ res.partner(1, 2, 3, 4, 5)       ║
# ║ total     ║ int           ║ 8                                ║
# ╚═══════════╩═══════════════╩═══════════════════════════════════╝# Inspect Odoo model
inspect_obj(env['res.partner'])
# Shows: type, module, documentation, Odoo model name, description, attributes
# Inspect Python object
inspect_obj(env['res.partner'].search)
# Shows: signature, documentation, source file
# Inspect custom function
def my_func(x, y=10):
    """Calculate sum"""
    return x + y
inspect_obj(my_func)The console uses custom prompts with emojis:
🐍 Odoo [1]: env['res.partner'].search_count([])
📤 Out[1]: 42
Default theme: monokai
Disable with: --no-syntax-highlight
Location: .odoo_console_history in project root
Persistent across sessions
- Autocomplete cache: 256 items (LRU cache)
 - Default value limit: 5 items
 - Repr truncation: 200 characters
 - Grid table format: For better readability
 
python3 odoo_ipython_console.py -d mydb --safe-modeRestricts potentially dangerous operations
Automatically detects and truncates binary data:
record = env['ir.attachment'].browse(1)
show(record)
# Binary fields shown as: <binary 1024 bytes>huge_list = list(range(10000))
show(records_with_huge_list)
# Output: list(len=10000) sample=[0, 1, 2]All helpers include comprehensive error handling with logging
%pdb on  # Auto-debug on exceptionsimport pdb; pdb.set_trace()%debug  # After exception occurs- 
Use profiler for slow queries:
profile_query(env['product.product'].search, [('active', '=', True)])
 - 
Cache repeated searches:
@lru_cache(maxsize=128) def get_active_partners(): return env['res.partner'].search([('active', '=', True)])
 - 
Limit field reads:
show(records, fields=['id', 'name', 'email'])
 - 
Use pagination for large datasets:
lsmodels(page=2, per_page=50) lsfields('product.product', page=3, per_page=100)
 
# Create records
partner = env['res.partner'].create({'name': 'Test'})
# Inspect before commit
show(partner)
# Commit changes
commit()
# Output: ✅ Transaction committed at 14:30:45
# Or rollback
rollback()
# Output: ↩️  Transaction rolled back at 14:30:50with env.cr.savepoint():
    # Changes here are isolated
    partner = env['res.partner'].create({'name': 'Temp'})
    # Automatic rollback if exception| Feature | PyCharm Console | Odoo Console | Status | 
|---|---|---|---|
| Multiline editing | ✅ | ✅ | Full | 
| Auto-indent | ✅ | ✅ | Full | 
| Syntax highlight | ✅ | ✅ | Monokai theme | 
| Auto-display results | ✅ | ✅ | Full | 
| Variables panel | ✅ | ✅ | lsvars() | 
| Object inspector | ✅ | ✅ | inspect_obj() | 
| History | ✅ | ✅ | Persistent | 
| Debugger | ✅ | ✅ | pdb integration | 
| Profiler | ✅ | ✅ | profile_query() | 
| Magic commands | ✅ | ✅ | Full IPython | 
| Async support | ✅ | ✅ | loop + await | 
| Smart completion | ✅ | ✅ | Jedi + custom | 
| Odoo models | ❌ | ✅ | Model-aware | 
| Domain builder | ❌ | ✅ | Operator hints | 
| Field completion | ❌ | ✅ | Meta-driven | 
- Python 3.8+
 - Odoo 16.0+ (tested on 16, 17)
 - IPython 8.10.0+
 - tabulate 0.9.0+
 - nest_asyncio 1.5.6+
 
# Check Jedi installation
pip install --upgrade jedi
# Launch without autocomplete
python3 odoo_ipython_console.py -d mydb --no-autocomplete# Check file permissions
ls -la .odoo_console_history
# Create manually if needed
touch .odoo_console_history
chmod 644 .odoo_console_history# Install/update Pygments
pip install --upgrade pygments
# Disable if needed
python3 odoo_ipython_console.py -d mydb --no-syntax-highlight# Reduce value fetch limit
python3 odoo_ipython_console.py -d mydb --fetch-values-limit 3
# Disable Jedi (in console)
%config Completer.use_jedi = False- Database Connection: Uses single cursor (no auto-reconnect)
 - Transaction Isolation: Changes visible only after 
commit() - Safe Output: Binary fields automatically handled
 - Cache: Model/field metadata cached for performance
 - Exit: Use 
exit()orCtrl+D 
Improvements welcome! Focus areas:
- Additional magic commands
 - Enhanced domain builder
 - Visual query builder
 - Export/import helpers
 - Performance optimizations
 
This project is licensed under the GNU Lesser General Public License v3.0 (LGPL-3.0) - same as Odoo framework.
Developer: AlexTkDev
Project URL: https://github.com/AlexTkDev/ipython-console-to-VScode
Developer URL: https://github.com/AlexTkDev
See LICENSE file for full license text.
Version: 2.0 PyCharm Edition
Last Updated: 2025-10-11
Compatibility: Odoo 16.0+, Python 3.8+