From 536668d8b992c7229f47ae85b4bbe63fb4a213f0 Mon Sep 17 00:00:00 2001 From: tuxcoder Date: Sat, 30 Sep 2023 12:58:24 +0200 Subject: [PATCH] update packages / nix packaging --- .gitignore | 2 + .vscode/settings.json | 5 +- flake.lock | 46 +++++- flake.nix | 166 ++++------------------ lenticular_cloud/model.py | 17 ++- lenticular_cloud/translations/__init__.py | 28 ++-- module.nix | 27 ++-- overlay.nix | 136 ++++++++++++++++++ requirements-dev.txt | 3 + requirements.txt | 2 +- shell.nix | 2 +- 11 files changed, 254 insertions(+), 180 deletions(-) create mode 100644 overlay.nix diff --git a/.gitignore b/.gitignore index 109d183..db5b905 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ node_modules *.egg-info /.tox /dist +build +result diff --git a/.vscode/settings.json b/.vscode/settings.json index 12b229e..6927ddd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,6 @@ { - "nixEnvSelector.nixFile": "${workspaceRoot}/shell.nix" + "nixEnvSelector.suggestion": false, + "nixEnvSelector.nixFile": "${workspaceRoot}/shell.nix", + "python.linting.mypyEnabled": true, + "python.linting.enabled": true } \ No newline at end of file diff --git a/flake.lock b/flake.lock index 46a7b16..c7614dc 100644 --- a/flake.lock +++ b/flake.lock @@ -16,14 +16,32 @@ "type": "github" } }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "nix-node-package": { "flake": false, "locked": { - "lastModified": 1645439390, - "narHash": "sha256-mYkNbWBzQkv7O0mVZ4llqo9ZNeeo/IWPJk5WMa34SgQ=", + "lastModified": 1694372307, + "narHash": "sha256-18dhHWJfa0QB0fPsaYvRwGd86BVn6xMkN6mDmiDKack=", "owner": "mkg20001", "repo": "nix-node-package", - "rev": "03285e212016db5f28530563b58cfcc5706ff73f", + "rev": "97ac59276f12f768062e4eb336fc77079d5fb6a0", "type": "github" }, "original": { @@ -34,11 +52,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1679037998, - "narHash": "sha256-WnlfwX3IbZ/+hgxNZokGBVDwN7EciJA3ivrKQqoRr00=", + "lastModified": 1696022471, + "narHash": "sha256-3U5nqHQ9JFUoY4GJ89ErqzRmkgAhPYjbPn4vP+CpltM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "1a19ae5b677797c0f2ba4f28304dd054964ed3b9", + "rev": "336d12bc4cdb0980f5ff450d7bc599bdb4ed5e74", "type": "github" }, "original": { @@ -50,9 +68,25 @@ "root": { "inputs": { "flake-compat": "flake-compat", + "flake-utils": "flake-utils", "nix-node-package": "nix-node-package", "nixpkgs": "nixpkgs" } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 965856b..c21abcd 100644 --- a/flake.nix +++ b/flake.nix @@ -2,7 +2,8 @@ description = "Lenticular cloud interface"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs"; - flake-compat = { + flake-utils.url = "github:numtide/flake-utils"; + flake-compat = { # for shell.nix url = "github:edolstra/flake-compat"; flake = false; }; @@ -11,150 +12,33 @@ flake = false; }; }; - outputs = inputs@{ self, nixpkgs, nix-node-package, ... }: - let - makeNode = nix-node-package.lib.nix-node-package.makeNode; - node-env = makeNode { }; - pkgs = nixpkgs.legacyPackages.x86_64-linux; - python_default = pkgs.python310; - nodejs = pkgs.nodejs; - lenticular_cloud = {python}: with python.pkgs; let + outputs = { self, nixpkgs, nix-node-package, flake-utils, ... }: + flake-utils.lib.eachDefaultSystem (system: let + pkgs = nixpkgs.legacyPackages.${system}.extend (import ./overlay.nix); + in rec { + formatter = pkgs.nixpkgs-fmt; + devShells.default = pkgs.python3.withPackages (ps: ( + pkgs.lenticular-cloud.propagatedBuildInputs ++ + pkgs.lenticular-cloud.testBuildInputs + )); - urlobject = buildPythonPackage rec { - pname = "URLObject"; - version = "2.4.3"; - src = fetchPypi { - inherit pname version; - sha256 = "47b2e20e6ab9c8366b2f4a3566b6ff4053025dad311c4bb71279bbcfa2430caa"; - }; - doCheck = true; - propagatedBuildInputs = [ - ]; - }; - flask-dance = with python.pkgs; buildPythonPackage rec { - pname = "Flask-Dance"; - version = "6.0.0"; - src = fetchPypi { - inherit pname version; - sha256 = "15bb3c412eb789a2d904bfd0fd44aac2d94f82703a51d14123fd336136d55db0"; - }; - doCheck = false; - propagatedBuildInputs = [ - requests - oauthlib - requests_oauthlib - flask - urlobject - ]; - checkInputs = [ - pytest - nose - pytest-mock - responses - freezegun - coverage - # testing sqlalchemy support - sqlalchemy - flask_sqlalchemy - # testing integration with other extensions - flask_login - flask-caching - betamax - # we need the `signedtoken` extra for `oauthlib` - # oauthlib[signedtoken] - ]; + packages.default = pkgs.lenticular-cloud; - }; - ory-hydra-client = buildPythonPackage rec { - pname = "ory-hydra-client"; - version = "2.0.3"; - src = ./libs/ory-hydra-client; - # doCheck = false; - propagatedBuildInputs = [ - urllib3 - python-dateutil - attrs - httpx - ]; - }; - in - buildPythonApplication rec { # TODO change to buildPythonApplication - pname = "lenticular_cloud"; - version = "0.2"; - src = ./.; - propagatedBuildInputs = [ - flask - flask-restful - flask_sqlalchemy - flask_wtf - flask-babel - flask_login - requests - requests_oauthlib - ldap3 - #ldap3-orm - pyotp - cryptography - blinker - ory-hydra-client - authlib # as oauth client lib - fido2 # for webauthn - flask_migrate # db migrations - - nodejs - #node-env - gunicorn - - flask-dance - ]; - testBuildInputs = with python.pkgs; [ - pytest - pytest-mypy - flask_testing - tox - - types-dateutil - - nose - mypy - - ]; - passthru = { - inherit python; - pythonPath = python.pkgs.makePythonPath propagatedBuildInputs; - }; - - - doCheck = false; - checkInputs = [ - pytest - ] ++ lenticular_settings.testBuildInputs; + checks = { + package = packages.default; + devShells = devShells.default; }; - in { - formatter.x86_64-linux = nixpkgs.legacyPackages.x86_64-linux.nixpkgs-fmt; - #packages.x86_64-linux.default = import ./shell.nix { inherit pkgs; }; - # TODO - - packages.x86_64-linux.default = lenticular_cloud {python=python_default;}; + }) // { nixosModules = { - default = (import "${self}/module.nix" { inherit lenticular_cloud; }); + default = import ./module.nix; + }; + overlays.default = import ./overlay.nix; + nixosConfigurations.testSystem = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + self.nixosModules.default + "${nixpkgs}/nixos/modules/virtualisation/qemu-vm.nix" + ]; }; }; - } - - -#ldap3-orm = with python.pkgs; buildPythonPackage rec { -# pname = "ldap3-orm"; -# version = "2.7.0"; -# src = fetchPypi { -# inherit pname version; -# sha256 = "8783886d4ce90d66da61ce24619593a265b50f0de1fbebe86df95c6788661664"; -# }; -# doCheck = false; -# propagatedBuildInputs = [ -# ldap3 -# six -# ];# -#}; - diff --git a/lenticular_cloud/model.py b/lenticular_cloud/model.py index fb1eafe..28e46d4 100644 --- a/lenticular_cloud/model.py +++ b/lenticular_cloud/model.py @@ -11,12 +11,14 @@ import logging import crypt import secrets import string +from sqlalchemy.orm import DeclarativeBase, MappedAsDataclass, Mapped, mapped_column, relationship, declarative_base from flask_sqlalchemy import SQLAlchemy +from flask_sqlalchemy.model import Model, DefaultMeta +from flask_sqlalchemy.extension import _FSAModel from flask_migrate import Migrate from datetime import datetime import uuid -import pyotp -from typing import Optional, Callable +from typing import Optional, List, Dict, Tuple, Any, Type, TYPE_CHECKING from cryptography.x509 import Certificate as CertificateObj from sqlalchemy.ext.declarative import DeclarativeMeta @@ -28,8 +30,17 @@ logger = logging.getLogger(__name__) db = SQLAlchemy() migrate = Migrate() +class BaseModelIntern(MappedAsDataclass, DeclarativeBase): + pass -BaseModel: DeclarativeMeta = db.Model +if TYPE_CHECKING: + class BaseModel (_FSAModel,BaseModelIntern): + pass +else: + BaseModel: Type[_FSAModel] = db.Model +class ModelUpdatedMixin: + created_at: Mapped[datetime] = mapped_column(db.DateTime, default=datetime.now()) + last_update: Mapped[datetime] = mapped_column(db.DateTime, default=datetime.now(), onupdate=datetime.now) class SecurityUser(UserMixin): diff --git a/lenticular_cloud/translations/__init__.py b/lenticular_cloud/translations/__init__.py index 21ffbdb..85bd7cc 100644 --- a/lenticular_cloud/translations/__init__.py +++ b/lenticular_cloud/translations/__init__.py @@ -14,24 +14,24 @@ LANGUAGES = { def get_locale() -> str: # if a user is logged in, use the locale from the user settings - user = current_user # type: Optional[User] + #user = current_user # type: Optional[User] return 'de' # prefer lang argument - if 'lang' in request.args: - lang = request.args['lang'] # type: str - if lang in LANGUAGES: - if not isinstance(user, User): - return lang - user.locale = lang - db.session.commit() + # if 'lang' in request.args: + # lang = request.args['lang'] # type: str + # if lang in LANGUAGES: + # if not isinstance(user, User): + # return lang + # user.locale = lang + # db.session.commit() - if isinstance(user, User): - return user.locale - # otherwise try to guess the language from the user accept - # header the browser transmits. We support de/fr/en in this - # example. The best match wins. - return request.accept_languages.best_match(['de']) + # if isinstance(user, User): + # return user.locale + # # otherwise try to guess the language from the user accept + # # header the browser transmits. We support de/fr/en in this + # # example. The best match wins. + # return request.accept_languages.best_match(['de']) def get_timezone() -> Optional[str]: # user = getattr(g, 'user', None) diff --git a/module.nix b/module.nix index 640c236..1e27f03 100644 --- a/module.nix +++ b/module.nix @@ -1,10 +1,7 @@ -{ lenticular_cloud }: { config, pkgs, lib, modulesPath, ... }: +{ config, pkgs, lib, ... }: let - python = pkgs.python310; - gevent = python.pkgs.gevent; - gunicorn = python.pkgs.gunicorn; - psycopg2 = python.pkgs.psycopg2; - lenticular-pkg = lenticular_cloud { inherit python;}; + cfg = config.services.lenticular-cloud; + python = pkgs.python3; in { options = with lib.options; { @@ -12,10 +9,12 @@ in enable = mkEnableOption "lenticluar service enable"; }; }; - imports = [ - ]; config = { - environment.systemPackages = [ lenticular-pkg ]; + environment.systemPackages = [ pkgs.lenticular-cloud ]; + + nixpkgs.overlays = [ + (import ./overlay.nix) + ]; users = { groups.lenticular = { @@ -35,12 +34,14 @@ in description = "lenticular account"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; + enable = cfg.enable; environment = let - python_path = python.pkgs.makePythonPath [ lenticular-pkg gevent psycopg2]; + python_path = with python.pkgs; makePythonPath [ lenticular-cloud gevent psycopg2]; in { CONFIG_FILE = "/etc/lenticular_cloud/production.conf"; - PYTHONPATH = "${lenticular-pkg.pythonPath}:${lenticular-pkg}/lib/python3.10/site-packages:${python_path}"; + PYTHONPATH = "${python_path}"; + # PYTHONPATH = "${lenticular-pkg.pythonPath}:${lenticular-pkg}/lib/python3.10/site-packages:${python_path}"; }; serviceConfig = { @@ -52,9 +53,9 @@ in #cat > /var/lib/lenticular/foobar.conf <