100-days-mlops-kodekloud

Fix a broken UV Lock File

Problem

The xFusionCorp Industries ML team uses uv and lockfiles to keep Python dependencies reproducible across machines. A teammate has left behind a requirements.in specification that does not match the team’s standard. Correct it and compile it into a pinned lockfile.

  1. A high-level dependency specification exists at /root/code/fraud-detection/requirements.in. uv is already installed.

  2. The corrected specification must meet the following requirements:

    • it lists exactly these four top-level packages: scikit-learn, mlflow, pandas, and numpy;
    • every package carries a version constraint that uv can actually satisfy against PyPI.
  3. Review the existing requirements.in, and correct everything that does not match the requirements above.

  4. From the project directory, compile the corrected specification into a pinned lockfile:

    uv pip compile requirements.in -o `requirements.txt`
    
  5. The resulting requirements.txt must pin each of the four top-level packages to an exact version using ==, and must also include the transitive dependencies that uvresolved.

Solution

  1. Update the requirements.in file like this:

     # Fraud detection project dependencies
     scikit-learn
     mlflow==3.12.0
     numpy
     pandas
    

    What we did here? We have replaced sklearn with scikit-learn, set mlflow required version 3.12.0 and added pandas library.

  2. Run the uv pip command to create requirements.txt from requirements.in:

     uv pip compile fraud-detection/requirements.in -o fraud-detection/requirements.txt
    
  3. It will create the requirements.txt like below:

     # This file was autogenerated by uv via the following command:
     #    uv pip compile fraud-detection/requirements.in -o requirements.txt
     aiohappyeyeballs==2.6.1
         # via aiohttp
     aiohttp==3.13.5
         # via mlflow
     aiosignal==1.4.0
         # via aiohttp
     alembic==1.18.4
         # via mlflow
     annotated-doc==0.0.4
         # via fastapi
     annotated-types==0.7.0
         # via pydantic
     anyio==4.13.0
         # via starlette
     attrs==26.1.0
         # via aiohttp
     blinker==1.9.0
         # via flask
     cachetools==7.1.1
         # via
         #   mlflow-skinny
         #   mlflow-tracing
     certifi==2026.4.22
         # via requests
     cffi==2.0.0
         # via cryptography
     charset-normalizer==3.4.7
         # via requests
     click==8.3.3
         # via
         #   flask
         #   mlflow-skinny
         #   uvicorn
     cloudpickle==3.1.2
         # via mlflow-skinny
     contourpy==1.3.3
         # via matplotlib
     cryptography==46.0.7
         # via
         #   google-auth
         #   mlflow
     cycler==0.12.1
         # via matplotlib
     databricks-sdk==0.108.0
         # via
         #   mlflow-skinny
         #   mlflow-tracing
     docker==7.1.0
         # via mlflow
     fastapi==0.136.1
         # via mlflow-skinny
     flask==3.1.3
         # via
         #   flask-cors
         #   mlflow
     flask-cors==6.0.2
         # via mlflow
     fonttools==4.63.0
         # via matplotlib
     frozenlist==1.8.0
         # via
         #   aiohttp
         #   aiosignal
     gitdb==4.0.12
         # via gitpython
     gitpython==3.1.50
         # via mlflow-skinny
     google-auth==2.52.0
         # via databricks-sdk
     graphene==3.4.3
         # via mlflow
     graphql-core==3.2.8
         # via
         #   graphene
         #   graphql-relay
     graphql-relay==3.2.0
         # via graphene
     greenlet==3.5.0
         # via sqlalchemy
     gunicorn==25.3.0
         # via mlflow
     h11==0.16.0
         # via uvicorn
     huey==2.6.0
         # via mlflow
     idna==3.15
         # via
         #   anyio
         #   requests
         #   yarl
     importlib-metadata==8.7.1
         # via
         #   mlflow-skinny
         #   opentelemetry-api
     itsdangerous==2.2.0
         # via flask
     jinja2==3.1.6
         # via flask
     joblib==1.5.3
         # via scikit-learn
     kiwisolver==1.5.0
         # via matplotlib
     mako==1.3.12
         # via alembic
     markupsafe==3.0.3
         # via
         #   flask
         #   jinja2
         #   mako
         #   werkzeug
     matplotlib==3.10.9
         # via mlflow
     mlflow==3.12.0
         # via -r fraud-detection/requirements.in
     mlflow-skinny==3.12.0
         # via mlflow
     mlflow-tracing==3.12.0
         # via mlflow
     multidict==6.7.1
         # via
         #   aiohttp
         #   yarl
     numpy==2.4.4
         # via
         #   -r fraud-detection/requirements.in
         #   contourpy
         #   matplotlib
         #   mlflow
         #   pandas
         #   scikit-learn
         #   scipy
         #   skops
     opentelemetry-api==1.41.1
         # via
         #   mlflow-skinny
         #   mlflow-tracing
         #   opentelemetry-sdk
         #   opentelemetry-semantic-conventions
     opentelemetry-proto==1.41.1
         # via
         #   mlflow-skinny
         #   mlflow-tracing
     opentelemetry-sdk==1.41.1
         # via
         #   mlflow-skinny
         #   mlflow-tracing
     opentelemetry-semantic-conventions==0.62b1
         # via opentelemetry-sdk
     packaging==26.2
         # via
         #   gunicorn
         #   matplotlib
         #   mlflow-skinny
         #   mlflow-tracing
         #   skops
     pandas==2.3.3
         # via
         #   -r fraud-detection/requirements.in
         #   mlflow
     pillow==12.2.0
         # via matplotlib
     prettytable==3.17.0
         # via skops
     propcache==0.5.2
         # via
         #   aiohttp
         #   yarl
     protobuf==6.33.6
         # via
         #   databricks-sdk
         #   mlflow-skinny
         #   mlflow-tracing
         #   opentelemetry-proto
     pyarrow==23.0.1
         # via mlflow
     pyasn1==0.6.3
         # via pyasn1-modules
     pyasn1-modules==0.4.2
         # via google-auth
     pycparser==3.0
         # via cffi
     pydantic==2.13.4
         # via
         #   fastapi
         #   mlflow-skinny
         #   mlflow-tracing
     pydantic-core==2.46.4
         # via pydantic
     pyparsing==3.3.2
         # via matplotlib
     python-dateutil==2.9.0.post0
         # via
         #   graphene
         #   matplotlib
         #   pandas
     python-dotenv==1.2.2
         # via mlflow-skinny
     pytz==2026.2
         # via pandas
     pyyaml==6.0.3
         # via mlflow-skinny
     requests==2.34.2
         # via
         #   databricks-sdk
         #   docker
         #   mlflow-skinny
     scikit-learn==1.8.0
         # via
         #   -r fraud-detection/requirements.in
         #   mlflow
         #   skops
     scipy==1.17.1
         # via
         #   mlflow
         #   scikit-learn
         #   skops
     six==1.17.0
         # via python-dateutil
     skops==0.14.0
         # via mlflow
     smmap==5.0.3
         # via gitdb
     sqlalchemy==2.0.49
         # via
         #   alembic
         #   mlflow
     sqlparse==0.5.5
         # via mlflow-skinny
     starlette==0.52.1
         # via
         #   fastapi
         #   mlflow-skinny
     threadpoolctl==3.6.0
         # via scikit-learn
     typing-extensions==4.15.0
         # via
         #   aiosignal
         #   alembic
         #   anyio
         #   fastapi
         #   graphene
         #   mlflow-skinny
         #   opentelemetry-api
         #   opentelemetry-sdk
         #   opentelemetry-semantic-conventions
         #   pydantic
         #   pydantic-core
         #   sqlalchemy
         #   starlette
         #   typing-inspection
     typing-inspection==0.4.2
         # via
         #   fastapi
         #   pydantic
     tzdata==2026.2
         # via pandas
     urllib3==2.7.0
         # via
         #   docker
         #   requests
     uvicorn==0.47.0
         # via mlflow-skinny
     wcwidth==0.7.0
         # via prettytable
     werkzeug==3.1.8
         # via
         #   flask
         #   flask-cors
     yarl==1.23.0
         # via aiohttp
     zipp==3.23.1
         # via importlib-metadata