polylith

David Anderson 2024-09-11T21:07:39.247319Z

Hello! Just curious if i'm missing something here. I got a python polylith fastapi project running, but when I make changes to the fastapi base I'm not seeing them take effect. > example change: modifying one endpoint to return false instead of true • using uv • a polylith base that's a fastapi app • no components • a polylith project pointing to the fastapi base • the polylith project runs using uv run run.py • tried deleting the __pycache__ in /projects/project_name and /bases/project_name • tried running uv run poly sync • tried running uv cache clean not sure if something is cached or why i can't see new changes to the api

licht1stein 2024-09-17T16:38:51.030819Z

uv in polylith is so exciting! I will update my large python polylith project next time I have to do anythign to use uv 🙂

licht1stein 2024-09-17T16:39:25.017329Z

It’s 6 distinct artifacts and a lot of components

2024-09-17T16:44:51.710539Z

It would be awesome to hear how things proceed in your work and if you have any feedback, let's keep in touch.

licht1stein 2024-09-17T16:49:08.440539Z

I will try to write it up in a post when I have a chance. Overall it was a very good experience, even though I was refactoring a large legacy code base into components and bases.

licht1stein 2024-09-17T16:49:23.750349Z

I used git submodules before for large layers of logic and hated that

licht1stein 2024-09-17T16:49:35.961139Z

Each update was a multi-step CI nightmare

2024-09-17T16:50:02.006029Z

I can imagine 😄

licht1stein 2024-09-17T16:50:14.696049Z

Now each projects builds into a separate docker image, everything deploys automatically

👏 1
licht1stein 2024-09-17T16:53:30.926989Z

Without exaggeration, two things that influenced me the most over the last few years are learning clojure and picking up polylith 🙂

2024-09-11T21:52:54.239019Z

Hi! What’s in your run.py?

David Anderson 2024-09-11T21:54:27.288509Z

import uvicorn

if __name__ == "__main__":
    uvicorn.run(
        "",
        host="0.0.0.0",
        port=8000,
        workers=1,
    )

2024-09-11T21:59:36.524489Z

The site_backend - guess that is the base, right? By changing code and not seeing the changes, is that while the app is running? If so, I think you would want to use the —reload option of FastAPI (uvicorn).

David Anderson 2024-09-11T22:05:34.241189Z

yeah site_backend is the name of the base. hmm.. not tryin to do a hot-reload or anything while keeping the program running, I'm stopping the code and re-running it and seeing old code run. Like any changes I make don't show up, even adding a new endpoint. is there a polytool command i need to run to re-compile the base?

David Anderson 2024-09-11T22:07:59.817089Z

also just tried the --reload command on uvicorn, no luck

2024-09-11T22:10:05.221439Z

No, you shouldn’t need to clear any caches or anything else but run the code. I’ll try it out on the example repo - I haven’t started a FastAPI in that way before, but it looks right to me.

🙌 1
2024-09-11T22:21:19.934049Z

I added a run.py with the same code as your example (but my base is in "example.greet_api.core:app", otherwise the same), Then I ran it with uv run development/run.py : tested the API, stopped the process, changed the response and ran again. The new response shows (as expected). It should be just as running any Python code. 🤔 Can you share the module where FastAPI is created (looks like an app.py in the base folder)?

2024-09-11T22:24:43.144739Z

Does your development pyproject.toml look something like this?

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build]
dev-mode-dirs = ["components", "bases", "development", "."]


[tool.polylith.bricks]
"bases/python_polylith/site_backend" = "python_polylith/site_backend"
(assuming that your top namespace is python_polylith )

David Anderson 2024-09-11T22:27:24.692649Z

[build-system]
requires = ["hatchling", "hatch-polylith-bricks"]
build-backend = "hatchling.build"

[project]
name = "site_backend"
version = "0.1.0"

requires-python = ">=3.12"

dependencies = [
...
]

[tool.hatch.build.targets.wheel]
packages = ["polylith_python"]

[tool.hatch.build.hooks.polylith-bricks]

[tool.polylith.bricks]
"../../bases/polylith_python/site_backend" = "polylith_python/site_backend"

2024-09-11T22:28:44.229389Z

Aha, that's the project-specific config right? What about the development config?

David Anderson 2024-09-11T22:29:21.208829Z

haven't been running it from the /development dir, been running from the project dir

David Anderson 2024-09-11T22:29:37.896779Z

don't have a dev config

2024-09-11T22:30:10.503929Z

I mean the pyproject.toml at the root of the repo/workspace.

2024-09-11T22:30:49.263079Z

Ok, so where is the run.py - is it also in the project folder?

David Anderson 2024-09-11T22:31:18.906919Z

yeah run.py is in the project folder

David Anderson 2024-09-11T22:31:29.246119Z

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "polylith-python"
version = "0.1.0"
description = "Polylith Python"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
    ...
]

[tool.uv]
managed=true
dev-dependencies = [
    "mypy~=1.8.0",
    "pytest~=7.4.3",
    "ruff~=0.2.0",
    "polylith-cli>=1.15.2",
]

[tool.hatch.metadata]
allow-direct-references = true

[tool.hatch.build]
dev-mode-dirs = ["components", "bases", "development", "."]

[tool.polylith.bricks]
"bases/polylith_python/greet_api" = "polylith_python/greet_api"
"components/polylith_python/greeting" = "polylith_python/greeting"
"components/polylith_python/log" = "polylith_python/log"
"bases/polylith_python/site_backend" = "polylith_python/site_backend"

[tool.ruff]
exclude = [
    ".git",
    ".github",
    "__pycache__",
    ".mypy_cache",
    ".ruff_cache",
    "dist",
    ".venv",
    "./development/*.py",
]

David Anderson 2024-09-11T22:31:55.294259Z

top level config^

2024-09-11T22:32:51.871519Z

That looks great!

2024-09-11T22:33:04.745959Z

I think I have an idea why things might not work.

2024-09-11T22:39:14.145669Z

Your run.py is in the project folder. And I guess you navigate to that folder and run the uv run command from there. I think uv will create a virtual environment in there and the code will run using that one. That would explain nothing changes if you modify the source code (that is at the top level, in the bases folder). When you run uv again, it will probably use the existing virtual environment and it probably also has put the source code in there too. I think you would need to clear out the virtual environment each time, but that is not the recommended workflow. I think you should consider developing and running code locally from the top-level. Your top-level pyproject is configured to be aware of the bases and components folder (it will not store them in the venv of the top-level). The changes you make in code will be reflected "live" there. The /projects section and the individual projects are for the deployment and when packaging wheels.

2024-09-11T22:40:57.203259Z

The top-level - the repo root, or the workspace - is the "development" area. This is where you add all the components and bases (in the root pyproject). You also have a /development folder for dev-scripts and code scratch files, but using that one is optional.

David Anderson 2024-09-11T22:44:01.544129Z

yayyy that works!

David Anderson 2024-09-11T22:45:50.937279Z

i had previously tried deleting the venv from /projects/project_name and re-running with uv which creates a new venv.. which isn't a great workflow, but also it wasn't running the new code changes even after deleting the venv. (i might have had a 2nd venv at the top level, kinda new to uv) running with uv from the top level fixes everything

2024-09-11T22:48:40.542229Z

Great! Another benefit from working at the the top-level is that you have access to all the code in the entire repo. You can run all bricks in a REPL, or start them with the uv command if you like. The individual projects, collect only the parts they need and is mainly there for packaging the wheels. The wheels are the ones you would install in your production environment.

2024-09-11T22:49:18.677809Z

So the project-specific folders shouldn't have any venvs. You only need one at the root.

✅ 1
David Anderson 2024-09-11T22:50:29.437819Z

that also means that deps for all existing projects should be in the list of deps at the top level pyproject.toml yeah?

2024-09-11T22:50:36.278059Z

Yes!

David Anderson 2024-09-11T22:51:24.863909Z

Appreciate the help 😃

2024-09-11T22:52:12.793969Z

Happy to help, and nice to learn that uv is used with Polylith. I added support for that just weeks ago 😄