Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a device_tags_python service that uses the python balena-sdk #33

Merged
merged 4 commits into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Don't send node_modules the daemon - we want the build server to install these.
node_modules/
path/
.git
repo.yml
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ This is a simple project which runs one container based on the [balena simple-se

This project serves up `"Hello World!"` on port `:80` of your balena device and additionally:
* Demonstrates how to use CURL to set tags (in the application's `start.sh`).
* sets the `stats.last_application_start` tag with the current timestamp when the application starts.
* Demonstrates how to use the javascript [balena-SDK][balena-sdk] in the application's `server.js`.
* sets the `stats.last_server_start` tag with the current timestamp whenever the node server starts.
* sets the `stats.last_request` tag with the current timestamp whenever the node server responds to an HTTP request.
* sets the `device_tags_node.last_application_start` tag with the current timestamp when the application starts.
* Demonstrates how to use the javascript [balena-SDK][balena-sdk] in the application's `device_tags_node/server.js`.
* sets the `device_tags_node.last_server_start` tag with the current timestamp whenever the node server starts.
* sets the `device_tags_node.last_request` tag with the current timestamp whenever the node server responds to an HTTP request.
* Demonstrates how to use the python [balena-SDK][balena-sdk-python] in the application's `device_tags_python/src/app.py`. To try to python version, you need to uncomment the respective section in the docker-compose.yml.
* sets the `device_tags_python.last_server_start` tag with the current timestamp whenever the python server starts.
* sets the `device_tags_python.last_request` tag with the current timestamp whenever the python server responds to an HTTP request.

### Setup

Expand All @@ -19,4 +22,5 @@ The scripts use the [`BALENA_API_KEY` environment variable][container-environmen

[simple-server-node]:https://github.com/balena-io-projects/simple-server-node
[balena-sdk]:https://github.com/balena-io/balena-sdk/
[balena-sdk-python]:https://github.com/balena-io/balena-sdk-python/
[container-environment]:https://docs.balena.io/runtime/runtime/#the-container-environment
4 changes: 0 additions & 4 deletions device_tags/start.sh

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
10 changes: 5 additions & 5 deletions device_tags/server.js → device_tags_node/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ let sdk;
// reply to request with "Hello World!"
app.get('/', function (req, res) {
if (sdk) {
// set the 'stats.lastrequest' tag but w/o blocking the response
// set the 'device_tags_node.lastrequest' tag but w/o blocking the response
sdk.models.device.tags
.set(process.env.BALENA_DEVICE_UUID, 'stats.last_request', Date.now())
.set(process.env.BALENA_DEVICE_UUID, 'device_tags_node.last_request', new Date().toISOString())
.catch(function(e) {
console.error('Error while setting stats.last_request tag', e);
console.error('Error while setting device_tags_node.last_request tag', e);
});
}
res.send('Hello World from device tags example!');
Expand All @@ -26,9 +26,9 @@ const server = app.listen(80, async function () {
try {
await sdk.auth.logout();
await sdk.auth.loginWithToken(process.env.BALENA_API_KEY);
await sdk.models.device.tags.set(process.env.BALENA_DEVICE_UUID, 'stats.last_server_start', Date.now());
await sdk.models.device.tags.set(process.env.BALENA_DEVICE_UUID, 'device_tags_node.last_server_start', new Date().toISOString());
} catch (err) {
console.error('Error while setting stats.last_server_start tag', err);
console.error('Error while setting device_tags_node.last_server_start tag', err);
}

const port = server.address().port;
Expand Down
4 changes: 4 additions & 0 deletions device_tags_node/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
echo "setting 'stats.laststart' tag"
sh curl_tags_api/set-device-tag.sh "device_tags_node.last_application_start" $(date +"%Y-%m-%dT%H:%M:%S%z")
echo "starting application"
npm start
25 changes: 25 additions & 0 deletions device_tags_python/Dockerfile.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# base-image for python on any machine using a template variable,
# see more about dockerfile templates here: https://www.balena.io/docs/learn/develop/dockerfile/
FROM balenalib/%%BALENA_ARCH%%-debian-python:3-bookworm

# use `install_packages` if you need to install dependencies,
# for instance if you need git, just uncomment the line below.
# RUN install_packages git

# Set our working directory
WORKDIR /usr/src/app

# Copy requirements.txt first for better cache on later pushes
COPY requirements.txt requirements.txt

# pip install python deps from requirements.txt on the resin.io build server
RUN pip install -r requirements.txt

# This will copy all files in our root to the working directory in the container
COPY . ./

# Enable udevd so that plugged dynamic hardware devices show up in our container.
# ENV UDEV=1

# main.py will run when container starts up on the device
CMD ["python","-u","src/app.py"]
9 changes: 9 additions & 0 deletions device_tags_python/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
click==8.0.4
balena-sdk==15.0.2
Flask==2.0.3
importlib-metadata==4.8.3
itsdangerous==2.0.1
Jinja2==3.0.3
MarkupSafe==2.0.1
Werkzeug==2.0.3
zipp==3.6.0
19 changes: 19 additions & 0 deletions device_tags_python/src/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from flask import Flask, render_template
app = Flask(__name__, template_folder='../views', static_folder='../views/public')

import os
import datetime
from balena import Balena
balena_sdk = Balena({
"balena_host": os.environ['BALENA_API_URL'].replace('https://api.', '')
})
balena_sdk.auth.login_with_token(os.environ['BALENA_API_KEY'])

@app.route('/')
def hello_world():
balena_sdk.models.device.tags.set(os.environ['BALENA_DEVICE_UUID'], 'device_tags_python.last_request', datetime.datetime.now().isoformat())
return render_template('index.html')

if __name__ == '__main__':
balena_sdk.models.device.tags.set(os.environ['BALENA_DEVICE_UUID'], 'device_tags_python.last_server_start', datetime.datetime.now().isoformat())
app.run(host='0.0.0.0', port=80)
76 changes: 76 additions & 0 deletions device_tags_python/views/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Welcome to balena!</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@300;400;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" type="text/css" media="screen" href="{{ url_for('static', filename='bootstrap.min.css') }}" />
<link rel="stylesheet" type="text/css" media="screen" href="{{ url_for('static', filename='main.css') }}" />
</head>
<body>
<div class="header">
<nav class="navbar">
<div class="container d-flex justify-content-center">
<a href="http://balena.io/" target="_blank">
<img style="width: 6rem; height: auto;" src="{{ url_for('static', filename='logo.svg') }}">
</a>
</div>
</nav>
</div>

<div class="container mt-5 mb-5 p-0 pb-5">

<div class="row d-flex flex-column align-items-center">
<h1>Welcome to balena!</h1>
<p class="text-center pl-5 pr-5 pt-0 pb-0">Now that you've deployed code to your device,<br /> explore the resources below to continue on your journey!</p>
</div>

<div class="row d-flex justify-content-center">
<div class="box">
<h5 class="title">Read our documentation</h5>
<ul>
<li>Learn how balena works behind the scenes</li>
<li>Run multiple containers in your application</li>
<li>Fast development with local development mode</li>
<li>Deploy device configurations across your fleet</li>
<li>And much more!</li>
</ul>
<br />
<a class="button" href="https://www.balena.io/docs">Explore the balena documentation</a>
</div>

<div class="box">
<h5 class="title">Discover more balena project ideas</h5>

<p>Find inspiration for what to build next, deploy another cool project,<br /> or join your device to an open fleet!</p>
<a class="button" href="https://hub.balena.io/">View projects on hub.balena.io</a>
<br />
<a href="https://github.com/balena-io-examples">balena example projects</a>
<span class="separator">|</span>
<a href="https://github.com/balenalabs">Projects by balena</a>
<span class="separator">|</span>
<a href="https://forums.balena.io/c/projects">Projects in our forums</a>
</div>

<div class="box">
<h5 class="title">Get additional help</h5>
<p>Need to ask a question or get product support?</p>
<a class="button" href="https://forums.balena.io/">Visit our forums</a>
<br />
<a href="https://www.balena.io/contact-sales/">Contact sales</a>
<span class="separator">|</span>
<a href="https://www.balena.io/support/">Learn about balena support</a>
</div>

</div>

</div>
<canvas id="canvas"></canvas>
<script src="{{ url_for('static', filename='confetti.js') }}"></script>
</body>
</html>
7 changes: 7 additions & 0 deletions device_tags_python/views/public/bootstrap.min.css

Large diffs are not rendered by default.

Loading
Loading