Skip to content

An HTTP API for the looper run command that works with the pydantic-based command models#441

Merged
simeoncarstens merged 46 commits intopepkit:feature-http-apifrom
tweag:tweag/http-api
Feb 8, 2024
Merged

An HTTP API for the looper run command that works with the pydantic-based command models#441
simeoncarstens merged 46 commits intopepkit:feature-http-apifrom
tweag:tweag/http-api

Conversation

@zz1874
Copy link
Collaborator

@zz1874 zz1874 commented Jan 19, 2024

Warning

Currently based on #440. Once that is merged, we'll make a new branch, feature-http-api, that will be based on the then updated dev branch and target feature-http-api with this PR. So don't merge just quite yet 🙂

This PR introduces a first version of an HTTP API to execute looper commands (#433).

Changes made:

  • Implemented a new HTTP API using FastAPI to run the looper run command.
  • Slightly modified the enrich_vars_cfg() function in looper/utils.py module to enable execution via both the CLI and the HTTP API.
  • Slightly refactor cli_pydantic.py

Endpoints

  • / (POST): allows users to trigger looper commands asynchronously . For now, because we only have the run command modeled as a pydantic model, only the run command is supported. Returns a unique job ID that can be used in the /status endpoint.
    This endpoint accepts a JSON payload with the run model and other top-level parameters such as looper_config, see the auto-generated documentation on http://127.0.0.1:8000/docs and / or looper/command_models/commands.py.
  • /status/<job ID> (GET): retrieve the status / results of a previously started job. Returns a JSON with, notably, a field console_output that contains all stdout / stderr from the performed looper run, once the job has finished.

Usage:

Run the app:

looper-serve [--host <host IP address>] [--port <port>]

Note

This assumes that all files specified in the arguments are available on the file system of the machine that is running the HTTP API server. Best make sure you use absolute file paths in all looper YAML configuration files.

To test this, you can clone the hello_looper repository and then run (for example) the following in a second terminal:

curl -X POST -H "Content-Type: application/json" -d '{"run": {"time_delay": 5}, "looper_config": "/path/to/hello_looper/.looper.yaml"}' "http://127.0.0.1:8000"

This will return a six-letter job ID, say abc123. Then get the result / output of the run with

curl -X GET -v localhost:8000/status/abc123

For better visualization / readability, you can post-process the output by piping it to jq ( | jq -r .console_output).

@nsheff
Copy link
Contributor

nsheff commented Jan 19, 2024

can you put the usage information into a readme?

simeoncarstens and others added 16 commits February 1, 2024 17:45
This allows, together with the hacked, threadable (but _not_
thread-safe) `yacman` version, to run `looper` commands in a
non-blocking way.
Everything will probably still work - after all,
`logmuse.logger_via_cli()` is called in `cli_looper.py` /
`cli_pydantic.py` which also sets up a logger.
Before this commit, the logging stdout we captured will be mixed if we
submit several jobs at the same time. This captures outputs for each
thread (job) separately.

See https://stackoverflow.com/questions/14890997/redirect-stdout-to-a-file-only-for-a-specific-thread.

Co-authored-by: Simeon Carstens <simeon.carstens@tweag.io>
This allows us to capture the output of the Bash scripts or commands
`looper` executes.
Co-authored-by: Zhihan Zhang <zhihan.zhang@tweag.io>
The module we use to capture console output does not seem to
distinguish easily between `stdout` and `stderr`. So we rather use a
generic `console_output` field in the job model that subsumes both.
This makes the Swagger documentation show the job schema for that endpoint.
* Apply formatter

* Add documentation for `POST` and `GET` requests

* Update looper/api/main.py

Co-authored-by: Simeon Carstens <simeon.carstens@tweag.io>

* Update looper/api/main.py

Co-authored-by: Simeon Carstens <simeon.carstens@tweag.io>

* Add where to access the API documentation

---------

Co-authored-by: Simeon Carstens <simeon.carstens@tweag.io>
@simeoncarstens simeoncarstens changed the title [WIP] An HTTP API for the looper run command that works with the pydantic-based CLI [WIP] An HTTP API for the looper run command that works with the pydantic-based command models Feb 2, 2024
@simeoncarstens simeoncarstens marked this pull request as ready for review February 2, 2024 10:24
@simeoncarstens simeoncarstens changed the title [WIP] An HTTP API for the looper run command that works with the pydantic-based command models An HTTP API for the looper run command that works with the pydantic-based command models Feb 2, 2024
Copy link
Contributor

@donaldcampbelljr donaldcampbelljr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good. Please proceed with merging #440 into its feature branch and then this PR into its feature branch when you are able.

@simeoncarstens simeoncarstens changed the base branch from tweag/run-hello-world to feature-http-api February 8, 2024 17:25
@simeoncarstens simeoncarstens merged commit ebd2fb8 into pepkit:feature-http-api Feb 8, 2024
@simeoncarstens
Copy link
Collaborator

Done 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants