bafser 1.0.0__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 (51) hide show
  1. bafser-1.0.0/.gitignore +4 -0
  2. bafser-1.0.0/LICENSE +21 -0
  3. bafser-1.0.0/PKG-INFO +197 -0
  4. bafser-1.0.0/README.md +184 -0
  5. bafser-1.0.0/pyproject.toml +30 -0
  6. bafser-1.0.0/src/bafser/__init__.py +48 -0
  7. bafser-1.0.0/src/bafser/app.py +237 -0
  8. bafser-1.0.0/src/bafser/bfs_config.example.py +16 -0
  9. bafser-1.0.0/src/bafser/data/__init__.py +0 -0
  10. bafser-1.0.0/src/bafser/data/_roles.py +39 -0
  11. bafser-1.0.0/src/bafser/data/_tables.py +5 -0
  12. bafser-1.0.0/src/bafser/data/image.py +109 -0
  13. bafser-1.0.0/src/bafser/data/log.py +154 -0
  14. bafser-1.0.0/src/bafser/data/operation.py +38 -0
  15. bafser-1.0.0/src/bafser/data/permission.py +18 -0
  16. bafser-1.0.0/src/bafser/data/role.py +128 -0
  17. bafser-1.0.0/src/bafser/data/user.py +181 -0
  18. bafser-1.0.0/src/bafser/data/user_role.py +50 -0
  19. bafser-1.0.0/src/bafser/db_session.py +69 -0
  20. bafser-1.0.0/src/bafser/logger.py +213 -0
  21. bafser-1.0.0/src/bafser/readme.md +184 -0
  22. bafser-1.0.0/src/bafser/scripts/add_user.py +39 -0
  23. bafser-1.0.0/src/bafser/scripts/add_user_role.py +43 -0
  24. bafser-1.0.0/src/bafser/scripts/change_user_password.py +32 -0
  25. bafser-1.0.0/src/bafser/scripts/init_db_values.py +32 -0
  26. bafser-1.0.0/src/bafser/scripts/remove_user_role.py +43 -0
  27. bafser-1.0.0/src/bafser/scripts/update_roles_permissions.py +24 -0
  28. bafser-1.0.0/src/bafser/table_base.py +69 -0
  29. bafser-1.0.0/src/bafser/utils/__init__.py +24 -0
  30. bafser-1.0.0/src/bafser/utils/create_file_response.py +13 -0
  31. bafser-1.0.0/src/bafser/utils/create_folder_for_file.py +7 -0
  32. bafser-1.0.0/src/bafser/utils/get_all_vars.py +10 -0
  33. bafser-1.0.0/src/bafser/utils/get_datetime_now.py +5 -0
  34. bafser-1.0.0/src/bafser/utils/get_json.py +13 -0
  35. bafser-1.0.0/src/bafser/utils/get_json_list_from_req.py +14 -0
  36. bafser-1.0.0/src/bafser/utils/get_json_values.py +28 -0
  37. bafser-1.0.0/src/bafser/utils/get_json_values_from_req.py +20 -0
  38. bafser-1.0.0/src/bafser/utils/get_secret_key.py +21 -0
  39. bafser-1.0.0/src/bafser/utils/import_all_tables.py +18 -0
  40. bafser-1.0.0/src/bafser/utils/ip_to_emoji.py +26 -0
  41. bafser-1.0.0/src/bafser/utils/jsonify_list.py +5 -0
  42. bafser-1.0.0/src/bafser/utils/parse_date.py +10 -0
  43. bafser-1.0.0/src/bafser/utils/permission_required.py +52 -0
  44. bafser-1.0.0/src/bafser/utils/randstr.py +8 -0
  45. bafser-1.0.0/src/bafser/utils/register_blueprints.py +12 -0
  46. bafser-1.0.0/src/bafser/utils/response_msg.py +7 -0
  47. bafser-1.0.0/src/bafser/utils/response_not_found.py +5 -0
  48. bafser-1.0.0/src/bafser/utils/use_db_session.py +17 -0
  49. bafser-1.0.0/src/bafser/utils/use_user.py +37 -0
  50. bafser-1.0.0/src/bafser/utils/use_userId.py +43 -0
  51. bafser-1.0.0/src/bafser/utils/use_user_optional.py +35 -0
@@ -0,0 +1,4 @@
1
+ .venv/
2
+ __pycache__/
3
+ build/
4
+ dist/
bafser-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 MixelTe
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
bafser-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,197 @@
1
+ Metadata-Version: 2.4
2
+ Name: bafser
3
+ Version: 1.0.0
4
+ Summary: Base for flask server
5
+ Project-URL: Homepage, https://github.com/MixelTe/bafser
6
+ Project-URL: Issues, https://github.com/MixelTe/bafser/issues
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Programming Language :: Python :: 3
11
+ Requires-Python: ==3.9.*
12
+ Description-Content-Type: text/markdown
13
+
14
+ # base for flask server by Mixel Te
15
+
16
+ ## requirements.txt
17
+ Python 3.9.5
18
+ ```
19
+ flask==2.1.2
20
+ sqlalchemy==2.0.19
21
+ werkzeug==2.3.6
22
+ sqlalchemy_serializer==1.4.1
23
+ pyjwt<2.10
24
+ flask_jwt_extended==4.5.2
25
+ PyMySQL==1.1.1
26
+ ```
27
+
28
+ ## usage
29
+ copy `bfs_config.example.py` to project root as `bfs_config.py`
30
+
31
+ create files:
32
+
33
+ .gitignore
34
+ ```
35
+ .venv
36
+ *__pycache__*
37
+ logs/
38
+ db/
39
+ /images
40
+ /fonts
41
+ secret_key_jwt.txt
42
+ ```
43
+
44
+ ```py
45
+ # data/_operations.py
46
+ from bfs import OperationsBase
47
+
48
+
49
+ class Operations(OperationsBase):
50
+ oper_id = ("oper_id", "Operation description")
51
+ oper_id2 = ("oper_id2", "Operation description")
52
+ ...
53
+ ```
54
+ ```py
55
+ # data/_roles.py
56
+ from bfs import RolesBase
57
+ from data._operations import Operations
58
+
59
+
60
+ class Roles(RolesBase):
61
+ role_name = 2
62
+ role_name2 = 3
63
+ ...
64
+
65
+
66
+ Roles.ROLES = {
67
+ Roles.role_name: {
68
+ "name": "Role name",
69
+ "operations": [
70
+ Operations.oper_id,
71
+ Operations.oper_id2,
72
+ ]
73
+ },
74
+ Roles.role_name2: {
75
+ "name": "Role name 2",
76
+ "operations": [
77
+ Operations.oper_id,
78
+ ]
79
+ },
80
+ }
81
+ ```
82
+ ```py
83
+ # data/_tables.py
84
+ from bfs import TablesBase
85
+
86
+
87
+ class Tables(TablesBase):
88
+ TableName = "TableName"
89
+ AnotherTableName = "AnotherTableName"
90
+ ```
91
+ ```py
92
+ # data/some_table.py
93
+ from bfs import SqlAlchemyBase, ObjMixin
94
+ from data._tables import Tables
95
+
96
+
97
+ class SomeTable(SqlAlchemyBase, ObjMixin):
98
+ __tablename__ = Tables.SomeTable
99
+ ...
100
+
101
+ ```
102
+ * `IdMixin` adds `id` column
103
+ * `ObjMixin` adds `id` and `deleted` columns
104
+
105
+ ```py
106
+ # main.py
107
+ import sys
108
+ from bfs import AppConfig, create_app
109
+ from scripts.init_dev_values import init_dev_values
110
+
111
+
112
+ app, run = create_app(__name__, AppConfig(
113
+ MESSAGE_TO_FRONTEND="",
114
+ DEV_MODE="dev" in sys.argv,
115
+ DELAY_MODE="delay" in sys.argv,
116
+ )
117
+ .add_data_folder("FONTS_FOLDER", "fonts")
118
+ .add_secret_key("API_SECRET_KEY", "secret_key_api.txt")
119
+ )
120
+
121
+ run(__name__ == "__main__", lambda: init_dev_values(True), port=5001)
122
+ ```
123
+
124
+ ### modifying User and Image
125
+ User:
126
+ ```py
127
+ from sqlalchemy import Column, String
128
+ from sqlalchemy.orm import Session
129
+
130
+ from bfs import UserBase
131
+ from data._roles import Roles
132
+
133
+
134
+ class User(UserBase):
135
+ newColumn = Column(String)
136
+
137
+ @classmethod
138
+ def new(cls, creator: "User", login: str, password: str, name: str, roles: list[int], newColumn: str, db_sess: Session = None) -> "User":
139
+ return super().new(creator, login, password, name, roles, db_sess, newColumn=newColumn)
140
+
141
+ @staticmethod
142
+ def _new(db_sess: Session, user_kwargs: dict, newColumn: str):
143
+ user = User(**user_kwargs, newColumn=newColumn)
144
+ changes = [("newColumn", newColumn)]
145
+ return user, changes
146
+
147
+ @staticmethod
148
+ def create_admin(db_sess: Session):
149
+ fake_creator = User.get_fake_system()
150
+ return User.new(fake_creator, "admin", "admin", "Админ", [Roles.admin], "newColumnValue", db_sess=db_sess)
151
+
152
+ ```
153
+ Image:
154
+ ```py
155
+ # to use relationship you must name the file something other than image.py
156
+ # img.py for the example, because of the way sqlalchemy finds classes
157
+ image = orm.relationship("data.img.Image")
158
+ ```
159
+ ```py
160
+ from typing import TypedDict, Union
161
+ from sqlalchemy import Column, String
162
+
163
+ from bfs import Image as ImageBase, get_json_values
164
+ from data.user import User
165
+
166
+
167
+ class ImageJson(TypedDict):
168
+ data: str
169
+ name: str
170
+ newColumnData: str
171
+
172
+
173
+ TError = str
174
+
175
+
176
+ class Image(ImageBase):
177
+ newColumn = Column(String)
178
+
179
+ @classmethod
180
+ def new(cls, creator: User, json: ImageJson) -> Union[tuple[None, TError], tuple["Image", None]]:
181
+ return super().new(creator, json)
182
+
183
+ @staticmethod
184
+ def _new(creator: User, json: ImageJson, image_kwargs):
185
+ newColumnData, values_error = get_json_values(json, ("newColumnData", None))
186
+ if values_error:
187
+ return None, None, values_error
188
+
189
+ img = Image(**image_kwargs, newColumn=newColumnData)
190
+ changes = [("newColumn", newColumnData)]
191
+ return img, changes, None
192
+ ```
193
+
194
+ #### csv header for requests log
195
+ ```csv
196
+ reqid;ip;uid;asctime;method;url;level;message;code;json
197
+ ```
bafser-1.0.0/README.md ADDED
@@ -0,0 +1,184 @@
1
+ # base for flask server by Mixel Te
2
+
3
+ ## requirements.txt
4
+ Python 3.9.5
5
+ ```
6
+ flask==2.1.2
7
+ sqlalchemy==2.0.19
8
+ werkzeug==2.3.6
9
+ sqlalchemy_serializer==1.4.1
10
+ pyjwt<2.10
11
+ flask_jwt_extended==4.5.2
12
+ PyMySQL==1.1.1
13
+ ```
14
+
15
+ ## usage
16
+ copy `bfs_config.example.py` to project root as `bfs_config.py`
17
+
18
+ create files:
19
+
20
+ .gitignore
21
+ ```
22
+ .venv
23
+ *__pycache__*
24
+ logs/
25
+ db/
26
+ /images
27
+ /fonts
28
+ secret_key_jwt.txt
29
+ ```
30
+
31
+ ```py
32
+ # data/_operations.py
33
+ from bfs import OperationsBase
34
+
35
+
36
+ class Operations(OperationsBase):
37
+ oper_id = ("oper_id", "Operation description")
38
+ oper_id2 = ("oper_id2", "Operation description")
39
+ ...
40
+ ```
41
+ ```py
42
+ # data/_roles.py
43
+ from bfs import RolesBase
44
+ from data._operations import Operations
45
+
46
+
47
+ class Roles(RolesBase):
48
+ role_name = 2
49
+ role_name2 = 3
50
+ ...
51
+
52
+
53
+ Roles.ROLES = {
54
+ Roles.role_name: {
55
+ "name": "Role name",
56
+ "operations": [
57
+ Operations.oper_id,
58
+ Operations.oper_id2,
59
+ ]
60
+ },
61
+ Roles.role_name2: {
62
+ "name": "Role name 2",
63
+ "operations": [
64
+ Operations.oper_id,
65
+ ]
66
+ },
67
+ }
68
+ ```
69
+ ```py
70
+ # data/_tables.py
71
+ from bfs import TablesBase
72
+
73
+
74
+ class Tables(TablesBase):
75
+ TableName = "TableName"
76
+ AnotherTableName = "AnotherTableName"
77
+ ```
78
+ ```py
79
+ # data/some_table.py
80
+ from bfs import SqlAlchemyBase, ObjMixin
81
+ from data._tables import Tables
82
+
83
+
84
+ class SomeTable(SqlAlchemyBase, ObjMixin):
85
+ __tablename__ = Tables.SomeTable
86
+ ...
87
+
88
+ ```
89
+ * `IdMixin` adds `id` column
90
+ * `ObjMixin` adds `id` and `deleted` columns
91
+
92
+ ```py
93
+ # main.py
94
+ import sys
95
+ from bfs import AppConfig, create_app
96
+ from scripts.init_dev_values import init_dev_values
97
+
98
+
99
+ app, run = create_app(__name__, AppConfig(
100
+ MESSAGE_TO_FRONTEND="",
101
+ DEV_MODE="dev" in sys.argv,
102
+ DELAY_MODE="delay" in sys.argv,
103
+ )
104
+ .add_data_folder("FONTS_FOLDER", "fonts")
105
+ .add_secret_key("API_SECRET_KEY", "secret_key_api.txt")
106
+ )
107
+
108
+ run(__name__ == "__main__", lambda: init_dev_values(True), port=5001)
109
+ ```
110
+
111
+ ### modifying User and Image
112
+ User:
113
+ ```py
114
+ from sqlalchemy import Column, String
115
+ from sqlalchemy.orm import Session
116
+
117
+ from bfs import UserBase
118
+ from data._roles import Roles
119
+
120
+
121
+ class User(UserBase):
122
+ newColumn = Column(String)
123
+
124
+ @classmethod
125
+ def new(cls, creator: "User", login: str, password: str, name: str, roles: list[int], newColumn: str, db_sess: Session = None) -> "User":
126
+ return super().new(creator, login, password, name, roles, db_sess, newColumn=newColumn)
127
+
128
+ @staticmethod
129
+ def _new(db_sess: Session, user_kwargs: dict, newColumn: str):
130
+ user = User(**user_kwargs, newColumn=newColumn)
131
+ changes = [("newColumn", newColumn)]
132
+ return user, changes
133
+
134
+ @staticmethod
135
+ def create_admin(db_sess: Session):
136
+ fake_creator = User.get_fake_system()
137
+ return User.new(fake_creator, "admin", "admin", "Админ", [Roles.admin], "newColumnValue", db_sess=db_sess)
138
+
139
+ ```
140
+ Image:
141
+ ```py
142
+ # to use relationship you must name the file something other than image.py
143
+ # img.py for the example, because of the way sqlalchemy finds classes
144
+ image = orm.relationship("data.img.Image")
145
+ ```
146
+ ```py
147
+ from typing import TypedDict, Union
148
+ from sqlalchemy import Column, String
149
+
150
+ from bfs import Image as ImageBase, get_json_values
151
+ from data.user import User
152
+
153
+
154
+ class ImageJson(TypedDict):
155
+ data: str
156
+ name: str
157
+ newColumnData: str
158
+
159
+
160
+ TError = str
161
+
162
+
163
+ class Image(ImageBase):
164
+ newColumn = Column(String)
165
+
166
+ @classmethod
167
+ def new(cls, creator: User, json: ImageJson) -> Union[tuple[None, TError], tuple["Image", None]]:
168
+ return super().new(creator, json)
169
+
170
+ @staticmethod
171
+ def _new(creator: User, json: ImageJson, image_kwargs):
172
+ newColumnData, values_error = get_json_values(json, ("newColumnData", None))
173
+ if values_error:
174
+ return None, None, values_error
175
+
176
+ img = Image(**image_kwargs, newColumn=newColumnData)
177
+ changes = [("newColumn", newColumnData)]
178
+ return img, changes, None
179
+ ```
180
+
181
+ #### csv header for requests log
182
+ ```csv
183
+ reqid;ip;uid;asctime;method;url;level;message;code;json
184
+ ```
@@ -0,0 +1,30 @@
1
+ [build-system]
2
+ requires = [
3
+ "hatchling >= 1.26",
4
+ "flask == 2.1.2",
5
+ "sqlalchemy == 2.0.19",
6
+ "werkzeug == 2.3.6",
7
+ "sqlalchemy_serializer == 1.4.1",
8
+ "pyjwt < 2.10",
9
+ "flask_jwt_extended == 4.5.2",
10
+ "PyMySQL == 1.1.1",
11
+ ]
12
+ build-backend = "hatchling.build"
13
+
14
+ [project]
15
+ name = "bafser"
16
+ version = "1.0.0"
17
+ authors = []
18
+ description = "Base for flask server"
19
+ readme = "README.md"
20
+ requires-python = "==3.9.*"
21
+ classifiers = [
22
+ "Programming Language :: Python :: 3",
23
+ "Operating System :: OS Independent",
24
+ ]
25
+ license = "MIT"
26
+ license-files = ["LICEN[CS]E*"]
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/MixelTe/bafser"
30
+ Issues = "https://github.com/MixelTe/bafser/issues"
@@ -0,0 +1,48 @@
1
+ # base for flask server by Mixel Te
2
+
3
+ from .utils.response_msg import response_msg
4
+ from .utils.get_json_values import get_json_values
5
+
6
+ from .utils.create_file_response import create_file_response
7
+ from .utils.create_folder_for_file import create_folder_for_file
8
+ from .utils.get_datetime_now import get_datetime_now
9
+ from .utils.get_json import get_json
10
+ from .utils.get_json_list_from_req import get_json_list_from_req
11
+ from .utils.get_json_values_from_req import get_json_values_from_req
12
+ from .utils.ip_to_emoji import ip_to_emoji, emoji_to_ip
13
+ from .utils.jsonify_list import jsonify_list
14
+ from .utils.parse_date import parse_date
15
+ from .utils.permission_required import create_permission_required_decorator
16
+ from .utils.permission_required import permission_required, permission_required_any
17
+ from .utils.randstr import randstr
18
+ from .utils.response_not_found import response_not_found
19
+ from .utils.use_db_session import use_db_session
20
+ from .utils.use_userId import use_userId, use_userId_optional
21
+ from .utils.use_user import use_user
22
+ from .utils.use_user_optional import use_user_optional
23
+
24
+ from .app import AppConfig, create_app
25
+ from .logger import get_logger_frontend, log_frontend_error, get_log_fpath, add_file_logger, ParametrizedLogger
26
+
27
+ from .db_session import SqlAlchemyBase
28
+ from .table_base import TableBase, IdMixin, ObjMixin
29
+ from .data._tables import TablesBase
30
+ from .data._roles import RolesBase
31
+ from .data.operation import OperationsBase
32
+ from .data.user_role import UserRole
33
+ from .data.user import UserBase
34
+ from .data.log import Log
35
+ from .data.role import Role
36
+ from .data.image import Image
37
+
38
+ from .scripts.init_db_values import init_db_values
39
+
40
+
41
+ class M:
42
+ DELETE = "DELETE"
43
+ GET = "GET"
44
+ HEAD = "HEAD"
45
+ OPTIONS = "OPTIONS"
46
+ PATCH = "PATCH"
47
+ POST = "POST"
48
+ PUT = "PUT"