I used Drake Binary Installation for Python from this site
https://drake.mit.edu/python_bindings.html#installation
Then when i checked to ensure I can import pydrake, I have got this:
dmitriy#dmitriy-Lenovo-ideapad-310-15ISK:/opt$ python3 -c 'import pydrake.all; print(pydrake.__file__)'
/opt/drake/lib/python3.8/site-packages/pydrake/__init__.py
But when I try execute this example:
import pydrake.all
builder = pydrake.systems.framework.DiagramBuilder()
plant, _ = pydrake.multibody.plant.AddMultibodyPlantSceneGraph(builder, 0.0)
pydrake.multibody.parsing.Parser(plant).AddModelFromFile(
pydrake.common.FindResourceOrThrow(
"drake/examples/pendulum/Pendulum.urdf"))
plant.Finalize()
diagram = builder.Build()
simulator = pydrake.systems.analysis.Simulator(diagram)
I get this:
No module named 'pydrake'
The documentation you cite shows how to export PYTHONPATH (or alternatively, how to us a virtualenv). Since the first command you posted works, you must have done those steps correctly. Thus, the second command should have also worked.
Maybe you ran the second command in a new terminal, without the correct environment set up?
Related
On nixos, I am trying to compile the hello world example listed in the agda documentation.
In my working directory, I have the following:
The hello-world agda program, hello-world.agda:
module hello-world where
open import IO
main = run (putStrLn "Hello, World!")
A nix shell file, shell.nix:
{ pkgs ? import <nixpkgs> { } }:
with pkgs;
mkShell {
buildInputs = [
(agda.withPackages (ps: [
ps.standard-library
]))
];
}
To enter a shell with the standard-library dependency available, I ran $ nix-shell shell.nix.
Then, trying to compile the program, I ran $ agda --compile hello-world.agda, as advised by the linked agda hello world documentation.
But that gave me the following error:
$ agda --compile hello-world.agda
Checking hello-world (/home/matthew/backup/projects/agda-math/hello-world.agda).
/home/matthew/backup/projects/agda-math/hello-world.agda:3,1-15
Failed to find source of module IO in any of the following
locations:
/home/matthew/backup/projects/agda-math/IO.agda
/home/matthew/backup/projects/agda-math/IO.lagda
/nix/store/7pg293b76ppv2rw2saf5lcbckn6kdy7z-Agda-2.6.2.2-data/share/ghc-9.0.2/x86_64-linux-ghc-9.0.2/Agda-2.6.2.2/lib/prim/IO.agda
/nix/store/7pg293b76ppv2rw2saf5lcbckn6kdy7z-Agda-2.6.2.2-data/share/ghc-9.0.2/x86_64-linux-ghc-9.0.2/Agda-2.6.2.2/lib/prim/IO.lagda
when scope checking the declaration
open import IO
It seems it should be finding the standard library, since I'm running from the nix-shell with agda's standard-library specified, but that error on open import IO looks like the standard library is somehow still not found.
Any idea what the problem is likely to be?
Or what else I can do to get agda working on nixos?
You might need to create a defaults file in AGDA_DIR (which typically refers to ~/.agda/ unless overwritten through environment variable) with the libraries you want to make available to your program:
echo standard-library >> ~/.agda/defaults
which should make the compiler automatically load the standard library.
Alternatively, you can pass them in on the command-line:
agda -l standard-library
or use a project-local .agda-lib file as follows:
name: my-libary
depend: standard-library
include: -- Optionally specify include paths
You should not need to specify the include paths with Nix, but in case you do, you can use the -i command line flag or add the path to the standard-library.agda-lib file in ~/.agda/libraries.
Expected Behavior (local environment: fresh MacOS 12.4 installation)
With no environment updates except $ pip3 install matplotlib, I can successfully run this simple plot from the Matplotlib documentation:
Example Code:
# testplot.py
import matplotlib.pyplot as plt
import numpy as np
# Data for plotting
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2 * np.pi * t)
fig, ax = plt.subplots()
ax.plot(t, s)
ax.set(xlabel='time (s)', ylabel='voltage (mV)',
title='About as simple as it gets, folks')
ax.grid()
fig.savefig("test.png")
plt.show()
Actual Output (saved to a .png after window opens):
Run $ python3 testplot.py in the terminal:
Observed Behavior (vscode python 3.8 dev container)
Disclaimer: This post does not address notebook-based plots (which work fine but are not always preferred)
However, when I run this in my dev container, I get the following error:
testplot.py:16: UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure.
plt.show()
First Attempted Solution:
Following this previously posted solution, I specified the backend (export MPLBACKEND=TKAgg) before running the interpreter, but the error persists.
Second Attempted Solution:
Following the comments, I added the following lines to the script:
import matplotlib
matplotlib.use('tkagg')
In the v3.8 dev container, this addition changes the error to:
Traceback (most recent call last):
File "testplot.py", line 5, in <module>
matplotlib.use('tkagg')
File "/usr/local/python/lib/python3.8/site-packages/matplotlib/__init__.py", line 1144, in use
plt.switch_backend(name)
File "/usr/local/python/lib/python3.8/site-packages/matplotlib/pyplot.py", line 296, in switch_backend
raise ImportError(
ImportError: Cannot load backend 'TkAgg' which requires the 'tk' interactive framework, as 'headless' is currently running
Note: adding these two lines broke the local script as well. The point of the local example was to show that it plots stuff without installing anything except matplotlib.
So, finally starting to get a stable nix environment that I can basically do all of my development in. Hooray!
Now I want to make it reproducible, as in yarn.lock (for those familiar with npm/yarn in javascript land) or Pipfile.lock (very similar for Python).
Basically the idea is that I would have a way to generate a similar lock file whenever I run nix-env -if my-env.nix, or after running this command, if that is how it would work. From this lock file, I could then exactly restore my nix profile, down to the exact versions of dependencies and sub-dependencies of the installed profile. This could be checked into git or whatever after testing out new improvements, and so a record of the environment would be maintained.
It seems to me this would be one of the most obvious use cases for Nix, and one of the major advantages over just using Docker (though the two aren't mutually exclusive), so I apologize if I've missed some relevant documentation.
What you're probably looking for is a shell.nix file like this:
let
pkgs = import (fetchTarball {
url = "https://github.com/NixOS/nixpkgs/archive/696c6bed4e8e2d9fd9b956dea7e5d49531e9d13f.tar.gz";
sha256 = "1v3yrpj542niyxp0h3kffsdjwlrkvj0mg4ljb85d142gyn3sdzd4";
}) {};
in pkgs.mkShell {
buildInputs = with pkgs; [
git
hello
];
}
Upon calling nix-shell (which by default uses the shell.nix file in the current directory), you'll be in an environment with git and hello from the specific given nixpkgs revision. This can be reproduced among all nix users (okay almost*). I can really recommend using shell.nix files for all development.
Alternatively, there's also the lesser known -r flag to nix-env, which states that
--remove-all, -r
Remove all previously installed packages first. This is equivalent to running nix-env -e '.*' first, except that everything happens in a single transaction.
You can effectively use it to replace the stateful ~/.nix-profile/manifest.nix. Create a file env.nix containing:
let
pkgs = import <nixpkgs> {};
in {
inherit (pkgs) git hello;
}
Now running nix-env -ir env.nix will install exactly git and hello and remove everything else, so you can reproduce your nix-env installations with this single file. To install additional things: Add it to the file and run the command again. You can also pin nixpkgs to a specific version as in the file above to not care about your nix-channel setup (which is also stateful).
Edit: It's also possible to get some packages from your channel and some of a specific nixpkgs revision:
let
pkgs = import <nixpkgs> {};
fixed = import (fetchTarball {
url = "https://github.com/NixOS/nixpkgs/archive/696c6bed4e8e2d9fd9b956dea7e5d49531e9d13f.tar.gz";
sha256 = "1v3yrpj542niyxp0h3kffsdjwlrkvj0mg4ljb85d142gyn3sdzd4";
}) {};
in {
inherit (pkgs) git;
inherit (fixed) hello;
}
*: The nix config, overlays and your system (Linux/Mac) can still influence this. It's a good idea to use import <nixpkgs> { config = {}; overlays = []; } for development to avoid this.
After many suggestions from folks on IRC, I was able to put together the following script, which takes a nix expression as its only argument, and copies the derivation file and records the nixpkgs versions locally while installing the specified environment:
#!/bin/bash
if [ -z "$1" ] || [ "${1: -4}" != ".nix" ] || [ ! -f "$1" ]
then
echo "No .nix file supplied"
exit -1
fi
ENV_DRV=$(nix-instantiate "$1")
cp "$ENV_DRV" ./env_backup.drv
chmod u+rw ./env_backup.drv
nix-env --set "$ENV_DRV"
NIXPKGS_VERSION=$(nix-instantiate --eval '<nixpkgs/lib>' -A version)
NIXOS_VERSION=$(nix-instantiate --eval '<nixos/lib>' -A version)
printf "nixpkgs: %s\\nnixos: %s" "$NIXPKGS_VERSION" "${NIXOS_VERSION}" > .nix_versions
Caveat: your nix expression should have the nix package in it, since we are using nix-env --set.
I haven't tried using a copied .drv file yet, but it somehow needs to be restored into the nix store; I've mainly included it as a last resort and for debugging. The output into .nix_versions should be more helpful, as these contain git commit hashes (after the last ".") that can be used to employ the correct revision of nixpkgs (thanks to infinisil on IRC):
pkgs = import "${(import <nixpkgs> {}).fetchFromGitHub { owner = "NixOS"; repo = "nixpkgs"; rev = "<your revision hash>"; sha256 = "<the hash of the output>"; }}" {}
To fill in the hash, either supply an incorrect hash to get the correct hash back, or just use the following: nix-prefetch-url --unpack github.com/nixos/nixpkgs/archive/<revision>.tar.gz.
Or, if manually checking out nixpkgs, you can just do e.g.:
with import ((builtins.getEnv "HOME") + "/workspace/nixpkgs") { }; # or:
with import "../nixpkgs" { }; # or similar
I haven't tested this sort of thing with nix-shell yet, but hope to do so soon.
I've just started using the Nix package manager on OSX and I'm attempting to create my first package for the pass binary (https://www.passwordstore.org) - which is not available in the Nixpkgs repository.
I'm attempting to specify a runtime dependency (getopt), however this doesn't appear to be available when the binary is used.
This is my packages's default.nix:
{ pkgs ? import <nixpkgs> {} }:
with pkgs;
let
version = "1.7.1";
in {
pass = stdenv.mkDerivation rec {
name = "pass-${version}";
src = fetchurl {
url = "https://git.zx2c4.com/password-store/snapshot/password-store-1.7.1.tar.xz";
sha256 = "0scqkpll2q8jhzcgcsh9kqz0gwdpvynivqjmmbzax2irjfaiklpn";
};
buildInputs = [ stdenv makeWrapper];
installPhase = ''
make install PREFIX=$out/artifact
makeWrapper $out/artifact/bin/pass $out/bin/pass \
--set PATH ${stdenv.lib.makeBinPath [ getopt ]}
'';
meta = {
homepage = "https://www.passwordstore.org";
description = "The standard unix password manager";
license = stdenv.lib.licenses.gpl2Plus;
};
};
}
I can successfully build this package (nix-build --show-trace) and install it (nix-env -i ./result).
Listing the runtime dependencies for my package shows getopt listed:
nix-store -qR $(which pass)
...
/nix/store/c5swmygzc0kmvpq6cfkvwm2yz1k57kqy-getopt-1.1.4
However when I come to use the binary (pass init my-key) I get the following error:
/nix/store/...-pass-1.7.1/artifact/bin/pass: line 302:
/usr/local/bin/getopt: No such file or directory
Can anyone advise what I'm doing wrong?
Thanks
It looks like getopt gets a special treatment. The darwin.sh script looks for it using brew and port and falls back to /usr/local. That's why the (correct) wrapper has no effect.
So the solution seems to be, to make it look for getopt in PATH, which is provided by the wrapper script. You can probably make it as simple as GETOPT=getopt (which is similar to openbsd.sh)
For patching source code, see the NixPkgs documentation
After running nix-build, you should run cat result/bin/pass to look at your wrapper script and make sure it looks OK. It should be a shell script that sets the PATH to include getopt and then calls result/artifact/bin/pass.
Then try running the wrapper script. Note that the wrapper should be in result/bin, not result/artifact/bin.
I have a single Python script called myscript.py and would like to package it up as a nix derivation with mkDerivation.
The only requirement is that my Python script has a run-time dependency, say, for the consul Python library (which itself depends on the requests and six Python libraries).
For example for myscript.py:
#!/usr/bin/env python3
import consul
print('hi')
How to do that?
I can't figure out how to pass mkDerivation a single script (its src seems to always want a directory, or fetchgit or similar), and also can't figure out how to make the dependency libraries available at runtime.
When you have a single Python file as your script, you don't need src in your mkDerivation and you also don't need to unpack any source code.
The default mkDerivation will try to unpack your source code; to prevent that, simply set dontUnpack = true.
myscript-package = pkgs.stdenv.mkDerivation {
name = "myscript";
propagatedBuildInputs = [
(pkgs.python36.withPackages (pythonPackages: with pythonPackages; [
consul
six
requests2
]))
];
dontUnpack = true;
installPhase = "install -Dm755 ${./myscript.py} $out/bin/myscript";
};
If your script is executable (which we ensure with install -m above) Nix will automatically replace your #!/usr/bin/env python3 line with one which invokes the right specific python interpreter (the one for python36 in the example above), and which does so in an environment that has the Python packages you've specifified in propagatedBuildInputs available.
If you use NixOS, you can then also put your package into environment.systemPackages, and myscript will be available in shells on that NixOS.
This helper function is really nice:
pkgs.writers.writePython3Bin "github-owner-repos" { libraries = [ pkgs.python3Packages.PyGithub ]; } ''
import os
import sys
from github import Github
if __name__ == '__main__':
gh = Github(os.environ['GITHUB_TOKEN'])
for repo in gh.get_user(login=sys.argv[1]).get_repos():
print(repo.ssh_url)
''
https://github.com/nixos/nixpkgs/blob/master/pkgs/build-support/writers/default.nix#L319