Hello, We would like, as part of real-time monito...
# ask-metaflow
s
Hello, We would like, as part of real-time monitoring of our Metaflow workflows, to log through calls to an external API every time a step finishes, or when a workflow concludes, or when an error occurs in a specific task. This logging is done through a library we've developed that sends messages to a PostgreSQL database. We've taken inspiration from what can be done with other scheduling tools like Airflow and Prefect, namely using callback functions. The equivalent in Metaflow would be a decorator. So, we've tried to make custom decorators on our end, but the only implementation that worked involves putting the following code in an
__init__.py
file:
Copy code
from metaflow.decorators import step, _import_plugin_decorators 
from metaflow.plugins import STEP_DECORATORS 
from .custom_step_decorator import TestDecorator 

STEP_DECORATORS.append(TestDecorator) 

_import_plugin_decorators(globals())
This allows us to import the decorator into the workflow code itself and apply it to the steps. However, we find this approach complex and are not sure how it fits into deployment on AWS with Step Functions. What would be the best way to proceed? On a related note, the package we use for logging is on GCP Artifact Registry. Is there a straightforward way to import it with GCP credentials, perhaps via the PyPI tag? How can we import this package for the entire workflow without having to do it for each step? Thank you for your response and have a great day!
d
Hello β€” you can check out extensions: https://github.com/Netflix/metaflow-extensions-template. As the documentation notes, this is advanced usage and things may break as we evolve Metaflow but it will work one way or another (we are heavy users of extensions and other ppl are using it too). It’s definitely more supported than the snippet you have above πŸ™‚
For the artifact registry, I believe the standard
@pypi
decorator will pick up authentication credentials from your pypi configuration and has been tested on the AWS equivalent of GCP artifact registry so it should work if you put your credentials there. @bulky-afternoon-92433 can confirm. If that doesn’t work, you can also try the bleeding edge decorators (see https://docs.metaflow.org/scaling/dependencies/libraries#bleeding-edge-versions-of-the-decorators) which support slightly different authentication slurping.
s
Hi, thanks for your answer ! I looked at previous messages and saw this discussion : https://outerbounds-community.slack.com/archives/C02116BBNTU/p1697501486790269 I tried to go through with it but am stuck close to a solution I think. When I try to bootstrap the environment, it doesn't find my custom package, even though the mamba command includes the right --index-url (when I try to install with the pip install --index-url, this works) I get the following error message :
ERROR: Could not find a version that satisfies the requirement job-tracker-ers==0.0.9 (from versions: none)
ERROR: No matching distribution found for job-tracker-ers==0.0.9
It's as if it didn't look in the index-url. Do you have any ideas on the matter ? Thanks again !
d
is this with the default
@pypi
or the bleeding edge one?
s
Default one
I also tried to install the bleeding edge, but then I get an environment error "no mamba binary found"
d
yes β€” the bleeding edge one uses mamba by default but you can have it use micromamba if you want too (see here: https://netflix.slack.com/archives/C02116BBNTU/p1697644492961639?thread_ts=1697501486.790269&cid=C02116BBNTU).
πŸ‘ 1
It’s easier for me to debug the bleeding edge ones as they have a lot of debugging messages enabled (use
METAFLOW_DEBUG_CONDA=1
as an env var) so I would try with those. If you want to stick with the default ones, @bulky-afternoon-92433 may be able to help when he comes online as I am a lot less familiar with that implementation. I do know it should pick up the index-url from the pip.conf so it is possible the pip bieng used is not using that pip.conf?
s
Oh you might be right on the pip used ! Great idea, I'm going to dig into that
Looking into the error with default
@pypi
, I found that the error comes from the --isolated option in pip install generated. which ignores user env variables and configuration. A bit annoying when you need it to connect to cloud artifact 😁
b
so some details on how the decorator handles indices: β€’ everything is read from the host systems pip.conf via
pip config list
β€’ if there's an index-url or extra-index-url, these are passed as part of the pip commands inside the underlying conda environment β—¦ this is also why there is a limitation regarding authentication, where currently the credentials need to be a part of the url. β€’ if there is a custom index-url configured, this will override pip defaults, leading to no lookup in pypi index β—¦ custom indices like AWS codeartifact can be configured with an upstream to make public packages available β—¦ alternatively the default pypi repo can be added as an extra index in the config
<https://pypi.org/simple>
πŸ‘ 1
one big caveat to keep in mind is that pip treats all indices equally, there is no hierarchy between index-url/extra-index, instead packages will be picked by a best-match-basis. Therefore if there is a real need to restrict the packages available or prioritize a private index, the public one probably shouldn't be part of the config.
good test for the pip.conf is to try and install a package raw on the host system:
Copy code
pip install --dry-run --only-binary=:all: somepackage==1.2.3
which is what is happening under the hood during environment resolving
can you provide some more details on how the Cloud Artifact auth is being handled for pip? if the auth is not part of the url, then for the default decorator it is not supported yet. There's a (possibly) related open issue to add support for ApplicationDefaultCredentials https://github.com/Netflix/metaflow/issues/1658
πŸ‘€ 1
s
Hi, first thank you for all the details on the matter ! I configured the upstream link to pypi from cloud artifact. In my pip.conf, I only have the URL with the password to CodeArtifact. When I try your command with my private package, it only works when I remove the --only-binary=all
Copy code
[global]
index-url = <https://aws:token@pypi-ers-111112222333.d.codeartifact.eu-central-1.amazonaws.com/pypi/pypi-ers-repository/simple/>
I might have to upload the whl instead of the tar.gz version
Yup, it works !
Thanks πŸ™‚
b
excellent πŸ™‚
the restriction to .whl only packages is to support cross-platform deployments (e.g. from an ARM laptop -> x86 cloud platform), as it was an easy option to fetch compatible wheels with the target platforms architecture. There is still some improvements we can do regarding this, which is already in place for Git sources, where we try and build a wheel out of the source, and check if it can run on the target platform based on tags. Same approach should work for the tar.gz source aswell, but need to implement this still πŸ™‚
πŸ‘ 1