python2mobile 1.0.1__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.
Files changed (50) hide show
  1. examples/example_ecommerce_app.py +189 -0
  2. examples/example_todo_app.py +159 -0
  3. p2m/__init__.py +31 -0
  4. p2m/cli.py +470 -0
  5. p2m/config.py +205 -0
  6. p2m/core/__init__.py +18 -0
  7. p2m/core/api.py +191 -0
  8. p2m/core/ast_walker.py +171 -0
  9. p2m/core/database.py +192 -0
  10. p2m/core/events.py +56 -0
  11. p2m/core/render_engine.py +597 -0
  12. p2m/core/runtime.py +128 -0
  13. p2m/core/state.py +51 -0
  14. p2m/core/validator.py +284 -0
  15. p2m/devserver/__init__.py +9 -0
  16. p2m/devserver/server.py +84 -0
  17. p2m/i18n/__init__.py +7 -0
  18. p2m/i18n/translator.py +74 -0
  19. p2m/imagine/__init__.py +35 -0
  20. p2m/imagine/agent.py +463 -0
  21. p2m/imagine/legacy.py +217 -0
  22. p2m/llm/__init__.py +20 -0
  23. p2m/llm/anthropic_provider.py +78 -0
  24. p2m/llm/base.py +42 -0
  25. p2m/llm/compatible_provider.py +120 -0
  26. p2m/llm/factory.py +72 -0
  27. p2m/llm/ollama_provider.py +89 -0
  28. p2m/llm/openai_provider.py +79 -0
  29. p2m/testing/__init__.py +41 -0
  30. p2m/ui/__init__.py +43 -0
  31. p2m/ui/components.py +301 -0
  32. python2mobile-1.0.1.dist-info/METADATA +238 -0
  33. python2mobile-1.0.1.dist-info/RECORD +50 -0
  34. python2mobile-1.0.1.dist-info/WHEEL +5 -0
  35. python2mobile-1.0.1.dist-info/entry_points.txt +2 -0
  36. python2mobile-1.0.1.dist-info/top_level.txt +3 -0
  37. tests/test_basic_engine.py +281 -0
  38. tests/test_build_generation.py +603 -0
  39. tests/test_build_test_gate.py +150 -0
  40. tests/test_carousel_modal.py +84 -0
  41. tests/test_config_system.py +272 -0
  42. tests/test_i18n.py +101 -0
  43. tests/test_ifood_app_integration.py +172 -0
  44. tests/test_imagine_cli.py +133 -0
  45. tests/test_imagine_command.py +341 -0
  46. tests/test_llm_providers.py +321 -0
  47. tests/test_new_apps_integration.py +588 -0
  48. tests/test_ollama_functional.py +329 -0
  49. tests/test_real_world_apps.py +228 -0
  50. tests/test_run_integration.py +776 -0
p2m/ui/components.py ADDED
@@ -0,0 +1,301 @@
1
+ """
2
+ P2M UI Components - Declarative component library
3
+ """
4
+
5
+ from typing import Any, Callable, Dict, List, Optional
6
+ from dataclasses import dataclass, field
7
+
8
+
9
+ @dataclass
10
+ class Component:
11
+ """Base component class"""
12
+
13
+ component_type: str
14
+ props: Dict[str, Any] = field(default_factory=dict)
15
+ children: List["Component"] = field(default_factory=list)
16
+
17
+ def add(self, child: "Component") -> "Component":
18
+ """Add a child component"""
19
+ self.children.append(child)
20
+ return self
21
+
22
+ def build(self) -> Dict[str, Any]:
23
+ """Build component tree as dictionary"""
24
+ return {
25
+ "type": self.component_type,
26
+ "props": self.props,
27
+ "children": [child.build() if isinstance(child, Component) else child
28
+ for child in self.children],
29
+ }
30
+
31
+ def __repr__(self) -> str:
32
+ return f"<{self.component_type} {self.props}>"
33
+
34
+
35
+ class Container(Component):
36
+ """Container component - wrapper for other components"""
37
+
38
+ def __init__(self, class_: str = "", direction: str = "column", scroll: bool = False, **props):
39
+ super().__init__(
40
+ component_type="Container",
41
+ props={
42
+ "class": class_,
43
+ "direction": direction,
44
+ "scroll": scroll,
45
+ **props,
46
+ }
47
+ )
48
+
49
+
50
+ class Text(Component):
51
+ """Text component - displays text content"""
52
+
53
+ def __init__(self, value: str, class_: str = "", **props):
54
+ super().__init__(
55
+ component_type="Text",
56
+ props={
57
+ "value": value,
58
+ "class": class_,
59
+ **props,
60
+ }
61
+ )
62
+
63
+
64
+ class Button(Component):
65
+ """Button component - clickable button"""
66
+
67
+ def __init__(
68
+ self,
69
+ label: str,
70
+ class_: str = "",
71
+ on_click=None,
72
+ on_click_args: Optional[List] = None,
73
+ **props,
74
+ ):
75
+ # on_click can be a callable or a string (handler name)
76
+ if callable(on_click):
77
+ on_click_name = on_click.__name__
78
+ else:
79
+ on_click_name = on_click # already a string or None
80
+
81
+ super().__init__(
82
+ component_type="Button",
83
+ props={
84
+ "label": label,
85
+ "class": class_,
86
+ "on_click": on_click_name,
87
+ "on_click_args": on_click_args or [],
88
+ **props,
89
+ },
90
+ )
91
+
92
+
93
+ class Input(Component):
94
+ """Input component - text input field"""
95
+
96
+ def __init__(
97
+ self,
98
+ placeholder: str = "",
99
+ class_: str = "",
100
+ on_change=None,
101
+ value: str = "",
102
+ input_type: str = "text",
103
+ **props,
104
+ ):
105
+ if callable(on_change):
106
+ on_change_name = on_change.__name__
107
+ else:
108
+ on_change_name = on_change # string or None
109
+
110
+ super().__init__(
111
+ component_type="Input",
112
+ props={
113
+ "placeholder": placeholder,
114
+ "class": class_,
115
+ "on_change": on_change_name,
116
+ "value": value,
117
+ "input_type": input_type,
118
+ **props,
119
+ },
120
+ )
121
+
122
+
123
+ class Image(Component):
124
+ """Image component - displays images"""
125
+
126
+ def __init__(self, src: str, class_: str = "", alt: str = "", **props):
127
+ super().__init__(
128
+ component_type="Image",
129
+ props={
130
+ "src": src,
131
+ "class": class_,
132
+ "alt": alt,
133
+ **props,
134
+ }
135
+ )
136
+
137
+
138
+ class List(Component):
139
+ """List component - renders list of items"""
140
+
141
+ def __init__(self, items: List[Any], render_item: Optional[Callable] = None,
142
+ class_: str = "", **props):
143
+ super().__init__(
144
+ component_type="List",
145
+ props={
146
+ "items": items,
147
+ "render_item": render_item.__name__ if render_item else None,
148
+ "class": class_,
149
+ **props,
150
+ }
151
+ )
152
+ self._render_item = render_item
153
+ self._items = items
154
+
155
+ def get_renderer(self) -> Optional[Callable]:
156
+ """Get the item renderer"""
157
+ return self._render_item
158
+
159
+ def get_items(self) -> List[Any]:
160
+ """Get items"""
161
+ return self._items
162
+
163
+
164
+ class Navigator(Component):
165
+ """Navigator component - handles navigation between screens"""
166
+
167
+ def __init__(self, routes: Dict[str, Callable], initial: str = "", **props):
168
+ super().__init__(
169
+ component_type="Navigator",
170
+ props={
171
+ "initial": initial,
172
+ **props,
173
+ }
174
+ )
175
+ self._routes = routes
176
+
177
+ def get_routes(self) -> Dict[str, Callable]:
178
+ """Get routes"""
179
+ return self._routes
180
+
181
+
182
+ class Screen(Component):
183
+ """Screen component - represents a screen/page"""
184
+
185
+ def __init__(self, name: str, class_: str = "", **props):
186
+ super().__init__(
187
+ component_type="Screen",
188
+ props={
189
+ "name": name,
190
+ "class": class_,
191
+ **props,
192
+ }
193
+ )
194
+
195
+
196
+ class Modal(Component):
197
+ """Modal component - displays modal dialog"""
198
+
199
+ def __init__(self, title: str = "", class_: str = "", visible: bool = False, **props):
200
+ super().__init__(
201
+ component_type="Modal",
202
+ props={
203
+ "title": title,
204
+ "class": class_,
205
+ "visible": visible,
206
+ **props,
207
+ }
208
+ )
209
+
210
+
211
+ class ScrollView(Component):
212
+ """ScrollView component - scrollable container"""
213
+
214
+ def __init__(self, class_: str = "", **props):
215
+ super().__init__(
216
+ component_type="ScrollView",
217
+ props={
218
+ "class": class_,
219
+ **props,
220
+ }
221
+ )
222
+
223
+
224
+ class Carousel(Component):
225
+ """Carousel component - horizontal scrollable row of items"""
226
+
227
+ def __init__(self, class_: str = "", **props):
228
+ super().__init__(
229
+ component_type="Carousel",
230
+ props={"class": class_, **props},
231
+ )
232
+
233
+
234
+ class Row(Component):
235
+ """Row component - horizontal layout"""
236
+
237
+ def __init__(self, class_: str = "", **props):
238
+ super().__init__(
239
+ component_type="Row",
240
+ props={
241
+ "class": class_,
242
+ "direction": "row",
243
+ **props,
244
+ }
245
+ )
246
+
247
+
248
+ class Column(Component):
249
+ """Column component - vertical layout"""
250
+
251
+ def __init__(self, class_: str = "", **props):
252
+ super().__init__(
253
+ component_type="Column",
254
+ props={
255
+ "class": class_,
256
+ "direction": "column",
257
+ **props,
258
+ }
259
+ )
260
+
261
+
262
+ class Card(Component):
263
+ """Card component - card container"""
264
+
265
+ def __init__(self, class_: str = "", **props):
266
+ super().__init__(
267
+ component_type="Card",
268
+ props={
269
+ "class": class_,
270
+ **props,
271
+ }
272
+ )
273
+
274
+
275
+ class Badge(Component):
276
+ """Badge component - small label"""
277
+
278
+ def __init__(self, label: str, class_: str = "", **props):
279
+ super().__init__(
280
+ component_type="Badge",
281
+ props={
282
+ "label": label,
283
+ "class": class_,
284
+ **props,
285
+ }
286
+ )
287
+
288
+
289
+ class Icon(Component):
290
+ """Icon component - displays icon"""
291
+
292
+ def __init__(self, name: str, class_: str = "", size: int = 24, **props):
293
+ super().__init__(
294
+ component_type="Icon",
295
+ props={
296
+ "name": name,
297
+ "class": class_,
298
+ "size": size,
299
+ **props,
300
+ }
301
+ )
@@ -0,0 +1,238 @@
1
+ Metadata-Version: 2.4
2
+ Name: python2mobile
3
+ Version: 1.0.1
4
+ Summary: Python to Mobile - Write mobile apps in pure Python with DSL
5
+ Author-email: P2M Team <team@python2mobile.dev>
6
+ License-Expression: MIT
7
+ Keywords: mobile,python,dsl,flutter,react-native,llm,ai
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Requires-Python: >=3.9
15
+ Description-Content-Type: text/markdown
16
+ Requires-Dist: click>=8.1.0
17
+ Requires-Dist: fastapi>=0.104.0
18
+ Requires-Dist: uvicorn>=0.24.0
19
+ Requires-Dist: watchdog>=3.0.0
20
+ Requires-Dist: jinja2>=3.1.0
21
+ Requires-Dist: pydantic>=2.0.0
22
+ Requires-Dist: python-dotenv>=1.0.0
23
+ Requires-Dist: requests>=2.31.0
24
+ Requires-Dist: openai>=1.3.0
25
+ Requires-Dist: anthropic>=0.7.0
26
+ Requires-Dist: toml>=0.10.0
27
+ Requires-Dist: websockets>=12.0
28
+ Requires-Dist: agno>=2.1.0
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest>=7.4.0; extra == "dev"
31
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
32
+ Requires-Dist: black>=23.0.0; extra == "dev"
33
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
34
+ Requires-Dist: mypy>=1.5.0; extra == "dev"
35
+
36
+ # Python2Mobile (P2M)
37
+
38
+ Write mobile apps in **pure Python** with a declarative DSL. P2M generates or runs native/hybrid apps for Android, iOS, and Web.
39
+
40
+ ## Features
41
+
42
+ - **Python DSL** - Write UI and logic in familiar Python syntax
43
+ - **Tailwind-like Styling** - Use CSS class names for mobile styling
44
+ - **Hot Reload** - See changes instantly during development
45
+ - **Multi-LLM Support** - OpenAI, Claude, Ollama, or any OpenAI-compatible API
46
+ - **Multiple Targets** - Generate React Native or Flutter code
47
+ - **DevServer** - Preview apps in browser before building
48
+
49
+ ## Quick Start
50
+
51
+ ```bash
52
+ pip install python2mobile
53
+
54
+ # Create a new app
55
+ p2m new myapp
56
+ cd myapp
57
+
58
+ # Run in development mode (hot reload)
59
+ p2m run
60
+
61
+ # Build for production
62
+ p2m build --target android
63
+ p2m build --target ios
64
+ p2m build --target web
65
+ ```
66
+
67
+ ## Example App
68
+
69
+ ```python
70
+ from p2m.core import Render
71
+ from p2m.ui import Container, Text, Button
72
+
73
+ def click_button():
74
+ print("Button clicked!")
75
+
76
+ def create_view():
77
+ container = Container(class_="bg-gray-100 min-h-screen flex items-center justify-center")
78
+ inner = Container(class_="text-center space-y-6 p-8 bg-white rounded-2xl shadow-lg")
79
+
80
+ text = Text("Welcome to P2M", class_="text-gray-800 text-2xl font-bold")
81
+ button = Button(
82
+ "Click Me",
83
+ class_="bg-blue-600 text-white font-semibold py-3 px-8 rounded-xl hover:bg-blue-700",
84
+ on_click=click_button
85
+ )
86
+
87
+ inner.add(text).add(button)
88
+ container.add(inner)
89
+ return container.build()
90
+
91
+ def main():
92
+ Render.execute(create_view)
93
+
94
+ if __name__ == "__main__":
95
+ main()
96
+ ```
97
+
98
+ ## Configuration
99
+
100
+ Create a `p2m.toml` file:
101
+
102
+ ```toml
103
+ [project]
104
+ name = "MyApp"
105
+ version = "0.1.0"
106
+ entry = "main.py"
107
+
108
+ [build]
109
+ target = ["android", "ios", "web"]
110
+ generator = "flutter" # or "react-native"
111
+ llm_provider = "openai" # openai | anthropic | ollama | openai-compatible
112
+ llm_model = "gpt-4o"
113
+ output_dir = "./build"
114
+ cache = true
115
+
116
+ [devserver]
117
+ port = 3000
118
+ hot_reload = true
119
+ mobile_frame = true
120
+
121
+ [style]
122
+ system = "tailwind"
123
+ ```
124
+
125
+ ## LLM Configuration
126
+
127
+ ### OpenAI
128
+ ```toml
129
+ [llm.openai]
130
+ api_key = "sk-..."
131
+ model = "gpt-4o"
132
+ ```
133
+
134
+ ### Claude (Anthropic)
135
+ ```toml
136
+ [llm.anthropic]
137
+ api_key = "sk-ant-..."
138
+ model = "claude-3-opus-20240229"
139
+ ```
140
+
141
+ ### Ollama (Local)
142
+ ```toml
143
+ [llm.ollama]
144
+ base_url = "http://localhost:11434"
145
+ model = "llama2"
146
+ ```
147
+
148
+ ### OpenAI Compatible
149
+ ```toml
150
+ [llm.custom]
151
+ base_url = "https://api.example.com/v1"
152
+ api_key = "your-api-key"
153
+ model = "your-model-name"
154
+ x_api_key = "optional-header"
155
+ ```
156
+
157
+ ## Architecture
158
+
159
+ ```
160
+ ┌─────────────────────────────────────────────────────┐
161
+ │ DEVELOPER │
162
+ │ writes in Python P2M │
163
+ └──────────────────────┬──────────────────────────────┘
164
+
165
+ ┌────────────▼────────────┐
166
+ │ p2m CLI │
167
+ │ (p2m run / p2m build) │
168
+ └────────────┬────────────┘
169
+
170
+ ┌─────────────┴──────────────┐
171
+ │ │
172
+ ┌────▼────┐ ┌─────▼──────┐
173
+ │ p2m run │ │ p2m build │
174
+ │ (dev) │ │ (prod) │
175
+ └────┬────┘ └─────┬──────┘
176
+ │ │
177
+ ┌────▼────────────┐ ┌──────▼───────────┐
178
+ │ P2M Runtime │ │ AI Code Generator│
179
+ │ - AST Parser │ │ - LLM Integration│
180
+ │ - Safe Eval │ │ - React Native │
181
+ │ - HTML Renderer │ │ - Flutter │
182
+ │ - Hot Reload │ │ - Web │
183
+ └────┬────────────┘ └──────┬───────────┘
184
+ │ │
185
+ ┌────▼────────────┐ ┌──────▼───────────┐
186
+ │ Web Visualizer │ │ /build/ │
187
+ │ localhost:3000 │ │ android/ │
188
+ │ Mobile Preview │ │ ios/ │
189
+ └─────────────────┘ │ web/ │
190
+ └──────────────────┘
191
+ ```
192
+
193
+ ## Project Structure
194
+
195
+ ```
196
+ p2m/
197
+ ├── __init__.py
198
+ ├── cli.py # CLI entry point
199
+ ├── config.py # Configuration management
200
+ ├── core/
201
+ │ ├── __init__.py
202
+ │ ├── runtime.py # Python runtime engine
203
+ │ ├── ast_walker.py # AST analysis
204
+ │ ├── render_engine.py # Component tree → HTML
205
+ │ ├── hot_reload.py # File watcher
206
+ │ └── event_bridge.py # JS ↔ Python bridge
207
+ ├── ui/
208
+ │ ├── __init__.py
209
+ │ ├── components.py # Base components
210
+ │ ├── layouts.py # Layout components
211
+ │ └── styles.py # Style system
212
+ ├── devserver/
213
+ │ ├── __init__.py
214
+ │ ├── server.py # FastAPI server
215
+ │ ├── templates.py # Jinja2 templates
216
+ │ └── websocket_handler.py # WebSocket bridge
217
+ ├── llm/
218
+ │ ├── __init__.py
219
+ │ ├── base.py # Base LLM interface
220
+ │ ├── openai_provider.py # OpenAI integration
221
+ │ ├── anthropic_provider.py # Claude integration
222
+ │ ├── ollama_provider.py # Ollama integration
223
+ │ └── factory.py # LLM factory
224
+ ├── build/
225
+ │ ├── __init__.py
226
+ │ ├── generator.py # Code generator
227
+ │ ├── react_native.py # React Native templates
228
+ │ ├── flutter.py # Flutter templates
229
+ │ └── cache.py # Build cache
230
+ └── utils/
231
+ ├── __init__.py
232
+ ├── logger.py # Logging
233
+ └── validators.py # Validation
234
+ ```
235
+
236
+ ## License
237
+
238
+ MIT
@@ -0,0 +1,50 @@
1
+ examples/example_ecommerce_app.py,sha256=0Bh7xLKUR-b8SeyfaSoF2E-jUTQuXqudTOyawtq-Fe8,5340
2
+ examples/example_todo_app.py,sha256=aXwktnqZu9fTuu2OKTyp-VBZiZY1PY8BeGXUs_Vc95g,4632
3
+ p2m/__init__.py,sha256=eaaxBoWz5zsbHCK_A_J0ky6aUfQZOnZTRqeLtCiwxLM,413
4
+ p2m/cli.py,sha256=Nw07QO67RZ6yJGfWxDs-y6qA777O2pNR9QRA_PQQ-jk,17854
5
+ p2m/config.py,sha256=HOaAyCHYAhPADJwVyIJdeg6KmIP53Q0ywQP4dvbjcTQ,6218
6
+ p2m/core/__init__.py,sha256=92EGYDO_gvZZ7E1fAriDG_5OApdThKjKTsjiTcTyXbs,394
7
+ p2m/core/api.py,sha256=lKqHpqJ0Dn_Yr6Dd7wtPxCbRE0sh0WZOqQKXwHYkVuE,5507
8
+ p2m/core/ast_walker.py,sha256=KDvBZsHjpmQvV01nqo5iaqtqlwS9bus0gS4oR0FDesg,5962
9
+ p2m/core/database.py,sha256=3UNpbLBk5R-Sik-Mbcse66dQx3nSu9l2s_ils0ldWIY,5629
10
+ p2m/core/events.py,sha256=CrqHYL1rSzKcr4D3ABKItdXSs_iql8oirj0xlG2N2_U,1300
11
+ p2m/core/render_engine.py,sha256=NMcnhSiHjJsPkOIA00Cdni-OKu1oGPYe4AsdpYxsh_M,24564
12
+ p2m/core/runtime.py,sha256=_lAS0HEUC0xm7_oMtuzYwY4Zz1xuIqnGyuprhcqMPFg,4505
13
+ p2m/core/state.py,sha256=g892vmyQeLFiRap3Q94XWEF5kJJOSxruc5N53514EOg,1428
14
+ p2m/core/validator.py,sha256=KJQEMrKil97aYENxl-EVwhmJInIeUEIN-paHHonEFrA,9755
15
+ p2m/devserver/__init__.py,sha256=iakn0n_aKlfEF2tTEmQYcn4lyKpmhGVyeRqegSKcQ_M,141
16
+ p2m/devserver/server.py,sha256=aogIjdePVQojK-1tRqltNBHricKBDnw1_3-5iUYiQMA,2871
17
+ p2m/i18n/__init__.py,sha256=L76Nw2JvKa8rzGtFafU94qxzwK1O68K-L2vw6uJohZM,179
18
+ p2m/i18n/translator.py,sha256=Mo9N3G9X70xFwDp8abSholStaqtQWkq1DLouCk5gDXc,2285
19
+ p2m/imagine/__init__.py,sha256=JXvfKo7raswHUYnkUCkf7ifWq34yuWvCVe208QMntAo,1041
20
+ p2m/imagine/agent.py,sha256=uAkbPLnpr8bGhYL8jfQcYmSeK1ahaH9W2wn21TgVj1s,15265
21
+ p2m/imagine/legacy.py,sha256=FVuvCswuWLXRasqhOISdF-z73Fyl8Xg4r0HMdrLI7aY,7517
22
+ p2m/llm/__init__.py,sha256=bUuVzJ67xLGV-FPVC7fBejWTpe-Yv_33Ee9SigpgbPU,531
23
+ p2m/llm/anthropic_provider.py,sha256=nDVudksnq468brHZdDbQve9I-vgmSgu9Q8iNnXbRgq0,2663
24
+ p2m/llm/base.py,sha256=C5rpsKZacwCjTVEQ0XlH20ux6G0_L1031GWYLtCI_Wc,1144
25
+ p2m/llm/compatible_provider.py,sha256=GnhsXHCoKUn0eB48fjE64YIvJyBfNXep4Ukqe1o2j_A,4112
26
+ p2m/llm/factory.py,sha256=GiizwKzh19gz2J08lRytRUniCG5yq4rVpFcEoR4C7-o,2277
27
+ p2m/llm/ollama_provider.py,sha256=bMACVJtbaQsN7ZWoHPy6XsbJFvlvL8U9-YQZO0_ysCc,3182
28
+ p2m/llm/openai_provider.py,sha256=EIoR5G_j_NBuNwKz_y6rTd19Ou7k7muqQLLUTjj7fo8,2715
29
+ p2m/testing/__init__.py,sha256=xT-zSz8QZ1Nf4jt2sPk8WRPgmOjWKAL11iyRuq_-KVU,1124
30
+ p2m/ui/__init__.py,sha256=tu19MdndY0qDBICCgV7Z7p--IlCZQsA9VJ4ywgJzxos,526
31
+ p2m/ui/components.py,sha256=VrSAijUj65_DLJkmx7fBnuchDXKtD_VItwpb6W3Ip-4,7809
32
+ tests/test_basic_engine.py,sha256=i_SYFrAASAi9Bj_bCK5eAFTpdPQsMXWfnbgsnNgmNfI,8211
33
+ tests/test_build_generation.py,sha256=yM88NI-jroEmHiAxJbDoOONENp2TaL_pCU0cH8jY0JM,29749
34
+ tests/test_build_test_gate.py,sha256=Ac4YwCppoO4TBP1VfF9i6ffxLTaxduH03q8YQwW7rT0,5694
35
+ tests/test_carousel_modal.py,sha256=Bu3GOMXPkhWDEDsvuKOfw8oefaXaIN5QKLGOAwUjym8,2876
36
+ tests/test_config_system.py,sha256=jyB7me5v41RAYTwOOTOBgQZc6dzEadcVzZzXuaLL3HI,7768
37
+ tests/test_i18n.py,sha256=5g6cCA_xJvYw2fDAqUFWAySHOqic5jQeyylml9rvP2s,3394
38
+ tests/test_ifood_app_integration.py,sha256=HvwUCy8S4QmtgfydBJAcB_mPeq-jEHToMRTcdxEEFIc,5902
39
+ tests/test_imagine_cli.py,sha256=4_JuzVjgwYIyRqHKb4jLqB59YoohNkajFwRLKCpXXJ8,3397
40
+ tests/test_imagine_command.py,sha256=WZl3mpM0PZlpm_-HC5x1oJnjtVDBHyWc1qI2boSrLKw,9201
41
+ tests/test_llm_providers.py,sha256=tuMaxim-RZChwlESIOVEVV-fjYDMURXeDcRh2KWki2U,9040
42
+ tests/test_new_apps_integration.py,sha256=_OSjwQGzNkRLn_geFcdLImMbSjpUgSThHAWMd9QxKKk,22744
43
+ tests/test_ollama_functional.py,sha256=WDNcLEo7FZnOxdiqraS9s3EDahQ8RWUr4od5BK7sX9U,8925
44
+ tests/test_real_world_apps.py,sha256=xZa2i5nXTFTI1L7l2X0mLxF6l4IQMitiJIDMcj-BN_8,6932
45
+ tests/test_run_integration.py,sha256=aZD1vx7MPYKiAQOLyiCByXOk0yI9SnvwLMKwyCtldX0,32541
46
+ python2mobile-1.0.1.dist-info/METADATA,sha256=GP_02pc-Fu5RMu1-vvQaSFMQpxDjBdcCjgSAvNi6gBU,7818
47
+ python2mobile-1.0.1.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
48
+ python2mobile-1.0.1.dist-info/entry_points.txt,sha256=mNxeUNlwXFdWbI2s1o3vVXOSXjd9G6vPlZsQlMg2jDE,37
49
+ python2mobile-1.0.1.dist-info/top_level.txt,sha256=sSRsQeWtjFSXKIQPaBeqoOkwFf1Csyg34U2L5RjP0OM,19
50
+ python2mobile-1.0.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ p2m = p2m.cli:main
@@ -0,0 +1,3 @@
1
+ examples
2
+ p2m
3
+ tests