Skip to content
/ pydiner Public template

Template for a generic Python project with dev sandboxes in containers. Includes examples of automated testing, log streaming, and relative imports.

License

Notifications You must be signed in to change notification settings

samkennerly/pydiner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pydiner

Keep your development environments clean.

The Dirty Fork

abstract

pydiner is a template for a generic Python project which:

These rules are intended to avoid dependency hell.

basics

To start a new project:

  1. Create a Git repo from this template.
  2. Delete any files and folders you don't want.
  3. Edit the Dockerfile to choose a Python version.
  4. Edit requirements.txt to choose Python packages.
  5. Open a terminal, cd to this folder, and run this command:
./kitchen

This should print a help message for the kitchen script.

kitchen functions

The kitchen script defines shell functions which run common Docker commands.

# Bake a Docker image named pydiner:monty
./kitchen bake monty

# Run Python in an interactive pydiner:monty container
./kitchen runit monty python

# Same as above, but with the current working directory mounted as /context
./kitchen serve monty python

# Run tests in an interactive pydiner:monty container
./kitchen runit monty python -m test

# Same as above, but use pytest to run tests
./kitchen runit monty pytest

# Freeze requirements.txt and rebuild pydiner:monty
./kitchen freeze monty

# Delete the image, its containers, and any leftovers
./kitchen eightysix monty

Typing ./kitchen before each command is optional if the kitchen script is sourced.

bake an image

./kitchen bake builds (or updates) a Docker image with copies of files from the build context.

  • Edit requirements.txt to specify which Python packages should be installed.
  • Edit .dockerignore to declare file patterns which should never be copied.
  • Edit Dockerfile to choose which non-ignored files are copied into images.

The default image name is pydiner:latest.

runit interactively

./kitchen runit runs a new interactive container from a previously-baked image.

  • Inside a container, baked-in copies of files are in the /context folder.
  • Modifying files inside the container does not affect the original files.
  • Type exit to exit the container. It should then self-destruct.

serve with mounted files

./kitchen serve runs a container with the current folder mounted as /context.

  • Processes inside the container can modify or delete mounted files.
  • Changes to mounted files will be visible inside and outside the container.
  • Any files baked into /context will be obscured by the fresh mounted files.

freeze

./kitchen freeze pins Python packages to ensure reproducible builds.

  • The first time an image is baked, pip installs packages automatically.
  • If an image is frozen, then baking it again uses the same package versions.
  • Freezing an image will overwrite requirements.txt.

contents

This repo contains examples of common project files:

dependencies

pydiner has exactly one dependency:

Windows users may need to edit the kitchen script for path compatibility.

examples

Caution: Remember to cd to this folder before using kitchen functions.

Bake a pydiner:latest image, freeze it, and serve bash.

[+] Building 0.9s (11/11) FINISHED                                docker:desktop-linux
 => [internal] load .dockerignore                                                 0.0s
 => => transferring context: 138B                                                 0.0s
 => [internal] load build definition from Dockerfile                              0.0s
 => => transferring dockerfile: 539B                                              0.0s
 => [internal] load metadata for docker.io/library/python:3.12.0                  0.7s
 => [1/6] FROM docker.io/library/python:3.12.0@sha256:7b8d65a924f596eb65306214f5  0.0s
 => [internal] load build context                                                 0.0s
 => => transferring context: 10.84kB                                              0.0s
 => CACHED [2/6] RUN apt-get -y update && apt-get -y install less tree vim        0.0s
 => CACHED [3/6] COPY requirements.txt /tmp                                       0.0s
 => CACHED [4/6] RUN pip install --upgrade pip && pip install --requirement /tmp  0.0s
 => [5/6] COPY [., /context]                                                      0.0s
 => [6/6] WORKDIR /context                                                        0.0s

...

root@pydiner:/context#

From the inside, a container looks like a Linux machine.

root@pydiner:/context# which python
/usr/local/bin/python
root@pydiner:/context# grep PRETTY_NAME /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
root@pydiner:/context#

Python can import packages from the src/ folder without hacking sys.path:

root@pydiner:/context# python
Python 3.12.0 (main, Nov  1 2023, 12:56:53) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pydiner
>>> pydiner.echo("Hello, World!")
2023-11-02 23:00:27 Hello, World!
>>> exit()
root@pydiner:/context#

Scripts in /context/bin are already on the system PATH.

root@pydiner:/context# scrambled -o example.txt eggs
2023-11-02 23:05:33 Read parameters from  /context/etc/default
2023-11-02 23:05:33 Calculate 24 permutations of 'eggs'
2023-11-02 23:05:33 Write output to /context/var/example.txt
root@pydiner:/context#

faq

How do I install pydiner?

Don't. Use it as a template for a new repository.

I'm stuck inside a container!

Press CTRL-D or type exit to exit a container.

Do I have to run containers as root?

Not if you create a USER. See the Dockerfile reference for details.

Can I run containers in the background?

Yes, but not with the kitchen script. See the Docker run reference.

What exception handler does pydiner use?

None. Programs stop immediately when something goes wrong.

What testing framework does pydiner use?

None, but it has been tested with pytest to ensure compatibility.

What logging framework does pydiner use?

None. utensils.achtung() prints to STDERR. utensils.echo() prints to STDOUT.

What are some other Python project templates?

Code style: black

About

Template for a generic Python project with dev sandboxes in containers. Includes examples of automated testing, log streaming, and relative imports.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published