Opyrator: turn a Python function into an HTTP API and a Streamlit UI
🪄 Turns your machine learning code into microservices with web API, interactive GUI, and more.
At a glance
- What is it?
- Opyrator wraps a single typed Python function in a FastAPI service and a Streamlit form. It is a fast way to demo a model, and a thin layer that will not carry a real production workload.
- Who is it for?
- Opyrator fits engineers who need to expose a typed Python function over HTTP or hand a colleague a form they can click, without writing FastAPI routes or Streamlit widgets by hand. It does not fit anyone who needs authentication, persistence, background jobs or a stable API contract, because the README labels the project an alpha version and the input and output models are the contract.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The gap Opyrator fills between a notebook function and a service
Most machine learning code ends its life as a function that takes a structured input and returns a structured output. Turning that into something another person can call means writing a FastAPI route, a Pydantic schema, a validation layer and a small web form, and then keeping all four in sync when the function changes. Opyrator's premise is that the function signature already contains that information. If the parameter and the return value are typed with Pydantic models, the README states that Opyrator derives the HTTP API and the web UI from those types.
The audience is narrow and specific: engineers who have a working Python function and want to show it to someone else this afternoon. The README is explicit that the project is an alpha version, "only suggested for experimental usage", which is a fair description of what a code generator over type hints can promise. It is not a serving framework with a scheduler, a queue or a model registry behind it.
How the type hints become an API and a UI
The mechanism is a contract on the function signature. The README states that an Opyrator-compatible function is required to have an input parameter and a return value based on Pydantic models, specified via type hints. In the hello world example, the Input model has a single message field of type str and the Output model mirrors it.
From that, two servers are generated. The HTTP API is built on FastAPI, so the input model becomes the request body schema and the OpenAPI document follows from it. The web UI is built on Streamlit, and the fields of the input model become form controls. The README lists OpenAPI, JSON Schema and Python type hints as the open standards underneath, with FastAPI, Streamlit and Pydantic as the components doing the work.
The consequence is that the model definition is the single source of truth. Add a field to Input and it appears in both surfaces. Change a type and validation changes in both. There is no separate schema file to drift.
Installing Opyrator and launching a first service
The README gives one installation command and requires Python 3.6 or newer. The package is on PyPI under the name opyrator.
pip install opyratorA minimal Opyrator function needs two Pydantic models and a function whose parameter is named input. The README's example is reproduced below; save it as my_opyrator.py.
from pydantic import BaseModel
class Input(BaseModel):
message: str
class Output(BaseModel):
message: str
def hello_world(input: Input) -> Output:
"""Returns the `message` of the input data."""
return Output(message=input.message)Launch the interactive UI by pointing the CLI at the module and function, separated by a colon. The README states that the output prints the address where the app is served on your local machine.
opyrator launch-ui my_opyrator:hello_worldSwap launch-ui for launch-api to serve the same function over HTTP instead. Again, the console output shows the local address.
opyrator launch-api my_opyrator:hello_worldThe examples in the repository follow the same pattern at a larger scale. The text generation demo is run from a clone of the repository with a port flag, which is the documented way to pick a port other than the default.
cd ./opyrator/examples/generate_text/
pip install -r requirements.txt
opyrator launch-ui app:generate_text --port 8051The repository also ships a playground image that bundles the demos, run with a port mapping. The README does not document what the container does beyond serving the playground on that port.
docker run -p 8080:8080 mltooling/opyrator-playground:latestWhere the generated service stops being enough
The first limitation is stated by the project itself: alpha version, experimental usage only. That is not boilerplate. A generated FastAPI app inherits FastAPI's defaults, and the README does not document authentication, rate limiting, request size limits or any access control on the generated endpoints. If the function is meant to be reachable from outside a trusted network, that gap is the whole problem.
The second is the signature constraint. The input parameter must be a Pydantic model and the return value must be one too. A function that takes three positional arguments, streams tokens, or returns a generator does not fit without a wrapper model and a rewrite. For streaming model output, the shape Opyrator generates is a single request and a single response.
The third is versioning. The release list shows v0.0.11 from May 2021 and no later release, so the API surface you build on is the one from that era, even though the repository has been pushed to more recently. Dependencies such as Streamlit, FastAPI and Pydantic have moved since, and the setup.py pins streamlit>=0.72 with no upper bound, which means a fresh install can resolve to a much newer Streamlit than the code was written against.
Finally, Opyrator is the wrong tool when the function is not the product. If you need a queue, a GPU pool, retries or per-tenant isolation, you are describing a serving platform, and Opyrator is a generator that produces one small app.
Opyrator compared with writing the FastAPI app yourself
The honest alternative is the stack Opyrator is built on: declare the same Pydantic models and write the FastAPI route yourself, then decide separately whether you need a UI. The difference is where the work sits. Hand-written FastAPI gives you control over dependencies, middleware, error handlers and the OpenAPI metadata, and it does not constrain the function signature, because you can shape the request however you like. Opyrator gives you the route, the schema and the form for free, and takes the signature constraint in exchange.
That trade is worth making when the function is stable and the goal is a demo or an internal tool. It is a bad trade when the endpoint is public, when the response is streamed, or when the request shape is not a flat model. A second alternative is to skip the HTTP layer entirely and let the Streamlit app call the function in-process, which removes the API from the picture but also removes the ability for another service to call it.
One thing Opyrator does that a hand-written app often does not: it generates both surfaces from one definition, so the demo and the API cannot disagree about what the input looks like.
Maintenance, licence and what to check before you depend on it
The repository is not archived and the last push was on 2026-09-08, so there is recent activity, but the published releases stop at v0.0.11 from 2021-05-01. That combination means the code on the default branch and the version on PyPI are not the same thing, and anyone installing with pip is installing the 2021 release. Upgrading means either waiting for a new release or installing from the repository, and the README does not document a supported upgrade path between versions.
The dependency list in setup.py is short and unpinned at the top end: typer, fastapi, uvicorn, streamlit>=0.72, plotly, pandas, numpy and loguru. numpy and pandas are installed even for a hello world function that uses neither, which is a real cost on a small container image.
The licence is MIT, which permits commercial use and modification provided the copyright notice and permission notice are retained. That is a statement about the licence text, not legal advice; if you redistribute the generated service, check how the MIT notice should travel with it.
Editorial conclusion
Opyrator fits engineers who need to expose a typed Python function over HTTP or hand a colleague a form they can click, without writing FastAPI routes or Streamlit widgets by hand. It does not fit anyone who needs authentication, persistence, background jobs or a stable API contract, because the README labels the project an alpha version and the input and output models are the contract. Before adopting it, verify the Python version you actually run (the README states 3.6+) and whether the Pydantic models you already use can be reused as the function signature.
Frequently asked questions
What does Opyrator mean by a Python function becoming a microservice?
The README states that Opyrator turns a Python function into a service with an auto-generated HTTP API based on FastAPI and an auto-generated web UI based on Streamlit. The function must take a single input parameter typed as a Pydantic model and return a Pydantic model.
How do I install Opyrator?
The README gives a single command, pip install opyrator, with Python 3.6 or newer as the requirement. The package is published on PyPI, and the most recent release listed is v0.0.11.
What is the difference between opyrator launch-ui and opyrator launch-api?
Both take a module and function reference such as my_opyrator:hello_world. launch-ui starts the Streamlit web interface, while launch-api starts the FastAPI HTTP service, and the README states the console prints the local address in each case.
Can Opyrator serve a function that returns a stream of tokens?
The README requires the return value to be based on a Pydantic model, and the generated API is a single request and response. Streaming output is not described in the README, so it would need a wrapper or a different tool.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ml-tooling-opyrator)