Python: Difference between revisions

Remove section mixing packages from nixpkgs & pip. This is extremely bad advice that should be avoided, not encouraged through docs. This kind of hacks leaves you with broken envs that cannot be reproduced.
Tags: Manual revert Visual edit
Jooooscha (talk | contribs)
Improve the how to package Python application section about projects that use setup.py
Line 255: Line 255:


== Package a Python application ==
== Package a Python application ==
It is possible to use <code>buildPythonApplication</code> to package python applications. As explained in the nixpkgs manual, it uses the widely used <code>setup.py</code> file in order to package properly the application. We now show how to package a simple python application: a basic flask web server.


First, we write the python code, say in a file <code>web_interface.py</code>. Here we create a basic flask web server:
=== With setup.py ===
To package a Python application that uses <code>setup.py</code> you can use <code>buildPythonApplication</code>. More details about this and similar functions can be found in [https://nixos.org/manual/nixpkgs/stable/#building-packages-and-applications the nixpkgs manual].
 
For example, we can package this simple flask server <code>main.py:</code>
<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
#!/usr/bin/env python
#!/usr/bin/env python


from flask import Flask
from flask import Flask
app = Flask(__name__)
app = Flask(__name__)


Line 272: Line 275:
</syntaxhighlight>
</syntaxhighlight>


Then, we create the <code>setup.py</code> file, which basically explains which are the executables:
We also need a <code>setup.py</code> file, like this:
<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
#!/usr/bin/env python
from setuptools import setup, find_packages
from setuptools import setup, find_packages


setup(name='demo-flask-vuejs-rest',
setup(name='myFlaskServer',
       version='1.0',
       version='1.0',
       # Modules to import from other scripts:
       # Modules to import from other scripts:
       packages=find_packages(),
       packages=find_packages(),
       # Executables
       # Executables
       scripts=["web_interface.py"],
       scripts=["main.py"],
     )
     )
</syntaxhighlight>
</syntaxhighlight>


Finally, our nix derivation is now trivial: the file <code>derivation.nix</code> just needs to provide the python packages (here flask):
Then, we use the <code>buildPythonApplication</code> in the <code>default.nix</code>:
<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
{ lib, python3Packages }:
{ pkgs ? import <nixpkgs> {} }:
with python3Packages;
 
buildPythonApplication {
pkgs.python3Packages.buildPythonApplication {
   pname = "demo-flask-vuejs-rest";
   pname = "myFlaskApp";
   version = "1.0";
   version = "0.1.0";


   propagatedBuildInputs = [ flask ];
   propagatedBuildInputs = with pkgs.python3Packages; [
    flask
  ];


   src = ./.;
   src = ./.;
}
}
</syntaxhighlight>
</syntaxhighlight>Finally, build your project using <code>nix-build</code>. The result will be executable in <code>./result/bin/app.py</code>.
 
and we can now load this derivation from our file <code>default.nix</code>:
<syntaxhighlight lang="nix">
{ pkgs ? import <nixpkgs> {} }:
pkgs.callPackage ./derivation.nix {}
</syntaxhighlight>
 
We can now build with:
<syntaxhighlight lang=console>
$ nix-build
[...]
$ ./result/bin/web_interface.py  
* Serving Flask app ".web_interface" (lazy loading)
[...]
</syntaxhighlight>
or just enter a nix-shell, and directly execute your program or python if it's easier to develop:
<syntaxhighlight lang=console>
$ nix-shell
[...]
[nix-shell]$ chmod +x web_interface.py
[nix-shell]$ ./web_interface.py
* Serving Flask app "web_interface" (lazy loading)
[...]
 
[nix-shell]$ python
Python 3.8.7 (default, Dec 21 2020, 17:18:55)
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import flask
>>>
</syntaxhighlight>


== Nixpkgs Python contribution guidelines ==
== Nixpkgs Python contribution guidelines ==