Install Flask on Redhat (repo available)
sudo dnf install python3-flask🚀 Run Flask App (No pip needed)
-
Save the
app.pysomewhere (e.g.,/home/tux/transferdepot/app.py) -
Run it directly:
python3 /home/tux/transferdepot/app.py
Or set FLASK_APP and use the built-in CLI:
export FLASK_APP=app.py
flask run --host=0.0.0.0 --port=8080📍 Flask RPM Notes on RHEL 8
-
Package:
python3-flask -
Installed location:
/usr/lib/python3.6/site-packages/flask/ -
Installed with all dependencies (
Werkzeug,Jinja2, etc.) -
Managed by
dnf, notpip= easy maintenance in air-gapped setup
Define two Routes
| Route | Method | Description |
| ---------------------- | ------ | ---------------------------------------------------------------- |
| `/upload` | POST | Accepts file upload (requires `Authorization: Bearer SECRET123`) |
| `/download/<filename>` | GET | Downloads a file from the upload folder |This is our basic app.py - before customization with two routes: upload, download
from flask import Flask, request, send_from_directory
import os
app = Flask(__name__)
UPLOAD_FOLDER = '/opt/transferdepot/uploads'
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
@app.route('/upload', methods=['POST'])
def upload():
token = request.headers.get('Authorization')
if token != 'Bearer SECRET123':
return 'Unauthorized', 401
file = request.files['file']
filepath = os.path.join(UPLOAD_FOLDER, file.filename)
file.save(filepath)
return 'File uploaded successfully', 200
@app.route('/download/<filename>', methods=['GET'])
def download(filename):
return send_from_directory(UPLOAD_FOLDER, filename)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)How to Run
python3 /home/tux/transferdepot/app.pyOr use Flask CLI:
export FLASK_APP=/home/tux/transferdepot/app.py
flask run --host=0.0.0.0 --port=8080First customization:
Add Zones
/opt/transferdepot/
├── logs/
└── zones/
├── MSE/
├── MP/
├── TTCS/
└── RS2/Assumption: Each directory is used for both uploads and downloads within that zone — file goes in, file gets picked up later from the same spot.
(Optional) - Add /wormhole Endpoint
-
A fun (and secure) route for transferring files between zones in a special manner (perhaps a "faster" or "VIP" route). This could be a unique endpoint for certain high-priority transfers.
Updated app.py with Zone-Based Logic
from flask import Flask, request, send_from_directory, abort
import os
app = Flask(__name__)
UPLOAD_ROOT = '/opt/transferdepot/uploads'
ZONES = ['MSE', 'MP', 'TTCS', 'RS2']
# Make sure zone folders exist
for zone in ZONES:
os.makedirs(os.path.join(UPLOAD_ROOT, zone), exist_ok=True)
@app.route('/upload/<zone>', methods=['POST'])
def upload(zone):
if zone not in ZONES:
return 'Invalid zone', 400
token = request.headers.get('Authorization')
if token != f'Bearer {zone}123':
return 'Unauthorized', 401
if 'file' not in request.files:
return 'No file part', 400
file = request.files['file']
save_path = os.path.join(UPLOAD_ROOT, zone, file.filename)
file.save(save_path)
return 'File uploaded to zone successfully', 200
@app.route('/download/<zone>/<filename>', methods=['GET'])
def download(zone, filename):
if zone not in ZONES:
abort(404)
return send_from_directory(os.path.join(UPLOAD_ROOT, zone), filename)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
🚀 The upload and download were eventually removed because I couldn't figure out what they were used for. It didn't work. We can put them back in for a good reason, but not because they used to be there.
Tests
Test Upload (from same machine or Frodo)
curl -X POST http://localhost:8080/upload/MSE/dropoff \
-H "Authorization: Bearer MSE123" \
-F "file=@myfile.txt"
Test Download
curl -O http://localhost:8080/download/MSE/pickup/b0b.txtResult:
-
secret.txtshould download to current directory -
activity.jsonlgets a log entry
Current State
-
TransferDepot app (
app.py) is built and ready. ✅-
Basic routes for upload and download are in place. ✅
-
Zone-based directories (
dropoff,pickup) are being created on the fly. ✅ -
Logging is active, storing each file transfer in
activity.jsonl. ✅ -
Authentication via bearer tokens (
Bearer <zone>123).
-
Next Steps -- TBD -- after demo and approval --
Here are a few things we can add with ease:
1. More Robust Security (Optional)
-
Stronger token handling: Instead of using hardcoded
Bearer <zone>123, we could introduce a more flexible method of handling authentication — perhaps with a shared secrets file or token generation system. -
IP whitelisting: Ensure that only trusted machines/servers can interact with the TransferDepot.
2. Add /status Endpoint (Optional)
-
Show the current status of the TransferDepot, such as:
-
Total number of files uploaded.
-
Size of current transfer directories.
-
Last 10 logs (for quick checks).
-
Zone status (available dropoff/pickup spaces).
-
3. Advanced Logging (Optional)
-
Currently, the app logs transfers to a single
activity.jsonl. We can:-
Expand logging to log failed attempts, errors, etc.
-
Set up file rotation to prevent
activity.jsonlfrom growing too large. -
Store logs separately per zone, if you want more detailed analysis per zone.
-
4. Add /wormhole Endpoint (Optional)
-
A fun (and secure) route for transferring files between zones in a special manner (perhaps a "faster" or "VIP" route). This could be a unique endpoint for certain high-priority transfers.
5. Systemd Integration
-
Turn the app into a systemd service so it starts automatically when the machine boots up. This would ensure TransferDepot runs persistently without needing manual
python3 app.pyevery time.
Example systemd service file:
[Unit]
Description=TransferDepot Service
After=network.target
[Service]
User=tux
WorkingDirectory=/home/tux/transferdepot
ExecStart=/usr/bin/python3 /home/tux/transferdepot/app.py
Restart=always
[Install]
WantedBy=multi-user.target
6. Testing and Monitoring (Optional)
-
Use curl to run tests across zones and check the logs.
-
Monitor performance, especially as file sizes increase, to see if you hit any memory or performance issues with large uploads.