Developer Blog

Tipps und Tricks für Entwickler und IT-Interessierte

JQ – Cheatsheet

Installing jq

On Mac OS

brew install jq

Useful arguments

When running jq, the following arguments may become handy:

ArgumentDescription
--versionOutput the jq version and exit with zero.
--sort-keysOutput the fields of each object with the keys in sorted order.

Basic concepts

The syntax for jq is pretty coherent:

SyntaxDescription
,Filters separated by a comma will produce multiple independent outputs
?Will ignores error if the type is unexpected
[]Array construction
{}Object construction
+Concatenate or Add
Difference of sets or Substract
lengthSize of selected element
|Pipes are used to chain commands in a similar fashion than bash

Dealing with json objects

DescriptionCommand
Display all keysjq 'keys'
Adds + 1 to all itemsjq 'map_values(.+1)'
Delete a keyjq 'del(.foo)'
Convert an object to arrayto_entries | map([.key, .value])

Dealing with fields

DescriptionCommand
Concatenate two fieldsfieldNew=.field1+' '+.field2

Dealing with json arrays

Slicing and Filtering

DescriptionCommand
Alljq .[]
Firstjq '.[0]'
Rangejq '.[2:4]'
First 3jq '.[:3]'
Last 2jq '.[-2:]'
Before Lastjq '.[-2]'
Select array of int by valuejq 'map(select(. >= 2))'
Select array of objects by value** jq ‘.[] | select(.id == “second”)’**
Select by type** jq ‘.[] | numbers’ ** with type been arrays, objects, iterables, booleans, numbers, normals, finites, strings, nulls, values, scalars

Mapping and Transforming

DescriptionCommand
Add + 1 to all itemsjq 'map(.+1)'
Delete 2 itemsjq 'del(.[1, 2])'
Concatenate arraysjq 'add'
Flatten an arrayjq 'flatten'
Create a range of numbersjq '[range(2;4)]'
Display the type of each itemjq 'map(type)'
Sort an array of basic typejq 'sort'
Sort an array of objectsjq 'sort_by(.foo)'
Group by a key – opposite to flattenjq 'group_by(.foo)'
Minimun value of an arrayjq 'min' .See also min, max, min_by(path_exp), max_by(path_exp)
Remove duplicatesjq 'unique' or jq 'unique_by(.foo)' or jq 'unique_by(length)'
Reverse an arrayjq 'reverse'

WSL: Wrong Date

When checking the date in WSl, it display the wrong date

❯ date
Wed Jul 26 15:28:20 CEST 2023

So setup the correct date, you could run either

❯ sudo hwclock -s

or setup a timesync daemon (described here)

Add these lines to the /etc/wsl.conf (note you will need to run your editor with sudo privileges, e.g: sudo nano /etc/wsl.conf):

[boot]
systemd=true

And close out of the nano editor using CTRL+O to save and CTRL+X to exit. Now close your WSL distro windows and run wsl.exe --shutdown from PowerShell, then restart your WSL instance. Upon launch you should have systemd running.

Now install systemd-timesyncd:

sudo apt install systemd-timesyncd
sudo systemctl edit systemd-timesyncd

In the second step, when editing, add the two lines beginning with [Unit], as shown below:

Now start it:

sudo systemctl start systemd-timesyncd

Check status with:

timedatectl status
timedatectl timesync-status

F# – Snippets

Mathematics

Sum of Squares

dotnet new --install Fable.Template

Create an new App

dotnet new fable

Prepare environment

dotnet tool restore

Fix NodeJS SSL Error

$ENV:NODE_OPTIONS="--openssl-legacy-provider"

Install dependencies and run app

npm install
npm start

F# – Working with Fable

Get started

Install Fable with

dotnet new --install Fable.Template

Create an new App

dotnet new fable

Prepare environment

dotnet tool restore

Fix NodeJS SSL Error

$ENV:NODE_OPTIONS="--openssl-legacy-provider"

Install dependencies and run app

npm install
npm start

Storybook – Troubleshooting

Error: Resource busy or locked

When starting storybook with npm run storybook, you always get the error EBUSY: resource busy or locked

Solution: modify .storybook/main.js

You can fix this by adding the following to the file .storybook/main.js

module.exports = {
  ...
  managerWebpack: (config, options) => {
    options.cache.set = () => Promise.resolve();
    return config;
  }
}
Google Cloud

Google Cloud Platform | Tipps und Tricks

Tipps und Tricks im Internet

https://cloud.google.com/sdk/docs/cheatsheet

https://medium.com/google-cloud/7-gcloud-tricks-you-probably-didnt-know-7f64a16869e7

https://github.com/dennyzhang/cheatsheet-gcp-A4

https://gist.github.com/pydevops/cffbd3c694d599c6ca18342d3625af97

Big Query – SQL

SELECT – exclude special fields

select * except(title, comment) from publicdata.samples.wikipedia limit 10

You could use select-except or select-replace. Maybe you have to change the sql dialect.

Authentication

JWT Token

Try https://jwt.io to decode/check the token

Django | How To – Templates konfigurieren

Allgemein / Vorbereitung

Um in einem Django-Projekt mit mehreren Anwendungen die HTML-Templates zu konfigurieren sind mehrere Schritte notwendig.

Ausgangsbasis ist die nachfolgende Verzeichnisstruktur (ein Projekt mit 2 Anwendungen).

Basisprojekt einrichten

➜ pipenv --python 3.10
➜ pipenv shell
➜ pip install django
➜ djangop-admin startproject project
➜ cd project
➜ mkdir apps
➜ mkdir apps\core
➜ django-admin startapp core apps\core
➜ mkdir apps\frontend
➜ django-admin startapp frontend apps\frontend

Dies ergibt die folgende Verzeichnisstruktur:

Hinweis: der Befehl startproject erstellt einen Ordner project, indem er einen weiteren Ordner project erstellt. Der erste Ordner dient dazu, sowohl das Django-Projekt, als auch die erstellten Anwendungen an einer gemeinsame Stelle zu speichern.

Der zweite Ordner project ist das Django-Projekt, in dem sich alle für das Projekt notwendigen Dateien befinden.

Wird in den nachfolgenden Beschreibungen vom dem Ordner project gesprochen, so ist immer der zweite gemeint (project/project)

➜ python manage.py migrate
➜ python manage.py createsuperuser --email admin@localhost --username admin
Password:
Password (again):
Superuser created successfully.

Anwendungen hinzufügen

Im nächsten Schritt werden die beiden erstellten Anwendungen (Core und Frontend) dem Django-Projekt hinzugefügt. Da sie in einem Unterverzeichnis (apps) liegen, muss ihre Konfiguration angepasst werden.

In dere Datei apps.py der jeweiligen Anwendung (apps/core/apps.py und apps/frontend/apps.py) wirr der Name angepasst:

Hinweis: Ohne diese Anpassung würde beim Start des Servers eine Fehlermeldung angezeigt

django.core.exceptions.ImproperlyConfigured: Cannot import 'frontend'. Check that 'apps.frontend.apps.FrontendConfig.name' is correct.

Im Anschluss daran werden die beiden Anwendungen dem Projekt hinzugefügt. Dies erfolgt in der Datei project/settings.py:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'apps.core',
    'apps.frontend'
]

Einfache Views erstellen

Ein Template ist die Basis eines Views.

Daher richten wir für jede Anwendung einen einfachen View ein: in apps/core/views.py und apps/frontend/views.py:

from django.shortcuts import render
from django.views import generic

class IndexView(generic.TemplateView):
    """
    IndexView:
    """
    module = 'indexView'
    template_name = 'core/index.html'

URLs für die Anwendungen hinzufügen

Im letzten Vorbereitungsschritt konfigurieren wir die URLs für unsere Anwendungen bzw die beiden eingerichteten Views:

from django.contrib import admin
from django.urls import path

import apps.core.views as core
import apps.frontend.views as frontend

urlpatterns = [
    path('admin/', admin.site.urls),
    path('frontend/', frontend.IndexView.as_view(), name='index'),
    path('core', core.IndexView.as_view(), name='index'),

]

Als Ergebnis sollten wir bei beiden URLs einen Fehler sehen.

Dies was zu erwarten, da wir die notwendigen Templates ja erst jetzt einrichten werden:

Template hinzufügen

Erstellen eines Templates für die Anwendung core: apps/core/templates/core/index.html

Der Verzeichnispfad des Templates setzt sich auch mehreren Teilen zusammen

apps/coreDas Startverzeichnis der Anwendung
templatesDer Default-Name des Verzeichnisses, in dem Django nach Templates sucht
coreDer Namespace als Unterscheidung, wenn es Templates mit gleichem Namen gibt
index.htmlDer Name des Templates

Erstellen Sie die Daten apps/core/templates/core/index.html und öffnen Sie dann den Browser:

http://localhost:8000/core

Zum Vergleich öffen wir die URL für unsere zweite Anwendung: frontend

http://localhost:8000/frontend

Im unteren Teil der Fehlermeldung findet sich aber eine hilfreiche Information:

Als erstes wir uns mitgeteilt, das ein gewünschtes Template in der nachfolgenden Reihenfolge gesucht wird. Es werden als (wir oben bereits erwähnt) mehrere Verzeichnisse durchsucht, um ein passendes Template zu finden.

Template-loader postmortem
Django tried loading these templates, in this order:

Using engine django:

Als erstes werden Verzeichnisse der Django-Installation durchsucht. Hierunter liegen z. B. die Templates für die Administration oder die Anmeldung.

django.template.loaders.app_directories.Loader: 
...\lib\site-packages\django\contrib\admin\templates\frontend\index.html (Source does not exist)

django.template.loaders.app_directories.Loader: 
...\lib\site-packages\django\contrib\auth\templates\frontend\index.html (Source does not exist)

Im Anschluss werden dann die Verzeichnisse unserer Anwendungen durchsucht.

django.template.loaders.app_directories.Loader: ...\project\apps\core\templates\frontend\index.html (Source does not exist)

django.template.loaders.app_directories.Loader: ...\project\apps\frontend\templates\frontend\index.html (Source does not exist)

Um nun ein gewünschtes Template zu finden, werden zwei Informationen benötigt:

  • der Name des Template
  • das Verzeichnis

Name des Templates

Der Name des Templates wird im View angegeben: apps/core/views.py:

class IndexView(generic.TemplateView):
    module = 'indexView'
    template_name = 'core/index.html'

Verzeichnis

Das Verzeichnis selbst wird über die Suchreihenfolge der zu verwendenden Template-Verzeichnisse ermittelt. Das erste Verzeichnis, dass das gewünschte Template beinhaltet, wird verwendet.

Ermitteln des Verzeichnisses

Im Falle unserer Anwendung frontend werden die nachfolgenden Verzeichnisse durchsucht, ob sie das Template core/index.html beinhalten:

UmgebungVerzeichnisTemplate gefunden
DJANGOlib\site-packages\django\contrib\admin\templates
DJANGOlib\site-packages\django\contrib\auth\templates
PROJEKTproject\apps\core\templatescore/index.html
PROJEKTproject\apps\frontend\templates

Template hinzufügen

Erstellen eines Templates für die Anwendung frontend: apps/frontend/templates/frontend/index.html

Weiteres Beispiel: Suchen des passenden Templates

Richten sie einen Neuen View in der Anwendung frontend ein: apps/frontend/views.py

class BaseView(generic.TemplateView):
    module = 'baseView'
    template_name = 'base.html' 

Erstellen Sie eine URL für diesen View in project/urls.py

urlpatterns = [
    path('admin/',      admin.site.urls),
    path('core',        core.IndexView.as_view(),      name='index'),
    path('frontend/',   frontend.IndexView.as_view(),  name='index'),
    path('base/',       frontend.BaseView.as_view(),   name='base'),
]

Öffnen Sie den Browser um diese URL anzuzeigen;

http://localhost:8000/base

Wie zu erwarten war, wird das Template nicht gefunden:

In keinem der bekannten Verzeichnisse gibt es ein Template base.html.

Gemeinsame Templates für alle Anwendungen

Um Templates einzurichten, die von mehreren Anwendungen verwendet werden, empfiehlt es sich, ein Verzeichnis templates auf der gleichen Ebene, wie die Anwendungen, einzurichten

In der Datei project/settings.py wird dieses Verzeichnis dem Django-Projekt hinzugefügt.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        ....

Öffnen Sie den Browser um diese URL anzuzeigen;

http://localhost:8000/base

Das zusätzliche Verzeichnis wird nun auch durchsucht:

Template-loader postmortem
Django tried loading these templates, in this order:

Using engine django:
django.template.loaders.filesystem.Loader: ...\project\templates\base.html (Source does not exist)
django.template.loaders.app_directories.Loader: ...\.venv\lib\site-packages\django\contrib\admin\templates\base.html (Source does not exist)
django.template.loaders.app_directories.Loader: ...\.venv\lib\site-packages\django\contrib\auth\templates\base.html (Source does not exist)
django.template.loaders.app_directories.Loader: ...\project\apps\core\templates\base.html (Source does not exist)
django.template.loaders.app_directories.Loader: ...\project\apps\frontend\templates\base.html (Source does not exist)

Erstellen Sie nun in diesem Verzeichnis (templates) das Template base.html

Öffnen Sie den Browser um diese URL anzuzeigen;

http://localhost:8000/base