renus 2.7.2__tar.gz → 2.7.4__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.
- {renus-2.7.2 → renus-2.7.4}/LICENSE +1 -1
- {renus-2.7.2/renus.egg-info → renus-2.7.4}/PKG-INFO +2 -2
- renus-2.7.4/README.md +135 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/cache.py +85 -32
- {renus-2.7.2 → renus-2.7.4}/renus/core/model.py +4 -2
- {renus-2.7.2 → renus-2.7.4}/renus/core/serialize.py +2 -4
- {renus-2.7.2 → renus-2.7.4/renus.egg-info}/PKG-INFO +2 -2
- {renus-2.7.2 → renus-2.7.4}/setup.py +2 -2
- renus-2.7.2/README.md +0 -1
- {renus-2.7.2 → renus-2.7.4}/MANIFEST.in +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/__init__.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/__main__.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/app.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/commands/__init__.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/commands/app/__init__.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/commands/app/run.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/commands/app/temp.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/commands/copy/__init__.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/commands/copy/run.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/commands/db/__init__.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/commands/db/run.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/commands/extension/__init__.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/commands/extension/build.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/commands/extension/remove.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/commands/extension/run.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/commands/help.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/commands/run.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/__init__.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/concurrency.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/config.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/cprint.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/datastructures.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/exception.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/formparsers.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/injection.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/log.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/middleware.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/request.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/response.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/routing.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/schedule.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/status.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/validation/__init__.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/validation/rules.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/validation/validate.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/core/websockets.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/util/__init__.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus/util/helper.py +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus.egg-info/SOURCES.txt +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus.egg-info/dependency_links.txt +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus.egg-info/entry_points.txt +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus.egg-info/requires.txt +0 -0
- {renus-2.7.2 → renus-2.7.4}/renus.egg-info/top_level.txt +0 -0
- {renus-2.7.2 → renus-2.7.4}/setup.cfg +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: renus
|
|
3
|
-
Version: 2.7.
|
|
3
|
+
Version: 2.7.4
|
|
4
4
|
Summary: Renus Core Framework
|
|
5
|
-
Home-page: https://github.com/
|
|
5
|
+
Home-page: https://github.com/kak-smko/renus
|
|
6
6
|
Author: Smko Bayazidi
|
|
7
7
|
Author-email: ba.smko@gmail.com
|
|
8
8
|
License: BSD
|
renus-2.7.4/README.md
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
|
|
2
|
+
# Renus
|
|
3
|
+
|
|
4
|
+
**Renus** is a lightweight ASGI framework/toolkit, which is ideal for building async web services in Python. It is production-ready and designed for large-scale projects while maintaining a lightweight footprint and high performance.
|
|
5
|
+
|
|
6
|
+
## ✨ Features
|
|
7
|
+
|
|
8
|
+
- 🚀 **High Performance**: Great overall performance against independent benchmarks.
|
|
9
|
+
- 🪶 **Lightweight**: Low-complexity HTTP web framework with few hard dependencies.
|
|
10
|
+
- 🔄 **Async Support**: Fully compatible with `asyncio` and `trio` backends.
|
|
11
|
+
- 🔌 **WebSocket Support**: Built-in support for WebSockets.
|
|
12
|
+
- 🛠️ **Background Tasks**: Handle in-process background tasks easily.
|
|
13
|
+
- 🔄 **Lifespan Events**: Manage startup and shutdown events for resource management.
|
|
14
|
+
- 📦 **Built-in Utilities**: CORS, GZip, Static Files, Streaming responses, Caching, Cryptography, Scheduling, and more.
|
|
15
|
+
- ✅ **Reliable**: 100% test coverage.
|
|
16
|
+
- 📝 **Type Safe**: 100% type annotated codebase.
|
|
17
|
+
|
|
18
|
+
## 📦 Installation
|
|
19
|
+
|
|
20
|
+
Install Renus using pip:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install renus
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 🚀 Quick Start
|
|
27
|
+
|
|
28
|
+
Here is a simple example to get you started with Renus:
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from renus.app import App
|
|
32
|
+
from renus.core.response import TextResponse, JsonResponse
|
|
33
|
+
from renus.core.routing import Router
|
|
34
|
+
|
|
35
|
+
# 1. Define route handlers
|
|
36
|
+
def home():
|
|
37
|
+
return TextResponse('Hello, world!')
|
|
38
|
+
|
|
39
|
+
def user(username):
|
|
40
|
+
return JsonResponse({'name': username})
|
|
41
|
+
|
|
42
|
+
async def websocket(ws):
|
|
43
|
+
await ws.accept()
|
|
44
|
+
await ws.send_text('Hello, world!')
|
|
45
|
+
await ws.close()
|
|
46
|
+
|
|
47
|
+
# 2. Define lifespan events (startup and shutdown)
|
|
48
|
+
async def lifespan(app):
|
|
49
|
+
print('Startup', app)
|
|
50
|
+
yield
|
|
51
|
+
print('Shutdown')
|
|
52
|
+
|
|
53
|
+
# 3. Setup routing
|
|
54
|
+
r = Router()
|
|
55
|
+
r.get('/', func=home)
|
|
56
|
+
r.get('/user/{username}', func=user)
|
|
57
|
+
r.ws('/ws', func=websocket)
|
|
58
|
+
|
|
59
|
+
# 4. Initialize the app
|
|
60
|
+
app = App(lifespan=lifespan)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Running the Application
|
|
64
|
+
|
|
65
|
+
You can run your application using an ASGI server like `uvicorn`:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
# main.py
|
|
69
|
+
import uvicorn
|
|
70
|
+
from renus.app import App
|
|
71
|
+
import routes.index # Import your routes module
|
|
72
|
+
|
|
73
|
+
app = App()
|
|
74
|
+
|
|
75
|
+
if __name__ == "__main__":
|
|
76
|
+
uvicorn.run(
|
|
77
|
+
"main:app",
|
|
78
|
+
host="127.0.0.1",
|
|
79
|
+
port=4000,
|
|
80
|
+
reload=True,
|
|
81
|
+
log_level="info",
|
|
82
|
+
headers=[
|
|
83
|
+
("X-Frame-Options", 'DENY'),
|
|
84
|
+
("Access-Control-Allow-Headers", '*'),
|
|
85
|
+
("Access-Control-Allow-Origin", '*')
|
|
86
|
+
]
|
|
87
|
+
)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Run it with:
|
|
91
|
+
```bash
|
|
92
|
+
python main.py
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## 📚 Documentation
|
|
96
|
+
|
|
97
|
+
For full documentation, advanced features, and API references, please visit the official documentation:
|
|
98
|
+
👉 **[Renus Documentation](https://codenus.com/en/renus)**
|
|
99
|
+
|
|
100
|
+
### Advanced Features
|
|
101
|
+
Renus comes packed with advanced features out of the box to help you build complex applications:
|
|
102
|
+
- **Caching**: Efficient data caching mechanisms.
|
|
103
|
+
- **Lifespan**: Manage application lifecycle events.
|
|
104
|
+
- **Cryptography**: Built-in cryptographic utilities.
|
|
105
|
+
- **Background Tasks**: Handle long-running tasks in the background.
|
|
106
|
+
- **Dependency Injection**: Powerful injection system.
|
|
107
|
+
- **Logging**: Integrated logging system.
|
|
108
|
+
- **Scheduling**: Schedule tasks to run at specific intervals.
|
|
109
|
+
- **Thread Pool**: Manage concurrent operations efficiently.
|
|
110
|
+
|
|
111
|
+
## 🤝 Contributing
|
|
112
|
+
|
|
113
|
+
Thank you for your interest in contributing to the Renus framework! We welcome all contributions from the community, whether they're bug reports, feature requests, documentation improvements, or code contributions.
|
|
114
|
+
|
|
115
|
+
### Coding Standards
|
|
116
|
+
- Follow **PEP 8** style guidelines.
|
|
117
|
+
- Use **type hints** for all new code (PEP 484).
|
|
118
|
+
- Keep lines under **88 characters** (Black's default line length).
|
|
119
|
+
|
|
120
|
+
### Testing
|
|
121
|
+
- Write unit tests for all new features using `pytest`.
|
|
122
|
+
- Include docstrings for all public methods and classes.
|
|
123
|
+
|
|
124
|
+
### Issue Reporting
|
|
125
|
+
When reporting bugs or requesting features:
|
|
126
|
+
- Check existing issues to avoid duplicates.
|
|
127
|
+
- Provide detailed reproduction steps for bugs.
|
|
128
|
+
- Include Python version, OS, and framework version.
|
|
129
|
+
- For feature requests, explain the use case and benefits.
|
|
130
|
+
|
|
131
|
+
Please read our [Contributing Guidelines](https://codenus.com/en/renus/3) for more details.
|
|
132
|
+
|
|
133
|
+
## 📄 License
|
|
134
|
+
|
|
135
|
+
*BSD 3-Clause License*
|
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import threading
|
|
2
3
|
import pickle
|
|
3
|
-
from datetime import datetime, timedelta
|
|
4
|
+
from datetime import UTC, datetime, timedelta
|
|
4
5
|
from hashlib import sha3_256
|
|
5
6
|
|
|
6
7
|
from renus.core.config import Config
|
|
7
8
|
from renus.core.log import Log
|
|
8
9
|
from renus.util.helper import encode64
|
|
9
10
|
|
|
11
|
+
try:
|
|
12
|
+
import fcntl
|
|
13
|
+
except ImportError: # Windows has no fcntl module
|
|
14
|
+
fcntl = None
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
import msvcrt
|
|
18
|
+
except ImportError: # non-Windows has no msvcrt module
|
|
19
|
+
msvcrt = None
|
|
20
|
+
|
|
10
21
|
try:
|
|
11
22
|
import redis
|
|
12
23
|
rds = redis.Redis()
|
|
@@ -17,11 +28,32 @@ class Cache:
|
|
|
17
28
|
depth = 1
|
|
18
29
|
folder_path = 'cache'
|
|
19
30
|
typ = Config('app').get('cacheDriver', 'file')
|
|
31
|
+
_lock = threading.RLock()
|
|
20
32
|
if typ=='redis':
|
|
21
33
|
assert rds is not None, "'redis' must be installed for Cache"
|
|
22
34
|
rd=rds
|
|
23
35
|
else:
|
|
24
36
|
rd=None
|
|
37
|
+
|
|
38
|
+
def _lock_file(self, file):
|
|
39
|
+
"""Acquire an exclusive lock on an open file (cross-platform)."""
|
|
40
|
+
if fcntl is not None:
|
|
41
|
+
fcntl.flock(file.fileno(), fcntl.LOCK_EX)
|
|
42
|
+
else: # Windows
|
|
43
|
+
file.seek(0)
|
|
44
|
+
msvcrt.locking(file.fileno(), msvcrt.LK_LOCK, 1)
|
|
45
|
+
|
|
46
|
+
def _unlock_file(self, file):
|
|
47
|
+
"""Release the lock on an open file (cross-platform)."""
|
|
48
|
+
if fcntl is not None:
|
|
49
|
+
fcntl.flock(file.fileno(), fcntl.LOCK_UN)
|
|
50
|
+
else: # Windows
|
|
51
|
+
file.seek(0)
|
|
52
|
+
try:
|
|
53
|
+
msvcrt.locking(file.fileno(), msvcrt.LK_UNLCK, 1)
|
|
54
|
+
except OSError:
|
|
55
|
+
pass
|
|
56
|
+
|
|
25
57
|
def __init__(self, prefix: str = '', use_hash=False) -> None:
|
|
26
58
|
self._prefix = prefix
|
|
27
59
|
self._use_hash = use_hash
|
|
@@ -33,36 +65,52 @@ class Cache:
|
|
|
33
65
|
:param value: value that save by key
|
|
34
66
|
:param expire: seconds to expire from now
|
|
35
67
|
"""
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
68
|
+
with self._lock:
|
|
69
|
+
if self.rd:
|
|
70
|
+
v=pickle.dumps(value,pickle.HIGHEST_PROTOCOL)
|
|
71
|
+
self.rd.set(self._prefix+key,v,expire)
|
|
72
|
+
return
|
|
73
|
+
expire = datetime.now(UTC) + timedelta(seconds=expire)
|
|
74
|
+
path = self._build_name(key, self.depth)
|
|
75
|
+
self._create_if_not_exist(path, value, expire)
|
|
76
|
+
|
|
77
|
+
def increment(self, key: str, value, expire: int = 60):
|
|
78
|
+
with self._lock:
|
|
79
|
+
if self.rd:
|
|
80
|
+
r=self.rd.get(self._prefix+key)
|
|
81
|
+
value= value if r is None else (pickle.loads(r)+value)
|
|
82
|
+
v=pickle.dumps(value,pickle.HIGHEST_PROTOCOL)
|
|
83
|
+
self.rd.set(self._prefix+key,v,expire)
|
|
84
|
+
return
|
|
85
|
+
expire = datetime.now(UTC) + timedelta(seconds=expire)
|
|
86
|
+
value=self.get(key,value-1)+1
|
|
87
|
+
path = self._build_name(key, self.depth)
|
|
88
|
+
self._create_if_not_exist(path, value, expire)
|
|
43
89
|
|
|
44
90
|
def get(self, key: str, default=None):
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
91
|
+
with self._lock:
|
|
92
|
+
if self.rd:
|
|
93
|
+
r=self.rd.get(self._prefix+key)
|
|
94
|
+
return default if r is None else pickle.loads(r)
|
|
95
|
+
path = self._build_name(key, self.depth)
|
|
96
|
+
return self._read_key(path, default)['value']
|
|
50
97
|
|
|
51
98
|
def expire(self, key, default=None):
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
99
|
+
with self._lock:
|
|
100
|
+
if self.rd:
|
|
101
|
+
return max(-1,self.rd.ttl(self._prefix+key))
|
|
102
|
+
path = self._build_name(key, self.depth)
|
|
103
|
+
t= self._read_key(path, default)['expire']
|
|
104
|
+
if t==-1:
|
|
105
|
+
return -1
|
|
106
|
+
return max(-1,int(t.timestamp()-datetime.now(UTC).timestamp()))
|
|
59
107
|
|
|
60
108
|
def delete(self, key):
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
109
|
+
with self._lock:
|
|
110
|
+
if self.rd:
|
|
111
|
+
return self.rd.delete(self._prefix+key)
|
|
112
|
+
path = self._build_name(key, self.depth)
|
|
113
|
+
return self._delete_file(f"storage/{self.folder_path}{path}")
|
|
66
114
|
|
|
67
115
|
def delete_expired(self):
|
|
68
116
|
filename = f'./storage/{self.folder_path}/'
|
|
@@ -86,7 +134,8 @@ class Cache:
|
|
|
86
134
|
except Exception as exc:
|
|
87
135
|
if n < 3:
|
|
88
136
|
return self._delete_file(path, n + 1)
|
|
89
|
-
|
|
137
|
+
else:
|
|
138
|
+
raise exc
|
|
90
139
|
return True
|
|
91
140
|
|
|
92
141
|
def _check_pass(self, line):
|
|
@@ -94,7 +143,7 @@ class Cache:
|
|
|
94
143
|
if len(res) < 2:
|
|
95
144
|
return True
|
|
96
145
|
expired, path = res
|
|
97
|
-
if (datetime.strptime(expired, '%Y-%m-%d %H:%M:%S').timestamp() < datetime.
|
|
146
|
+
if (datetime.strptime(expired, '%Y-%m-%d %H:%M:%S').timestamp() < datetime.now(UTC).timestamp()):
|
|
98
147
|
self._delete_file(f'storage/{self.folder_path}{path}')
|
|
99
148
|
return False
|
|
100
149
|
return True
|
|
@@ -105,11 +154,15 @@ class Cache:
|
|
|
105
154
|
try:
|
|
106
155
|
os.makedirs(os.path.dirname(filename), exist_ok=True)
|
|
107
156
|
with open(filename, 'wb') as output:
|
|
157
|
+
self._lock_file(output)
|
|
108
158
|
pickle.dump(expire, output, pickle.HIGHEST_PROTOCOL)
|
|
109
159
|
pickle.dump(value, output, pickle.HIGHEST_PROTOCOL)
|
|
110
|
-
|
|
160
|
+
self._unlock_file(output)
|
|
161
|
+
except Exception as e:
|
|
111
162
|
if n < 3:
|
|
112
163
|
self._create_if_not_exist(path, value, expire, n + 1)
|
|
164
|
+
else:
|
|
165
|
+
raise e
|
|
113
166
|
|
|
114
167
|
def _read_key(self, path, default=None, n=0):
|
|
115
168
|
filename = f'storage/{self.folder_path}{path}'
|
|
@@ -120,13 +173,13 @@ class Cache:
|
|
|
120
173
|
with open(filename, 'rb') as input:
|
|
121
174
|
expire = pickle.load(input)
|
|
122
175
|
value = pickle.load(input)
|
|
123
|
-
except Exception:
|
|
176
|
+
except Exception as e:
|
|
124
177
|
if n < 3:
|
|
125
178
|
return self._read_key(path, default, n + 1)
|
|
126
179
|
else:
|
|
127
|
-
|
|
180
|
+
raise e
|
|
128
181
|
|
|
129
|
-
if expire < datetime.now(
|
|
182
|
+
if expire.timestamp() < datetime.now(UTC).timestamp():
|
|
130
183
|
self._delete_file(filename)
|
|
131
184
|
return {'value': default, 'expire': -1}
|
|
132
185
|
return {'value': value, 'expire': expire}
|
|
@@ -177,4 +230,4 @@ def cache_func(time: int, prefix=''):
|
|
|
177
230
|
|
|
178
231
|
return wrapper
|
|
179
232
|
|
|
180
|
-
return dec
|
|
233
|
+
return dec
|
|
@@ -25,6 +25,9 @@ class ReModel:
|
|
|
25
25
|
elif isinstance(v, list):
|
|
26
26
|
v = self._process_list_items(v, field_type)
|
|
27
27
|
|
|
28
|
+
elif isinstance(v, datetime):
|
|
29
|
+
v = v.replace(tzinfo=timezone.utc)
|
|
30
|
+
|
|
28
31
|
setattr(self, k, v)
|
|
29
32
|
|
|
30
33
|
def _process_list_items(self, items, field_type):
|
|
@@ -366,8 +369,7 @@ class ModelBase(Generic[M]):
|
|
|
366
369
|
self.visible_fields = fields
|
|
367
370
|
return self
|
|
368
371
|
|
|
369
|
-
|
|
370
|
-
def boot_event(typ: str, old, new, session):
|
|
372
|
+
def boot_event(self,typ: str, old, new, session):
|
|
371
373
|
pass
|
|
372
374
|
|
|
373
375
|
@staticmethod
|
|
@@ -19,10 +19,8 @@ _DECIMAL_RE = re.compile(r'^-?\d+\.\d+$')
|
|
|
19
19
|
|
|
20
20
|
class jsonEncoder(json.JSONEncoder):
|
|
21
21
|
def default(self, o):
|
|
22
|
-
if isinstance(o, datetime.datetime):
|
|
23
|
-
return o.isoformat()
|
|
24
|
-
elif isinstance(o, datetime.date):
|
|
25
|
-
return o.isoformat() + 'T00:00:00Z'
|
|
22
|
+
if isinstance(o, (datetime.datetime, datetime.date)):
|
|
23
|
+
return o.isoformat()
|
|
26
24
|
elif isinstance(o, datetime.time):
|
|
27
25
|
r = o.isoformat()
|
|
28
26
|
if o.microsecond:
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: renus
|
|
3
|
-
Version: 2.7.
|
|
3
|
+
Version: 2.7.4
|
|
4
4
|
Summary: Renus Core Framework
|
|
5
|
-
Home-page: https://github.com/
|
|
5
|
+
Home-page: https://github.com/kak-smko/renus
|
|
6
6
|
Author: Smko Bayazidi
|
|
7
7
|
Author-email: ba.smko@gmail.com
|
|
8
8
|
License: BSD
|
|
@@ -2,9 +2,9 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name='renus',
|
|
5
|
-
version='2.7.
|
|
5
|
+
version='2.7.4',
|
|
6
6
|
description='Renus Core Framework',
|
|
7
|
-
url='https://github.com/
|
|
7
|
+
url='https://github.com/kak-smko/renus',
|
|
8
8
|
author='Smko Bayazidi',
|
|
9
9
|
author_email='ba.smko@gmail.com',
|
|
10
10
|
license='BSD',
|
renus-2.7.2/README.md
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# renus
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|