nextmv-py icon indicating copy to clipboard operation
nextmv-py copied to clipboard

Allows requirements as code

Open merschformann opened this issue 7 months ago • 2 comments

Description

Allows the user to specify requirements as code. I.e., the user can now setup their app without having to create app.yaml and requirements.txt files.

Example of a push.py file (next to the main.py file containing the actual app/model code):

import datetime
import os

from nextmv import cloud

# App directory is the same as this file.
app_dir = os.path.dirname(os.path.abspath(__file__))

# Create and push the app to the cloud.
client = cloud.Client(api_key=os.getenv("NEXTMV_API_KEY"))
app = cloud.Application(client=client, id=os.getenv("<app-id>"))
app.push(
    app_dir=app_dir,
    verbose=True,  # See some output from the push process.
    manifest=cloud.Manifest(
        files=[
            "main.py",  # The main file of the app.
        ],
        python=cloud.ManifestPython(
            pip_requirements=[
                "nextmv==0.28.1",
                "ortools==9.12.4544",
            ],
        ),
        type=cloud.ManifestType.PYTHON,
        runtime=cloud.ManifestRuntime.PYTHON,
    ),
)

# Create a new version and update the staging instance to use it.
version_id = f"sandbox-auto-{datetime.datetime.now().strftime('%Y-%m-%dT%H-%M-%S')}"
app.new_version(id=version_id, name=f"Auto version {version_id}")
app.update_instance(id="staging", name="staging", version_id=version_id)

The example above does the following:

  • Make sure to push from the directory of the app independent of where it was called from.
  • Use a NEXTMV_API_KEY from env for auth.
  • Push the code for <app-id> app.
  • Bundle main.py (which contains the model code).
  • Define all requirements.
  • Set the app type to Python.
  • Set the runtime to one suiting Python apps.
  • Automatically create a version for the pushed code.
  • Update the staging instance to use the new version.

Changes

  • Allows the user to fully define and push the app in Python.

merschformann avatar May 28 '25 20:05 merschformann

Quick response @sebastian-quintero :

  1. The comment I posted
    • Done. Thanks for the reminder! :heart:
  2. Are we checking anywhere that main.py exists and throwing an exception in case it doesn't?
    • I am not sure, but the code that handles the directory push is the same as the one handling this "Python push". So, I am not sure whether it should be in scope for this PR. I can add it if missing though.
  3. Can you add a little something to the docs (tutorials), that reflects this change? Maybe in the pushing an app section.
    • Yeah, good call. I changed the relevant section around a bit. Let me know what you think. :blush:

merschformann avatar May 28 '25 22:05 merschformann

I gave it another restructure @sebastian-quintero . I combined the "dir" approach and "python" approach (was a terrible name) into one "file strategy" that has a directory based and a code based option. I also renamed the external strategy to object strategy. I also like your model name, but I think "object" is spot on about what is happening. Maybe too bold though. :shrug:

I hope this makes sense. :blush:

merschformann avatar May 29 '25 00:05 merschformann

Merge merge merge

sebastian-quintero avatar May 29 '25 20:05 sebastian-quintero