fancy-policeman-6755
05/02/2024, 1:10 PMpants run
on the target runnable pex, every time I touch any code on my repo (which is in itself quite light), Pants starts rebuilding all the requirements like this
Building 26 requirements for my_app.pex from the 3rdparty/python/default.lock resolve: Jinja2<4.0,>=3.0.0, PyYAML>=6.0.1
which (even with pantsd
enabled) takes well over 30 seconds every time, even for very minor code changes on my side. I've checked the common issues and global options, but I feel I'm missing something here.fancy-policeman-6755
05/02/2024, 1:11 PMpants.toml
(slightly cleaned up, there's also some black
and flake8
options around there, plus the sources config) is basically
[GLOBAL]
pants_version = "2.18.3"
backend_packages = [
"pants.backend.python",
]
local_cache = true
pantsd = true
[source]
...
[python]
enable_resolves = true
default_resolve = "default"
interpreter_constraints = ["==3.11.*"]
[python.resolves]
default = "3rdparty/python/default.lock"
tools-external = "3rdparty/python/tools-external.lock"
[python-repos]
indexes = ["<https://some.internal.repo/repository/pip-cache/simple>"]
[setuptools]
install_from_resolve = "tools-external"
requirements = ["//tools/external:requirements"]
wide-midnight-78598
05/02/2024, 1:18 PM.pants.d
folder that might point at a culprit?
• Does this happen when you just run pants package
on the pex?
• Does -ldebug
give any potential insight as to why it's packaging requirements?
• Are you using or modifying any of the ignore items? https://www.pantsbuild.org/2.20/reference/global-options#pants_ignore https://www.pantsbuild.org/2.20/reference/global-options#pants_ignore_use_gitignorefancy-policeman-6755
05/02/2024, 2:03 PMany of the ignore items🤦
fancy-policeman-6755
05/02/2024, 2:03 PM.*/
fancy-policeman-6755
05/02/2024, 2:03 PM.pants.d
fancy-policeman-6755
05/02/2024, 2:04 PMfancy-policeman-6755
05/02/2024, 2:20 PMpants package
on the pex? -> Yeah, same behaviour
• It actually still happens even if I set pants_ignore_use_gitignore = false
. Every time I add a new character, it goes on "building 26 requirements".
• Added pants -ldebug
but I don't get much other info 😕
• The logs in .pants.d
show me the same stuff,
16:17:59.15 [33m[WARN][0m /home/.../specifiers.py:255: DeprecationWarning: Creating a LegacyVersion has been deprecated and will be removed in the next major release
warnings.warn(
16:18:21.90 [INFO] Completed: Building 26 requirements for some_app.pex from the 3rdparty/python/default.lock resolve: Jinja2<4.0,>=3.0.0, PyYAML>=6.0.1, beautifulsoup4<5.0,>=4.12.2... (498 characters truncated)
16:18:21.98 [INFO] Wrote dist/some_app.pex
wide-midnight-78598
05/02/2024, 2:54 PMwide-midnight-78598
05/02/2024, 2:56 PMpants package
? Or is it ONLY after some code has been manipulated?wide-midnight-78598
05/02/2024, 2:58 PMwide-midnight-78598
05/02/2024, 3:38 PMdry-architect-80370
05/02/2024, 8:42 PMpants run path/to/your_main_file.py
?fancy-policeman-6755
05/03/2024, 6:04 AMOr is it ONLY after some code has been manipulated?Yeah, exactly, only after manipulating code. I see that multistage build trick but it seems very targeted for the building of Dockerfiles, I'd have to see if I can adapt it. @dry-architect-80370
Is it the same when you runActually no! Then it's fine. However, the PEX uses a custom entrypoint to launch a FastAPI server via gunicorn. Not sure there'd be an easy way to reproduce this with?pants run path/to/your_main_file.py
pants run <file>
.dry-architect-80370
05/03/2024, 8:29 AMfancy-policeman-6755
05/03/2024, 9:42 AMpex_binary(
name="some_api_pex",
script="gunicorn",
args=[
"<http://some_api.app:create()|some_api.app:create()>",
"--worker-class",
"uvicorn.workers.UvicornWorker",
],
dependencies=[
":some_api_src",
"//:requirements#gunicorn",
"//:requirements#uvicorn",
],
output_path="some_api.pex",
)
where the :some_api_src
are just the python sourceswide-midnight-78598
05/03/2024, 12:06 PMscie
packages.dry-architect-80370
05/03/2024, 12:07 PM:some_api_src
dep to just <http://some_api.app|some_api.app>
(not sure what's the correct syntax to point it to a single file, but it's def doable), otherwise I have no other ideaswide-midnight-78598
05/03/2024, 12:43 PMPEX_TOOLS=1 python3.11 hellofastapi-pex.pex venv --bin-path prepend --compile --rm all ./venv
./venv/bin/uvicorn hellofastapi.main:app
python_sources(
name="libhellofastapi",
sources=["**/*.py"],
)
pex_binary(
name="hellofastapi-deps",
include_sources=False,
include_tools=True,
dependencies=["//:reqs#uvicorn", "//:reqs#fastapi", "//:reqs#numpy", "//:reqs#pywebview", "//:reqs#gunicorn"]
)
pex_binary(
name="hellofastapi-srcs",
include_requirements=False,
include_tools=True,
dependencies=[":libhellofastapi"]
)
pex_binary(
name="hellofastapi-pex",
dependencies=[":hellofastapi-srcs", ":hellofastapi-deps"],
include_tools=True,
)
fancy-policeman-6755
05/07/2024, 11:13 AMuvicorn
and gunicorn
are the heaviest dependencies in there (there's also fastapi, dash, and a bunch of other heavy things). If I understand right, I'd have to explicitly define them in the hellofastapi-deps
pex, which defeats a bit the point of pants
autodiscovery.fancy-policeman-6755
05/07/2024, 11:17 AMif __name__ == "__main__":
import uvicorn
uvicorn.run(create_app(), debug=True, ...)
in the module that creates the FastAPI app that is called in the pex entrypoint by gunicorn. Then I can just run directly the module, without having to build the whole pex. It's not exactly the same as in the production env, but for testing minor code change it's enough.