Skip to content

Commit

Permalink
Add examples with configurations
Browse files Browse the repository at this point in the history
  • Loading branch information
brentvollebregt committed Oct 5, 2024
1 parent f46cbdd commit 47c3b47
Show file tree
Hide file tree
Showing 16 changed files with 319 additions and 0 deletions.
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
include README.md
include LICENSE
graft auto_py_to_exe/web
prune examples
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,15 @@ Instead of inserting the same data into the UI over and over again, you can expo

This JSON config export action does not save the output directory automatically as moving hosts could mean different directory structures. If you want to have the output directory in the JSON config, add the directory under `nonPyinstallerOptions.outputDirectory` in the JSON file (will need to create a new key).

## Examples

The [examples/](./examples/) directory offers some examples of how to write your scripts and package them with auto-py-to-exe.

- [Basic (console application)](./examples/1-basic/readme.md)
- [No Console (as typically desired for GUI-based applications)](./examples/2-no-console/readme.md)
- [Images and other non-.py files (static files to be included)](./examples/3-images-and-other-non-py-files/readme.md)
- [Persistent data (like databases)](./examples/4-persistent-data/readme.md)

## Video

If you need something visual to help you get started, [I made a video for the original release of this project](https://youtu.be/OZSZHmWSOeM); some things may be different but the same concepts still apply.
Expand Down
17 changes: 17 additions & 0 deletions examples/1-basic/auto-py-to-exe-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": "auto-py-to-exe-configuration_v1",
"pyinstallerOptions": [
{
"optionDest": "filenames",
"value": "./main.py"
},
{
"optionDest": "onefile",
"value": true
},
{
"optionDest": "console",
"value": true
}
]
}
4 changes: 4 additions & 0 deletions examples/1-basic/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import sys

print("Hello world")
print(f"Running with Python {sys.version}")
34 changes: 34 additions & 0 deletions examples/1-basic/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Example 1 - Basic

This example is a basic Hello World application. Nothing is out of the ordinary in this example.

## Packaging

To package this, you can use `auto-py-to-exe` and use "Console Based".

- "Console Based" is needed because we need to be able to output the `print` call. If we were to use "Window Based", we would no longer have access to stdout and it would be like we were running the script as a .pyw file - in this case `print` would error.

### Using the Configuration

1. Open a terminal in this directory (`examples/1-basic`)
2. Execute `auto-py-to-exe --config auto-py-to-exe-config.json` to open auto-py-to-exe with the supplied config
3. Click the big blue convert button at the bottom
4. When done, click the big blue "OPEN OUTPUT FOLDER" to view the output exe

## Running

Run the output exe using the terminal. If you double-click on it, it will run, but the console will close immediately. Running the exe from the terminal will allow you to see the output.

To run the exe using the terminal in Windows (similar for other OS'):

1. Open cmd
2. cd to the directory that the exe was generated in
3. Execute `main.exe` to run the executable.

Here is an example of the output:

```
C:\Users\USER\Repos\auto-py-to-exe\examples\1-basic\output>main.exe
Hello world
Running with Python 3.9.9 (tags/v3.9.9:ccb0e6a, Nov 15 2021, 18:08:50) [MSC v.1929 64 bit (AMD64)]
```
17 changes: 17 additions & 0 deletions examples/2-no-console/auto-py-to-exe-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": "auto-py-to-exe-configuration_v1",
"pyinstallerOptions": [
{
"optionDest": "filenames",
"value": "./main.py"
},
{
"optionDest": "onefile",
"value": true
},
{
"optionDest": "console",
"value": false
}
]
}
11 changes: 11 additions & 0 deletions examples/2-no-console/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import tkinter as tk

# Setup the window
window = tk.Tk()

# Add the label
greeting = tk.Label(text="Hello from Tkinter", padx=40, pady=15)
greeting.pack()

# Keep the script running until the GUI closes
window.mainloop()
20 changes: 20 additions & 0 deletions examples/2-no-console/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Example 2 - No Console

This example is a basic GUI application.

## Packaging

To package this, you can use `auto-py-to-exe` and use "Window Based".

- Make sure "Window Based" is used otherwise a blank terminal will also appear (which we do not need as we are not calling `print`).

### Using the Configuration

1. Open a terminal in this directory (`examples/2-no-console`)
2. Execute `auto-py-to-exe --config auto-py-to-exe-config.json` to open auto-py-to-exe with the supplied config
3. Click the big blue convert button at the bottom
4. When done, click the big blue "OPEN OUTPUT FOLDER" to view the output exe

## Running

You can run the exe using a terminal or by double-clicking it. Since we have used `window.mainloop()`, the application will keep running until the window is closed.
5 changes: 5 additions & 0 deletions examples/3-images-and-other-non-py-files/assets/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"data1": 1,
"data2": 2,
"data3": 3
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"version": "auto-py-to-exe-configuration_v1",
"pyinstallerOptions": [
{
"optionDest": "filenames",
"value": "./main.py"
},
{
"optionDest": "onefile",
"value": true
},
{
"optionDest": "console",
"value": false
},
{
"optionDest": "datas",
"value": "./assets;assets/"
}
]
}
34 changes: 34 additions & 0 deletions examples/3-images-and-other-non-py-files/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import os
import sys
import tkinter as tk
from pathlib import Path


def resource_path(relative_path):
"""Get the absolute path to the resource, works for dev and for PyInstaller"""
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
# If we are still in dev mode, make our paths start from the folder this file is in
base_path = Path(__file__).parent

return os.path.join(base_path, relative_path)


# Setup the window
window = tk.Tk()

# Show the image
image = tk.PhotoImage(file=resource_path("assets/image.gif"))
image_label = tk.Label(window, image=image)
image_label.pack()

# Show the contents of the JSON file
with open(resource_path("assets/data.json")) as f:
data = f.read()
data_label = tk.Label(text=data, padx=40, pady=15)
data_label.pack()

# Keep the script running until the GUI closes
window.mainloop()
26 changes: 26 additions & 0 deletions examples/3-images-and-other-non-py-files/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Example 3 - Images and Other Non-.py Files

This example is a GUI application that also references a GIF (image) and a JSON file.

## Packaging

To package this, you can use `auto-py-to-exe` and use "Window Based". To add the GIF and JSON files, in the "Additional Files" section, click "Add Folder" and select the "assets" folder in this directory.

- Make sure "Window Based" is used otherwise a blank terminal will also appear (which we do not need as we are not calling `print`).
- Adding the assets folder to the "Additional Files" section will make sure all files in that folder are included. When using "One Directory", you will be able to see the folder within the "\_internal" folder.
- You can use either "One Directory" or "One File" for this. The usage of `resource_path` in main.py means both will work.

### Using the Configuration

1. Open a terminal in this directory (`examples/3-images-and-other-non-py-files`)
2. Execute `auto-py-to-exe --config auto-py-to-exe-config.json` to open auto-py-to-exe with the supplied config
3. Click the big blue convert button at the bottom
4. When done, click the big blue "OPEN OUTPUT FOLDER" to view the output exe

## Running

You can run the exe using a terminal or by double-clicking it. Since we have used `window.mainloop()`, the application will keep running until the window is closed.

## Notes

If you have used "One File" mode, any changes made to the JSON file will be overwritten every time. See example 4 for how to stop this.
17 changes: 17 additions & 0 deletions examples/4-persistent-data/auto-py-to-exe-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": "auto-py-to-exe-configuration_v1",
"pyinstallerOptions": [
{
"optionDest": "filenames",
"value": "./main.py"
},
{
"optionDest": "onefile",
"value": true
},
{
"optionDest": "console",
"value": true
}
]
}
41 changes: 41 additions & 0 deletions examples/4-persistent-data/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import json
import os
from pathlib import Path

DEFAULT_DATA = {"count": 0}

# First we identify where the persistent data should sit.
# It cannot be packaged inside our exe because if "One File" mode is used, it will be overwritten every time.
# For this example, I put the data file in the following folder:
# - If Windows: C:/Users/Brent/AppData/Local/AutoPyToExeDemo
# - If something else: The users home folder
# For your implementation, you can pick somewhere else - as long as it isn't in the project.
if os.name == "nt":
data_folder_location = Path.home() / "AppData/Local/AutoPyToExeDemo"
else:
data_folder_location = Path.home() / "AutoPyToExeDemo"

# We create the directory if it doesn't exist. We also make sure to create any parents if they don't exist.
data_folder_location.mkdir(parents=True, exist_ok=True)

# Next we check if the file exists. If not, we create it and put default data into it.
data_file_location = data_folder_location / "data.json"
if not data_file_location.exists():
print(f"Data file doesn't exist. Creating at {data_file_location}")
with open(str(data_file_location), "w") as f:
json.dump(DEFAULT_DATA, f, indent=2)
else:
print(f"Data file exists at {data_file_location}")

# We read the file in (as we know it exists now)
with open(str(data_file_location), "r") as f:
data = json.load(f)
print(f"Current contents: {data}")

# We update the contents of the file
data["count"] += 1

# We write the file back
with open(str(data_file_location), "w") as f:
json.dump(data, f, indent=2)
print(f"Saved new contents: {data}")
62 changes: 62 additions & 0 deletions examples/4-persistent-data/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Example 4 - Persistent Data

This example demonstrates how you can manage persistent data outside your executable. This is needed when you have something like a SQLite database or something else used to store data between application runs.

When using "One File" mode, you should not store files you want to persist beside the executable because they will be overwritten on the next run. If you are using "One Directory", this is not an issue as the executable doesn't have to extract itself every time.

## Packaging

To package this, you can use `auto-py-to-exe` and use "Console Based".

- "Console Based" is needed because we need to be able to output the `print` call. If we were to use "Window Based", we would no longer have access to stdout and it would be like we were running the script as a .pyw file - in this case `print` would error.

> "Console Based" is only required for the demonstration as `print` calls are made. If you do not need stdout (like `print` does) in your application, you can use "Window Based".
### Using the Configuration

1. Open a terminal in this directory (`examples/4-persistent-data`)
2. Execute `auto-py-to-exe --config auto-py-to-exe-config.json` to open auto-py-to-exe with the supplied config
3. Click the big blue convert button at the bottom
4. When done, click the big blue "OPEN OUTPUT FOLDER" to view the output exe

## Running

Run the output exe using the terminal. If you double-click on it, it will run, but the console will close immediately. Running the exe from the terminal will allow you to see the output.

To run the exe using the terminal in Windows (similar for other OS'):

1. Open cmd
2. cd to the directory that the exe was generated in
3. Execute `main.exe` to run the executable.

When running the exe, you will see:

- The target folder gets created if it doesn't exist
- The data file gets created with default data if it doesn't exist
- Even run increments the `count` value in the JSON file

Here is an example of the output:

```
C:\Users\USER\Repos\auto-py-to-exe\examples\4-persistent-data\output>main.exe
Data file doesn't exist. Creating at C:\Users\USER\AppData\Local\AutoPyToExeDemo\data.json
Current contents: {'count': 0}
Saved new contents: {'count': 1}
C:\Users\USER\Repos\auto-py-to-exe\examples\4-persistent-data\output>main.exe
Data file exists at C:\Users\USER\AppData\Local\AutoPyToExeDemo\data.json
Current contents: {'count': 1}
Saved new contents: {'count': 2}
C:\Users\USER\Repos\auto-py-to-exe\examples\4-persistent-data\output>main.exe
Data file exists at C:\Users\USER\AppData\Local\AutoPyToExeDemo\data.json
Current contents: {'count': 2}
Saved new contents: {'count': 3}
C:\Users\USER\Repos\auto-py-to-exe\examples\4-persistent-data\output>main.exe
Data file exists at C:\Users\USER\AppData\Local\AutoPyToExeDemo\data.json
Current contents: {'count': 3}
Saved new contents: {'count': 4}
C:\Users\USER\Repos\auto-py-to-exe\examples\4-persistent-data\output>
```

0 comments on commit 47c3b47

Please sign in to comment.