CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-mpremote

Tool for interacting remotely with MicroPython devices

Pending
Overview
Eval results
Files

mounting.mddocs/

File System Mounting

Mount local directories on MicroPython devices for seamless development workflows, enabling direct access to local files from device code without explicit file transfers.

Capabilities

Directory Mounting

Mount local filesystem directories to make them accessible from MicroPython device code.

def do_mount(state, args):
    """
    Mount local directory on device.
    
    Parameters:
    - state: State object with active transport
    - args: Mount configuration arguments
    
    Args attributes:
    - path: List containing local directory path to mount
    - unsafe_links: Boolean to follow symbolic links outside mount directory
    
    Makes local directory contents accessible via device filesystem,
    enabling seamless development workflows.
    """

Directory Unmounting

Unmount previously mounted local directories and clean up resources.

def do_umount(state, path):
    """
    Unmount local directory.
    
    Parameters:
    - state: State object with active transport  
    - path: Mount path to unmount (unused, unmounts current mount)
    
    Removes mounted directory access and cleans up transport resources.
    """

Command-Line Interface

Basic Mounting Operations

# Mount current directory
mpremote mount .

# Mount specific directory
mpremote mount /path/to/project

# Mount with symbolic link following
mpremote mount --unsafe-links /path/with/symlinks

# Mount and execute code
mpremote mount . exec "import my_module"

# Unmount current directory
mpremote umount

Development Workflow Integration

# Mount project directory and run main script
mpremote mount . run main.py

# Mount source directory and start REPL for testing
mpremote mount src/ repl

# Mount library directory and install dependencies
mpremote mount libs/ mip install --target /mounted/libs extra-package

Usage Examples

Interactive Development

from mpremote.main import State
from mpremote.commands import do_mount, do_umount

# Set up connected device state
state = State()
# ... connect to device ...

# Mount current directory
args = type('Args', (), {
    'path': ['.'],
    'unsafe_links': False
})()
do_mount(state, args)

# Now device can access local files directly
# ... do development work ...

# Unmount when done
do_umount(state, None)

Project Development Workflow

# Project structure:
# project/
# ├── main.py
# ├── lib/
# │   ├── sensors.py
# │   └── networking.py
# ├── config/
# │   └── settings.py
# └── tests/
#     └── test_sensors.py

# Mount project root
mpremote mount project/

# Device can now import modules directly:
mpremote exec "
import main
import lib.sensors
import config.settings
"

# Run tests
mpremote exec "
import tests.test_sensors
tests.test_sensors.run_all()
"

# Run main application
mpremote run main.py

Rapid Prototyping

# Create and test code iteratively
echo "
def test_function():
    return 'Hello from mounted file!'

if __name__ == '__main__':
    print(test_function())
" > prototype.py

# Mount and test immediately
mpremote mount . exec "import prototype; print(prototype.test_function())"

# Modify file and test again without file transfer
echo "
def test_function():
    return 'Updated function!'
    
def new_feature():
    return 'New functionality added!'
" > prototype.py

mpremote exec "
# Reload module to get changes
import sys
if 'prototype' in sys.modules:
    del sys.modules['prototype']
import prototype
print(prototype.test_function())
print(prototype.new_feature())
"

Library Development

# Develop MicroPython library with live testing
mkdir my_sensor_lib
cd my_sensor_lib

cat > sensor.py << 'EOF'
class TemperatureSensor:
    def __init__(self, pin):
        from machine import ADC
        self.adc = ADC(pin)
    
    def read_celsius(self):
        # Convert ADC reading to temperature
        raw = self.adc.read()
        voltage = raw * 3.3 / 1024
        return (voltage - 0.5) * 100
EOF

cat > test_sensor.py << 'EOF'
from sensor import TemperatureSensor

def test_sensor():
    # Test with mock or real hardware
    temp = TemperatureSensor(0)
    reading = temp.read_celsius()
    print(f'Temperature: {reading:.1f}°C')
    return reading

if __name__ == '__main__':
    test_sensor()
EOF

# Mount library directory and test
mpremote mount . exec "import test_sensor; test_sensor.test_sensor()"

Mount Behavior and Limitations

File Access Behavior

When a directory is mounted:

  • Read Access: Device can read all files in mounted directory
  • Write Access: Device can create/modify files (changes affect local filesystem)
  • Import Support: Python modules can be imported directly from mounted path
  • Path Resolution: Mounted directory appears as part of device filesystem

Symbolic Link Handling

# Default: symbolic links outside mount directory are not followed
mpremote mount /project  # Safe mode

# Allow following external symbolic links (potentially unsafe)
mpremote mount --unsafe-links /project

Safety considerations:

  • Default behavior prevents access outside mounted directory
  • --unsafe-links allows following links that point outside mount root
  • Use --unsafe-links only with trusted content

Performance Considerations

  • Network Overhead: Each file access requires communication with host
  • Caching: mpremote may cache file contents for performance
  • Large Files: Large file access may be slower than local device storage
  • Real-time: Not suitable for high-frequency file operations

Advanced Usage Patterns

Multi-Directory Development

# Mount multiple directories in sequence (only one active at a time)
mpremote mount ./src exec "import core_module"
mpremote umount
mpremote mount ./tests exec "import test_suite; test_suite.run()"
mpremote umount
mpremote mount ./config exec "import settings; print(settings.CONFIG)"

Configuration Management

# Separate code and configuration
mkdir project config

echo "
# Configuration settings
DEBUG = True
SENSOR_PIN = 4
WIFI_SSID = 'development'
" > config/settings.py

echo "
def load_config():
    import settings
    return {
        'debug': settings.DEBUG,
        'sensor_pin': settings.SENSOR_PIN, 
        'wifi_ssid': settings.WIFI_SSID
    }
" > project/config_loader.py

# Mount config directory
mpremote mount config/ exec "
import settings
print('Config loaded:', settings.DEBUG, settings.SENSOR_PIN)
"

# Switch to project directory
mpremote umount
mpremote mount project/ exec "
import config_loader
config = config_loader.load_config()
print('Loaded config:', config)
"

Template and Asset Management

# Manage web templates and static assets
mkdir webapp
mkdir webapp/templates
mkdir webapp/static

echo "<html><body><h1>{{title}}</h1></body></html>" > webapp/templates/index.html
echo "body { font-family: Arial; }" > webapp/static/style.css

# Mount and serve web content
mpremote mount webapp/ exec "
import os
print('Templates:', os.listdir('templates'))
print('Static files:', os.listdir('static'))

# Read template
with open('templates/index.html', 'r') as f:
    template = f.read()
    print('Template:', template)
"

Error Handling

Mounting operations may encounter various error conditions:

from mpremote.transport import TransportError
from mpremote.commands import CommandError

try:
    do_mount(state, args)
except TransportError as e:
    print(f"Mount failed: {e}")
    # Possible causes:
    # - Device communication error
    # - Transport not connected
except OSError as e:
    print(f"Local filesystem error: {e}")
    # Possible causes:
    # - Directory doesn't exist
    # - Permission denied
    # - Invalid path

Common Error Scenarios

# Directory doesn't exist
mpremote mount /nonexistent/path
# Error: Directory not found

# Permission denied
mpremote mount /root/restricted
# Error: Permission denied

# Already mounted
mpremote mount .
mpremote mount other_dir  # Will replace previous mount

Best Practices

Security Considerations

# Safe mounting - restrict to project directory
mpremote mount ./project

# Avoid mounting system directories
# DON'T: mpremote mount /
# DON'T: mpremote mount /home/user

# Use absolute paths for clarity
mpremote mount "$(pwd)/src"

Development Workflow

# Organize project structure for mounting
project/
├── src/           # Main source code
├── lib/           # Local libraries
├── config/        # Configuration files
├── tests/         # Test files
└── data/          # Data files

# Mount specific directories as needed
mpremote mount src/ exec "import main_module"
mpremote mount tests/ exec "import test_runner; test_runner.run_all()"

Performance Optimization

# Minimize file operations during mount
# Good: Load configuration once
mpremote mount config/ exec "
import settings
CONFIG = settings.get_config()
"

# Avoid: Repeated file access
# Suboptimal: mpremote exec "import settings; print(settings.DEBUG)"

Install with Tessl CLI

npx tessl i tessl/pypi-mpremote

docs

cli-reference.md

code-execution.md

device-config.md

device-connection.md

filesystem.md

index.md

mounting.md

package-management.md

repl.md

romfs.md

tile.json