Home » Tutorials » How to Make a File Transfer App in Python

How to Make a File Transfer App in Python

Imagine we’re building a bridge between two islands, but instead of cars, we’re sending files across, and our bridge is made of Python code. We’ll use tkinter as our toolbox to build a user-friendly control panel. Then, we’ll dive into the world of socket programming, which is like setting up the telephone lines between our islands, allowing them to talk to each other and send precious cargo (our files) back and forth.

In today’s tutorial, we’re going to create a File Transfer App. You’ll learn how to transfer files in Python, which is ideal for users on the same network, this App facilitates smooth file sharing directly through our Python code.

Let’s get started!

Table of Contents

Necessary Libraries

Make sure to install the tkinter library via the terminal or your command prompt for the code to function properly:

$ pip install tk

Imports

We begin by importing socket for device communication, followed by os for file operations. Then, we import tkinter to create our graphical user interface (GUI), along with specific classes from tkinter that will be crucial in our application.

import socket
import os
import tkinter as tk
from tkinter import filedialog, Label, Button, Entry, messagebox

FileTransferApp Class

Next, we lay out a blueprint for our file transfer app, giving the main window a title, setting its dimensions, choosing a background color, and disabling resizing.

class FileTransferApp:
   def __init__(self, master):
       self.master = master
       self.master.title("File Transfer App - The Pycodes")
       self.master.geometry("450x560")
       self.master.configure(bg="lightblue")
       self.master.resizable(False, False)

Instance Variable

  self.filename = None  # Instance variable for filename

What we did here is create a variable to store and remember the name of the file.

Create Widgets

After that, we create the visuals for our app. This includes the target_ip label, followed by the ‘IP address’ entry box. We also add three buttons “Select, Send, Receive” File, each triggering a specific function when pressed.

Lastly, the app displays the local IP address.

       self.create_widgets()
   def create_widgets(self):
       # Entry for target IP address
       self.ip_entry_label = Label(self.master, text="Target IP:", bg="lightblue", font="arial 12 bold")
       self.ip_entry_label.place(x=190, y=100)


       self.ip_entry = Entry(self.master, width=40, font="arial 12")
       self.ip_entry.place(x=50, y=130)


       # Button to select a file
       self.select_file_button = Button(self.master, text="Select File", command=self.select_file, font="arial 11")
       self.select_file_button.place(x=170, y=190)


       # Button to send file
       self.send_button = Button(self.master, text="Send File", command=self.send_file, font="arial 11")
       self.send_button.place(x=50, y=230)


       # Button to receive file
       self.receive_button = Button(self.master, text="Receive File", command=self.receive_file, font="arial 11")
       self.receive_button.place(x=300, y=230)


       # Display local IP address
       self.local_ip_label = Label(self.master, text=f"My Local IP is: {socket.gethostbyname(socket.gethostname())}", bg="lightblue", fg="black", font="arial 10 bold")
       self.local_ip_label.place(x=50, y=280)

Button’s Functions

Select File

Now we define the functions for the buttons, this one opens a dialog where the user can select and store a file, and if he doesn’t select a file, an error message will appear.

   def select_file(self):
       self.filename = filedialog.askopenfilename(initialdir=os.getcwd(), title='Select File',
                                                  filetypes=(('All files', '*.*'),))
       if not self.filename:
           messagebox.showerror("ERROR", "No file selected")

Send File

Following that, we create this function to send the selected and stored file to the device, using the local IP address provided by the user. This function also displays a message indicating the success of the process or reports an error if the transfer fails or the target IP address was not entered.

   def send_file(self):
       target_ip = self.ip_entry.get()
       if target_ip and self.filename:
           try:
               with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s, open(self.filename, 'rb') as file:
                   s.connect((target_ip, 8080))
                   while file_data := file.read(1024):
                       s.send(file_data)
                   messagebox.showinfo("Success", "Data has been transmitted successfully")
           except Exception as e:
               messagebox.showerror("ERROR", f"Error: {e}")
       else:
           messagebox.showerror("ERROR", "Please enter a target IP and select a file")

Receive File

Here, we define a function to save the sent file data to a specified directory. It also displays an error message if the file is not received or if the recipient has not selected a directory to receive the sent data.

   def receive_file(self):
       filename1 = filedialog.asksaveasfilename(initialdir=os.getcwd(), title='Save Received File in',
                                                filetypes=(('All files', '*.*'),))
       if filename1:
           try:
               with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
                   s.bind(('0.0.0.0', 8080))
                   s.listen(1)
                   conn, addr = s.accept()
                   with conn, open(filename1, 'wb') as file:
                       while file_data := conn.recv(1024):
                           file.write(file_data)
                   messagebox.showinfo("Success", "File has been received successfully")
           except Exception as e:
               messagebox.showerror("ERROR", f"Error: {e}")
       else:
           messagebox.showerror("ERROR", "Please enter a valid filename")

Main Block

Lastly, this part creates the main window sets up the GUI elements, and starts the program’s main loop (keep it running) until the user chooses not to.

if __name__ == "__main__":
   root = tk.Tk()
   Label(root, text="Simple File Transfer",bg="lightblue",fg="red",font="arial 20 bold").place(x=50, y=50)
   app = FileTransferApp(root)
  
   root.mainloop()

Example

Full Code

import socket
import os
import tkinter as tk
from tkinter import filedialog, Label, Button, Entry, messagebox


class FileTransferApp:
   def __init__(self, master):
       self.master = master
       self.master.title("File Transfer App - The Pycodes")
       self.master.geometry("450x560")
       self.master.configure(bg="lightblue")
       self.master.resizable(False, False)


       self.filename = None  # Instance variable for filename


       self.create_widgets()


   def create_widgets(self):
       # Entry for target IP address
       self.ip_entry_label = Label(self.master, text="Target IP:", bg="lightblue", font="arial 12 bold")
       self.ip_entry_label.place(x=190, y=100)


       self.ip_entry = Entry(self.master, width=40, font="arial 12")
       self.ip_entry.place(x=50, y=130)


       # Button to select a file
       self.select_file_button = Button(self.master, text="Select File", command=self.select_file, font="arial 11")
       self.select_file_button.place(x=170, y=190)


       # Button to send file
       self.send_button = Button(self.master, text="Send File", command=self.send_file, font="arial 11")
       self.send_button.place(x=50, y=230)


       # Button to receive file
       self.receive_button = Button(self.master, text="Receive File", command=self.receive_file, font="arial 11")
       self.receive_button.place(x=300, y=230)


       # Display local IP address
       self.local_ip_label = Label(self.master, text=f"My Local IP is: {socket.gethostbyname(socket.gethostname())}", bg="lightblue", fg="black", font="arial 10 bold")
       self.local_ip_label.place(x=50, y=280)


   def select_file(self):
       self.filename = filedialog.askopenfilename(initialdir=os.getcwd(), title='Select File',
                                                  filetypes=(('All files', '*.*'),))
       if not self.filename:
           messagebox.showerror("ERROR", "No file selected")


   def send_file(self):
       target_ip = self.ip_entry.get()
       if target_ip and self.filename:
           try:
               with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s, open(self.filename, 'rb') as file:
                   s.connect((target_ip, 8080))
                   while file_data := file.read(1024):
                       s.send(file_data)
                   messagebox.showinfo("Success", "Data has been transmitted successfully")
           except Exception as e:
               messagebox.showerror("ERROR", f"Error: {e}")
       else:
           messagebox.showerror("ERROR", "Please enter a target IP and select a file")


   def receive_file(self):
       filename1 = filedialog.asksaveasfilename(initialdir=os.getcwd(), title='Save Received File in',
                                                filetypes=(('All files', '*.*'),))
       if filename1:
           try:
               with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
                   s.bind(('0.0.0.0', 8080))
                   s.listen(1)
                   conn, addr = s.accept()
                   with conn, open(filename1, 'wb') as file:
                       while file_data := conn.recv(1024):
                           file.write(file_data)
                   messagebox.showinfo("Success", "File has been received successfully")
           except Exception as e:
               messagebox.showerror("ERROR", f"Error: {e}")
       else:
           messagebox.showerror("ERROR", "Please enter a valid filename")


if __name__ == "__main__":
   root = tk.Tk()
   Label(root, text="Simple File Transfer", bg="lightblue", fg="red", font="arial 20 bold").place(x=80, y=50)
   app = FileTransferApp(root)


   root.mainloop()

Happy Coding!

2 thoughts on “How to Make a File Transfer App in Python”

  1. Hey would you mind sharing which blog platform you’re using?

    I’m looking to start my own blog in the near future but I’m having a difficult
    time making a decision between BlogEngine/Wordpress/B2evolution and Drupal.
    The reason I ask is because your design and style seems
    different then most blogs and I’m looking for something completely unique.
    P.S Sorry for getting off-topic but I had to ask!

    1. Oh, absolutely, happy to share! I’m actually on WordPress. I decided to go with a custom theme to give my blog that unique touch you mentioned. Honestly, choosing the right platform can be quite the journey, but WordPress has been super versatile for me. And hey, no worries about the detour – it’s a great question!

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top