microweb 0.1.1__py3-none-any.whl → 0.1.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
microweb/cli.py CHANGED
@@ -183,31 +183,47 @@ def verify_static_files_exist(static_files, static_dir):
183
183
  return existing_files, missing_files
184
184
 
185
185
  def upload_boot_py(port, module_name):
186
- """Create and upload boot.py to import the app module."""
186
+ """Create and upload boot.py that imports the specified app module."""
187
187
  boot_content = f"import {module_name}\n"
188
- import tempfile
189
- with tempfile.NamedTemporaryFile('w', delete=False, encoding='utf-8') as tmp:
190
- tmp.write(boot_content)
191
- tmp_path = tmp.name
188
+
189
+ with open("boot.py", "w", encoding="utf-8") as f:
190
+ f.write(boot_content)
191
+
192
192
  try:
193
- print_colored(f"⬆️ Uploading boot.py to import {module_name}...", color='cyan')
194
- upload_file(tmp_path, port, destination='boot.py')
193
+ print_colored(f"⬆️ Uploading boot.py to import '{module_name}'...", color='cyan')
194
+ upload_file("boot.py", port, destination='boot.py')
195
+ print_colored("✅ boot.py uploaded successfully.", color='green')
195
196
  finally:
196
- os.unlink(tmp_path)
197
+ os.remove("boot.py")
198
+
197
199
 
198
200
  def remove_boot_py(port):
199
- """Remove boot.py from the ESP32 filesystem."""
201
+ """Replace boot.py on ESP32 with minimal content using ampy."""
202
+ boot_content = "import gc\ngc.collect()\n"
203
+ boot_filename = "boot.py"
204
+
205
+ # Write minimal boot.py locally
206
+ with open(boot_filename, "w", encoding="utf-8") as f:
207
+ f.write(boot_content)
208
+
200
209
  try:
201
- print_colored("🗑️ Removing boot.py from ESP32...", color='cyan')
202
- cmd = ['mpremote', 'connect', port, 'exec', "import os; os.remove('boot.py')"]
203
- result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
210
+ print_colored(f"🗑️ Replacing boot.py on ESP32 (port {port}) using ampy...", color='cyan')
211
+ cmd = ["ampy", "--port", port, "put", boot_filename]
212
+ result = subprocess.run(cmd, capture_output=True, text=True, timeout=15)
213
+
204
214
  if result.returncode != 0:
205
- print_colored(f"⚠️ Could not remove boot.py: {result.stderr.strip()}", color='yellow')
215
+ print_colored(f"⚠️ Failed to replace boot.py: {result.stderr.strip()}", color='yellow')
206
216
  else:
207
- print_colored("boot.py removed successfully.", color='green')
217
+ print_colored("boot.py replaced successfully.", color='green')
218
+
208
219
  except Exception as e:
209
- print_colored(f"Error removing boot.py: {e}", color='red')
220
+ print_colored(f"Error replacing boot.py: {e}", color='red')
221
+
222
+ finally:
223
+ if os.path.exists(boot_filename):
224
+ os.remove(boot_filename)
210
225
 
226
+
211
227
  @click.group()
212
228
  def cli():
213
229
  pass
@@ -215,33 +231,45 @@ def cli():
215
231
  @cli.command()
216
232
  @click.option('--port', default=None, help='Serial port, e.g., COM10')
217
233
  @click.option('--erase', is_flag=True, help='Erase all flash before writing firmware')
218
- def flash(port, erase):
219
- """Flash MicroPython and MicroWeb to the ESP32."""
234
+ @click.option('--esp8266', is_flag=True, help='Flash ESP8266 firmware instead of ESP32')
235
+ @click.option('--firmware', type=click.Path(exists=True), help='Custom firmware .bin file to flash')
236
+ def flash(port, erase, esp8266, firmware):
237
+ """Flash MicroPython and MicroWeb to the ESP32 or ESP8266."""
220
238
  if not port:
221
239
  ports = [p.device for p in serial.tools.list_ports.comports()]
222
240
  port = ports[0] if ports else None
223
241
  if not port:
224
- print_colored("No ESP32 found. Specify --port, e.g., --port COM10.", color='red')
242
+ print_colored("No ESP device found. Specify --port, e.g., --port COM10.", color='red')
225
243
  return
244
+
245
+ chip_name = "ESP8266" if esp8266 else "ESP32"
246
+ if firmware:
247
+ firmware_path = os.path.abspath(firmware)
248
+ print_colored(f"Using custom firmware: {firmware_path}", color='cyan')
249
+ else:
250
+ firmware_file = f"{chip_name}_GENERIC-20250415-v1.25.0.bin"
251
+ firmware_path = pkg_resources.resource_filename('microweb', f'firmware/{firmware_file}')
252
+
226
253
  if erase:
227
- print_colored("You requested --erase. This will erase ALL data on the ESP32!", color='yellow')
254
+ print_colored(f"You requested --erase. This will erase ALL data on the {chip_name}!", color='yellow')
228
255
  confirm = input("Type 'erase' to continue, or anything else to cancel: ")
229
256
  if "erase" not in confirm.lower():
230
257
  print_colored("Erase cancelled.", color='yellow')
231
258
  return
232
- print_colored(f"Erasing all flash on {port}...", color='yellow')
259
+ print_colored(f"Erasing all flash on {port} ({chip_name})...", color='yellow')
233
260
  esptool.main(['--port', port, 'erase_flash'])
261
+
234
262
  try:
235
263
  print_colored(f"Checking for MicroPython on {port}...", color='blue')
236
264
  if check_micropython(port):
237
265
  print_colored(f"MicroPython detected on {port}. Skipping firmware flash.", color='green')
238
266
  else:
239
- firmware_path = pkg_resources.resource_filename('microweb', 'firmware/ESP32_GENERIC-20250415-v1.25.0.bin')
240
267
  if not os.path.exists(firmware_path):
241
- print_colored(f"Error: Firmware file not found at {firmware_path}. Ensure it is included in the package.", color='red')
268
+ print_colored(f"Error: Firmware file not found at {firmware_path}.", color='red')
242
269
  return
243
- print_colored(f"Flashing firmware on {port}...", color='blue')
270
+ print_colored(f"Flashing {chip_name} firmware on {port}...", color='blue')
244
271
  esptool.main(['--port', port, 'write_flash', '-z', '0x1000', firmware_path])
272
+
245
273
  print_colored("Uploading core files...", color='blue')
246
274
  core_files = [
247
275
  ('firmware/boot.py', 'boot.py'),
@@ -255,12 +283,15 @@ def flash(port, erase):
255
283
  print_colored(f"Error: Source file {src_path} not found.", color='red')
256
284
  return
257
285
  upload_file(src_path, port, destination=dest)
286
+
258
287
  print_colored("Verifying uploaded files...", color='blue')
259
288
  verify_files(port, [dest for _, dest in core_files])
260
- print_colored("MicroWeb flashed successfully", color='green')
289
+ print_colored(f"MicroWeb flashed successfully to {chip_name}", color='green')
290
+
261
291
  except Exception as e:
262
292
  print_colored(f"Error during flash: {e}", color='red')
263
293
 
294
+
264
295
  @cli.command()
265
296
  @click.argument('file')
266
297
  @click.option('--port', default=None, help='Serial port, e.g., COM10')
@@ -338,12 +369,13 @@ def run(file, port, check_only, static, force, no_stop, timeout, add_boot, remov
338
369
  if not port:
339
370
  print_colored("No ESP32 found. Specify --port, e.g., --port COM10.", color='red')
340
371
  return
341
- if not check_micropython(port):
342
- print_colored(f"MicroPython not detected on ESP32. Please run 'microweb flash --port {port}' first.", color='red')
343
- return
344
372
  if remove_boot:
345
373
  remove_boot_py(port)
346
374
  return
375
+ if not check_micropython(port):
376
+ print_colored(f"MicroPython not detected on ESP32. Please run 'microweb flash --port {port}' first.", color='red')
377
+ return
378
+
347
379
  try:
348
380
  print_colored(f"\nGetting remote file information from {port}...", color='blue')
349
381
  remote_files = get_remote_file_info(port)
microweb/uploader.py CHANGED
@@ -33,7 +33,7 @@ def upload_file(file_path, port=None,destination=None):
33
33
  raise Exception(f"File {file_name} not found after upload")
34
34
 
35
35
  except subprocess.TimeoutExpired:
36
- raise Exception(f"Upload timeout for {file_name}")
36
+ raise Exception(f"Upload timeout for {file_name} or that's uploaded that is effect to boot.py that is why timeout. ")
37
37
  except Exception as e:
38
38
  raise Exception(f"Upload error for {file_name}: {e}")
39
39
 
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: microweb
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: A web server framework for MicroPython . Easily build and deploy web applications using MicroPython.
5
5
  Home-page: https://github.com/ishanoshada/microweb
6
- Author: Your Name
6
+ Author: Ishan Oshada
7
7
  Keywords: micropython,esp32,web server,embedded,iot,http,microcontroller,python
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: License :: OSI Approved :: MIT License
@@ -11,6 +11,7 @@ Classifier: Operating System :: OS Independent
11
11
  Classifier: Topic :: Software Development :: Embedded Systems
12
12
  Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
13
13
  Description-Content-Type: text/markdown
14
+ License-File: LICENSE
14
15
  Requires-Dist: pyserial
15
16
  Requires-Dist: esptool
16
17
  Requires-Dist: click
@@ -20,6 +21,7 @@ Dynamic: description
20
21
  Dynamic: description-content-type
21
22
  Dynamic: home-page
22
23
  Dynamic: keywords
24
+ Dynamic: license-file
23
25
  Dynamic: requires-dist
24
26
  Dynamic: summary
25
27
 
@@ -87,6 +89,7 @@ With MicroWeb, you get routing, templates, JSON, static files, and more—making
87
89
  - [Example Usage](#example-usage)
88
90
  - [Minimal Example (`tests/2/app.py`)](#minimal-example-tests2apppy)
89
91
  - [Static Files and Templates Example (`tests/1/app.py`)](#static-files-and-templates-example-tests1apppy)
92
+ - [Portfolio Demo (`tests/portfolio/`)](#portfolio-demo-testsportfolio)
90
93
  - [Wi-Fi Configuration](#wi-fi-configuration)
91
94
  - [Accessing the Web Server](#accessing-the-web-server)
92
95
  - [CLI Tool Usage Examples](#cli-tool-usage-examples)
@@ -96,7 +99,7 @@ With MicroWeb, you get routing, templates, JSON, static files, and more—making
96
99
  - [Contributing](#contributing)
97
100
  - [License](#license)
98
101
 
99
-
102
+ ![example](/src/img.jpg)
100
103
 
101
104
  ## Features
102
105
 
@@ -109,7 +112,7 @@ With MicroWeb, you get routing, templates, JSON, static files, and more—making
109
112
  - **MicroPython Detection**: Verifies MicroPython before running scripts.
110
113
  - **Easy Cleanup**: Remove all files from the ESP32 home directory using `microweb remove --port COM10 --remove`—try this if you need to reset or clean up your device.
111
114
 
112
- ![uml](/uml.svg)
115
+ ![uml](/src/uml.svg)
113
116
 
114
117
  ---
115
118
  ## Installation
@@ -131,20 +134,30 @@ pip install .
131
134
 
132
135
  > **Note:** The workspace does not contain a git repository. If you want to contribute or track changes, initialize one with `git init`.
133
136
 
137
+
134
138
  ---
135
139
 
136
140
  ## Usage
137
141
 
138
- ### Flashing the ESP32
139
-
140
142
  Flash MicroPython and MicroWeb:
141
143
 
142
144
  ```bash
143
145
  microweb flash --port COM10
144
146
  ```
145
147
 
146
- - Erases the ESP32 flash (if `--erase` is used).
147
- - Uploads core files (`boot.py`, `main.py`, `microweb.py`, `wifi.py`, and all static files).
148
+ #### Options:
149
+
150
+ * `--erase`
151
+ Erase the entire flash memory before flashing firmware.
152
+
153
+ * `--esp8266`
154
+ Flash ESP8266 firmware instead of the default ESP32.
155
+
156
+ * `--firmware firmware.bin`
157
+ Use a custom `.bin` firmware file. This overrides the default firmware for ESP32 or ESP8266 ( any ).
158
+
159
+
160
+
148
161
 
149
162
  ---
150
163
 
@@ -156,15 +169,35 @@ Upload and run a MicroPython script:
156
169
  microweb run app.py --port COM10
157
170
  ```
158
171
 
159
- After running `app.run()`, the ESP32 will host a Wi-Fi access point (AP) if it cannot connect to a configured network. You can then connect your device to this AP and access the web server using the ESP32's IP address (typically `http://192.168.4.1` in AP mode).
160
-
161
-
162
- - Validates the `.py` file and checks for MicroPython.
172
+ - Validates your `.py` file and checks for MicroPython on the device.
163
173
  - Uploads and executes the script.
174
+ - Checks and uploads only changed files by default.
164
175
  - Prompts to run `microweb flash` if MicroPython is not detected.
176
+ - After running `app.run()`, the ESP32 will host a Wi-Fi access point (AP) if it cannot connect to a configured network. You can then connect your device to this AP and access the web server using the ESP32's IP address (typically `http://192.168.4.1` in AP mode).
165
177
 
166
178
  ---
167
179
 
180
+ ### Boot Script Management
181
+
182
+ You can configure your ESP32 to automatically start your application after any power cycle or reset by managing the `boot.py` file:
183
+
184
+ - **Add boot script (auto-run on power-up):**
185
+ ```bash
186
+ microweb run app.py --add-boot --port COM10
187
+ ```
188
+ This uploads a `boot.py` that will auto-run your app every time the ESP32 is powered on or reset. After upload, you can disconnect the ESP32 from your computer and power it from any source; the server will start automatically.
189
+
190
+ - **Remove boot script:**
191
+ ```bash
192
+ microweb run app.py --remove-boot --port COM10
193
+ ```
194
+ This removes the `boot.py` file, so your app will not auto-run on power-up.
195
+
196
+ ---
197
+
198
+
199
+
200
+
168
201
  ## Example Usage
169
202
 
170
203
  ### Minimal Example (`tests/2/app.py`)
@@ -254,6 +287,21 @@ app.run()
254
287
 
255
288
  ---
256
289
 
290
+ ### Portfolio Demo (`tests/portfolio/`)
291
+
292
+ The `tests/portfolio/` directory contains a full-featured portfolio web app built with MicroWeb, demonstrating:
293
+
294
+ - Multi-page routing (`/`, `/about`, `/projects`, `/contact`)
295
+ - Dynamic template rendering with variables
296
+ - Static assets (CSS, JS, images)
297
+ - API endpoints (e.g., `/api/info` returns JSON)
298
+ - Responsive, animated UI using HTML/CSS/JS
299
+ - Example of serving a personal portfolio from an ESP32
300
+
301
+ See `tests/portfolio/app.py` and the `static/` folder for a complete, ready-to-deploy example.
302
+
303
+ ---
304
+
257
305
  ## Wi-Fi Configuration
258
306
 
259
307
  Configure Wi-Fi via:
@@ -322,6 +370,7 @@ For more details, run `microweb --help`.
322
370
 
323
371
  ## Project Structure
324
372
 
373
+
325
374
  ```
326
375
  microweb/
327
376
  ├── microweb/
@@ -332,18 +381,13 @@ microweb/
332
381
  │ ├── cli.py
333
382
  │ ├── firmware/
334
383
  │ │ ├── ESP32_GENERIC-20250415-v1.25.0.bin
335
- │ │ ├── boot.py
336
- │ │ ├── main.py
337
- ├── static/
338
- │ │ ├── index.html
339
- │ │ ├── style.css
340
- │ │ ├── welcome.html
341
- │ │ ├── wifi_updated.html
342
- ├── setup.py
343
- ├── README.md
344
-
384
+ │ │ ├── boot.py # Minimal boot script
385
+ │ │ ├── main.py # Imports and runs your app module
386
+ ├── setup.py # Packaging and install configuration
387
+ ├── README.md # Project documentation
345
388
  ```
346
389
 
390
+
347
391
  ---
348
392
 
349
393
  ## Troubleshooting
@@ -361,3 +405,4 @@ Fork and submit pull requests at [https://github.com/ishanoshada/microweb](https
361
405
 
362
406
  ---
363
407
 
408
+ **Repository Views** ![Views](https://profile-counter.glitch.me/microweb/count.svg)
@@ -0,0 +1,15 @@
1
+ microweb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ microweb/cli.py,sha256=MoFSGG1AXvza4pwFxhoT9R65-9Jo7VtMslXN993kfv4,27919
3
+ microweb/microweb.py,sha256=WlDV1Fk5M4EsvmmkWKVLWaoZh6Vgl9G0qORFsQEQ3iM,12799
4
+ microweb/uploader.py,sha256=4aTFBMwIIKzONuvXla70ch7yT1pJ8XDmInYBPfVqcok,3164
5
+ microweb/wifi.py,sha256=S2gOOmTKp2G1uUHxOH0DHQ_k7QSERKHDCm89qv-WlKs,904
6
+ microweb/firmware/ESP32_GENERIC-20250415-v1.25.0.bin,sha256=HrGohHPjKqak1F3BtbatQLwfBhKOeqhUjkOM-kYz2hs,1702240
7
+ microweb/firmware/ESP8266_GENERIC-20250415-v1.25.0.bin,sha256=DcEkzHgtDl-BCwap6UbgKhirHjbWepSgd8PonauaVcY,636820
8
+ microweb/firmware/boot.py,sha256=1522jvxAjGk-y7X4mzMilB4pMQ6KrAgosDXRAMtac8k,22
9
+ microweb/firmware/main.py,sha256=g_rg-1qpQEzvQoSnhXairx_v7xHNuGDJVrmbdziKt1A,10
10
+ microweb-0.1.3.dist-info/licenses/LICENSE,sha256=7tSPQeJFv8168MWaFKTWEqYRvM9Lh5xsBh-US0mxUF0,1070
11
+ microweb-0.1.3.dist-info/METADATA,sha256=EsCNvIOp8eJ2c6gM_9lw1dTKaLlP5teu09Eo54bgnQ8,13725
12
+ microweb-0.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
13
+ microweb-0.1.3.dist-info/entry_points.txt,sha256=yBGjIy-e3mx-HHkmkGNLBcSDEALB327du5KuauZHmg4,46
14
+ microweb-0.1.3.dist-info/top_level.txt,sha256=CkRcDTo-nv4JTieAZPKFC-EGKYYQmKNq5C8zU2k5zRM,9
15
+ microweb-0.1.3.dist-info/RECORD,,
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Ishan Oshada
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,13 +0,0 @@
1
- microweb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- microweb/cli.py,sha256=RGrSlbzwfxB1SffKrxBcinPzft1L3VzdtTHNNWrxmnQ,27065
3
- microweb/microweb.py,sha256=WlDV1Fk5M4EsvmmkWKVLWaoZh6Vgl9G0qORFsQEQ3iM,12799
4
- microweb/uploader.py,sha256=EGUXscOAQ0gZJKBaRyAr5XzmxCWhabgh-QO3fBE2a38,3097
5
- microweb/wifi.py,sha256=S2gOOmTKp2G1uUHxOH0DHQ_k7QSERKHDCm89qv-WlKs,904
6
- microweb/firmware/ESP32_GENERIC-20250415-v1.25.0.bin,sha256=HrGohHPjKqak1F3BtbatQLwfBhKOeqhUjkOM-kYz2hs,1702240
7
- microweb/firmware/boot.py,sha256=1522jvxAjGk-y7X4mzMilB4pMQ6KrAgosDXRAMtac8k,22
8
- microweb/firmware/main.py,sha256=g_rg-1qpQEzvQoSnhXairx_v7xHNuGDJVrmbdziKt1A,10
9
- microweb-0.1.1.dist-info/METADATA,sha256=R-CD1owSm-Sb3cqX0Rj0ApJmnVzTcpkSP3d3vaW_KGU,12058
10
- microweb-0.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
- microweb-0.1.1.dist-info/entry_points.txt,sha256=yBGjIy-e3mx-HHkmkGNLBcSDEALB327du5KuauZHmg4,46
12
- microweb-0.1.1.dist-info/top_level.txt,sha256=CkRcDTo-nv4JTieAZPKFC-EGKYYQmKNq5C8zU2k5zRM,9
13
- microweb-0.1.1.dist-info/RECORD,,