Python? Test out our new Python tutorial

You’ve likely seen the Getting Started guides in our documentation. Well, we’ve got a new one for Python which we’d like to get your feedback on. You can find python-hellofly-flask in the Fly Examples repositories, complete with the Getting Started article in the Readme. Give it a try and let us know here how it went.

Dj

Thanks for the Python demo app! I enjoyed deploying it, and Fly.io seems like a fantastic platform.

I would love to see the Python builder support Poetry. Poetry is a tool for Python dependency management and packaging. I’ve been working with Poetry for some time now, with and without Docker, in a variety of personal and enterprise projects. It has a number of compelling benefits, including:

  • Automatic virtual environment management: Poetry automatically manages the virtualenv for the application.
  • Automatic dependency management: rather than having to run pip freeze > requirements.txt, Poetry automatically manages a configuration file called pyproject.toml, which enables SemVer-level control over dependencies and can be used by other Python tools. Poetry also manages a lockfile called poetry.lock to automatically track specific versions and hashes for every dependency.
  • Dependency resolution: Poetry will automatically resolve any dependency version conflicts.
  • Dependency separation: Poetry can maintain separate lists of dependencies for development and production in the pyproject.toml. Production installs can skip development dependencies to speed up Docker builds.
  • Builds: Poetry has features for easily building the project into a Python package.

If you’re open to supporting Poetry, I would be happy to get you a GitHub PR to update the demo app correspondingly.

To start, the directories would be restructured to support proper Python packaging, without disrupting the pre-existing commands:

~/path/to/fly-apps/python-hellofly-flask
❯ git mv hellofly.py hellofly/__init__.py

~/path/to/fly-apps/python-hellofly-flask
❯ git mv templates hellofly/templates

~/path/to/fly-apps/python-hellofly-flask
❯ git status

On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
(use "git restore --staged <file>..." to unstage)
renamed: hellofly.py -> hellofly/__init__.py
renamed: templates/hello.html -> hellofly/templates/hello.html

~/path/to/fly-apps/python-hellofly-flask
❯ git commit -m "Restructure project to support Python packaging"

The requirements.txt would be refactored into a pyproject.toml configuration file like this:

# pyproject.toml
[tool.poetry]
name = "hellofly"
version = "0.0.1"
authors = ["Fly <support@fly.io>"]
description = "Fly.io configuration within pyproject.toml."
homepage = "https://github.com/fly-apps/python-hellofly-flask"

[tool.poetry.dependencies]
python = "^3.9"
click = "^7"
flask = "^1"
gunicorn = "^20"
itsdangerous = "^1"
jinja2 = "^2"
markupsafe = "^1"
werkzeug = "^1"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

After running a poetry install, the changes would look like this:

~/path/to/fly-apps/python-hellofly-flask
❯ git rm requirements.txt

~/path/to/fly-apps/python-hellofly-flask
❯ git add --all

~/path/to/fly-apps/python-hellofly-flask
❯ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: poetry.lock
new file: pyproject.toml
deleted: requirements.txt

The builder could check the project directory for a pyproject.toml and run Poetry if one is found. See heroku/heroku-buildpack-python#796 for some related discussion of how this might look on Heroku. Heroku hasn’t implemented Poetry support yet, as far as I know, so this could give you an edge over Heroku.

I could think of some interesting future directions for this. You’re already using TOML for configuration, so the Fly.io configuration could even be added directly to pyproject.toml (flyproject.toml?). For Python projects, this could obviate the need for both the Procfile and the fly.toml.

# pyproject.toml
[tool.fly]
app = "hellofly-python"

[tool.fly.build]
builtin = "python"

[tool.fly.run]
web = "gunicorn hellofly:app"

[tool.fly.services]
http_checks = []
internal_port = 8080
protocol = "tcp"
script_checks = []

[tool.poetry]
name = "hellofly"
version = "0.0.1"
authors = ["Fly <support@fly.io>"]
description = "Fly.io configuration within pyproject.toml."
homepage = "https://github.com/fly-apps/python-hellofly-flask"

[tool.poetry.dependencies]
python = "^3.9"
click = "^7"
flask = "^1"
gunicorn = "^20"
itsdangerous = "^1"
jinja2 = "^2"
markupsafe = "^1"
werkzeug = "^1"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

In the meantime, I can continue configuring Poetry through Docker. Thanks for your consideration, and keep up the good work.

2 Likes

I created an issue on the github page: Attempting to deploy fails · Issue #2 · fly-apps/python-hellofly-flask · GitHub, but it looks like for some reason the app is being identified as a Django app during flyctl launch. That command eventually succeeds, but attempts to run flyctl deploy fail. I was able to get around this by manually updating the Dockerfile and it all worked, but from what I can tell this tutorial is not quite working smoothly out of the box at the moment.

2 Likes

Do you have an example Dockerfile that might work for Django? I’m trying to deploy a Django/Postgres site to Fly.io with poetry, but I’m not sure what the Dockerfile should look like.

I found a sample Django project but it doesn’t look finished yet.

I encountered the same problem a couple of days ago.

Hi @whgerard1 and @127001!

We’ve been discussing what to do with old learning examples in the fly-apps org.

Things move fast around here! As a rule, if it’s not linked from the docs and/or it hasn’t been touched in a year, I’d expect it not to work, at least not without some adaptation. This will apply to the contents of old blog posts as well.

There are, as of today, 90 of these repos. Not all of them will be particularly useful at this point. At the same time, we hesitate to simply remove examples that people could use as a starting point, so we’ll probably be archiving a lot of them soon.

Edit: Doing a better job making sure everything actually in the docs is up to date is a separate but related exactly the same issue. :slight_smile: (My bad, I see that even though this is an old example and forum post, it is in fact the one linked from the docs).

1 Like

Now I need to make the above its own topic. @whgerard1 and @127001 apologies for the confusion, carry on as you were, but thanks for lighting a fire under me on that anyway.

1 Like

Thanks for the response. Makes sense that some of these would fall out of date, and it did in fact still serve as a useful starting point, so I understand why you would want to keep them around / archived as references rather than just deleting them entirely, even if they aren’t being actively maintained. Thought I would give you all a heads up since this one is linked from the Python getting started page in the docs, as you mentioned, in case this wasn’t already on your radar.

1 Like

Thanks @whgerard1, you’d be totally right to think that if we use it in our docs, we should keep it working!

(from one angle or another, i.e. either keep it working or change the docs! :smiley: )

Fly.io looks really good. If you can publish solid docs and examples for Django + Poetry + Postgres, I think it would help the Python users. That’s the main thing holding me back from using it.

We’d love to get some help improving our Python and Django runtime support. Is anyone in this thread interested?

The work would mostly be documentation and tweaking our flyctl launcher to drop the right Dockerfile and Django config.

@jsierles I’d be interested. I’m having a very hard time deploying my flask web app with celery workers and a SQLite database mounted on a shared volume

Just to add what @whgerard1 mentioned, the fact that the supported documentation refers to broken examples isn’t a great onboarding experience. I don’t mean to sound ungrateful or pedantic over this, but I wasted a good chunk of time arriving at the conclusion that the example was wrong. It leaves a bad taste, to be honest with you.

@catflydotio, you mention that you should keep it working. Is there a plan to actually follow through with this? The front door to your product should be seamless, in my opinion.

Sorry to hear you hit that seam in our front door, @flypi! We’re currently recruiting Python folks specifically for this reason.

I have an interest in that. I am not sure, what would be the right way to reach you about that. I opened a github issue and pull request. The pull request has been closed without comment.