aboutsummaryrefslogtreecommitdiff
path: root/flake.nix
blob: 4e10a124f6707279d10d60cf39787b74e5e3860e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# UGE / L2 / Intro to relational databases / Python project prototype
# Author: Pacien TRAN-GIRARD
# Licence: EUPL-1.2

{
  inputs = {
    # for python3Packages.embrace: https://github.com/NixOS/nixpkgs/pull/131425
    nixpkgs.url = "github:pacien/nixpkgs/3faf31d";
    #nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs = { self, nixpkgs, flake-utils }:
  flake-utils.lib.eachDefaultSystem (system:
  with import nixpkgs { inherit system; };
  let

    python = python39;

    pythonWithDependencies = python.withPackages (ps: with ps; [
      uvicorn           # server for the web app
      fastapi           # simple Python framework to build web apps
      aiofiles          # to let fastapi serve static resources (CSS, JS, ...)
      python-multipart  # to let fastapi handle form submissions
      jinja2            # HTML templating engine
      passlib           # for account password hashing
      psycopg2          # PostgreSQL driver for Python
      embrace           # bridges raw SQL queries to Python functions
    ]);

    develPackagesAndScripts = [
      postgresql_13        # PostgreSQL server with the standard admin tools.
      python.pkgs.ipython  # Interactive Python REPL for experimenting.

      # More pleasant alternative to psql, with colours and auto-completion.
      # Custom configuration to suppress irrelevant warnings and messages.
      (writeShellScriptBin "pgcli" ''
        ${pgcli}/bin/pgcli --pgclirc "${writeText "pgclirc" ''
          [main]
          keyring = False
          less_chatty = True
        ''}" "$@"
      '')

      # Script for initialising an independent development database.
      # This creates a default empty database name "postgres" and owned by the
      # current user. Data are stored in ./development_database/pgdata.
      (writeShellScriptBin "dev-initdb" ''
        initdb \
          --no-locale \
          --encoding UTF8 \
          --auth-host reject \
          --auth-local peer \
          "$@"
      '')

      # Script for starting an independent development posgresql server.
      # Accepts connections only through a local UNIX-domain socket.
      (writeShellScriptBin "dev-postgres" ''
        postgres \
          -h "" \
          -k "$PGHOST" \
          -d 2 \
          "$@"
      '')

      # Script for starting the Uvicorn local development server.
      # `--reload-dir` arguments necessary to prevent the database directory
      # from triggering automatic application reload.
      # See: https://github.com/encode/uvicorn/issues/984
      (writeShellScriptBin "dev-serve" ''
        uvicorn \
          --reload-dir app \
          --reload-dir templates \
          --reload \
          --app-dir app \
          app:main \
          "$@"
      '')
    ];

    exportEnvVar = k: v: ''export ${k}="${v}"; echo ${k}=\"${v}\"'';
    exportDevelEnvVars = lib.mapAttrsToList exportEnvVar develEnvVars;
    develEnvVars = rec {
      PGDATA = "$PWD/development_database/pgdata";
      PGHOST = "$PWD/development_database";
      PGPORT = "5432";
      PGDATABASE = "app";
      DATABASE_URL = "postgresql:///${PGDATABASE}?host=${PGHOST}";
      COOKIE_SECRET_KEY = "insecure for development";
    };

  in {

    devShell = mkShell rec {
      buildInputs = [ pythonWithDependencies ] ++ develPackagesAndScripts;

      shellHook = ''
        echo -e "\nDEVSHELL ENVIRONMENT VARIABLES:"
        ${lib.concatStringsSep "\n" exportDevelEnvVars}

        echo -e "\nDEVSHELL COMMANDS:"
        ls "${symlinkJoin { name = "env"; paths = buildInputs; }}/bin"

        # Use the default user shell instead of Bash
        $(${finger_bsd}/bin/finger $USER \
          | ${gnugrep}/bin/grep -oP 'Shell: \K.*')

        exit $?
      '';
    };

  });
}