Title: Remote development on the Raspberry Pi (or Amazon EC2) - PyImageSearch

URL Source: https://pyimagesearch.com/2019/07/01/remote-development-on-the-raspberry-pi-or-amazon-ec2/

Published Time: 2019-07-01T14:00:37+00:00

Markdown Content:
[![Image 1](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20450'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_header.jpg)

In this blog post, you will learn how to perform remote development on a Raspberry Pi (or Amazon EC2 server). You will discover how to configure your host machine to connect to these systems and remotely perform Python development.

Today’s tutorial is actually a chapter for my upcoming book, [_Raspberry Pi for Computer Vision_](https://pyimagesearch.com/raspberry-pi-for-computer-vision/).

As I was writing the chapter I realized that the guide wasn’t specific to the RPi and could actually be used for _anyone_ who needed to configure a remote system for development (and in particular, using the Python programming language).

Therefore, I decided to take the chapter and convert it into a blog post.

**Using this tutorial you will learn how to configure:**

1.  Your Raspberry Pi for remote computer vision development
2.  An Amazon AWS server for remote deep learning
3.  _**…or any other system that you can connect to remotely!**_

**To learn how to configure your Raspberry Pi, Amazon EC2 instance, or server for remote Python development, _just keep reading!_**

In the first part of this tutorial, we’ll discuss the concept of **remote development** and why it’s not only _convenient_ for us as programmers, but also why you _should_ be doing it when writing code on your non-host machine.

From there I’ll provide you with my three favorite methods to connecting to a Raspberry Pi, AWS instance, or remote server.

We’ll then discuss two easy to use methods for transferring files from your host machine to a remote system.

**Finally, we’ll wrap up the post with a discussion of Python IDEs that can be used to write code on a remote system.**

### What is remote development?

[![Image 2](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20450%20366'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_flowchart.png)

**Figure 1:** Remote Python development flowchart.

**Remote development** assumes that you have two computers:

1.  Your **host machine** (also called your **local machine**) that has your monitor, keyboard, and mouse attached to.
2.  The **remote machine** where your code is executing.

Or, more simply put:

1.  Your host machine is your laptop/desktop sitting on your desk where you normally work.
2.  Your remote machine is the machine you login to via your host machine.

To perform development you first connect to the remote machine from your host.

There are a number of ways to connect to the remote machine, including SSH, VNC, Jupyter Notebooks, and others. We’ll be covering these methods later in this guide.

Once you’re connected to the remote machine you can then:

1.  **Write code** on the remote machine
2.  **Execute code** on the remote machine

**Figure 1** illustrates the concept of using your host machine to login to a device, writing code on the remote system, and then executing it.

While you are still typing using the keyboard on your local system, the commands/code itself are actually being executed on the remote machine.

### Why would I want to write my code remotely?

**If you’re working with a cloud-based instance** such as Amazon EC2, Microsoft Azure, etc., then you do not have physical access to the machine (meaning there is no keyboard/mouse to use).

In that situation you need to login to the server and perform remote development — and you’ll want to ensure that your local host is configured properly for remote development.

**If you’re using a Raspberry Pi** then you certainly _could_ connect a keyboard, monitor, and mouse, _but that’s not always necessary!_

First, you’ll have the hassle of setting up the additional hardware — it’s clunky to set up, you’ll lose space on your desk, and worst of all, you’ll constantly be switching back and forth between your RPi keyboard and your laptop/desktop keyboard.

Secondly, even with the release of the Raspberry Pi 4, the RPi itself is still very underpowered compared to your laptop/desktop — **you won’t (and shouldn’t) be able to utilize powerful programming IDEs on the Pi itself.**

When it comes to Python development, [PyCharm](https://www.jetbrains.com/pycharm/) is quite literally the standard.

However, IDEs like PyCharm, while super powerful, are resource hogs, consuming quite a bit of RAM and CPU cycles — on a resource-constrained device such as the RPi, running such an IDE is _computationally wasteful._

Instead, you should:

*   Configure your local machine to connect to the Pi
*   Code on your laptop/desktop
*   And then have those files transferred (potentially automatically) to the Pi so you can run the code itself on the remote machine.

**In the remainder of this tutorial, I’ll show you how to configure your host machine to create a _seamless transition_, making it _feel_ like you’re writing code on your host but you’re _actually_ writing code on the remote system.**

### Connecting to a remote machine or Raspberry Pi

There are a number of methods, protocols, and procedures to connect to a remote machine.

The methods discussed in this section are _certainly_ not exhaustive, but they _are_ my favorites and ones you will _absolutely_ encounter when performing remote development.

#### Secure Shell (SSH)

![Image 3](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20717'%3E%3C/svg%3E)

**Figure 2:** Secure Shell (SSH) is essential to remote development with Unix systems such as Ubuntu, macOS, EC2, and Raspbian.

The first method, and arguably the most simple, is to utilize Secure Shell (SSH), which is the `ssh` command on Unix machines.

To use SSH you need:

*   An SSH server installed and running on your remote machine.
*   An SSH client installed on your local machine.
*   The IP address, username, and password of the remote system.

Most systems will have an SSH **server**. On Ubuntu, if you need to install an SSH server, simply:

$ sudo apt-get install openssh-server

On macOS, you only need to enable _“Remote Login”_:

sudo systemsetup -setremotelogin on

**See below** for two options to enable an **SSH server on the Raspberry Pi.**

If you’re working with a Unix-based machine (such as Linux or macOS), the `ssh` **client** is installed by default. If you are using Windows you may need to install it

_**Note:** I haven’t used Windows in over 10+ years and do not officially support Windows on the PyImageSearch blog. The last I checked [PuTTY](https://www.putty.org/) was still a good option but I’ll leave SSH install on Windows up to you._

Provided you have SSH installed, first open a terminal/command line on your host machine.

You’ll then need the following:

1.  The IP address of the machine you are connecting to.
2.  The username of the user you’ll be logging into on the remote machine.
3.  The password of the respective user.

Once you have that information, you can use the following command as a template:

$ ssh username@ip\_address

If you are using Amazon EC2, you may need to supply a private key instead of a password:

$ ssh -i ~/keyfile.pem username@ip\_address # AWS EC2

For example, if the IP address of my remote machine is `10.0.0.90` and my username is `adrian` , the `ssh` command becomes:

$ ssh adrian@10.0.0.90

I can then supply my password and login to the remote machine. Once logged in, I can now execute any command I wish (provided I have the proper permissions, of course) on the remote machine.

#### X11 forwarding

[![Image 4](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20560%20142'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_x11_forwarding_header.png)

**Figure 3:** X11 forwarding allows a remote system to render a GUI window on your local system. X forwarding is useful for remote development over high-speed connections and when the GUI is relatively static. It does not perform well for animations and video.

Did you know that you can use SSH to see basic GUI windows from your Python scripts and programs?

First, you need an X-Window manager:

*   If your host is **Ubuntu** (or another Linux distro), it is built-in.
*   If your host is **macOS**, you should download + install [xQuartz](https://www.xquartz.org/).
*   If your host is **Windows**, I _think_ you need [Xming](https://sourceforge.net/projects/xming/) these days still (It has been over 10 years since I’ve used Windows so you should do your own research).

All you need to do is enable X11 forwarding via the `-X` switch:

$ ssh -X username@ip\_address

[![Image 5](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20404'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_x11_forwarding.jpg)

**Figure 4:** A remote X11 window displayed on my Mac using the Xquartz app and an SSH connection.

Here I’ve launched a Python script named `example.py`. This script loads an image from disk and displays it to my local host’s screen via `cv2.imshow` call.

Since I have X11 forwarding enabled, the window opened via OpenCV is displayed on my host machine. Remember, the code is executed remotely and the image is rendered remotely but displayed locally.

You might be wondering:

Is X11 forwarding useful for video streaming?

In short, the answer is “no, don’t bother.” The X11 forwarding protocol doesn’t compress the images at all or effectively to make video streaming possible. **Do not attempt to use X11 forwarding for apps where the content changes often or there are video feeds.**

#### A quick note on SSH on the Raspberry Pi

It’s important to note that SSH is turned off by default on the Raspberry Pi, meaning that you cannot connect to your RPi via SSH without first enabling it.

There are a few methods to enable SSH on the Raspberry Pi.

**Option 1:** You may enable it via the _Desktop user interface:_

[![Image 6](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20480%20550'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_raspbian_desktop_rpi_configuration.png)

**Figure 5:** The Raspberry Pi Configuration desktop GUI is accessed from the main menu.

From there, find the _“Interfaces”_ tab and enable SSH:

[![Image 7](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20487%20444'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_raspbian_ssh.png)

**Figure 6:** Enabling SSH on the Raspberry Pi via the Desktop. SSH is essential for remote development on the Raspberry Pi.

**Option 2:** The second method is to use the following command to enable it:

$ sudo service ssh start

The problem with this method is that requires you to have physical access to the RPi to type in the command.

The second issue is that if you reboot the Raspberry Pi, SSH will not automatically start (i.e., starting SSH will not persist across reboots).

**Option 3:** Similar to _Option 1_, you may enter the Raspberry Pi Configuration via the _command line:_

[![Image 8](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20518%20240'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_raspbian_ssh_01.png)

**Figure 7:** The `raspi-config` command allows you to change system settings.

From there, you’ll be presented with a terminal menu:

[![Image 9](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20399'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_raspbian_ssh_02.png)

**Figure 8:** Select _“5 Interfacing Options”_ to find SSH and other interface settings for the Raspberry Pi. Once you turn on SSH you can begin remote development with your Raspberry Pi.

Then you’ll be presented with the interfaces, one of which is SSH:

[![Image 10](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20400'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_raspbian_ssh_03.png)

**Figure 9:** SSH for Raspberry Pi can be turned on from the _“P2 SSH”_ menu item.

A reboot will be required. From there you can use the Raspberry Pi’s IP address to connect to it remotely. To find your RPi’s IP address, simply use the `ifconfig` command:

[![Image 11](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20439'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_raspbian_ifconfig.png)

**Figure 10:** To find the IP address of your Raspberry Pi, use the `ifconfig` command. Here my RPi is connected to my `wlan0` interface on the `192.168.1.150` IP.

Another way to find a Raspberry Pi on your network is to go to our router’s client page. This is useful if you don’t have a screen and keyboard/mouse connected to your RPi at the time.

### Virtual Network Computing (VNC)

![Image 12](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20810'%3E%3C/svg%3E)

**Figure 11:** VNC is a graphical way to connect to remote systems such as the Raspberry Pi or another computer on your network that has a desktop environment.

If you prefer a graphical user interface (GUI) instead of the command line when working on your remote machine, then you can use VNC.

To use VNC you need:

*   A VNC server installed and running on your remote machine.
*   A VNC client installed on your local machine.
*   The IP address, username, and password of the remote system.

**However, keep in mind that VNC assumes you have GUI/desktop manager running on your remote system.**

For the Raspberry Pi, that’s a perfectly fine assumption to make — the RPi launches a window manager on boot (provided you are using the standard install of Raspbian, of course).

However, for a remote server, such as Amazon EC2 or Microsoft Azure, _you likely don’t have a window manager_.

**In those situations, you _cannot_ use VNC and should instead use SSH.**

How to install a VNC server is dependent on your operating system so you’ll want to do your own research on that (as I cannot provide instructions for every single operating system).

**That said, I have provided VNC server install instructions for Raspbian and Ubuntu, two of the most popular operating systems you’ll want to install VNC server on.**

#### Installing VNC Server on Raspbian

Luckily for us, it is easy to get VNC going on the Raspbian OS.

You have two options:

**Option 1:** Use the _Desktop configuration_ to change the setting:

Refer to **Figure 5** to open the _“Raspberry Pi Configuration”_ user interface. Then enable VNC via the radio button:

[![Image 13](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20485%20442'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_raspbian_vnc_00.png)

**Figure 12:** Enabling VNC on the Raspberry Pi via the desktop user interface.

This method requires a reboot.

**Option 2:** Enable VNC Server with the _command line:_

At the command line, run `sudo raspi-config` (refer to **Figure 7**).

Then, navigate to the _“5 Interfacing Options”_ menu item (refer to **Figure 8**).

Finally, select _“P3 VNC”:_

[![Image 14](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20467'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_raspbian_vnc_01.png)

**Figure 13:** Enabling VNC via the command line on the Raspberry Pi. We used the `raspi-config` command to open the configuration settings.

Enable VNC and you’ll be good to go after a reboot.

#### Installing VNC Server on Ubuntu

There are multiple methods to install a VNC Server on Ubuntu.

**Option 1:** Given that my preference is **Real VNC** (for both server and client), you could start by [installing their .deb file](https://www.realvnc.com/en/connect/download/vnc/linux/) for the easiest method:

[![Image 15](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20493'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_ubuntu_vnc_server.png)

**Figure 14:** Installing the RealVNC branded VNC Server on Linux can be accomplished with their .deb package file.

To install a .deb file in Ubuntu, you can double click the icon in the file browser/desktop. Alternatively, you may run .deb files from the command line:

$ sudo dpkg -i VNC-Server-6.4.1-Linux-x64.deb

**Option 2:** Alternatively, there is plenty of information online on how to manually install a VNC server from the command line.

Rather than regurgitating someone else’s installation guide here, I’m providing links to promising tutorials:

*   [https://www.cyberciti.biz/faq/install-and-configure-tigervnc-server-on-ubuntu-18-04/](https://www.cyberciti.biz/faq/install-and-configure-tigervnc-server-on-ubuntu-18-04/)
*   [https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-vnc-on-ubuntu-18-04](https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-vnc-on-ubuntu-18-04)

If you find a tutorial that you particularly like for installing VNC via the command line, please share it in the comments section of this post.

#### Real VNC Client

My preferred VNC client is [**Real VNC**](https://www.realvnc.com/en/) which is available for macOS, Linux, Windows, and other operating systems.

You can download the [Real VNC client appropriate for your system using this link](https://www.realvnc.com/en/connect/download/viewer/).

Once you have both (1) VNC server running on your remote machine and (2) the VNC client running on your local machine, follow the steps in **Figure 11**:

1.  Enter the IP address of the remote machine.
2.  Enter the username and password for the account on the remote system.
3.  Enjoy your VNC connection!

From there you have remote access to the desktop and GUI manager on the remote machine.

So, what’s the catch?

**The problem with VNC is that it’s slow due to network latency.** Even on local networks, VNC can appear to be a bit “laggy” at times.

**I personally only use VNC when:**

1.  I need to access my Raspberry Pi on a local network.
2.  I need to run Python scripts that utilize `cv2.imshow` so I can visualize the output.

If your network connection is strong, you can use VNC and `cv2.imshow` calls to debug real-time Python and OpenCV scripts; however, if your connection is weak and you consistently need to use `cv2.imshow`, you should simply use a physical monitor attached to your “remote” machine.

### Jupyter Notebooks

[![Image 16](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20254'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_jupyter_notebook.png)

**Figure 15:** Jupyter Notebooks are great environments if you can stay contained in your web browser. The community loves Jupyter Notebooks for sharing code demos. There are times when you’ll find that Jupyter limits your development, however.

Jupyter Notebooks have become super popular for Python development.

I encourage you to use them, **provided you understand that Jupyter Notebooks are _not_ a replacement for the command** **line — _they are just a different tool in your tool belt_.**

Just because you can execute commands and code via a Jupyter Notebook does not mean you can ignore learning the command line (and vice versa).

**To be a well-rounded developer you need to learn how to use _both_.**

The benefit of Jupyter Notebooks is that you have an interactive IDLE environment that you access via your web browser — you simply point your web browser at the IP address/port of the Jupyter Notebook running on your remote machine and access it. To utilize Jupyter Notebooks you first need to install it on your remote machine:

$ workon your\_env\_name
$ pip install jupyter

If you are using Python virtual environments (recommended) you will need to install the jupyter package into whichever Python environment you use to use Jupyter Notebooks inside of.

As a quick sanity check, you can launch a jupyter notebook via:

$ jupyter notebook

Your web browser will launch automatically if your notebook is running on the local machine and you are also on your local machine.

[![Image 17](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20378'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_jupyter.png)

**Figure 16:** To create a new Python Jupyter Notebook file, simply use the _“New”_ menu in the corner. You may also launch a web-based terminal from this menu.

If your notebook is running remotely, you need to launch a web browser and enter the server IP address and port (`http://10.0.0.90:8888` ) into the URL box.

From there, you can create a new notebook by pressing _“New”_ and _“Python 3”_ as shown in **Figure 16**.

You can insert Python code or system commands into a Notebook in _“Cells”_. Go ahead and press _“Insert”_ > _“Insert cell below”_ a few times. From there you can enter Python code normally. System commands are preceded with `!` (refer to cell _“In \[3\]”_ of **Figure 15**).

#### What about displaying images in Jupyter?

Jupyter does not have access to your system GUI.

Therefore, `cv2.imshow` and any other GUI command will not work.

If you would like to display images inside your Jupyter notebook, I recommend using matplotlib.

The only caveat is that matplotlib’s default channel ordering for display is RGB. As you likely know, OpenCV’s default is BGR. So you must swap the Blue and Red channels (`cv2.cvtColor` ) prior to displaying with matplotlib in a Jupyter notebook. Here’s a quick example:

[![Image 18](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20585%20600'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_jupyter_image.png)

**Figure 17:** Displaying images in Jupyter notebooks for remote computer vision development or developing tutorials.

For further details, be sure to [refer to my previous post](https://pyimagesearch.com/2014/11/03/display-matplotlib-rgb-image/).

### Transferring files to your remote machine or Raspberry Pi

In this section, you will learn how to transfer files from your host machine to your remote machine.

There are many methods to accomplish this task, but my two favorite methods include using SCP/SFTP or using a remotely mounted drive.

#### Manual SCP or SFTP

[![Image 19](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20439'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_transmit.png)

**Figure 18:** Transmit is a macOS app for uploading/downloading files to/from remote machines using FTP/SFTP.

If you need to transfer files to your remote machine (such as moving the code associated with your purchase of [_Raspberry Pi for Computer Vision_](https://pyimagesearch.com/raspberry-pi-for-computer-vision/) from your laptop to your RPi), **I highly recommend using SCP/SFTP.**

If you are using a Unix-based machine you can use the SCP command:

$ scp foo.py username@ip\_address:~/foobar\_project

**Here I am moving a file named `foo.py` _from_ local machine _to_ my remote machine in the `~/foobar_project` folder.**

Note how I am supplying the name of the file along with the IP address and username of the remote machine (the password is supplied after I execute the command).

**Similarly, I can transfer files back from my remote machine to my local machine:**

$ scp username@ip\_address:~/foobar\_project/bar.py ~/foobar\_project

This command transfers a file named `bar.py` back to my local machine in my local machine’s `~/foobar_project` folder.

If you prefer to use a GUI-based program for SCP/SFTP I would recommend using [FileZilla](https://filezilla-project.org/) (all OSes) or [Transmit](https://www.panic.com/transmit/) for macOS (**Figure 18**).

**Using these programs you can simply “drag and drop” files back and forth.**

Of course, the biggest problem with SCP and SFTP is that they are _manual_ — **you cannot _automatically_ transfer files back and forth** (at least not without additional commands).

The _“Developing Python scripts remotely via an IDE”_ section of this tutorial will show you how to automatically transfer files from your host machine to your remote system, but for now, let’s take a look at remote mounted drives.

#### Remote mounted drive

[![Image 20](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20598%20256'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_sshfs.png)

**Figure 19:** Using the SSH file system (SSHFS) you can remotely mount a remote system and access its file system, just like you would on your host machine (i.e., via macOS Finder, the Ubuntu/Raspbian GUI, Windows Explorer, etc.). ([image source](https://www.cyberciti.biz/faq/how-to-mount-remote-directory-filesystems-with-sshfs-on-linux/))

I’m not the biggest fan of remote mounted machines or drives, but they are worth noting here.

Using the SSH file system (SSHFS) you can remote mount a remote system and access its file system, just like you would on your host machine (i.e., via macOS Finder, the Ubuntu/Raspbian GUI, Windows Explorer, etc.).

The problem I’ve always encountered with remote mounted devices is that:

1.  Connections mysteriously drop.
2.  Files don’t always transfer.

Instead, if I want a file to sync automatically (such as when I save/update a file), I use a dedicated IDE, which is exactly what we’ll be covering in the next section.

### Developing Python scripts remotely via an IDE

In this section, you will learn about two software development IDEs that will make working with Python on remote machines a breeze.

#### Sublime Text with SFTP plugin

**[Sublime Text](https://www.sublimetext.com/3)** is a popular code editor.

The editor is free but you can [purchase an optional license](https://www.sublimetext.com/buy?v=3.0) (which I recommend you do if you find yourself using Sublime Text — always be sure to support those who build software you regularly use!).

One of the benefits of Sublime Text is that it allows for extendability via plugins/packages.

For remote developing you should use the **[Sublime Text SFTP plugin](https://codexns.io/products/sftp_for_sublime)**. This plugin is also free but has an [optional paid version](https://codexns.io/products/sftp_for_sublime/buy) (which again, you should consider purchasing if you use the SFTP plugin often). The [installation instructions for the plugin are listed here](https://codexns.io/products/sftp_for_sublime/install).

Once installed, you can launch the Sublime Text editor:

[![Image 21](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20492'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_sublime_text_001.jpg)

**Figure 20:** Sublime Text, a popular text/code editor can work with remote files using a plugin.

Open the command palette via _“shift + command + p”_.

From there, select _“SFTP: Setup Server…”_:

[![Image 22](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20208'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_sublime_text_002.jpg)

**Figure 21:** Selecting the SFTP setup via Sublime Text’s command palette.

You’ll then be prompted with a template JSON file with options you can fill out.

[![Image 23](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20492'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_sublime_text_003.jpg)

**Figure 22:** Sublime Text’s SFTP configuration file needs to be updated before you can connect to a remote system for development.

You’ll want to edit the `host` and `user` to be the IP address and username of your remote machine. You can also specify the password if you want to avoid entering it each time.

You should also specify the `remote_path` which is the default path of where you’ll be placed when logging in — **I typically recommend setting the `remote_path` to be the path of the home directory for the user.**

After editing, my SFTP configuration looks like the following:

[![Image 24](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20632'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_sublime_text_004.jpg)

**Figure 23:** A custom Sublime Text SFTP configuration for a Raspberry Pi on my network.

Next, save the file:

[![Image 25](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20478'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_sublime_text_005.jpg)

**Figure 24:** Saving the SFTP configuration with a name that I’ll recognize later if I want to work on this remote system using Sublime Text again.

Notice how I am prompted with a dialog box asking me to name the file. **You should give the file a descriptive name.** Here I am naming my file `rpi_office` to indicate that this is the Raspberry Pi in my office.

After saving the file I can then select _“SFTP: Browser Server…”_ (via the command palette again):

[![Image 26](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20259'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_sublime_text_006.jpg)

**Figure 25:** From the Sublime Text command palette, select “SFTP: Browse Server…” so that you can log in to a remote system and list files.

And then select my _“rpi\_office”_:

[![Image 27](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20262'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_sublime_text_007.jpg)

**Figure 26:** Selecting my “rpi\_office” remote SFTP configuration in Sublime Text.

I then enter my password and am dropped into the `/home/pi` directory.

From there I select _“Folder Actions”_ followed by _“New File”_ to create a new file named `test.py` :

[![Image 28](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20189'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_sublime_text_008.jpg)

**Figure 27:** Creating plus naming a new file called `test.py` on a remote system (Raspberry Pi) via the Sublime Text SFTP plugin.

I can then save the file, the contents of which are automatically updated on the Raspberry Pi.

Executing the script from an SSH connection, you can see the text _“Hello, PyImageSearch Reader!”_ is displayed to my terminal (again, noting that the code itself was executed on the Raspberry Pi and not my local machine).

[![Image 29](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20254'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_sublime_text_009.jpg)

**Figure 28:** As you can see, I’m SSH’ed into my remote Raspberry Pi. I’ve executed the Python script that was just saved to the remote system automatically via Sublime Text’s SFTP plugin.

#### A quick note to Amazon EC2 users

If you are using Amazon EC2 or any other authentication method that requires an SSH key, you need to edit the `sftp_flags` option during server setup.

Specifically, you’ll want to edit to look like the following:

[![Image 30](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20132'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_sublime_text_010.jpg)

**Figure 29:** Using Sublime Text’s SFTP plugin with Amazon EC2 systems requires that you insert the path to your encryption key (.pem file) in your configuration.

Notice how I have updated `sftp_flags` to include the `-i` option, followed by the path to my SSH key. The SFTP plugin then knows to perform the proper authentication using this file.

_**Note:**_ _While you edit remote code on your local machine, your system will automatically generate/download temporary files that you see on your screen. When you “Save” your code, it is automatically updated to the remote machine. If you ever also need these files on your local system, I would recommend using SCP/SFTP to transfer the files. You may also use the “Save as” command in Sublime to save a file locally._

### PyCharm with automatic upload deployment

If you are looking for a more full-fledged IDE, I recommend using **[PyCharm](https://www.jetbrains.com/pycharm/)** which has essentially become the de facto standard for Python IDEs.

I’m a _huge_ fan of PyCharm, and if my Python code ends up spanning more than 1-2 files, I tend to use PyCharm over Sublime Text. That said, PyCharm is a _big_ IDE — it’s _not_ small and minimal like Sublime Text is.

Similar to Sublime Text, we can also configure PyCharm to:

1.  Use a remote Python interpreter (including a Python virtual environment on a remote machine).
2.  Automatically transfer edited files, ensuring that code is updated on your remote machine.

This feature requires that you have **PyCharm Professional** installed ([click here to see the features and benefits of **PyCharm Professional**](https://www.jetbrains.com/pycharm/features/editions_comparison_matrix.html)).

Assuming you have PyCharm installed, let’s create a project that performs automatic upload deployment.

Start by creating a new project:

[![Image 31](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20401'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_pycharm_001.jpg)

**Figure 30:** Creating a new project in PyCharm locally prior to setting it up for remote development.

I have named this project _“RPiTest”_.__

You’ll then want to expand the _“Project Interpreter”_ option to expand the Python interpreter options:

[![Image 32](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20401'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_pycharm_002.jpg)

**Figure 31:** In PyCharm, select _“Python Interpreter”_ to configure the Python environment for the project.

Select the _“Existing interpreter”_ radio button and then click the _“…”_ which will open a new window similar to the following:

[![Image 33](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20415'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_pycharm_003.jpg)

**Figure 32:** Select the _“Existing Interpreter”_ option in PyCharm.

Select the _“SSH Interpreter”_ option and then _“New server configuration”_:

[![Image 34](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20415'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_pycharm_004.jpg)

**Figure 33:** Select _“New server configuration”_ and enter the IP address, and username of the remote system.

Here I have entered the IP address and username my Raspberry Pi.

Click the _“Next”_ button and then enter the password for your server:

[![Image 35](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20415'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_pycharm_005.jpg)

**Figure 34:** Enter your remote system’s password and ensure that you save the password (checkbox) so that you don’t need to enter it upon each save.

Make sure you check the _“Save password”_ checkbox to ensure your password is saved, otherwise you will have to re-enter it each time you want to save/modify a file (which will become quite frustrating and tedious).

The next window will prompt you to select a Python interpreter, which will by default be `/usr/bin/python`:

[![Image 36](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20415'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_pycharm_006.jpg)

**Figure 35:** Be sure to select the virtual environment on the remote system that you’d like to use as your Python interpreter.

Since we’re using Python virtual environments we should instead click the _“…”_ and navigate to the `python` binary inside the `/home/pi/.virtualenvs/py3cv3/bin/python` directory:

[![Image 37](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20423'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_pycharm_007.jpg)

**Figure 36:** Navigate to the Python executable within the appropriate .virtualenvs folder to select your remote interpreter.

Select _“Ok”_ to confirm the Python virtual environment choice. Notice how the Python interpreter path has now been updated to to be `/home/pi/.virtualenvs/py3cv3/bin/python`. Click the “Finish” button to finish creating the Python virtual environment.

PyCharm will now provide us with details on our _“Existing interpreter”_ along with the _“Remote project location”_:

[![Image 38](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20401'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_pycharm_008.jpg)

**Figure 37:** Be sure to edit the PyCharm _“Remote project location”_ under the _“Existing Interpreter”_ section so that your project files are stored in a known location.

However, we don’t want our project to live in `/tmp/pycharm_project_409` on the Raspberry Pi. **Instead, we want this project to live in `/home/pi/RPiTest`.** To make this update, you can either use the _“…”_ button to navigate or simply manually type in the path into the field.

Click the _“Create”_ button and then the PyCharm IDE will then load:

[![Image 39](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20428'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_pycharm_009.jpg)

**Figure 38:** PyCharm Professional has now been configured for remote development over an SSH/SFTP connection.

It may take 5-10 minutes for PyCharm to index the Python virtual environment and project files on your Raspberry Pi, so be patient.

Let’s add a new file to the project.

Right click on the RPiTest directory in the project and then select _“New”_ and _“File”_:

[![Image 40](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20389'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_pycharm_010.jpg)

**Figure 39:** Adding a new Python file to our PyCharm remote project.

We’ll name this file `pycharm_test.py`:

[![Image 41](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20367'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_pycharm_011.jpg)

**Figure 40:** Saving a Python script on a remote machine via PyCharm called `pycharm_test.py`.

I’ve updated the file to include the following code:

[![Image 42](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20560'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_pycharm_012.jpg)

**Figure 41:** A test script was developed and saved to a remote system via PyCharm.

Notice how PyCharm is indicating that the file has been _**automatically**_ uploaded to the Raspberry Pi for us. You can validate that the file has been automatically uploaded by logging into the Raspberry Pi via a terminal and checking the file contents:

[![Image 43](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20353'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_pycharm_013.jpg)

**Figure 42:** Over an SSH connection in my terminal, I’ve verified that after saving a file via PyCharm to my remote Raspberry Pi, that the file is, in fact, updated.

**When it comes to remote Python development it’s hard to beat PyCharm with automatic upload.**

Yes, there are more steps involved (at least when compared to configuring Sublime Text), but once you have it working, _it’s well worth it!_

_**Note:**_ _While you edit remote code on your local machine, your system will automatically generate/download temporary files that you see on your screen. When you “Save” your code, it is automatically updated to the remote machine._

### Executing code via the command line

When performing remote Python development, my personal recommendation is to:

1.  Use either **Sublime Text** or **PyCharm** with automatic SFTP enabled.
2.  Execute my Python scripts via **command line using SSH**.

You are free to use whichever option you prefer. Perhaps you like to use Jupyter Notebooks. Or maybe you feel like you have more control using manual SFTP upload. **All options are perfectly okay, it’s just a matter of your own preference.**

That said, I’m going to give you a quick demonstration of executing a script via the command line over SSH.

First, I am going to login to my Raspberry Pi (or AWS server) using SSH:

$ ssh pi@192.168.1.150
$ ls \*.py
simple\_example.py

I have listed the contents of my home directory and see I have an existing file named `simple_example.py`.

I’d like to edit this file so I’m also going to login via Sublime Text and open it:

[![Image 44](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20240'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2019/07/remote_development_simple_example_editor.jpg)

**Figure 43:** I’ve opened a file on my remote system using Sublime Text’s SFTP plugin. Now we’re going to edit the file an execute it.

Here you can see `simple_example.py` is now open in Sublime Text.

I’m going to take the opportunity to edit this file and include a [command line argument](https://pyimagesearch.com/2018/03/12/python-argparse-command-line-arguments/) — the code listing now looks like:

\# import the necessary packages
import argparse

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add\_argument("-n", "--name", help="your name")
args = vars(ap.parse\_args())

# greet the user
print("Hello there, {}!".format(args\["name"\]))

I save the file via Sublime Text and then switch back to my terminal. I can then execute the Python script via:

$ python simple\_example.py --name Adrian
Hello there, Adrian!

Note how I’ve [supplied the command line argument to the script](https://pyimagesearch.com/2018/03/12/python-argparse-command-line-arguments/) — we use command line arguments quite often on PyImageSearch so make sure you take the time now to understand how they work.

Also, note how the script has been executed not on my local machine, but on the remote Raspberry Pi.

### What's next? We recommend [PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/?utm_source=blogPost&utm_medium=bottomBanner&utm_campaign=What%27s%20next%3F%20I%20recommend).

**Course information:**  
84 total classes • 114+ hours of on-demand code walkthrough videos • Last updated: February 2024  
★★★★★ 4.84 (128 Ratings) • 16,000+ Students Enrolled

**I strongly believe that if you had the right teacher you could _master_ computer vision and deep learning.**

Do you think learning computer vision and deep learning has to be time-consuming, overwhelming, and complicated? Or has to involve complex mathematics and equations? Or requires a degree in computer science?

That’s _not_ the case.

All you need to master computer vision and deep learning is for someone to explain things to you in _simple, intuitive_ terms. _And that’s exactly what I do_. My mission is to change education and how complex Artificial Intelligence topics are taught.

If you're serious about learning computer vision, your next stop should be PyImageSearch University, the most comprehensive computer vision, deep learning, and OpenCV course online today. Here you’ll learn how to _successfully_ and _confidently_ apply computer vision to your work, research, and projects. Join me in computer vision mastery.

**Inside PyImageSearch University you'll find:**

*   ✓ **84 courses** on essential computer vision, deep learning, and OpenCV topics
*   ✓ **84 Certificates** of Completion
*   ✓ **114+ hours** of on-demand video
*   ✓ **Brand new courses released _regularly_**, ensuring you can keep up with state-of-the-art techniques
*   ✓ **Pre-configured Jupyter Notebooks in Google Colab**
*   ✓ Run all code examples in your web browser — works on Windows, macOS, and Linux (no dev environment configuration required!)
*   ✓ Access to **centralized code repos for _all_ 536+ tutorials** on PyImageSearch
*   ✓ **Easy one-click downloads** for code, datasets, pre-trained models, etc.
*   ✓ **Access** on mobile, laptop, desktop, etc.

[Click here to join PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/?utm_source=blogPost&utm_medium=bottomBanner&utm_campaign=What%27s%20next%3F%20I%20recommend)

Summary
-------

In this tutorial, you discovered my personal recommendations when performing remote Python development on the Raspberry Pi, Amazon EC2, or any other remote server instance.

When you’re connecting to the machine I recommend using:

*   SSH
*   VNC
*   Jupyter Notebooks

When editing code remotely I suggest you use either:

*   Sublime Text with SFTP plugin
*   PyCharm with automatic upload deployment

My personal preference is to edit code via either Sublime Text or PyCharm and then execute via SSH + command line. That said, you should take the time to play with each option. One method is not always better than the others and you may find you prefer one method over the other in the majority of situations — that’s perfectly okay!

Keep in mind that these are all tools in your tool belt, learn how to use them all and you’ll have more tools available to you.

I hope you enjoyed this tutorial!

**To be notified when future tutorials are published here on PyImageSearch (and obtain my free computer vision and deep learning resource guide), _just enter your email address in the form below!_**

![Image 45](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20410%20567'%3E%3C/svg%3E)

#### Join the PyImageSearch Newsletter and Grab My FREE 17-page Resource Guide PDF

Enter your email address below to **join the PyImageSearch Newsletter** and **download my FREE 17-page Resource Guide PDF** on Computer Vision, OpenCV, and Deep Learning.