.. _getting_started: =============== Getting Started =============== .. _installing: Installing ========== Installing Rust --------------- PyOxidizer is a Rust application and requires Rust 2018 (1.31 or newer) to be installed in order to build PyOxidizer itself as well as Python application binaries. You can verify your installed version of Rust by running:: $ rustc --version rustc 1.35.0 (3c235d560 2019-05-20) If you don't have Rust installed, https://www.rust-lang.org/ has very detailed instructions on how to install it. Rust releases a new version every 6 weeks and language development moves faster than other programming languages. It is common for the Rust packages provided by common package managers to lag behind the latest Rust release by several releases. For that reason, use of the ``rustup`` tool for managing Rust is highly recommended. If you are a security paranoid individual and don't want to follow the official ``rustup`` install instructions involving a ``curl | sh`` (your paranoia is understood), you can find instructions for alternative installation methods at https://github.com/rust-lang/rustup.rs/#other-installation-methods. Other System Dependencies ------------------------- You will need a working C compiler/toolchain in order to build some Rust crates and their dependencies. If Rust cannot find a C compiler, it should print a message at build time and give you instructions on how to install one. There is a known issue with PyOxidizer on Fedora 30+ that will require you to install the ``libxcrypt-compat`` package to avoid an error due to a missing ``libcrypt.so.1`` file. See https://github.com/indygreg/PyOxidizer/issues/89 for more info. Installing PyOxidizer --------------------- PyOxidizer can be installed from its latest published crate:: $ cargo install pyoxidizer From a Git repository using cargo:: # The latest commit in source control. $ cargo install --git https://github.com/indygreg/PyOxidizer.git --branch main pyoxidizer $ A specific release $ cargo install --git https://github.com/indygreg/PyOxidizer.git --tag pyoxidizer Or by cloning the Git repository and building the project locally:: $ git clone https://github.com/indygreg/PyOxidizer.git $ cd PyOxidizer $ cargo install --path pyoxidizer .. note:: PyOxidizer's project policy is for the ``main`` branch to be stable. So it should always be relatively safe to use ``main`` instead of a released version. Once the ``pyoxidizer`` executable is installed, try to run it:: $ pyoxidizer PyOxidizer 0.1 Gregory Szorc Build and distribute Python applications USAGE: pyoxidizer [SUBCOMMAND] ... Congratulations, PyOxidizer is installed! Now let's move on to using it. Your First PyOxidizer Project ============================= The ``pyoxidizer init`` command will create a new [Rust] project which supports embedding Python. Invoke it with the directory you want to create your new project in:: $ pyoxidizer init pyapp This should have printed out details on what happened and what to do next. If you actually ran this in a terminal, hopefully you don't need to continue following the directions here as the printed instructions are sufficient! But if you aren't, keep reading. The default project created by ``pyoxidizer init`` will produce an executable that embeds Python and starts a Python REPL by default. Let's test that:: $ cd pyapp $ pyoxidizer run no existing PyOxidizer artifacts found processing config file /home/gps/src/pyapp/pyoxidizer.toml resolving Python distribution... ... Compiling pyapp v0.1.0 (/home/gps/src/pyapp) Finished dev [unoptimized + debuginfo] target(s) in 53.14s Running `target/debug/testapp` >>> If all goes according to plan, you just started a Rust executable which started a Python interpreter, which started an interactive Python debugger! Try typing in some Python code:: >>> print("hello, world") hello, world It works! (To exit the REPL, press CTRL+d or CTRL+z.) Continue reading :ref:`managing_projects` to learn more about the ``pyoxidizer`` tool. Or read on for a preview of how to customize your application's behavior. Customizing Python and Packaging Behavior ========================================= Embedding Python in a Rust executable and starting a REPL is cool and all. But you probably want to do something more exciting. Inside the project's root directory is an autogenerated ``pyoxidizer.toml`` file. This file configures how the embedded Python interpreter is built as well as defines default run-time behavior. See :ref:`new_project_layout` if you are interested in what all the files do. Open ``pyoxidizer.toml`` in your favorite editor and find the ``[[python_run]]`` section. This section configures what to do when the interpreter starts. By default, it should have a ``mode = "repl"`` line. Let's comment that out or delete it and replace it with the following:: [[embedded_python_run]] mode = "eval" code = "import uuid; print(uuid.uuid4())" We're now telling the interpreter to effectively run the Python statement ``eval(import uuid; print(uuid.uuid4())`` when it starts. Test that out:: $ pyoxidizer run Compiling pyembed v0.1.0 (/home/gps/src/pyapp/pyembed) Compiling pyapp v0.1.0 (/home/gps/src/pyapp) Finished dev [unoptimized + debuginfo] target(s) in 3.92s Running `target/debug/pyapp` 96f776c8-c32d-48d8-8c1c-aef8a735f535 It works! This is still pretty trivial. But it demonstrates how the ``pyoxidizer.toml`` is used to influence the behavior of built binaries. Let's do something a little bit more complicated, like package an existing Python application! Find the existing ``[[python_packages]]`` section in the ``pyoxidizer.toml``. Now let's add the following lines after the last of those sections:: [[packaging_rule]] type = "pip-install-simple" package = "pyflakes==2.1.1" And change the ``[[embedded_python_run]]`` section to:: [[embedded_python_run]] mode = "eval" code = "from pyflakes.api import main; main()" This tells PyOxidizer that you want to install version 2.1.1 of the ``pyflakes`` package. At build time, this will effectively perform a ``pip install pyflakes==2.1.1`` and take all installed files and add them to the produced binary. Let's try that:: $ pyoxidizer run -- --help Compiling pyembed v0.1.0 (/home/gps/tmp/pyapp/pyembed) Compiling pyapp v0.1.0 (/home/gps/tmp/pyapp) Finished dev [unoptimized + debuginfo] target(s) in 5.49s Running `target/debug/pyapp --help` Usage: pyapp [options] Options: --version show program's version number and exit -h, --help show this help message and exit You've just produced an executable for pyflakes! There are far more powerful packaging and configuration settings available. Read all about them at :ref:`config_files` and :ref:`packaging`. Or continue on to :ref:`managing_projects` to learn more about the ``pyoxidizer`` tool.