ivoryzhang commited on
Commit
6f2393d
·
1 Parent(s): c99cc42

first commit

Browse files
Dockerfile ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Base image with Python
2
+ FROM python:3.10-slim
3
+
4
+ # Set working directory
5
+ WORKDIR /app
6
+
7
+ # Copy the entire project into the container
8
+ COPY . /app
9
+
10
+ # Install dependencies
11
+ RUN pip install --no-cache-dir -r requirements.txt
12
+
13
+ # If your app has additional requirements:
14
+ # RUN pip install --no-cache-dir -r requirements.txt
15
+
16
+ # Expose the default port
17
+ EXPOSE 7860
18
+
19
+ # Run your app
20
+ CMD ["python", "app.py"]
README.md CHANGED
@@ -1,11 +1,3 @@
1
- ---
2
- title: IvoryOS
3
- emoji: 📊
4
- colorFrom: green
5
- colorTo: pink
6
- sdk: docker
7
- pinned: false
8
- license: mit
9
- ---
10
 
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
+ # IvoryOS-HF Space
 
 
 
 
 
 
 
 
2
 
3
+ A demonstration of Ivory OS running in a Flask app inside a Hugging Face Space.
app.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from demo_code_plugin.demo_code import pump, sdl, balance
2
+ from demo_code_plugin.plugin import source_code
3
+
4
+ if __name__ == "__main__":
5
+ import ivoryos
6
+ from ivoryos.config import Config
7
+ _config = Config()
8
+ _config.SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:'
9
+ # from ivoryos_plugin.hello_world import plugin
10
+ # USE CASE 1 - start OS using current module
11
+ ivoryos.run(__name__, config=_config, blueprint_plugins=source_code, port=7860)
12
+
13
+ # # USE CASE 2 - start OS using current module and enable LLM with Ollama
14
+ # ivoryos.run(__name__, model="llama3.1", llm_server='localhost')
demo_code_plugin/__init__.py ADDED
File without changes
demo_code_plugin/demo_code.py ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ import time
3
+ from abc import ABC
4
+
5
+ import ivoryos
6
+
7
+
8
+ class AbstractPump:
9
+
10
+ def __init__(self, com_port: str):
11
+ self.com_port = com_port
12
+ self.dictionary = {}
13
+ self.logger = logging.getLogger("pump")
14
+
15
+ def dose_liquid(self, amount_in_ml: float, rate_ml_per_minute: float = 1):
16
+ """dose liquid"""
17
+ self.logger.info("dosing liquid")
18
+ self.logger.info(f"pretending dosing {amount_in_ml} at {rate_ml_per_minute} ml/min")
19
+ return 1
20
+
21
+
22
+
23
+ class AbstractBalance:
24
+
25
+ def __init__(self, com_port: str):
26
+ self.com_port = com_port
27
+ self._value = None
28
+ self.logger = logging.getLogger("balance")
29
+
30
+ @property
31
+ def setter_value(self):
32
+ return self._value
33
+
34
+ @setter_value.setter
35
+ def setter_value(self, value):
36
+ self._value = value
37
+
38
+ def weigh_sample(self):
39
+ time.sleep(1)
40
+ self.logger.info(f"Weighing sample using {self.com_port}")
41
+ return 1
42
+
43
+ def dose_solid(self, amount_in_mg: float):
44
+ """this function is used to dose solid"""
45
+ time.sleep(1)
46
+ self.logger.info(f"Dosing {amount_in_mg} mg using {self.com_port}")
47
+ return 1
48
+
49
+ def _helper(self):
50
+ """helper function will not be extracted and displayed over function panel"""
51
+ pass
52
+
53
+
54
+
55
+
56
+ class AbstractSDL(ABC):
57
+ def __init__(self, pump: AbstractPump, balance: AbstractBalance):
58
+ self.pump = pump
59
+ self.balance = balance
60
+ self.logger = logging.getLogger(f"logger_name")
61
+
62
+ def analyze(self):
63
+ self.logger.info("analyze")
64
+ time.sleep(1)
65
+ return 1
66
+
67
+
68
+ def dose_solid(self,
69
+ amount_in_mg: float = 5,
70
+ solid_name: str = "Acetaminophen"
71
+ ):
72
+ """dose current chemical"""
73
+ print("dosing solid")
74
+ self.balance.dose_solid(amount_in_mg=amount_in_mg)
75
+ self.balance.weigh_sample()
76
+ time.sleep(1)
77
+ self.logger.info(f"dosing solid {amount_in_mg} mg of {solid_name}")
78
+ return 1
79
+
80
+ def dose_solvent(self,
81
+ solvent_name: str = "Methanol",
82
+ amount_in_ml: float = 5,
83
+ rate_ml_per_minute: float = 1
84
+ ):
85
+ print("dosing liquid")
86
+ self.logger.info(f"dosing {amount_in_ml} ml of {solvent_name} solvent at {rate_ml_per_minute} ml/min")
87
+ time.sleep(1)
88
+ return 1
89
+
90
+
91
+ def equilibrate(self,
92
+ temp: float,
93
+ duration: float
94
+ ):
95
+ print("equilibrate")
96
+ self.logger.info(f"equilibrate at {temp} for {duration}")
97
+ time.sleep(1)
98
+
99
+ def simulate_error(self):
100
+ raise ValueError("some error")
101
+
102
+ def _send_command(self):
103
+ """helper function"""
104
+ pass
105
+
106
+
107
+
108
+ # initializing hardware
109
+ balance = AbstractBalance("Fake com port 1")
110
+ pump = AbstractPump("Fake com port 2")
111
+ sdl = AbstractSDL(pump, balance)
112
+
113
+
114
+ if __name__ == "__main__":
115
+ ivoryos.run(__name__)
demo_code_plugin/plugin.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ivoryos
2
+ from flask import render_template, Blueprint, current_app
3
+ import os
4
+
5
+ source_code = Blueprint("source_code", __name__, template_folder=os.path.join(os.path.dirname(__file__), "templates"))
6
+
7
+ # # [main route] the route url can be anything, but "main" is needed as entry point
8
+ @source_code.route('/')
9
+ def main():
10
+ base_exists = "base.html" in current_app.jinja_loader.list_templates()
11
+ filepath = os.path.join(os.path.dirname(__file__), 'demo_code.py')
12
+ with open(filepath, 'r', encoding='utf-8') as f:
13
+ code = f.read()
14
+ return render_template('example.html', base_exists=base_exists, code=code)
15
+
16
+
demo_code_plugin/templates/example.html ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% if base_exists %}
2
+ {% extends 'base.html' %}
3
+ {% block title %}Source code{% endblock %}
4
+ {% else %}
5
+ <html lang="en">
6
+ <head>
7
+ <meta charset="UTF-8">
8
+ <meta name="viewport" content="width=device-width, initial-scale=1">
9
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha2/dist/css/bootstrap.min.css" integrity="sha384-aFq/bzH65dt+w6FI2ooMVUpc+21e0SRygnTpmBvdBgSdnuTN7QbdgL+OapgHtvPp" crossorigin="anonymous">
10
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css">
11
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha2/dist/js/bootstrap.bundle.min.js" integrity="sha384-qKXV1j0HvMUeCBQ+QVp7JcfGl760yU08IQ+GpUo5hlbpg51QRiuqHAJz8+BrxE/N" crossorigin="anonymous"></script>
12
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
13
+ </head>
14
+ {% endif %}
15
+
16
+
17
+ {% block body %}
18
+ <div class="container mt-4">
19
+ <h2>Source Code</h2>
20
+ <pre><code class="language-python">{{ code|e }}</code></pre>
21
+ </div>
22
+ {% endblock %}
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ ivoryos>=1.0.4