solara-enterprise 1.30.0__py2.py3-none-any.whl → 1.31.0__py2.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.
@@ -1,2 +1,3 @@
1
1
  "Enterprise features for Solara"
2
- __version__ = "1.30.0"
2
+
3
+ __version__ = "1.31.0"
@@ -56,7 +56,7 @@ def add_document(base_url: str, route: solara.Route, build_path: Path, documents
56
56
  else:
57
57
  # split by h1 and h2
58
58
  parts: List[List[Any]] = [[]]
59
- ids = [None]
59
+ ids = []
60
60
  titles = [soup.title.string if soup.title else ""]
61
61
  current = parts[-1]
62
62
  # remove invisible title elements
solara_enterprise/ssg.py CHANGED
@@ -1,11 +1,12 @@
1
+ import concurrent.futures.thread
1
2
  import logging
2
- import multiprocessing.pool
3
3
  import threading
4
4
  import time
5
5
  import typing
6
6
  import urllib
7
+ import weakref
7
8
  from pathlib import Path
8
- from typing import List, Optional
9
+ from typing import List, Optional, Tuple
9
10
 
10
11
  import solara
11
12
  from rich import print as rprint
@@ -29,7 +30,7 @@ class Playwright(threading.local):
29
30
 
30
31
 
31
32
  pw = Playwright()
32
- playwrights: List[Playwright] = []
33
+ _used: List[Tuple["playwright.sync_api.Browser", "playwright.sync_api._context_manager.PlaywrightContextManager"]] = []
33
34
 
34
35
 
35
36
  class SSGData(TypedDict):
@@ -44,15 +45,48 @@ def _get_playwright():
44
45
  return pw
45
46
  from playwright.sync_api import sync_playwright
46
47
 
48
+ pw.number = 42
47
49
  pw.context_manager = sync_playwright()
48
50
  pw.sync_playwright = pw.context_manager.start()
49
51
 
50
52
  pw.browser = pw.sync_playwright.chromium.launch(headless=not settings.ssg.headed)
51
53
  pw.page = pw.browser.new_page()
52
- playwrights.append(pw)
54
+ _used.append((pw.browser, pw.context_manager))
53
55
  return pw
54
56
 
55
57
 
58
+ def _worker_with_cleanup(*args, **kwargs):
59
+ try:
60
+ concurrent.futures.thread._worker(*args, **kwargs)
61
+ finally:
62
+ pw = _get_playwright()
63
+ pw.browser.close()
64
+ pw.context_manager.__exit__(None, None, None)
65
+
66
+
67
+ class CleanupThreadPoolExecutor(concurrent.futures.ThreadPoolExecutor):
68
+ def _adjust_thread_count(self):
69
+ # copy of the original code with _worker replaced
70
+ # if idle threads are available, don't spin new threads
71
+ if self._idle_semaphore.acquire(timeout=0):
72
+ return
73
+
74
+ # When the executor gets lost, the weakref callback will wake up
75
+ # the worker threads.
76
+ def weakref_cb(_, q=self._work_queue):
77
+ q.put(None)
78
+
79
+ num_threads = len(self._threads)
80
+ if num_threads < self._max_workers:
81
+ thread_name = "%s_%d" % (self._thread_name_prefix or self, num_threads)
82
+ t = threading.Thread(
83
+ name=thread_name, target=_worker_with_cleanup, args=(weakref.ref(self, weakref_cb), self._work_queue, self._initializer, self._initargs)
84
+ )
85
+ t.start()
86
+ self._threads.add(t) # type: ignore
87
+ concurrent.futures.thread._threads_queues[t] = self._work_queue # type: ignore
88
+
89
+
56
90
  def ssg_crawl(base_url: str):
57
91
  license.check("SSG")
58
92
  import solara.server.app
@@ -69,31 +103,26 @@ def ssg_crawl(base_url: str):
69
103
  # although in theory we should be able to run this with multiple threads
70
104
  # there are issues with uvloop:
71
105
  # e.g.: "Racing with another loop to spawn a process."
72
- thread_pool = multiprocessing.pool.ThreadPool(1)
106
+ thread_pool = CleanupThreadPoolExecutor(max_workers=1)
73
107
 
74
108
  results = []
75
109
  for route in routes:
76
- results.append(thread_pool.apply_async(ssg_crawl_route, [f"{base_url}/", route, build_path, thread_pool]))
110
+ results.append(thread_pool.submit(ssg_crawl_route, f"{base_url}/", route, build_path, thread_pool))
77
111
 
78
112
  def wait(async_result):
79
- results = async_result.get()
113
+ results = async_result.result()
80
114
  for result in results:
81
115
  wait(result)
82
116
 
83
117
  for result in results:
84
118
  wait(result)
85
- thread_pool.close()
86
- thread_pool.join()
87
- for pw in playwrights:
88
- assert pw.browser is not None
89
- assert pw.context_manager is not None
90
- pw.browser.close()
91
- pw.context_manager.__exit__(None, None, None)
119
+
120
+ thread_pool.shutdown()
92
121
 
93
122
  rprint("Done building SSG")
94
123
 
95
124
 
96
- def ssg_crawl_route(base_url: str, route: solara.Route, build_path: Path, thread_pool: multiprocessing.pool.ThreadPool):
125
+ def ssg_crawl_route(base_url: str, route: solara.Route, build_path: Path, thread_pool: CleanupThreadPoolExecutor):
97
126
  # if route
98
127
  url = base_url + (route.path if route.path != "/" else "")
99
128
  if not route.children:
@@ -146,7 +175,7 @@ def ssg_crawl_route(base_url: str, route: solara.Route, build_path: Path, thread
146
175
  rprint(f"Skipping existing render: {path}")
147
176
  results = []
148
177
  for child in route.children:
149
- result = thread_pool.apply_async(ssg_crawl_route, [url + "/", child, build_path / Path(route.path), thread_pool])
178
+ result = thread_pool.submit(ssg_crawl_route, url + "/", child, build_path / Path(route.path), thread_pool)
150
179
  results.append(result)
151
180
  return results
152
181
 
@@ -1,13 +1,14 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: solara-enterprise
3
- Version: 1.30.0
3
+ Version: 1.31.0
4
4
  Dynamic: Summary
5
5
  Project-URL: Home, https://www.github.com/widgetti/solara
6
6
  Author-email: "Maarten A. Breddels" <maartenbreddels@gmail.com>, Mario Buikhuizen <mariobuikhuizen@gmail.com>
7
7
  License: Not open source, contact contact@solara.dev for licencing.
8
8
  License-File: LICENSE
9
9
  Classifier: License :: Free for non-commercial use
10
- Requires-Dist: solara==1.30.0
10
+ Requires-Dist: solara-server==1.31.0
11
+ Requires-Dist: solara-ui==1.31.0
11
12
  Provides-Extra: all
12
13
  Requires-Dist: solara-enterprise[auth]; extra == 'all'
13
14
  Requires-Dist: solara-enterprise[cache]; extra == 'all'
@@ -1,6 +1,6 @@
1
- solara_enterprise/__init__.py,sha256=f6ygSLlQDtvby6-n5y_34u7Y3i_YhpykKxJ6ateEkRU,56
1
+ solara_enterprise/__init__.py,sha256=vG6BIPBmxJi9QnG-XEOBuf7G4XvVPTohOVlUVacScJg,57
2
2
  solara_enterprise/license.py,sha256=GCGEs3x9rtKf0dYUcHkx-yteIQuRlgnS8hPbl9BDAXs,412
3
- solara_enterprise/ssg.py,sha256=Effd_X5VbTFIbyrGlZDAnoUWID1VbQb8w59xjVLJsu8,7752
3
+ solara_enterprise/ssg.py,sha256=uw3397RX0Qmg-OqOsgwaePDymhUvZTTFcBKkSWy1uCk,8935
4
4
  solara_enterprise/auth/__init__.py,sha256=83RGLIkVJrb6R1iZxg5YS0R3kaCmqMHu4qs8S74LJXo,513
5
5
  solara_enterprise/auth/components.py,sha256=mTazvLWJrduS6CrcsY60BJgkvQztH5X67CkOCRFXYV4,4038
6
6
  solara_enterprise/auth/flask.py,sha256=Y__abnQPnP1cdQAkU8BBg9FuWMZ1rNnUmTLE_x19MlE,3539
@@ -14,10 +14,10 @@ solara_enterprise/cache/memory_size.py,sha256=5PAUaxVvHMIFINA3Z4z48zDvAATTFkEd0e
14
14
  solara_enterprise/cache/multi_level.py,sha256=hMjruI1cwNwDajaRXAJ7TxQqfw5XWRvtYuAU7M4f_W8,710
15
15
  solara_enterprise/cache/redis.py,sha256=_GlACNJ5hfpRJ2Hw_2k3ma6gwEVLoVNTplS0Q5cGcRk,779
16
16
  solara_enterprise/search/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- solara_enterprise/search/index.py,sha256=iBdvVyM_v7UGPlwBnPwWIBMLhy3ezFSTBvzmeb7SKW4,3307
17
+ solara_enterprise/search/index.py,sha256=W98DC_6SmQDCfX5YcmS6OfZbO0LheleBmo0FUI7NOqU,3303
18
18
  solara_enterprise/search/search.py,sha256=rnVHP81AwL0GR8s5vnNU6rpEIqCVnZSgwfFfCuoibCQ,467
19
19
  solara_enterprise/search/search.vue,sha256=Aoyp9XPK9dDlKCymJqAtT6eoTsEoAOIe6zXiJYup5f4,6127
20
- solara_enterprise-1.30.0.dist-info/METADATA,sha256=y4VnOTR6RtpxV0P0Jq3f2uOi1FhW5Ylqxc-0sefa_Hw,949
21
- solara_enterprise-1.30.0.dist-info/WHEEL,sha256=q6Ejfpj4HRnt7o1XWgEOo5g7W0PKmxxzhdMpcVNBe68,105
22
- solara_enterprise-1.30.0.dist-info/licenses/LICENSE,sha256=04_xbTWtvdcQomu6IXsIkniKk8EcD9P1GyJM2dYPoSU,59
23
- solara_enterprise-1.30.0.dist-info/RECORD,,
20
+ solara_enterprise-1.31.0.dist-info/METADATA,sha256=5X2Nqy5Cgu_JiSbFzwtLlrwzfGQrLrSWoQ5MpIhrgtM,989
21
+ solara_enterprise-1.31.0.dist-info/WHEEL,sha256=L5_n4Kc1NmrSdVgbp6hdnwwVwBnoYOCnbHBRMD-qNJ4,105
22
+ solara_enterprise-1.31.0.dist-info/licenses/LICENSE,sha256=04_xbTWtvdcQomu6IXsIkniKk8EcD9P1GyJM2dYPoSU,59
23
+ solara_enterprise-1.31.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.22.4
2
+ Generator: hatchling 1.22.2
3
3
  Root-Is-Purelib: true
4
4
  Tag: py2-none-any
5
5
  Tag: py3-none-any