Open source book about making Python packages.

Overview

Python packages

Build Netlify Status Website

Tomas Beuzen & Tiffany Timbers

Python packages are a core element of the Python programming language and are how you create organized, reusable, and shareable code in Python. Python Packages is an open source book that describes modern and efficient workflows for creating Python packages.

This book is currently under development. Please feel free to provide comments or suggestions in a GitHub issue.

Building the book

Jupyter Book (HTML)

If you'd like develop and build the py-pkgs book to HTML:

  1. Clone this repository;
  2. Run pip install -r requirements.txt (it is recommended you do this within a virtual environment);
  3. Make any desired changes to source files;
  4. Build the book using the build_jupybook.sh script:
$ cd py-pkgs
$ sh build_jupybook.sh

A fully-rendered HTML version of the book will be built in py-pkgs/_build/html/.

Bookdown (PDF)

If you'd like develop and build the py-pkgs book to PDF:

  1. Install Docker;
  2. Pull the py-pkgs images: docker pull tbeuzen/pypkgs:latest;
  3. Make any desired changes to source files;
  4. Build the book using the build_bookdown.sh script:
$ cd py-pkgs
$ sh build_bookdown.sh

A fully-rendered PDF version of the book will be built in py-pkgs/bookdown/_book/.

Contributing

Contributions are welcome and greatly appreciated! If you're interested in contributing to this project, take a look at the contributor guide.

Colophon

This book was written in JupyterLab and compiled using Jupyter Book. The source is hosted on GitHub and is deployed online at https://py-pkgs.org with Netlify.

Acknowledgements

We'd like to thank everyone that has contributed to the development of Python Packages. This is an open source book that began as supplementary material for the University of British Columbia's Master of Data Science program and was subsequently developed openly on GitHub where it has been read, revised, and supported by many students, educators, practitioners and hobbyists. Without you all, this book wouldn't be nearly as good as it is, and we are deeply grateful. A special thanks to those who have directly contributed to the text via GitHub (in alphabetical order): @Carreau, @dcslagel.

The scope and intent of this book was inspired by the fantastic R Packages book written by Hadley Wickham and Jenny Bryan, a book that has been a significant resource for the R community over the years. We hope that Python Packages will eventually play a similar role in the Python community.

Comments
  • How to package a Python feedback

    How to package a Python feedback

    3.1. partypy: simulate attendance at your party!

    • [x] Love the package name partpy 😂
    • [x] Can we give some more details at a high level after we write "We can repeat this process as many times as we like to generate multiple estimates of how many guests might attend our real-life event." to explain how we will use these multiple estimates to get a final, single estimate of how many people might attend your party. Many of our readers may not be data scientists, or data scientists that have expertise with simulations. So we should clearly and explicitly close the loop here.
    • [x] print(f"Average guests: {results.mean()}") does not print anything out that I can see when the book is rendered.
    • [x] in the "partypy: simulate attendance at your party!" section, I think we should call it "Simulate attendance at your party!" and not use the packaged code, that's a bit confusing I think. I think the raw/unpackaged code should be here to show and explain the example. Perhaps then you can refactor it into functions, and then say, the remainder of this chapter will package up these functions?
    • [x] There is also a big expert leap going on in this section with regards to the raw data > histogram. How does this magic happen? I think my feedback above, will help this. I am slightly worried that this package example is too complex, and so it distracts from the point of the chapter (packaging your code), but let me read on and see...
    • [x] How do we interpret the histogram? This section seems a bit unfinished. This interpretation is needed to close the motivational loop.
    opened by ttimbers 13
  • add a note or warning about upper caps on dependencies?

    add a note or warning about upper caps on dependencies?

    Hi @TomasBeuzen and @ttimbers -- thank you again for this great guide.

    I'm wondering if it would be worth adding some sort of callout somewhere, like a note or warning, about putting upper caps on dependencies?

    By "upper caps" I mean what you get when you accept the default "caret" operator that poetry uses, to mean "This version and any version that is less than a 'major' version change under semantic versioning".

    As you show here for your "adding dependencies example": https://github.com/py-pkgs/py-pkgs/blob/eb68c4fcb7b48cf736d064e023aabdea7070dd91/py-pkgs/bookdown/03-how-to-package-a-python.Rmd#L644

    and also shown here for Python itself: https://github.com/py-pkgs/py-pkgs/blob/eb68c4fcb7b48cf736d064e023aabdea7070dd91/py-pkgs/bookdown/03-how-to-package-a-python.Rmd#L492

    Guessing you know what I mean but just making sure I'm clear.

    The basic issue with this default is that it's "infectious" -- it forces everyone else that depends on your package to meet the same constraints. This means that they can't, e.g., use a newer version of some dependency that fixes a security issue.

    By making their caret operator a default, poetry promotes this, as does language in their documentation. I think for the poetry devs this recommendation makes sense, because they are thinking mainly in terms of deployed applications, and because they think every package should adhere to the strictest interpretation of Semantic Versioning.

    But it can have really painful knock-on effects for downstream users, especially relative beginners like me who have no idea why everything is suddenly broken. I have run into issues resulting from accepting that default for my own packages.

    The knock-on effects can get pretty nuanced (and I'm not sure I understand them all). See these detailed blog posts from @henryiii for more background: https://iscinumpy.dev/post/bound-version-constraints/ https://iscinumpy.dev/post/poetry-versions/

    Like you all (and @henryiii ) I really like poetry because it provides an all-in-one solution, but I'm a bit worried about a lot of people reading your wonderful guide, just accepting the defaults, and then we're all forced to specify python=>3.8.1 <4.0 and jedi^0.19 all the time. I really don't want to constantly have to be tracking when all my dependencies release new versions.

    Not sure where the best place to insert this kind of language would be, but just thought I'd suggest it so maybe others can avoid my pain 🙂

    opened by NickleDave 10
  • Changing the book example

    Changing the book example

    @ttimbers I've been thinking a lot about a potentially different package we could develop through the book that will make it easier to showcase various important elements of the packaging process:

    • multiple functions/sub-packages
    • functions that create plots/writing tests for viz
    • shipping data with the package
    • something with multiple dependencies (e.g., numpy, matplotlib, etc)
    • etc

    One idea I had was to build a package similar to my simple pyguest package. A package for estimating attendance at an event (like a party or wedding) using simulations of Bernoulli RVs and probabilities stored in a dataframe. It's simple, easy to describe, easy to expand (e.g., add functionality to also simulate if +1's will come), we could ship example data with it, we could have plotting function (e.g., histogram of simulation outcomes). Also the name partypy is currently available on pypi 😆 Let me know what you think. I can always whip up a quick draft of what Chapter 3 How to package a Python might look like with this revised package.

    enhancement 
    opened by TomasBeuzen 8
  • Major book refactoring and revision

    Major book refactoring and revision

    This PR includes:

    • General structural changes to book and repo (closes: #28)
    • Added a preface and introduction (closes: #31, closes: #32)
    • Move some chapters to appendices
    opened by TomasBeuzen 7
  • Chapter 9 - Python Packaging Cheatsheet

    Chapter 9 - Python Packaging Cheatsheet

    I've been developing some packages lately and have found myself going over this book searching for particular commands I know I want to use. As someone who understands what's going on and only needs the commands to execute certain tasks, I think a "cheatsheet" would be really helpful (maybe as an appendix or preface?). I envision a very simply document showing the step-by-step commands for creating a package, but without much (if any) documentation, e.g.:

    Package Set Up

    1. Create directory structure: cookiecutter https://github.com/UBC-MDS/cookiecutter-ubc-mds.git
    2. Initialize poetry: cd pkg-name & poetry init etc

    Package Buidling/Testing

    1. Add dependencies: poetry add numpy
    2. Add dev dependencies: poetry add --dev sphinx
    3. Lock dependency list/install dependencies/install package locally: poetry install etc

    Documentation

    1. Modify contents of docs
    2. Download napoleon: poetry add --dev sphinxcontrib-napoleon
    3. Render code documentation with poetry run sphinx-apidoc -f -o docs/source foocat
    4. Render package documentation: cd docs, then poetry run make html etc
    chapter 
    opened by TomasBeuzen 7
  • Advice for moving existing packages to pypi?

    Advice for moving existing packages to pypi?

    I've really enjoyed the book and plan to implement your suggestions to two packages that I currently have. I have these currently on GitHub that I install via pip install git+XXX, so they show up in my environment using their existing names (when I do pip list). I also already have GitHub project names for these two projects.

    But now, I kind of want to start over to get these packages going, yet I already have folders and GitHub projects for these packages. I also already have conda environments set up using these package names as well. So, how do you best recommend starting up new repos for these two new packages, when I don't really want to change the names of these pypi versions? For example, I have a package called jakomics that I would like to put into pypi with that name, but I already have all of this history and "code baggage" using that name?

    Hopefully this isn't too vague of a question, but I'm also sure I'm not the first to convert a local package to a pypi package. Thanks for your help!

    opened by jeffkimbrel 6
  • Question: semantic release

    Question: semantic release

    How come (in section 7.2.2) the CI/CD pipeline is not (re-)triggered when the python-semantic-release package commits a new version to the 'main' branch? Shouldn't a new commit count as a push and therefore start a new pipeline execution (which would start an infinite loop)?

    name: ci-cd
    
    on: [push, pull_request]
    
    jobs:
    
    opened by Seth-Julien-de-Lampon 5
  • Creating an actual

    Creating an actual "py-pkgs" package on PyPI

    We use the hypothetical foocat package throughout the book at the moment. But in all chapters after "The Whole Game" it would be great to have this package available on pypi so that readers can actually pip install it and run through the code. Even better, we could pip install it so that later chapters can actually execute the code they are showing, rather than having it embedded in markdown.

    opened by TomasBeuzen 5
  • Issue on page /03-how-to-package-a-python.html

    Issue on page /03-how-to-package-a-python.html

    Hi there,

    I'm having trouble getting the example to run. I cannot seem to get the module to import.

    I'm at section 3.5. I've installed poetry (poetry --version returns 1.1.12), and set up a conda environment (pycounts).

    The guide is a little unclear about if the poetry calls need to be within the conda env or not, but neither works. From the pycounts folder, if I run poetry install I get the following

    The virtual environment found in C:\Users\taren\miniconda3\envs\pycounts seems to be broken.
    Recreating virtualenv pycounts-tZwN6m1u-py3.9 in C:\Users\taren\AppData\Local\pypoetry\Cache\virtualenvs\pycounts-tZwN6m1u-py3.9
    Installing dependencies from lock file
    
    Installing the current project: pycounts (0.1.0)
    

    However, opening a python shell and trying to import the module gives:

    >>> from pycounts.pycounts import count_words
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ModuleNotFoundError: No module named 'pycounts
    

    Repeating these steps but not in the conda env does not give the warning about a broken virtual env

    Installing dependencies from lock file
    
    Installing the current project: pycounts (0.1.0)
    

    But the import error is the same:

    >>> from pycounts.pycounts import count_words
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ModuleNotFoundError: No module named 'pycounts'
    

    Is there any chance you could help diagnose the issue? I'm using Windows. I've tried:

    • A complete wipe of miniconda, including all envs
    • Deleting the package and starting again
    • Removing and reinstalling poetry

    Really appreciate any help.

    opened by tarensanders 4
  • 📖 CONTENT: refer to poetry docs for installation

    📖 CONTENT: refer to poetry docs for installation

    Looks like the command to install Poetry has been changed. The current command in the book is causing issues... This PR updates it. If this changes a lot, perhaps we just want to point at the installation page long-term so this is not so brittle?

    opened by ttimbers 4
  • Issue on page /03-how-to-package-a-python.html

    Issue on page /03-how-to-package-a-python.html

    Thanks for the great work - really very helpful to get up to speed in Python with some background in R.

    Two minor points:

    1. we can now build our documentation with sphinx using the following command from our root package directory This did not work for me (on Windows) from the root directory, but from directory docs.

    2. At some points in the html-document, the string "\newpage" appears.

    opened by mtkerbeR 4
  • Issue on page 04-package-structure

    Issue on page 04-package-structure

    The mention of namespaces on this page is fine if rudimentary. However, there is also the concept of a "namespace package", something that my organization is making use of. This involves a somewhat different project structure than is shown in the book's examples; and it presupposes that there will be multiple projects sharing the same namespace, which may or may not reside in the same repository.

    opened by mcowpert 1
  • More tool agnostic version of `poetry run pytest`: `python -m pytest`

    More tool agnostic version of `poetry run pytest`: `python -m pytest`

    In the attention block of https://py-pkgs.org/03-how-to-package-a-python#testing-your-package:

    If you’re not developing your package in a conda virtual environment, poetry will automatically create a virtual environment for you using a tool called venv (read more in the documentation). You’ll need to tell poetry to use this environment by prepending any command you run with poetry run, like: poetry run pytest tests/.

    If you want the code to be a bit more tool agnostic (i.e., not always rely on poetry), it seems that after you install pytest into whatever environment you are in, you can reference pytest by using python -m. The book already uses python -c earlier to create the text file for the example, so this can also be mentioned?

    Using poetry run:

    (py-pkgs-poetry) [email protected] pycounts_poetry % poetry run pytest tests/
    ============================================ test session starts =============================================
    platform darwin -- Python 3.10.3, pytest-7.1.2, pluggy-1.0.0
    rootdir: /Users/danielchen/temp/py-pkgs-poetry/pycounts
    collected 1 item                                                                                             
    
    tests/test_pycounts.py .                                                                               [100%]
    
    ============================================= 1 passed in 0.00s ==============================================
    

    Using python -m:

    (py-pkgs-poetry) [email protected] pycounts_poetry % python -m pytest tests/
    ============================================ test session starts =============================================
    platform darwin -- Python 3.10.3, pytest-7.1.2, pluggy-1.0.0
    rootdir: /Users/danielchen/temp/py-pkgs-poetry/pycounts
    collected 1 item                                                                                             
    
    tests/test_pycounts.py .                                                                               [100%]
    
    ============================================= 1 passed in 0.00s ==============================================
    
    opened by chendaniely 0
  • Note about conventional commits

    Note about conventional commits

    The tip in 3.5 (page /03-how-to-package-a-python.html) refers to the "Angular style" for Git commit messages:

    In this book, we use the Angular style for Git commit messages.

    Just learned that style follows what's known as "conventional commits": https://www.conventionalcommits.org/ (it also references the angular conventions for other types)

    opened by chendaniely 0
  • Additions for the next round of revision or second edition

    Additions for the next round of revision or second edition

    edited by Tomas Beuzen

    This is a scratchpad for topics we'd like to add or cover more comprehensively in the book:

    • Dependency updating with Dependabot. This would fit nicely in the cookiecutter and book.
    • Advanced fixture usage:
      • Mocking
      • Setting up environments for test to run in, e.g., directory structures, environment variables, etc.
    • Style checking and formatting:
      • Using flake8 and/or black, and integrating into CI
    • Packages with extensions in other languages (relevant comment)
    • Releasing packages to Anaconda/conda-forge repositories
    • Mention PyScaffold as an alternative templating tool
    • Consider changing poetry to pdm (see discussions in #95)
    • Consider providing more guidance on file/directory/repository/distribution/package naming conventions (see https://github.com/py-pkgs/py-pkgs-cookiecutter/issues/48 and this post)
    • Consider adding more information/examples about namespace packages - currently we only briefly mention them at the bottom of [Section 4.2.1](https://py-pkgs.org/04-package-structure#package-contents (see #119)
    enhancement 
    opened by ttimbers 0
Releases(v0.5)
Owner
Python Packages
Online source and support material for the Python Packages book
Python Packages
Shell scripts made simple 🐚

zxpy Shell scripts made simple 🐚 Inspired by Google's zx, but made much simpler and more accessible using Python. Rationale Bash is cool, and it's ex

Tushar Sadhwani 492 Dec 27, 2022
Learn the basics of Python. These tutorials are for Python beginners. so even if you have no prior knowledge of Python, you won’t face any difficulty understanding these tutorials.

01_Python_Introduction Introduction 👋 Python is a modern, robust, high level programming language. It is very easy to pick up even if you are complet

Milaan Parmar / Милан пармар / _米兰 帕尔马 245 Dec 30, 2022
Visualization of COVID-19 Omicron wave data in Seoul, Osaka, Tokyo, Hong Kong and Shanghai. 首尔、大阪、东京、香港、上海由新冠病毒 Omicron 变异株引起的本轮疫情数据可视化分析。

COVID-19 in East Asian Megacities This repository holds original Python code for processing and visualization COVID-19 data in East Asian megacities a

STONE 10 May 18, 2022
Programa que organiza pastas automaticamente

📂 Folder Organizer 📂 Programa que organiza pastas automaticamente Requisitos • Como usar • Melhorias futuras • Capturas de Tela Requisitos Antes de

João Victor Vilela dos Santos 1 Nov 02, 2021
A web UI for managing your 351ELEC device ROMs.

351ELEC WebUI A web UI for managing your 351ELEC device ROMs. Requirements Python 3 or Python 2.7 are required. If the ftfy package is installed, it w

Ben Phelps 5 Sep 26, 2022
Shai-Hulud - A qtile configuration for the (spice) masses

Shai-Hulud - A qtile configuration for the (spice) masses Installation Notes These dotfiles are set up to use GNU stow for installation. To install, f

16 Dec 30, 2022
A streaming animation of all the edits to a given Wikipedia page.

WikiFilms! What is it? A streaming animation of all the edits to a given Wikipedia page. How it works. It works by creating a "virtual camera," which

Tal Zaken 2 Jan 18, 2022
SimilarWeb for Team ACT v.0.0.1

SimilarWeb for Team ACT v.0.0.1 This module has been built to provide a better environment specifically for Similarweb in Team ACT. This module itself

Sunkyeong Lee 0 Dec 29, 2021
Curses frontend for Canto daemon

Canto Curses The curses (text) client for canto-daemon. Canto-daemon is required to work and is found at: http://github.com/themoken/canto-next Requir

Jack Miller 86 Dec 28, 2022
Opensource Desktop application for kenobi.

Kenobi-Server WIP Opensource desktop application for Kenobi. Download the apple watch app to get started. What is this repo? It's repo for the opensou

Aayush 9 Oct 08, 2022
Python Commodore BBS multi-client

python-cbm-bbs-petscii Python Commodore BBS multi-client This is intended for commodore 64, c128 and most commodore compatible machines (as the new Co

7 Sep 16, 2022
A website to collect vintage 4 tracks cassette recorders.

Vintage 4tk cassette recorders A website to collect vintage 4 tracks cassette recorders. Local development setup Copy and customize Django settings (e

1 May 01, 2022
Python with braces. Because Python is awesome, but whitespace is awful.

Bython Python with braces. Because Python is awesome, but whitespace is awful. Bython is a Python preprosessor which translates curly brackets into in

1 Nov 04, 2021
CDM Device Checker for python

CDM Device Checker for python

zackmark29 79 Dec 14, 2022
Assignment for python course, BUPT 2021.

pyFuujinrokuDestiny Assignment for python course, BUPT 2021. Notice username and password must be ASCII encoding. If username exists in database, syst

Ellias Kiri Stuart 3 Jun 18, 2021
A Desktop application for the signalum python library

Signalum Desktop A Desktop application on the Signalum Python Library/CLI Tool. The Signalum Desktop application is an attempt to develop a single too

BISOHNS 35 Feb 15, 2021
This program goes thru reddit, finds the most mentioned tickers and uses Vader SentimentIntensityAnalyzer to calculate the ticker compound value.

This program goes thru reddit, finds the most mentioned tickers and uses Vader SentimentIntensityAnalyzer to calculate the ticker compound value.

195 Dec 13, 2022
Web-based Sudoku solver built using Python. A demonstration of how backtracking works.

Sudoku Solver A web-based Sudoku solver built using Python and Python only The motivation is to demonstrate how Backtracking algorithm works. Some of

Jerry Ng 2 Dec 31, 2022
This is a repository built by the community for the community.

Nutshell Machine Learning Machines can see, hear and learn. Welcome to the future 🌍 The repository was built with a tree-like structure in mind, it c

Edem Gold 82 Nov 18, 2022
A dashboard for your code. A build system.

NOTICE: THIS REPO IS NO LONGER UPDATED Changes Changes is a build coordinator and reporting solution written in Python. The project is primarily built

Dropbox 763 Sep 09, 2022