Skip to content

Commit afcc021

Browse files
committed
python-ecosys/uminio: Add uminio package.
uminio is a MicroPython client for MinIO object storage. This commit add the uminio filder and all its content in the python-ecosys folder. Original implementation for AWS S3: https://github.com/DanielMilstein/uboto3/ Signed-off-by: Luigi Palumbo <[email protected]>
1 parent 34c4ee1 commit afcc021

File tree

4 files changed

+444
-0
lines changed

4 files changed

+444
-0
lines changed

python-ecosys/uminio/README.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# uminio
2+
3+
`uminio` is a MicroPython library designed to facilitate uploading files directly from a MicroPython-enabled device (like an ESP32 or ESP8266) to MinIO object storage. It implements the necessary AWS Signature Version 4 for an S3 PUT Object request. This allows you to store data, sensor readings, images, or any other files from your microcontroller projects in the cloud.
4+
5+
Forked from `uboto3` [https://github.com/DanielMilstein/uboto3](https://github.com/DanielMilstein/uboto3)
6+
7+
## Features
8+
9+
* **Direct S3 Upload:** Upload files directly to an MinIO bucket without needing an intermediary server.
10+
* **AWS Signature V4:** Implements the required request signing process.
11+
* **HMAC-SHA256:** Includes a MicroPython-compatible HMAC-SHA256 implementation for signing.
12+
* **Time Synchronization:** Includes a helper function to synchronize the device's time using NTP, which is crucial for MinIO request signing.
13+
* **Minimal Dependencies:** Built with standard MicroPython libraries like `urequests`, `uhashlib`, `ubinascii`, `utime`, and `network`.
14+
15+
## Requirements
16+
17+
* MicroPython firmware flashed on your device.
18+
* Network connectivity (WiFi) configured on the device.
19+
* The following MicroPython libraries:
20+
* `urequests`
21+
* `uhashlib`
22+
* `ubinascii`
23+
* `utime`
24+
* `network`
25+
* `ntptime` (for time synchronization)
26+
27+
## Setup
28+
29+
1. **Copy `__init__.py`:** Create a `uminio` folder in the `/lib` directory of your MicroPython device and copy the `__init__.py` file into it.
30+
2. **MinIO Credentials & Configuration:**
31+
Import the `MinioClient` class in your MicroPython script and configure it with your MinIO server details. You can do this by setting the following variables in your script:
32+
```python
33+
from uminio import MinioClient
34+
# --- MinIO Client Configuration ---
35+
MINIO_ENDPOINT = "192.168.1.100:9000" # Your MinIO server IP address and port
36+
MINIO_ACCESS_KEY = "YOUR_ACCESS_KEY" # Your MinIO access key
37+
MINIO_SECRET_KEY = "YOUR_SECRET_KEY" # Your MinIO secret key
38+
MINIO_REGION = "eu-east-1" # The region for your MinIO server
39+
MINIO_USE_HTTPS = False # Set to True if your MinIO server uses HTTPS
40+
41+
mc = MinioClient(
42+
endpoint=MINIO_ENDPOINT,
43+
access_key=MINIO_ACCESS_KEY,
44+
secret_key=MINIO_SECRET_KEY,
45+
region=MINIO_REGION,
46+
use_https=MINIO_USE_HTTPS,
47+
)
48+
```
49+
**Important Security Note:** Hardcoding credentials directly into the script is generally not recommended for production environments. Consider alternative methods for managing secrets on your device if security is a major concern.
50+
51+
3. **IAM Permissions:**
52+
Ensure the MinIO user associated with the `MINIO_ACCESS_KEY` and `MINIO_SECRET_KEY` has the necessary permissions to put objects into the specified bucket.
53+
54+
55+
## Usage Example
56+
57+
Here's how to use `uminio` to upload a local file from your MicroPython device to MinIO:
58+
59+
```python
60+
import network
61+
import time
62+
from uminio import MinioClient
63+
# --- MinIO Client Configuration ---
64+
MINIO_ENDPOINT = "192.168.1.100:9000" # Your MinIO server IP address and port
65+
MINIO_ACCESS_KEY = "YOUR_ACCESS_KEY" # Your MinIO access key
66+
MINIO_SECRET_KEY = "YOUR_SECRET_KEY" # Your MinIO secret key
67+
MINIO_REGION = "eu-east-1" # The region for your MinIO server
68+
MINIO_USE_HTTPS = False # Set to True if your MinIO server uses HTTPS
69+
70+
mc = MinioClient(
71+
endpoint=MINIO_ENDPOINT,
72+
access_key=MINIO_ACCESS_KEY,
73+
secret_key=MINIO_SECRET_KEY,
74+
region=MINIO_REGION,
75+
use_https=MINIO_USE_HTTPS,
76+
)
77+
# --- Network Configuration (Example for ESP32/ESP8266) ---
78+
WIFI_SSID = "YOUR_WIFI_SSID"
79+
WIFI_PASSWORD = "YOUR_WIFI_PASSWORD"
80+
81+
def connect_wifi():
82+
sta_if = network.WLAN(network.STA_IF) #
83+
if not sta_if.isconnected():
84+
print("Connecting to WiFi...")
85+
sta_if.active(True)
86+
sta_if.connect(WIFI_SSID, WIFI_PASSWORD)
87+
while not sta_if.isconnected():
88+
time.sleep(1)
89+
print("Network Config:", sta_if.ifconfig())
90+
91+
# --- Main Application ---
92+
def main():
93+
# 1. Connect to WiFi
94+
connect_wifi()
95+
96+
# 2. Synchronize time (critical for MinIO authentication)
97+
mc.sync_time() #
98+
99+
# 3. Create a dummy file to upload (or use an existing file)
100+
local_file_to_upload = "data.txt"
101+
bucket_name = "my_bucket" # Ensure this bucket exists in MinIO
102+
s3_object_name = "my_device_data/data.txt" # Desired path and name in S3
103+
content_type = "text/plain" #
104+
105+
try:
106+
with open(local_file_to_upload, "w") as f:
107+
f.write("Hello from MicroPython!\n")
108+
f.write(f"Timestamp: {time.time()}\n")
109+
print(f"Created dummy file: {local_file_to_upload}")
110+
except OSError as e:
111+
print(f"Error creating file: {e}")
112+
return
113+
114+
# 4. Upload the file
115+
print(f"Attempting to upload '{local_file_to_upload}' to MinIO bucket '{bucket_name}' as '{s3_object_name}'...")
116+
if mc.upload_file(local_file_to_upload, bucket_name, s3_object_name, content_type): #
117+
print("Upload successful!")
118+
else:
119+
print("Upload failed.")
120+
121+
if __name__ == "__main__":
122+
main()
123+
```
124+
125+
## Contributing
126+
Feel free to fork this repository, submit issues, and create pull requests if you have improvements or bug fixes.
127+
128+
## License
129+
This project is licensed under the MIT License - see the LICENSE file for details.
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import network
2+
import time
3+
from uminio import MinioClient
4+
5+
# --- MinIO Client Configuration ---
6+
MINIO_ENDPOINT = "192.168.1.100:9000" # Your MinIO server IP address and port
7+
MINIO_ACCESS_KEY = "YOUR_ACCESS_KEY" # Your MinIO access key
8+
MINIO_SECRET_KEY = "YOUR_SECRET_KEY" # Your MinIO secret key
9+
MINIO_REGION = "eu-east-1" # The region for your MinIO server
10+
MINIO_USE_HTTPS = False # Set to True if your MinIO server uses HTTPS
11+
12+
mc = MinioClient(
13+
endpoint=MINIO_ENDPOINT,
14+
access_key=MINIO_ACCESS_KEY,
15+
secret_key=MINIO_SECRET_KEY,
16+
region=MINIO_REGION,
17+
use_https=MINIO_USE_HTTPS,
18+
)
19+
# --- Network Configuration (Example for ESP32/ESP8266) ---
20+
WIFI_SSID = "YOUR_WIFI_SSID"
21+
WIFI_PASSWORD = "YOUR_WIFI_PASSWORD"
22+
23+
24+
def connect_wifi():
25+
sta_if = network.WLAN(network.STA_IF)
26+
if not sta_if.isconnected():
27+
print("Connecting to WiFi...")
28+
sta_if.active(True)
29+
sta_if.connect(WIFI_SSID, WIFI_PASSWORD)
30+
while not sta_if.isconnected():
31+
time.sleep(1)
32+
print("Network Config:", sta_if.ifconfig())
33+
34+
35+
# --- Main Application ---
36+
def main():
37+
# 1. Connect to WiFi
38+
connect_wifi()
39+
40+
# 2. Synchronize time (critical for MinIO authentication)
41+
mc.sync_time()
42+
43+
# 3. Create a dummy file to upload (or use an existing file)
44+
local_file_to_upload = "data.txt"
45+
bucket_name = "my_bucket" # Ensure this bucket exists in MinIO
46+
s3_object_name = "my_device_data/data.txt" # Desired path and name in S3
47+
content_type = "text/plain"
48+
49+
try:
50+
with open(local_file_to_upload, "w") as f:
51+
f.write("Hello from MicroPython!\n")
52+
f.write(f"Timestamp: {time.time()}\n")
53+
print(f"Created dummy file: {local_file_to_upload}")
54+
except OSError as e:
55+
print(f"Error creating file: {e}")
56+
return
57+
58+
# 4. Upload the file
59+
print(
60+
f"Attempting to upload '{local_file_to_upload}' to MinIO bucket '{bucket_name}' as '{s3_object_name}'..."
61+
)
62+
if mc.upload_file(local_file_to_upload, bucket_name, s3_object_name, content_type):
63+
print("Upload successful!")
64+
else:
65+
print("Upload failed.")
66+
67+
68+
if __name__ == "__main__":
69+
main()

python-ecosys/uminio/manifest.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
metadata(version="0.0.1", description="MIcroPython client for MinIO object storage.")
2+
3+
package("uminio")

0 commit comments

Comments
 (0)