eshaan7 / flask-shell2http Goto Github PK
View Code? Open in Web Editor NEWExecute shell commands via HTTP server (via flask's endpoints).
Home Page: https://flask-shell2http.readthedocs.io/
License: BSD 3-Clause "New" or "Revised" License
Execute shell commands via HTTP server (via flask's endpoints).
Home Page: https://flask-shell2http.readthedocs.io/
License: BSD 3-Clause "New" or "Revised" License
First of all, thank you for this project! It was very easy to set up a couple of endpoints.
Now, I am trying to create another endpoint for a command which returns binary output and I'm getting an error:
"'utf-8' codec can't decode byte 0xff in position 0: invalid start byte"
Is there a way to configure an endpoint to return binary data, for example, in base64?
Is it possible to handle command that shall work on files provide be the caller? If so how?
This extension is quite configurable and different users may choose to use it differently. For this, we should add more examples under examples/. These can be something new or ones already listed in the README.md.
Few ideas:
create an ENUM class for all statuses types
I ran a few tests for an API I built to run a certain command line program, however I noticed that the keys returned are always for a given route, no matter what the parameters are, is this a feature?
I am currently moving a Flask app to Gunicorn and am having an issue where I cannot ever retrieve a report even though it appears that the command will eventually be successfully run. I will send a post to an API endpoint and will receive a successful response that includes the key and result_url
, but when I make a get request to that url, I only receive the "No report exists for key..." response. At first I thought it might be a delay, but even with repeated get requests I am not able to receive reports.
I have been looking through your documentation to get a better idea of how to access reports and understand how long before they expire/disappear. I had noticed previously that if I keep making a request for a specific key, it will eventually return No report exists for key
even if one had previously existed. I am wondering if you have run into similar issues and if you could point me in the right direction to try to track down these reports or log them somewhere more permanent. I also tried playing with the Executor a bit, but am not entirely sure where to start with that.
Thank you for the help.
Tests can be derived from the examples.
Hello @eshaan7 thanks for this project I really like it ๐
but I've got a simple question about the command variables, it's possible to use format string in python to select the right place of the variable?
for example
>>> command = "curl {url} --timeout {timeout}".format(url="http://google.com/",timeout=20)
"curl http://google.com/ --timeout 20"
Should implement logging in the package. The logging configuration should be customizable by the user.
From Flask's docs: https://flask.palletsprojects.com/en/1.1.x/logging/#other-libraries
It would be great to make the calls idempotent to some degree so that if you call it twice you can still follow the result without having to manually reconstruct the correct result url.
The error JSON could have the correct result_url
so you don't need to construct it.
Failed to get result {'error': 'future_key 2ea86600 already exists'}
There could be an option during call to ignore if theres an existing entry and overwrite it?
BTW awesome lib, this was exactly what I was looking for. ๐ค
As listed in Flask's official docs, we should add a testing suite to this project.
See Point number 5 here.
I added some basic key checking but I wanted to know if there was a better way to add it, or if you want me to open a PR which adds some kind of hook to allow a custom function to be run on either the get or post to validate the args and in doing so allow for some kind of key / auth check?
# base_entrypoint.py
# change import to local version
from .api import Shell2HttpAPI
# api.py
# auth function
def check_stack_api_key(challenge_key: str) -> bool:
key = os.environ.get("STACK_API_KEY", None) # Get key from environment
if key is None:
return False
if challenge_key == key:
return True
return False
class Shell2HttpAPI(MethodView):
def get(self):
...
# call the auth check
stack_api_key = request.args.get("STACK_API_KEY", None)
if not check_stack_api_key(challenge_key=stack_api_key):
raise Exception("STACK_API_KEY doesn't match.")
def post(self):
...
# call the auth check
json_input = request.get_json()
if not check_stack_api_key(
challenge_key=json_input.get("STACK_API_KEY", None)
):
raise Exception("STACK_API_KEY doesn't match.")
When using &wait=true
, the callback_fn
cannot be used to modify the result because it is called after the future completes.
This happens if one calls future.done()
to wait before the callback fn is executed, it would not work as intended.
Originally posted by tomvanderputte November 6, 2023
Is it possible to intercept and change the dynamic arguments before the command is triggered?
The reason is: the arguments point to input/output files in a certain location. The application that sends the POST requests is not aware of this location (nor do I want it to be), so it sends only the filename.
So I want to edit the arguments/parameters to predfix the sent arguments with the correct path. How could I achieve this?
I figured out that the issue has to do with having multiple Gunicorn workers handling requests. The report only exists for the same worker that handled the original request. I am not sure how to solve it yet, but there you have it.
Originally posted by @dale-wahl in #24 (comment)
There is an ImportError while running 'flask run'
ImportError: cannot import name 'safe_join' from 'flask.helpers' (/env/lib/python3.9/site-packages/flask/helpers.py)
safe_join was removed from flask.helpers in flask version 2.1.0 released on 28-03-2022
From flask Version 2.1.0 CHANGES.rst
safe_join is removed, use werkzeug.utils.safe_join instead.
Hey,
I am currently trying to use a vanilla flask route along with routes defined by shell2http, however, when I access the vanilla flask route, I get a 404. Any idea on how I can do this?
An important test case is missing.
See codecov diff: https://codecov.io/gh/Eshaan7/flask-shell2http/src/master/flask_shell2http/classes.py#L146
Is it possible to interrupt command (like CTRL+C)?
For example, I started Locust (load testing framework) for one file, now I want to stop it and start one more test with other params.
2023-04-25 23:12:39 ERROR:flask_shell2http:future_key ebbb407f already exists 2023-04-25 23:12:39 ERROR:flask_shell2http:No report exists for key: 'ebbb407f'.
These are interspersed with working calls.
I turned off wait=true
and switched to polling. This reduced the problem but didn't eliminate it.
Are there any docs on how to endure the key doesn't already exist? I don't believe I'm managing the keys externally to shell2http.
Thanks so much.
Currently, flask-shell2http works just like any other flask extension; you create an object from a class to which you pass the flask application instance. We could follow a different approach making it solely available as a pluggable Flask.Blueprint
.
Some initial ideas:
Shell2HTTP
class could derive from the Flask.Blueprint
class; that way we can drop the init_app
method, the register_command
can be a wrapper over the Flask.Blueprint.add_url_rule
method (it already is, but it works on app.add_url_rule
). Then, the enduser would do something like,from flask_shell2http import Shell2HTTP
# default blueprint instantiation
shell2http_bp = Shell2HTTP('awesome', __name__, url_prefix='/commands')
# extra method by flask-shell2http
shell2http_bp.register_command(endpoint="echo", command_name="echo", ...)
and then in the application factory,
app = Flask(__name__)
app.register_blueprint(shell2http_bp)
This would open doors for many other features since Flask.Flask
and Flask.Blueprint
derive from the same abstract base class and flask blueprints are very powerful.
I have an issue where the output of my cli tool is JSON but then the nested JSON inside the report
field is all messed up and it seems I can't properly json.loads
the main result. I wonder if there might be a way to detect json and include it properly rather than escaped inside as a substring?
Hello, I'm using flask-shell2http for communication and launching commands across docker containers. I'm trying to run a very simple script on one container from another container just to get the capability working. When I first ran the command from one container, I didn't have my permissions set on the script that was located on the other container but a key was still given to that command. Once I fixed the permissions on the script and tried to run the command again, it tried to give the same key value and I get an error in return saying future_key already exists
How can I fix this? Thank you and I am finding this application extremely useful.
Question why am i getting a permission denied error on one of your example scripts for running a post to a python file
no need to give any example other than it dont work lol
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.