以下是文档信息的英文翻译:
# SA-Admin
Built on **Sanic** and leveraging the low-code framework **AMIS** for the frontend, SA-Admin simplifies frontend configuration for backend developers. With the power and lightweight nature of Sanic, it allows the backend manager to cover a wider range and achieve stronger functionality.
<img src="./Readme_image2.jpeg" alt="Readme_image1" style="zoom:25%;" />
<img src="./Readme_image3.png" alt="Readme_image1" style="zoom: 25%;" />
<img src="./Readme_image4.png" alt="Readme_image1" style="zoom:25%;" />
<img src="./Readme_image5.png" alt="Readme_image1" style="zoom:25%;" />
## Installation
Currently, there is no PyPI installation method available. You can clone the repository to your local environment and run it directly:
```python
python3 main.py
```
This will run and debug the application.
## Usage
To use SA-Admin, you need to have a basic understanding of Sanic or Flask. The framework is loosely based on Django and uses the Tortoise ORM, Jinja2 templates, and the frontend is built with Baidu's low-code framework, AMIS. AMIS is a convenient frontend framework, but it may require some time to familiarize yourself with. With it, you can control the frontend pages directly using JSON.
The code includes comments that you can refer to directly.
Specific usage:
1. Database Configuration
Database configuration is in the `main.py` file. If you need to switch to a different database, it is recommended to change it to MySQL or PostgreSQL because Tortoise supports asynchronous calls to these two databases directly, and the speed is really impressive.
```python
sa_config.TEST_DATABASE_URL = "sqlite://security_test_db.sqlite3"
```
2. Administrator Configuration
The initial password for the administrator is `SAdmin: SAdmin@123`. If you need to change it to your own password, please modify the parameter.
```python
sa_config.INITIAL_ADMIN_PASSWORD = "SAdmin@123" # Password used when creating the initial admin account
```
3. Configure the port and run the command
If necessary, you can change the port:
```python
app.run(
host="127.0.0.1",
port=22222,
workers=1,
debug=True,
auto_reload=True
)
```
Command Explanation:
- `workers=1`: This configures multi-task processing. However, in high-concurrency situations, due to the time-consuming switch between parallelism and asynchronous operations, it may be slower than a single instance. If needed, it is recommended to run multiple processes, but for now, it's better not to use `workers`. The choice depends on the actual scenario.
- `auto_reload=True`: This enables automatic reloading, which is very useful. You don't need to manually reload when you make code changes.
4. Design the frontend AMIS using an editor
For the first time using AMIS, take some time to read the AMIS documentation and understand how to use its components. I spent three days reading the documentation and getting familiar with various components.
You can directly use the AMIS online editor for interface design:
AMIS Editor:
[https://aisuda.github.io/amis-editor-demo/#/hello-world](https://aisuda.github.io/amis-editor-demo/#/hello-world)
<img src="./Readme_image6.png" alt="Readme_image1" style="zoom:25%;" />
5. Edit the frontend components and copy the code directly.
<img src="./Readme_image1.png" alt="Readme_image1" style="zoom:33%;" />
6. In the frontend code area, create a JSON file and paste the code.
7. Reference the newly created code in the main framework.
The main framework file is `./admin/pages/site.json`. To modify and reference it:
- Copy the entire main framework code.
- Go to the AMIS editor, create a new page, paste the code, and add a column according to your preferences.
- After editing, copy it back to `site.json`. Modify the `data` section to `"schema": {}`, which represents the content on the right side of the page.
You can also refer to my approach by saving the content of the newly added page as a separate JSON file and referencing it using `schemaApi`. Please refer to the `site.json` file for details.
Below is the JSON format for AMIS:
```json
{
"status": 0, // Required item in the response
"msg": "", // Required item in the response
"data": { // JSON representing the elements of the page
"pages": [
{ // Title layer for the navigation bar
"label": "Home",
"url": "/", // URL for this layer to facilitate navigation to other layers
"redirect": "/login" // What page to navigate to when the page initializes
},
{
"label": "Function Navigation", // This layer becomes the navigation bar
"children": [ // Column layer for the navigation bar
{
"label": "Login/Register",
"url": "login",
"schema": {} // The content here represents the content on the right side of the page
},
{
"label": "The number of items here represents the number of columns in the navigation bar",
"url": "login",
"schema": {} // The content here represents the content on the right side of the page
}
]
}
]
}
}
```
## Final Notes
This is a simple admin management interface. Please modify it according to your specific needs. With AMIS's features, it can roughly meet 90% of the requirements for admin management interfaces. For the remaining 10%, you may need some assistance from a frontend UI.
### Performance Notes
I tested it with ApiPost7, but the results were not as ideal as others have claimed. It might be due to the use of multiple workers. I wrote a 60-second asynchronous request test [./test/access_url.pu], and the approximate number of requests handled by one process is between 20,000 and 26,000, with no packet loss. The request rate is approximately 400 requests per second under Sanic's processing.
When I ran three processes simultaneously, the number of simultaneous requests dropped to about 14,000, so I'm not sure if it's due to resource limitations on my laptop (Macbook14 M1) or something else. If you have sufficient resources, you can use my code or improve it and conduct further testing. On average, it's a stress load of about 2,300 requests per second, which I think is quite good for an admin dashboard.
<img src="./Readme_image7.png" alt="Readme_image7" style="zoom:33%;" />
When I ran ten processes, the number of simultaneous requests remained at around 14,000, with no errors.
<img src="./Readme_image8.png" alt="Readme_image8" style="zoom:33%;" />
Raw data
{
"_id": null,
"home_page": "",
"name": "Sanic-SAdmin",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": "",
"keywords": "",
"author": "",
"author_email": "A-Corner <a.corner.vj@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/5c/1f/86991a95c1350248acef37f9e531d76c0640b65b76325befcf33b9443f72/Sanic_SAdmin-0.1.1.tar.gz",
"platform": null,
"description": "\u4ee5\u4e0b\u662f\u6587\u6863\u4fe1\u606f\u7684\u82f1\u6587\u7ffb\u8bd1\uff1a\n\n# SA-Admin\n\nBuilt on **Sanic** and leveraging the low-code framework **AMIS** for the frontend, SA-Admin simplifies frontend configuration for backend developers. With the power and lightweight nature of Sanic, it allows the backend manager to cover a wider range and achieve stronger functionality.\n\n<img src=\"./Readme_image2.jpeg\" alt=\"Readme_image1\" style=\"zoom:25%;\" />\n\n<img src=\"./Readme_image3.png\" alt=\"Readme_image1\" style=\"zoom: 25%;\" />\n\n<img src=\"./Readme_image4.png\" alt=\"Readme_image1\" style=\"zoom:25%;\" />\n\n<img src=\"./Readme_image5.png\" alt=\"Readme_image1\" style=\"zoom:25%;\" />\n\n## Installation\n\nCurrently, there is no PyPI installation method available. You can clone the repository to your local environment and run it directly:\n\n```python\npython3 main.py\n```\n\nThis will run and debug the application.\n\n## Usage\n\nTo use SA-Admin, you need to have a basic understanding of Sanic or Flask. The framework is loosely based on Django and uses the Tortoise ORM, Jinja2 templates, and the frontend is built with Baidu's low-code framework, AMIS. AMIS is a convenient frontend framework, but it may require some time to familiarize yourself with. With it, you can control the frontend pages directly using JSON.\n\nThe code includes comments that you can refer to directly.\n\nSpecific usage:\n\n1. Database Configuration\n\n Database configuration is in the `main.py` file. If you need to switch to a different database, it is recommended to change it to MySQL or PostgreSQL because Tortoise supports asynchronous calls to these two databases directly, and the speed is really impressive.\n\n ```python\n sa_config.TEST_DATABASE_URL = \"sqlite://security_test_db.sqlite3\"\n ```\n\n2. Administrator Configuration\n\n The initial password for the administrator is `SAdmin: SAdmin@123`. If you need to change it to your own password, please modify the parameter.\n\n ```python\n sa_config.INITIAL_ADMIN_PASSWORD = \"SAdmin@123\" # Password used when creating the initial admin account\n ```\n\n3. Configure the port and run the command\n\n If necessary, you can change the port:\n\n ```python\n app.run(\n host=\"127.0.0.1\",\n port=22222,\n workers=1,\n debug=True,\n auto_reload=True\n )\n ```\n\n Command Explanation:\n\n - `workers=1`: This configures multi-task processing. However, in high-concurrency situations, due to the time-consuming switch between parallelism and asynchronous operations, it may be slower than a single instance. If needed, it is recommended to run multiple processes, but for now, it's better not to use `workers`. The choice depends on the actual scenario.\n\n - `auto_reload=True`: This enables automatic reloading, which is very useful. You don't need to manually reload when you make code changes.\n\n4. Design the frontend AMIS using an editor\n\n For the first time using AMIS, take some time to read the AMIS documentation and understand how to use its components. I spent three days reading the documentation and getting familiar with various components.\n\n You can directly use the AMIS online editor for interface design:\n\n AMIS Editor:\n\n [https://aisuda.github.io/amis-editor-demo/#/hello-world](https://aisuda.github.io/amis-editor-demo/#/hello-world)\n\n <img src=\"./Readme_image6.png\" alt=\"Readme_image1\" style=\"zoom:25%;\" />\n\n5. Edit the frontend components and copy the code directly.\n\n <img src=\"./Readme_image1.png\" alt=\"Readme_image1\" style=\"zoom:33%;\" />\n\n6. In the frontend code area, create a JSON file and paste the code.\n\n7. Reference the newly created code in the main framework.\n\n The main framework file is `./admin/pages/site.json`. To modify and reference it:\n\n - Copy the entire main framework code.\n - Go to the AMIS editor, create a new page, paste the code, and add a column according to your preferences.\n - After editing, copy it back to `site.json`. Modify the `data` section to `\"schema\": {}`, which represents the content on the right side of the page.\n\nYou can also refer to my approach by saving the content of the newly added page as a separate JSON file and referencing it using `schemaApi`. Please refer to the `site.json` file for details.\n\nBelow is the JSON format for AMIS:\n\n```json\n{\n \"status\": 0, // Required item in the response\n \"msg\": \"\", // Required item in the response\n \"data\": { // JSON representing the elements of the page\n \"pages\": [\n { // Title layer for the navigation bar\n \"label\": \"Home\",\n \"url\": \"/\", // URL for this layer to facilitate navigation to other layers\n \"redirect\": \"/login\" // What page to navigate to when the page initializes\n },\n {\n \"label\": \"Function Navigation\", // This layer becomes the navigation bar\n \"children\": [ // Column layer for the navigation bar\n {\n \"label\": \"Login/Register\",\n \"url\": \"login\",\n \"schema\": {} // The content here represents the content on the right side of the page\n },\n {\n \"label\": \"The number of items here represents the number of columns in the navigation bar\",\n \"url\": \"login\",\n \"schema\": {} // The content here represents the content on the right side of the page\n }\n ]\n }\n ]\n }\n}\n```\n\n## Final Notes\n\nThis is a simple admin management interface. Please modify it according to your specific needs. With AMIS's features, it can roughly meet 90% of the requirements for admin management interfaces. For the remaining 10%, you may need some assistance from a frontend UI.\n\n### Performance Notes\n\nI tested it with ApiPost7, but the results were not as ideal as others have claimed. It might be due to the use of multiple workers. I wrote a 60-second asynchronous request test [./test/access_url.pu], and the approximate number of requests handled by one process is between 20,000 and 26,000, with no packet loss. The request rate is approximately 400 requests per second under Sanic's processing.\n\nWhen I ran three processes simultaneously, the number of simultaneous requests dropped to about 14,000, so I'm not sure if it's due to resource limitations on my laptop (Macbook14 M1) or something else. If you have sufficient resources, you can use my code or improve it and conduct further testing. On average, it's a stress load of about 2,300 requests per second, which I think is quite good for an admin dashboard.\n\n<img src=\"./Readme_image7.png\" alt=\"Readme_image7\" style=\"zoom:33%;\" />\n\nWhen I ran ten processes, the number of simultaneous requests remained at around 14,000, with no errors.\n\n<img src=\"./Readme_image8.png\" alt=\"Readme_image8\" style=\"zoom:33%;\" />\n",
"bugtrack_url": null,
"license": "",
"summary": "The Admin backend created by the combination of Sanic And Amis manages SANic-admin",
"version": "0.1.1",
"project_urls": {
"Bug Tracker": "https://github.com/A-Corner/Sanic-Admin",
"Homepage": "https://github.com/A-Corner/Sanic-Admin"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "085b2adcc14c621542bce789dd6ad9bea5fe1f4c7c3d41f9dc048ed5b18cc730",
"md5": "4d656305b8d5d4df4271284e1e0ddf1d",
"sha256": "d0d48f203d265414bf9250c879ceb875870049bd8f723287a2ac9106ae18374a"
},
"downloads": -1,
"filename": "Sanic_SAdmin-0.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "4d656305b8d5d4df4271284e1e0ddf1d",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 43964950,
"upload_time": "2023-11-02T08:48:16",
"upload_time_iso_8601": "2023-11-02T08:48:16.184239Z",
"url": "https://files.pythonhosted.org/packages/08/5b/2adcc14c621542bce789dd6ad9bea5fe1f4c7c3d41f9dc048ed5b18cc730/Sanic_SAdmin-0.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "5c1f86991a95c1350248acef37f9e531d76c0640b65b76325befcf33b9443f72",
"md5": "d97cd28264f0d9b0c7b3a3a7c3c08081",
"sha256": "3d3e10e3dc6f126127706639be5747d0416e0c581b95a8c5c6a43833804cb974"
},
"downloads": -1,
"filename": "Sanic_SAdmin-0.1.1.tar.gz",
"has_sig": false,
"md5_digest": "d97cd28264f0d9b0c7b3a3a7c3c08081",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 43794210,
"upload_time": "2023-11-02T08:48:35",
"upload_time_iso_8601": "2023-11-02T08:48:35.326608Z",
"url": "https://files.pythonhosted.org/packages/5c/1f/86991a95c1350248acef37f9e531d76c0640b65b76325befcf33b9443f72/Sanic_SAdmin-0.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-11-02 08:48:35",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "A-Corner",
"github_project": "Sanic-Admin",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "aiodns",
"specs": [
[
"==",
"3.0.0"
]
]
},
{
"name": "aiofiles",
"specs": [
[
"==",
"23.2.1"
]
]
},
{
"name": "aiohttp",
"specs": [
[
"==",
"3.8.5"
]
]
},
{
"name": "aiosignal",
"specs": [
[
"==",
"1.3.1"
]
]
},
{
"name": "aiosqlite",
"specs": [
[
"==",
"0.17.0"
]
]
},
{
"name": "amqp",
"specs": [
[
"==",
"5.1.1"
]
]
},
{
"name": "anyio",
"specs": [
[
"==",
"4.0.0"
]
]
},
{
"name": "argon2-cffi",
"specs": [
[
"==",
"23.1.0"
]
]
},
{
"name": "argon2-cffi-bindings",
"specs": [
[
"==",
"21.2.0"
]
]
},
{
"name": "async-timeout",
"specs": [
[
"==",
"4.0.3"
]
]
},
{
"name": "atlastk",
"specs": [
[
"==",
"0.13.3"
]
]
},
{
"name": "attrs",
"specs": [
[
"==",
"23.1.0"
]
]
},
{
"name": "billiard",
"specs": [
[
"==",
"4.1.0"
]
]
},
{
"name": "Brotli",
"specs": [
[
"==",
"1.1.0"
]
]
},
{
"name": "captcha",
"specs": [
[
"==",
"0.5.0"
]
]
},
{
"name": "celery",
"specs": [
[
"==",
"5.3.4"
]
]
},
{
"name": "certifi",
"specs": [
[
"==",
"2023.7.22"
]
]
},
{
"name": "cffi",
"specs": [
[
"==",
"1.15.1"
]
]
},
{
"name": "charset-normalizer",
"specs": [
[
"==",
"3.2.0"
]
]
},
{
"name": "click",
"specs": [
[
"==",
"8.1.7"
]
]
},
{
"name": "click-didyoumean",
"specs": [
[
"==",
"0.3.0"
]
]
},
{
"name": "click-plugins",
"specs": [
[
"==",
"1.1.1"
]
]
},
{
"name": "click-repl",
"specs": [
[
"==",
"0.3.0"
]
]
},
{
"name": "cryptography",
"specs": [
[
"==",
"41.0.4"
]
]
},
{
"name": "frozenlist",
"specs": [
[
"==",
"1.4.0"
]
]
},
{
"name": "h11",
"specs": [
[
"==",
"0.14.0"
]
]
},
{
"name": "html5tagger",
"specs": [
[
"==",
"1.3.0"
]
]
},
{
"name": "httpcore",
"specs": [
[
"==",
"0.18.0"
]
]
},
{
"name": "httptools",
"specs": [
[
"==",
"0.6.0"
]
]
},
{
"name": "httpx",
"specs": [
[
"==",
"0.25.0"
]
]
},
{
"name": "idna",
"specs": [
[
"==",
"3.4"
]
]
},
{
"name": "install",
"specs": [
[
"==",
"1.3.5"
]
]
},
{
"name": "iso8601",
"specs": [
[
"==",
"1.1.0"
]
]
},
{
"name": "Jinja2",
"specs": [
[
"==",
"3.1.2"
]
]
},
{
"name": "kombu",
"specs": [
[
"==",
"5.3.2"
]
]
},
{
"name": "MarkupSafe",
"specs": [
[
"==",
"2.1.3"
]
]
},
{
"name": "multidict",
"specs": [
[
"==",
"6.0.4"
]
]
},
{
"name": "packaging",
"specs": [
[
"==",
"23.1"
]
]
},
{
"name": "Pillow",
"specs": [
[
"==",
"10.0.1"
]
]
},
{
"name": "prompt-toolkit",
"specs": [
[
"==",
"3.0.39"
]
]
},
{
"name": "pycares",
"specs": [
[
"==",
"4.3.0"
]
]
},
{
"name": "pycparser",
"specs": [
[
"==",
"2.21"
]
]
},
{
"name": "PyJWT",
"specs": [
[
"==",
"2.8.0"
]
]
},
{
"name": "pypika-tortoise",
"specs": [
[
"==",
"0.1.6"
]
]
},
{
"name": "python-dateutil",
"specs": [
[
"==",
"2.8.2"
]
]
},
{
"name": "pytz",
"specs": [
[
"==",
"2023.3.post1"
]
]
},
{
"name": "PyYAML",
"specs": [
[
"==",
"6.0.1"
]
]
},
{
"name": "sanic",
"specs": [
[
"==",
"23.6.0"
]
]
},
{
"name": "Sanic-Cors",
"specs": [
[
"==",
"2.2.0"
]
]
},
{
"name": "sanic-ext",
"specs": [
[
"==",
"23.6.0"
]
]
},
{
"name": "sanic-jinja2",
"specs": [
[
"==",
"2022.11.11"
]
]
},
{
"name": "sanic-routing",
"specs": [
[
"==",
"23.6.0"
]
]
},
{
"name": "six",
"specs": [
[
"==",
"1.16.0"
]
]
},
{
"name": "sniffio",
"specs": [
[
"==",
"1.3.0"
]
]
},
{
"name": "tortoise",
"specs": [
[
"==",
"0.1.1"
]
]
},
{
"name": "tortoise-orm",
"specs": [
[
"==",
"0.20.0"
]
]
},
{
"name": "tracerite",
"specs": [
[
"==",
"1.1.0"
]
]
},
{
"name": "typing_extensions",
"specs": [
[
"==",
"4.8.0"
]
]
},
{
"name": "tzdata",
"specs": [
[
"==",
"2023.3"
]
]
},
{
"name": "ujson",
"specs": [
[
"==",
"5.8.0"
]
]
},
{
"name": "uvloop",
"specs": [
[
"==",
"0.17.0"
]
]
},
{
"name": "vine",
"specs": [
[
"==",
"5.0.0"
]
]
},
{
"name": "wcwidth",
"specs": [
[
"==",
"0.2.6"
]
]
},
{
"name": "websockets",
"specs": [
[
"==",
"11.0.3"
]
]
},
{
"name": "yarl",
"specs": [
[
"==",
"1.9.2"
]
]
}
],
"lcname": "sanic-sadmin"
}