From a1c2120c54f18ef4928c5a48c14ff4bde04d6734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20S=2E=20Dokken?= Date: Tue, 14 Nov 2023 14:48:56 +0100 Subject: [PATCH] Minor additional comments regarding pyproject.toml syntax that might be unfamiliar. Add copyright notice with myself. Slightly modify covered topics in last lecture (more to come in separate branch). --- _config.yml | 2 +- index.md | 2 +- .../From Script to Project.ipynb | 201 +++++++++--------- 3 files changed, 103 insertions(+), 102 deletions(-) diff --git a/_config.yml b/_config.yml index 244cf5d..d97f7e8 100644 --- a/_config.yml +++ b/_config.yml @@ -6,7 +6,7 @@ author: | Joakim Sundnes, Ola Skavhaug, Jonathan Feinberg, Karl-Erik Holter, Vidar Tonaas Fauske, Benjamin Ragan-Kelley, Lisa Pankewitz, Sebastian Mitusch, Simon Funke, Ingeborg Gjerde, Vegard Vinje, - and Miroslav Kuchta + Miroslav Kuchta and Jørgen S. Dokken exclude_patterns: - .nox diff --git a/index.md b/index.md index 48e2ccf..d7cd1eb 100644 --- a/index.md +++ b/index.md @@ -16,7 +16,7 @@ video](play.png "Play video")](https://youtube.com/channel/UCpOB3OcVNTqnIiXcagei The lecture was initially created by Hans Petter Langtangen and extended by Joakim Sundnes, Ola Skavhaug, Jonathan Feinberg, Karl-Erik Holter, Vidar Tonaas Fauske, Benjamin Ragan-Kelley, Lisa Pankewitz, Sebastian -Mitusch, Simon Funke, Ingeborg Gjerde, Vegard Vinje and Miroslav Kuchta. +Mitusch, Simon Funke, Ingeborg Gjerde, Vegard Vinje, Miroslav Kuchta and Jørgen S. Dokken. It is being taught on a yearly basis at University of Oslo under the name [IN3110/IN4110](http://www.uio.no/studier/emner/matnat/ifi/IN3110/). diff --git a/lectures/production/from-script-to-project/From Script to Project.ipynb b/lectures/production/from-script-to-project/From Script to Project.ipynb index 56a89ee..b482c90 100644 --- a/lectures/production/from-script-to-project/From Script to Project.ipynb +++ b/lectures/production/from-script-to-project/From Script to Project.ipynb @@ -25,8 +25,7 @@ "4. Add tests\n", "5. Deploy your application/library\n", "\n", - "\n", - "The final version of this lecture are available here: \n", + "The final version of this lecture are available here:\n", "\n", "Source code:\n", "https://github.com/UiO-IN3110/monty_hall_game\n", @@ -41,28 +40,28 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Our test case " + "## Our test case\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "We will use the `Monty Hall Game` implementation from last week as an example." + "We will use the `Monty Hall Game` implementation from last week as an example.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "" + "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "This `project` currently consists of the game file itself and some html templates:" + "This `project` currently consists of the game file itself and some html templates:\n" ] }, { @@ -73,7 +72,7 @@ "monty_hall_game/\n", " game_server.py # Start web server\n", " templates/*.html # Templates for web-server\n", - "```" + "```\n" ] }, { @@ -82,37 +81,36 @@ "source": [ "**Goal**:\n", "Make the game available as a project with:\n", - "* a *command line* interface \n", - "* a *web* interface\n", - "* online and offline documentation\n", - "* tests \n", - "* error handling." + "\n", + "- a _command line_ interface\n", + "- a _web_ interface\n", + "- online and offline documentation\n", + "- tests\n", + "- error handling.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Step 1. Organize your script into modules and functions." + "## Step 1. Organize your script into modules and functions.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "We would like to offer a command line interface and a web interface. To achieve this, \n", - "we separate the game logic into a separate package (which is simply a directory with Python modules). \n", + "We would like to offer a command line interface and a web interface. To achieve this,\n", + "we separate the game logic into a separate package (which is simply a directory with Python modules).\n", "\n", "```bash\n", "myproject/\n", " monty_hall_game/ # Game package\n", - " __init__.py # Init file module \n", + " __init__.py # Init file module\n", " monty_hall_game.py # Core game module\n", - "``` \n", - "\n", - "\n", + "```\n", "\n", - "The core game module contains the class `MontyHallGame`, which implements the core functionality of the game. Here is a the user interface for the game package:" + "The core game module contains the class `MontyHallGame`, which implements the core functionality of the game. Here is a the user interface for the game package:\n" ] }, { @@ -121,7 +119,7 @@ "source": [ "Let's look at the user interface of the package.\n", "\n", - "Setting up the game:" + "Setting up the game:\n" ] }, { @@ -208,7 +206,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We can now play one round:" + "We can now play one round:\n" ] }, { @@ -273,7 +271,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Printing the game statistics:" + "Printing the game statistics:\n" ] }, { @@ -299,14 +297,14 @@ "metadata": {}, "source": [ "With this package, we can build scripts that expose the game to the user via the command line and the web-interface.\n", - "We implement these in the folder `bin` (for binary files. We use this name of convention reasons, even though our files are not really bindary files)." + "We implement these in the folder `bin` (for binary files. We use this name of convention reasons, even though our files are not really bindary files).\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Our new directory structure is:" + "Our new directory structure is:\n" ] }, { @@ -316,34 +314,34 @@ "```bash\n", "myproject/\n", " bin/ # Scripts\n", - " play_monty_hall_cli.py # Start game with command line interface \n", + " play_monty_hall_cli.py # Start game with command line interface\n", " play_monty_hall_web.py # Start game with web-server\n", " monty_hall_game/ # Game package\n", - " __init__.py # Init file module \n", + " __init__.py # Init file module\n", " monty_hall_game.py # Core game module\n", - " templates/*.html # Templates for web-server \n", - "```" + " templates/*.html # Templates for web-server\n", + "```\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Let's look at the code in more detail (see files in `monty-hall-game1` folder)" + "Let's look at the code in more detail (see files in `monty-hall-game1` folder)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Step 2. Add installation files and instructions" + "## Step 2. Add installation files and instructions\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Record dependencies with requirements.txt" + "### Record dependencies with requirements.txt\n" ] }, { @@ -351,7 +349,7 @@ "metadata": {}, "source": [ "Our project has some dependencies to run it, such as `flask`,\n", - "and other dependencies to \"develop\" it such as pytest and (later) sphinx:" + "and other dependencies to \"develop\" it such as pytest and (later) sphinx:\n" ] }, { @@ -393,7 +391,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The dependencies can be automatically installed with" + "The dependencies can be automatically installed with\n" ] }, { @@ -452,8 +450,8 @@ "source": [ "### Setuptools\n", "\n", - "Further, we can create a setup file to simplify the installation of our game. \n", - "First thing we need is a `pyproject.toml` file:" + "Further, we can create a setup file to simplify the installation of our game.\n", + "First thing we need is a `pyproject.toml` file:\n" ] }, { @@ -497,6 +495,16 @@ "%pycat monty-hall-game4/pyproject.toml" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We note that we here have used a few new features compared to what we covered in [Structuring Python code](../../python/packages_and_testing.ipynb).\n", + "\n", + "- `dynamic`: Some fields can be modified by other packages, scripts etc. when installing. One example is the list of dependencies, that we now let `setuptools` fetch from `requirements.txt`. See [Dynamic metadata](https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html#dynamic-metadata) for more information on this\n", + "- `[project-scripts]`: creates an alias from calling the `monty_hall_game.cli.main()` function from the command line as `monty-hall-cli`. The syntax is `package.submodule:function`.\n" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -504,8 +512,8 @@ "We can now install the `monty_hall_game` package with\n", "\n", "```bash\n", - "pip install . \n", - "```" + "pip install .\n", + "```\n" ] }, { @@ -513,9 +521,10 @@ "metadata": {}, "source": [ "Using the Python package manager `pip` has the advantage that we can uninstall the package again:\n", + "\n", "```bash\n", "pip uninstall uio-monty-hall-game\n", - "```" + "```\n" ] }, { @@ -578,14 +587,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Installation instructions" + "### Installation instructions\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Finally it is good practice to add a installation instructions to the README.md file:" + "Finally it is good practice to add a installation instructions to the README.md file:\n" ] }, { @@ -641,14 +650,14 @@ "metadata": {}, "source": [ "### New files\n", - " \n", + "\n", "```bash\n", "monty_hall_game/\n", " README.md # Installation instructions\n", " requirements.txt # List of project dependencies\n", " dev-requirements.txt # List of development dependencies\n", " pyproject.toml # SetupTools file\n", - "```" + "```\n" ] }, { @@ -716,7 +725,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Step 3. Add documentation" + "## Step 3. Add documentation\n" ] }, { @@ -729,7 +738,7 @@ "\n", "Let's look at the code in more detail (see files in `monty-hall-game2` folder)\n", "\n", - "Once done, we can access the docstrings as usual:" + "Once done, we can access the docstrings as usual:\n" ] }, { @@ -795,20 +804,20 @@ "\n", " Among other things, the quickstart guide will ask for the documentation folder. I typically choose `docs` for this.\n", "\n", - "2. Use \n", + "2. Use\n", " ```bash\n", " mkdir -p docs/api\n", " sphinx-apidoc -o docs/api monty_hall_game\n", " ```\n", - " to add documentation for each module. \n", - "3. Edit `docs/index.rst` to change the content of your main page. \n", + " to add documentation for each module.\n", + "3. Edit `docs/index.rst` to change the content of your main page.\n", "4. Compile the documentation with:\n", " ```bash\n", " cd docs\n", " make html\n", " ```\n", " (make sure that the module is in sys.path or installed).\n", - "5. The documentation is available on `docs/_build/html/index.html`." + "5. The documentation is available on `docs/_build/html/index.html`.\n" ] }, { @@ -876,7 +885,7 @@ "metadata": {}, "source": [ "#### New files (autogenerated with `sphinx-quickstart` and `sphinx-apidoc`)\n", - " \n", + "\n", "```bash\n", " docs/\n", " conf.py # Sphinx configuration file\n", @@ -886,9 +895,9 @@ " docs/api\n", " modules.rst # Module page\n", " monty_hall_game.rst # Module page\n", - "``` \n", + "```\n", "\n", - "**Tip**: I use https://readthedocs.org/ to host my documentation. It also automatically generates your documentation when you push to your github repo. " + "**Tip**: I use https://readthedocs.org/ to host my documentation. It also automatically generates your documentation when you push to your github repo.\n" ] }, { @@ -933,21 +942,21 @@ "\n", "We will use `pytest` as testing framework.\n", "New files:\n", - " \n", + "\n", "```bash\n", "monty_hall_game/\n", " tests\n", " test_game_module.py\n", "```\n", "\n", - "We can run the test suite with" + "We can run the test suite with\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Let's look at the code in more detail (see files in `monty-hall-game4` folder)" + "Let's look at the code in more detail (see files in `monty-hall-game4` folder)\n" ] }, { @@ -986,7 +995,6 @@ "\n", "**Quick guide to GitHub actions**\n", "\n", - "\n", "create `.github/workflows/test.yml` (any `name.yml` will do, you can have several) with steps:\n", "\n", "1. checkout the repo\n", @@ -1045,13 +1053,11 @@ " pytest -v --color=yes\n", "```\n", "\n", - "\n", "Check:\n", "\n", "https://github.com/UiO-IN3110/monty_hall_game/actions\n", "\n", - "\n", - "Check the build status page to see if your build passes or fails according to the return status of the build command by visiting your GitHub repository and selecting `actions`." + "Check the build status page to see if your build passes or fails according to the return status of the build command by visiting your GitHub repository and selecting `actions`.\n" ] }, { @@ -1066,24 +1072,24 @@ " requirements.txt # Dependencies\n", " setup.py # Setuptools\n", " monty_hall_game/ # Main module\n", - " __init__.py \n", + " __init__.py\n", " web.py\n", " cli.py\n", - " game_exceptions.py \n", + " game_exceptions.py\n", " monty_hall_game.py\n", " templates/*.html\n", " static/*.{png,jpg}\n", " docs/ # Sphinx documentation (mostly autogenerated)\n", - " conf.py \n", - " index.rst \n", - " Makefile \n", - " modules.rst \n", - " monty_hall_game.rst \n", + " conf.py\n", + " index.rst\n", + " Makefile\n", + " modules.rst\n", + " monty_hall_game.rst\n", " tests # tests in pytest format\n", " test_game_module.py\n", " .github/workflows/test.yml # continuous integration\n", - " .gitignore \n", - "```" + " .gitignore\n", + "```\n" ] }, { @@ -1098,15 +1104,13 @@ "pip install monty_hall_game\n", "```\n", "\n", - "\n", "This is possible by uploading the package to the Python Package Index (PyPI).\n", "\n", - "\n", "1. Create a source and wheel distribution with the following command:\n", "\n", "```bash\n", "python -m pip install build\n", - "python -m build . \n", + "python -m build .\n", "```\n", "\n", "2. Upload the distribution to pypi (will ask for the pypi credentials) with:\n", @@ -1114,7 +1118,6 @@ "```bash\n", "twine upload -r test dist/*\n", "```\n", - " \n", "\n", "Result see https://test.pypi.org/project/uio-monty-hall-game/\n" ] @@ -1305,7 +1308,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Final directory layout" + "## Final directory layout\n" ] }, { @@ -1434,46 +1437,44 @@ " requirements.txt # Dependencies\n", " setup.py # Setuptools\n", " monty_hall_game/ # Our package\n", - " __init__.py \n", - " game_exceptions.py \n", - " monty_hall_game.py \n", - " \n", - " bin/ # Scripts \n", - " play_monty_hall_cli.py \n", - " play_monty_hall_web.py \n", + " __init__.py\n", + " game_exceptions.py\n", + " monty_hall_game.py\n", + "\n", + " bin/ # Scripts\n", + " play_monty_hall_cli.py\n", + " play_monty_hall_web.py\n", " templates/*.html\n", " docs/ # Sphinx documentation (mostly autogenerated)\n", - " conf.py \n", - " index.rst \n", - " Makefile \n", - " modules.rst \n", - " monty_hall_game.rst \n", + " conf.py\n", + " index.rst\n", + " Makefile\n", + " modules.rst\n", + " monty_hall_game.rst\n", " tests # tests in pytest format\n", " test_game_module.py\n", " .github/workflows/test.yml # continuous integration\n", - " .gitignore \n", - "```" + " .gitignore\n", + "```\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "\n", "## Summary of today's topics\n", "\n", - "* **Installation**\n", - " * requirements.txt\n", - " * Package + setup.py \n", - " * README.md \n", - "* **Testing**\n", - " * py.test\n", - " * Continuous integration (with GitHub)\n", - "* **Documentation**\n", - " * Sphinx\n", - " * ReadTheDocs\n", - "* **Deployment / Publishing**\n", - " * Deployment of Python packages with PyPI\n" + "- **Installation**\n", + " - requirements.txt\n", + " - Package + pyproject.toml\n", + " - README.md\n", + "- **Testing**\n", + " - Continuous integration (with GitHub)\n", + "- **Documentation**\n", + " - Sphinx\n", + " - ReadTheDocs\n", + "- **Deployment / Publishing**\n", + " - Deployment of Python packages with PyPI\n" ] } ],