cloudoll 3.0.0__tar.gz → 3.0.2__tar.gz

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 (44) hide show
  1. {cloudoll-3.0.0 → cloudoll-3.0.2}/PKG-INFO +4 -4
  2. cloudoll-3.0.2/cloudoll/__init__.py +1 -0
  3. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/cli.py +1 -0
  4. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/clitool/m2d.py +5 -2
  5. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/clitool/process.py +23 -7
  6. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/clitool/watch.py +2 -2
  7. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/utils/common.py +2 -3
  8. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/web/core.py +1 -1
  9. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/web/requests.py +53 -51
  10. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll.egg-info/PKG-INFO +4 -4
  11. {cloudoll-3.0.0 → cloudoll-3.0.2}/pyproject.toml +3 -3
  12. {cloudoll-3.0.0 → cloudoll-3.0.2}/setup.cfg +1 -1
  13. cloudoll-3.0.0/cloudoll/__init__.py +0 -1
  14. {cloudoll-3.0.0 → cloudoll-3.0.2}/LICENSE +0 -0
  15. {cloudoll-3.0.0 → cloudoll-3.0.2}/README.md +0 -0
  16. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/__main__.py +0 -0
  17. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/clitool/__init__.py +0 -0
  18. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/clitool/cli_main.py +0 -0
  19. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/clitool/spinner.py +0 -0
  20. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/logging/__init__.py +0 -0
  21. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/mail/__init__.py +0 -0
  22. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/mail/smtp.py +0 -0
  23. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/orm/__init__.py +0 -0
  24. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/orm/base.py +0 -0
  25. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/orm/err.py +0 -0
  26. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/orm/field.py +0 -0
  27. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/orm/model.py +0 -0
  28. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/orm/mysql.py +0 -0
  29. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/orm/parse.py +0 -0
  30. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/orm/postgres.py +0 -0
  31. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/template/__init__.py +0 -0
  32. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/utils/__init__.py +0 -0
  33. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/utils/snowflake.py +0 -0
  34. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/web/__init__.py +0 -0
  35. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/web/exception.py +0 -0
  36. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/web/html.py +0 -0
  37. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/web/jwt.py +0 -0
  38. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll/web/settings.py +0 -0
  39. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll.egg-info/SOURCES.txt +0 -0
  40. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll.egg-info/dependency_links.txt +0 -0
  41. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll.egg-info/entry_points.txt +0 -0
  42. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll.egg-info/requires.txt +0 -0
  43. {cloudoll-3.0.0 → cloudoll-3.0.2}/cloudoll.egg-info/top_level.txt +0 -0
  44. {cloudoll-3.0.0 → cloudoll-3.0.2}/setup.py +0 -0
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudoll
3
- Version: 3.0.0
3
+ Version: 3.0.2
4
4
  Summary: Assist in quickly creating distributable microservices based on aiohttp, with a focus on simplicity and ease of use.
5
- Home-page: https://gitee.com/chuchur/cloudoll-py
5
+ Home-page: https://github.com/smallerqiu/cloudoll-py
6
6
  Author: Qiu
7
7
  Author-email: Qiu <smallerqiu@gmail.com>
8
8
  License-Expression: MIT
9
- Project-URL: Homepage, https://gitee.com/chuchur/cloudoll-py
10
- Project-URL: Repository, https://gitee.com/chuchur/cloudoll-py
9
+ Project-URL: Homepage, https://github.com/smallerqiu/cloudoll-py
10
+ Project-URL: Repository, https://github.com/smallerqiu/cloudoll-py
11
11
  Keywords: Microservices,aiohttp,cloudoll
12
12
  Classifier: Programming Language :: Python :: 3
13
13
  Classifier: Programming Language :: Python :: 3.6
@@ -0,0 +1 @@
1
+ __version__ = "3.0.2"
@@ -1,4 +1,5 @@
1
1
  from pathlib import Path
2
+ import traceback
2
3
  import click
3
4
  import asyncio
4
5
  import os
@@ -27,7 +27,7 @@ async def create_model(pool, table_name) -> str:
27
27
  tb = f"\nclass {snake_to_camel(table_name)}(Model):\n\n"
28
28
  tb += f"\t__table__ = '{table_name}'\n\n"
29
29
  for f in rows:
30
- fields = get_col(f, pool.driver)
30
+ fields: dict = get_col(f, pool.driver)
31
31
  # print("fields",fields)
32
32
  name = fields["name"]
33
33
  column_type = fields["column_type"]
@@ -193,7 +193,8 @@ async def create_tables(pool, model_name: str, tables: list):
193
193
  else:
194
194
  raise ImportError(f"Module {model_name} not found or invalid.")
195
195
 
196
- def get_col(field, driver="mysql"):
196
+
197
+ def get_col(field, driver="mysql") -> dict:
197
198
  if driver == "mysql":
198
199
  fields = {
199
200
  "name": field["Field"],
@@ -235,6 +236,8 @@ def get_col(field, driver="mysql"):
235
236
  "comment": field["comment"],
236
237
  }
237
238
  return fields
239
+ else:
240
+ raise ValueError(f"Database {driver} not support.")
238
241
 
239
242
 
240
243
  def get_col_sql(field):
@@ -27,10 +27,10 @@ class ProcessManager:
27
27
  def get_run_dir():
28
28
  home = Path.home()
29
29
  if platform.system() == "Windows":
30
- run_dir = home / f"AppData/Local/cloudoll"
30
+ run_dir = home / f"AppData/Local/cloudoll"
31
31
  else:
32
32
  run_dir = home / f".cloudoll"
33
-
33
+
34
34
  try:
35
35
  run_dir.mkdir(parents=True, exist_ok=True, mode=0o700)
36
36
  except (PermissionError, OSError):
@@ -41,7 +41,7 @@ class ProcessManager:
41
41
  @staticmethod
42
42
  def get_pid_path(name: str):
43
43
  run_dir = ProcessManager.get_run_dir()
44
- return run_dir / f"cloudoll-{name}.pid"
44
+ return run_dir / f"{name}.pid"
45
45
 
46
46
  @staticmethod
47
47
  def save_pid(name: str, pid: int) -> None:
@@ -57,6 +57,7 @@ class ProcessManager:
57
57
 
58
58
  @staticmethod
59
59
  def safe_exit(service_name: str):
60
+ pid = 0
60
61
  try:
61
62
  pid = ProcessManager.get_running_pid(service_name)
62
63
  if not pid:
@@ -111,8 +112,6 @@ class ProcessManager:
111
112
  valid_identifiers = [
112
113
  f"--name {service_name}",
113
114
  f"-n {service_name}",
114
- f"--name={service_name}",
115
- f"-n={service_name}",
116
115
  ]
117
116
  cmdline = " ".join(psutil.Process(os.getpid()).cmdline())
118
117
  return (
@@ -205,7 +204,16 @@ class ProcessManager:
205
204
  return
206
205
 
207
206
  fmt = "{:<15} {:<8} {:<8} {:<12} {:<8} {:<10} {:<15}"
208
- headers = ["Services", "PID", "Status", "RunTime", "CPU%", "Mem(MB)", "Process"]
207
+ headers = [
208
+ "Services",
209
+ "PID",
210
+ "Status",
211
+ "Env",
212
+ "RunTime",
213
+ "CPU%",
214
+ "Mem(MB)",
215
+ "Process",
216
+ ]
209
217
  rows = []
210
218
  for pid_file in sorted(pid_dir.glob("*.pid")):
211
219
  service = pid_file.stem
@@ -225,11 +233,19 @@ class ProcessManager:
225
233
  uptime = datetime.now() - start_time
226
234
  runtime = str(uptime).split(".")[0]
227
235
 
236
+ "env"
237
+ args = ProcessManager.load_start_args(service)
238
+ env_value = "-"
239
+ if "-env" in args:
240
+ index = args.index("-env")
241
+ if index + 1 < len(args):
242
+ env_value = args[index + 1]
228
243
  rows.append(
229
244
  [
230
245
  service,
231
246
  pid,
232
247
  "🟢 Running",
248
+ env_value,
233
249
  runtime,
234
250
  f"{cpu_percent:.1f}",
235
251
  f"{mem_mb:.1f}",
@@ -239,4 +255,4 @@ class ProcessManager:
239
255
  except Exception as e:
240
256
  rows.append([service, "???", "error", "-", "-", "-", str(e)])
241
257
 
242
- click.echo(tabulate(rows, headers=headers, tablefmt="rounded_outline"))
258
+ click.echo(tabulate(rows, headers=headers, tablefmt="rounded_grid"))
@@ -19,7 +19,7 @@ from cloudoll.utils.common import check_port_open
19
19
 
20
20
  class CloudollFilter(DefaultFilter):
21
21
  def __init__(self, ignore_dirs: tuple = ()) -> None:
22
- self.ignore_dirs = self.ignore_dirs + tuple("logs")
22
+ self.ignore_dirs: tuple = self.ignore_dirs + tuple("logs")
23
23
  if ignore_dirs:
24
24
  self.ignore_dirs = self.ignore_dirs + ignore_dirs
25
25
 
@@ -112,7 +112,7 @@ def mian_app(tty_path, config, entry, env):
112
112
 
113
113
  async def create_main_app(config, entry, env):
114
114
  await check_port_open(config["server"]["port"])
115
- App = app.create(env=env, config=config, entry_model=entry)
115
+ App: Application = app.create(env=env, config=config, entry_model=entry)
116
116
  return web.AppRunner(App.app, shutdown_timeout=0.1)
117
117
 
118
118
 
@@ -1,8 +1,6 @@
1
1
  import asyncio
2
2
  from cloudoll.logging import warning
3
3
 
4
- EADDRINUSE: int
5
-
6
4
 
7
5
  class Object(dict):
8
6
  # __setattr__ = dict.__setitem__
@@ -46,7 +44,8 @@ async def check_port_open(port: int, delay: float = 1) -> None:
46
44
  asyncio.Protocol, host="0.0.0.0", port=port
47
45
  )
48
46
  except OSError as e:
49
- if e.errno != EADDRINUSE:
47
+ print(e.errno)
48
+ if e.errno != 48:
50
49
  raise
51
50
  warning("port %d is already in use, waiting %d...", port, i)
52
51
  await asyncio.sleep(delay)
@@ -157,7 +157,7 @@ class Application(object):
157
157
  def __init__(self):
158
158
  self._loop = None
159
159
  self.env = None
160
- self.app = None
160
+ self.app: web.Application = None
161
161
  self._route_table = web.RouteTableDef()
162
162
  self._middleware = []
163
163
  self.config = {}
@@ -1,28 +1,43 @@
1
1
  import aiohttp
2
2
  import asyncio
3
- from typing import Optional, Dict, Any, Union
3
+
4
+ # import ssl
5
+ from typing import Optional, Dict, Union, List, Any
6
+
7
+ JSONType = Union[Dict[str, Any], List[Any], str, int, float, bool, None]
4
8
 
5
9
 
6
10
  class AsyncRequest:
7
11
  def __init__(
8
12
  self,
9
- timeout: int = 30,
10
- max_retries: int = 3,
13
+ timeout: float = 30.0,
14
+ max_retries: int = 1,
11
15
  retry_delay: float = 1.0,
12
- session: Optional[aiohttp.ClientSession] = None,
16
+ keep_alive: bool = True,
17
+ use_cookies: bool = False,
18
+ proxy: Optional[str] = None,
19
+ # session: Optional[aiohttp.ClientSession] = None,
20
+ # connector: Optional[aiohttp.BaseConnector] = None,
21
+ # ssl: Union[bool, ssl.SSLContext] = True,
13
22
  ):
14
- """
15
- Asynchronous HTTP request client
16
-
17
- :param timeout: Request timeout(Second)
18
- :param max_retries: Maximum retry attempts
19
- :param retry_delay: Retry delay(Second)
20
- :param session: Reusable aiohttp session
21
- """
22
- self.timeout = aiohttp.ClientTimeout(total=timeout)
23
+ self.timeout = timeout
23
24
  self.max_retries = max_retries
24
25
  self.retry_delay = retry_delay
25
- self._session = session
26
+ # self.session = session
27
+ # self.connector = connector
28
+ self.use_cookies = use_cookies
29
+ self.keep_alive = keep_alive
30
+
31
+ self.session: aiohttp.ClientSession = aiohttp.ClientSession(
32
+ proxy=proxy,
33
+ connector=(
34
+ aiohttp.TCPConnector(keepalive_timeout=self.timeout)
35
+ if self.keep_alive
36
+ else None
37
+ ),
38
+ timeout=aiohttp.ClientTimeout(total=self.timeout),
39
+ cookie_jar=aiohttp.CookieJar() if self.use_cookies else None,
40
+ )
26
41
 
27
42
  async def request(
28
43
  self,
@@ -30,32 +45,19 @@ class AsyncRequest:
30
45
  url: str,
31
46
  params: Optional[Dict[str, Any]] = None,
32
47
  data: Optional[Union[Dict[str, Any], str, bytes]] = None,
33
- json_data: Optional[Any] = None,
48
+ json_data: Optional[JSONType] = None,
34
49
  headers: Optional[Dict[str, str]] = None,
35
50
  cookies: Optional[Dict[str, str]] = None,
36
51
  allow_redirects: bool = True,
37
52
  raise_for_status: bool = True,
38
- ) -> aiohttp.ClientResponse:
39
- """
40
- Perform asynchronous HTTP requests
41
-
42
- :param method: HTTP方法 (GET, POST, PUT, DELETE等)
43
- :param url: Request URL
44
- :param params: URL query parameters
45
- :param data: Request body data (Forms or raw data)
46
- :param json_data: JSON formatted request body data
47
- :param headers: Request headers
48
- :param cookies: Cookies
49
- :param allow_redirects: Whether to allow redirects
50
- :param raise_for_status: Whether to raise an exception for HTTP errors
51
- :return: aiohttp.ClientResponse
52
- """
53
- session = self._session or aiohttp.ClientSession(timeout=self.timeout)
53
+ proxy: Optional[str] = None,
54
+ # parse_json: bool = False,
55
+ ) -> Union[dict, str, aiohttp.ClientResponse]:
54
56
  last_exception = None
55
57
 
56
58
  for attempt in range(self.max_retries):
57
59
  try:
58
- async with session.request(
60
+ response = await self.session.request(
59
61
  method=method,
60
62
  url=url,
61
63
  params=params,
@@ -64,29 +66,30 @@ class AsyncRequest:
64
66
  headers=headers,
65
67
  cookies=cookies,
66
68
  allow_redirects=allow_redirects,
67
- ) as response:
68
- if raise_for_status:
69
- response.raise_for_status()
70
- return response
69
+ proxy=proxy,
70
+ )
71
+ return response
71
72
 
72
73
  except (aiohttp.ClientError, asyncio.TimeoutError) as e:
73
74
  last_exception = e
74
75
  if attempt < self.max_retries - 1:
75
76
  await asyncio.sleep(self.retry_delay * (attempt + 1))
76
77
  continue
78
+ # finally:
79
+ # if use_temp_session:
80
+ # await session.close()
77
81
 
78
- if self._session is None:
79
- await session.close()
80
-
81
- raise last_exception or RuntimeError("Request failed")
82
+ raise last_exception or RuntimeError(
83
+ f"Request failed after {self.max_retries} attempts"
84
+ )
82
85
 
83
86
  async def get(
84
87
  self,
85
88
  url: str,
86
89
  params: Optional[Dict[str, Any]] = None,
87
90
  headers: Optional[Dict[str, str]] = None,
88
- **kwargs
89
- ) -> aiohttp.ClientResponse:
91
+ **kwargs,
92
+ ) -> Union[dict, str, aiohttp.ClientResponse]:
90
93
  """Send a GET request"""
91
94
  return await self.request("GET", url, params=params, headers=headers, **kwargs)
92
95
 
@@ -96,8 +99,8 @@ class AsyncRequest:
96
99
  data: Optional[Union[Dict[str, Any], str, bytes]] = None,
97
100
  json_data: Optional[Any] = None,
98
101
  headers: Optional[Dict[str, str]] = None,
99
- **kwargs
100
- ) -> aiohttp.ClientResponse:
102
+ **kwargs,
103
+ ) -> Union[dict, str, aiohttp.ClientResponse]:
101
104
  """Send a POST request"""
102
105
  return await self.request(
103
106
  "POST", url, data=data, json_data=json_data, headers=headers, **kwargs
@@ -109,8 +112,8 @@ class AsyncRequest:
109
112
  data: Optional[Union[Dict[str, Any], str, bytes]] = None,
110
113
  json_data: Optional[Any] = None,
111
114
  headers: Optional[Dict[str, str]] = None,
112
- **kwargs
113
- ) -> aiohttp.ClientResponse:
115
+ **kwargs,
116
+ ) -> Union[dict, str, aiohttp.ClientResponse]:
114
117
  """Send a PUT request"""
115
118
  return await self.request(
116
119
  "PUT", url, data=data, json_data=json_data, headers=headers, **kwargs
@@ -118,15 +121,14 @@ class AsyncRequest:
118
121
 
119
122
  async def delete(
120
123
  self, url: str, headers: Optional[Dict[str, str]] = None, **kwargs
121
- ) -> aiohttp.ClientResponse:
124
+ ) -> Union[dict, str, aiohttp.ClientResponse]:
122
125
  """Send a DELETE request"""
123
126
  return await self.request("DELETE", url, headers=headers, **kwargs)
124
127
 
125
128
  async def close(self) -> None:
126
- """Close the aiohttp session if it exists """
127
- if self._session is not None:
128
- await self._session.close()
129
- self._session = None
129
+ """Close the aiohttp session if it exists"""
130
+ if self.session is not None:
131
+ await self.session.close()
130
132
 
131
133
  async def __aenter__(self):
132
134
  return self
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudoll
3
- Version: 3.0.0
3
+ Version: 3.0.2
4
4
  Summary: Assist in quickly creating distributable microservices based on aiohttp, with a focus on simplicity and ease of use.
5
- Home-page: https://gitee.com/chuchur/cloudoll-py
5
+ Home-page: https://github.com/smallerqiu/cloudoll-py
6
6
  Author: Qiu
7
7
  Author-email: Qiu <smallerqiu@gmail.com>
8
8
  License-Expression: MIT
9
- Project-URL: Homepage, https://gitee.com/chuchur/cloudoll-py
10
- Project-URL: Repository, https://gitee.com/chuchur/cloudoll-py
9
+ Project-URL: Homepage, https://github.com/smallerqiu/cloudoll-py
10
+ Project-URL: Repository, https://github.com/smallerqiu/cloudoll-py
11
11
  Keywords: Microservices,aiohttp,cloudoll
12
12
  Classifier: Programming Language :: Python :: 3
13
13
  Classifier: Programming Language :: Python :: 3.6
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "cloudoll"
7
- version = "3.0.0"
7
+ version = "3.0.2"
8
8
  description = "Assist in quickly creating distributable microservices based on aiohttp, with a focus on simplicity and ease of use."
9
9
  authors = [
10
10
  {name = "Qiu", email = "smallerqiu@gmail.com"},
@@ -39,8 +39,8 @@ dependencies = [
39
39
  ]
40
40
 
41
41
  [project.urls]
42
- Homepage = "https://gitee.com/chuchur/cloudoll-py"
43
- Repository = "https://gitee.com/chuchur/cloudoll-py"
42
+ Homepage = "https://github.com/smallerqiu/cloudoll-py"
43
+ Repository = "https://github.com/smallerqiu/cloudoll-py"
44
44
 
45
45
  [project.scripts]
46
46
  cloudoll = "cloudoll.cli:cli"
@@ -6,7 +6,7 @@ long_description = file: README.md
6
6
  long_description_content_type = text/markdown
7
7
  author = Qiu
8
8
  author_email = smallerqiu@gmail.com
9
- url = https://gitee.com/chuchur/cloudoll-py
9
+ url = https://github.com/smallerqiu/cloudoll-py
10
10
 
11
11
  [options]
12
12
  packages = find:
@@ -1 +0,0 @@
1
- __version__ = "3.0.0"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes