panther 3.9.0__tar.gz → 4.0.1__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.
- {panther-3.9.0 → panther-4.0.1}/PKG-INFO +93 -71
- panther-4.0.1/README.md +192 -0
- {panther-3.9.0 → panther-4.0.1}/panther/__init__.py +1 -1
- panther-4.0.1/panther/_load_configs.py +263 -0
- {panther-3.9.0 → panther-4.0.1}/panther/_utils.py +26 -49
- panther-4.0.1/panther/app.py +205 -0
- panther-4.0.1/panther/authentications.py +166 -0
- {panther-3.9.0 → panther-4.0.1}/panther/background_tasks.py +25 -14
- {panther-3.9.0 → panther-4.0.1}/panther/base_request.py +38 -14
- panther-4.0.1/panther/base_websocket.py +275 -0
- panther-4.0.1/panther/caching.py +125 -0
- {panther-3.9.0 → panther-4.0.1}/panther/cli/create_command.py +20 -10
- panther-4.0.1/panther/cli/monitor_command.py +97 -0
- {panther-3.9.0 → panther-4.0.1}/panther/cli/template.py +38 -20
- {panther-3.9.0 → panther-4.0.1}/panther/cli/utils.py +32 -18
- panther-4.0.1/panther/configs.py +118 -0
- panther-4.0.1/panther/db/connections.py +139 -0
- panther-4.0.1/panther/db/cursor.py +43 -0
- panther-4.0.1/panther/db/models.py +84 -0
- panther-4.0.1/panther/db/queries/__init__.py +1 -0
- panther-4.0.1/panther/db/queries/base_queries.py +127 -0
- panther-4.0.1/panther/db/queries/mongodb_queries.py +128 -0
- panther-4.0.1/panther/db/queries/pantherdb_queries.py +110 -0
- panther-4.0.1/panther/db/queries/queries.py +391 -0
- {panther-3.9.0 → panther-4.0.1}/panther/db/utils.py +17 -18
- panther-4.0.1/panther/events.py +44 -0
- {panther-3.9.0 → panther-4.0.1}/panther/exceptions.py +26 -12
- {panther-3.9.0 → panther-4.0.1}/panther/file_handler.py +2 -2
- panther-4.0.1/panther/generics.py +163 -0
- {panther-3.9.0 → panther-4.0.1}/panther/logging.py +7 -2
- panther-4.0.1/panther/main.py +231 -0
- {panther-3.9.0 → panther-4.0.1}/panther/middlewares/base.py +3 -0
- {panther-3.9.0 → panther-4.0.1}/panther/monitoring.py +8 -5
- panther-4.0.1/panther/pagination.py +48 -0
- {panther-3.9.0 → panther-4.0.1}/panther/panel/apis.py +32 -5
- {panther-3.9.0 → panther-4.0.1}/panther/panel/urls.py +2 -1
- panther-4.0.1/panther/permissions.py +13 -0
- {panther-3.9.0 → panther-4.0.1}/panther/request.py +6 -13
- panther-4.0.1/panther/response.py +193 -0
- panther-4.0.1/panther/routings.py +189 -0
- panther-4.0.1/panther/serializer.py +228 -0
- {panther-3.9.0 → panther-4.0.1}/panther/test.py +31 -21
- {panther-3.9.0 → panther-4.0.1}/panther/utils.py +28 -16
- {panther-3.9.0 → panther-4.0.1}/panther/websocket.py +7 -4
- {panther-3.9.0 → panther-4.0.1}/panther.egg-info/PKG-INFO +93 -71
- {panther-3.9.0 → panther-4.0.1}/panther.egg-info/SOURCES.txt +10 -5
- panther-4.0.1/panther.egg-info/requires.txt +16 -0
- {panther-3.9.0 → panther-4.0.1}/setup.py +8 -8
- {panther-3.9.0 → panther-4.0.1}/tests/test_authentication.py +50 -51
- {panther-3.9.0 → panther-4.0.1}/tests/test_background_tasks.py +31 -35
- {panther-3.9.0 → panther-4.0.1}/tests/test_caching.py +21 -20
- {panther-3.9.0 → panther-4.0.1}/tests/test_cli.py +8 -3
- panther-4.0.1/tests/test_database.py +524 -0
- panther-4.0.1/tests/test_events.py +123 -0
- panther-4.0.1/tests/test_generics.py +226 -0
- {panther-3.9.0 → panther-4.0.1}/tests/test_multipart.py +10 -10
- {panther-3.9.0 → panther-4.0.1}/tests/test_panel_apis.py +10 -7
- {panther-3.9.0 → panther-4.0.1}/tests/test_request.py +101 -101
- panther-4.0.1/tests/test_response.py +456 -0
- {panther-3.9.0 → panther-4.0.1}/tests/test_routing.py +227 -150
- panther-4.0.1/tests/test_run.py +67 -0
- {panther-3.9.0 → panther-4.0.1}/tests/test_serializer.py +118 -36
- panther-4.0.1/tests/test_throttling.py +74 -0
- {panther-3.9.0 → panther-4.0.1}/tests/test_utils.py +39 -42
- {panther-3.9.0 → panther-4.0.1}/tests/test_websockets.py +148 -14
- panther-3.9.0/README.md +0 -170
- panther-3.9.0/panther/_load_configs.py +0 -266
- panther-3.9.0/panther/app.py +0 -225
- panther-3.9.0/panther/authentications.py +0 -135
- panther-3.9.0/panther/base_websocket.py +0 -198
- panther-3.9.0/panther/caching.py +0 -90
- panther-3.9.0/panther/cli/monitor_command.py +0 -71
- panther-3.9.0/panther/configs.py +0 -111
- panther-3.9.0/panther/db/connection.py +0 -92
- panther-3.9.0/panther/db/models.py +0 -49
- panther-3.9.0/panther/db/queries/__init__.py +0 -1
- panther-3.9.0/panther/db/queries/mongodb_queries.py +0 -89
- panther-3.9.0/panther/db/queries/pantherdb_queries.py +0 -81
- panther-3.9.0/panther/db/queries/queries.py +0 -276
- panther-3.9.0/panther/main.py +0 -307
- panther-3.9.0/panther/middlewares/db.py +0 -18
- panther-3.9.0/panther/middlewares/redis.py +0 -47
- panther-3.9.0/panther/permissions.py +0 -13
- panther-3.9.0/panther/response.py +0 -113
- panther-3.9.0/panther/routings.py +0 -172
- panther-3.9.0/panther/serializer.py +0 -122
- panther-3.9.0/panther.egg-info/requires.txt +0 -16
- panther-3.9.0/tests/test_database.py +0 -514
- panther-3.9.0/tests/test_mongodb.py +0 -48
- panther-3.9.0/tests/test_run.py +0 -79
- panther-3.9.0/tests/test_simple_responses.py +0 -116
- {panther-3.9.0 → panther-4.0.1}/LICENSE +0 -0
- {panther-3.9.0 → panther-4.0.1}/panther/cli/__init__.py +0 -0
- {panther-3.9.0 → panther-4.0.1}/panther/cli/main.py +0 -0
- {panther-3.9.0 → panther-4.0.1}/panther/cli/run_command.py +0 -0
- {panther-3.9.0 → panther-4.0.1}/panther/db/__init__.py +0 -0
- {panther-3.9.0 → panther-4.0.1}/panther/middlewares/__init__.py +0 -0
- {panther-3.9.0 → panther-4.0.1}/panther/panel/__init__.py +0 -0
- {panther-3.9.0 → panther-4.0.1}/panther/panel/utils.py +0 -0
- {panther-3.9.0 → panther-4.0.1}/panther/status.py +0 -0
- {panther-3.9.0 → panther-4.0.1}/panther/throttling.py +0 -0
- {panther-3.9.0 → panther-4.0.1}/panther.egg-info/dependency_links.txt +0 -0
- {panther-3.9.0 → panther-4.0.1}/panther.egg-info/entry_points.txt +0 -0
- {panther-3.9.0 → panther-4.0.1}/panther.egg-info/top_level.txt +0 -0
- {panther-3.9.0 → panther-4.0.1}/pyproject.toml +0 -0
- {panther-3.9.0 → panther-4.0.1}/setup.cfg +0 -0
- {panther-3.9.0 → panther-4.0.1}/tests/test_status.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: panther
|
3
|
-
Version:
|
3
|
+
Version: 4.0.1
|
4
4
|
Summary: Fast & Friendly, Web Framework For Building Async APIs
|
5
5
|
Home-page: https://github.com/alirn76/panther
|
6
6
|
Author: Ali RajabNezhad
|
@@ -13,21 +13,21 @@ Classifier: Programming Language :: Python :: 3.12
|
|
13
13
|
Requires-Python: >=3.10
|
14
14
|
Description-Content-Type: text/markdown
|
15
15
|
License-File: LICENSE
|
16
|
-
Requires-Dist: bson~=0.5
|
17
16
|
Requires-Dist: httptools~=0.6
|
18
|
-
Requires-Dist: pantherdb==1.
|
19
|
-
Requires-Dist: pydantic~=2.
|
20
|
-
Requires-Dist: rich~=13.
|
21
|
-
Requires-Dist: uvicorn~=0.
|
22
|
-
Requires-Dist:
|
17
|
+
Requires-Dist: pantherdb==2.1.0
|
18
|
+
Requires-Dist: pydantic~=2.6
|
19
|
+
Requires-Dist: rich~=13.7
|
20
|
+
Requires-Dist: uvicorn~=0.27
|
21
|
+
Requires-Dist: pytz~=2024.1
|
23
22
|
Provides-Extra: full
|
24
23
|
Requires-Dist: redis==5.0.1; extra == "full"
|
25
|
-
Requires-Dist:
|
24
|
+
Requires-Dist: motor~=3.3; extra == "full"
|
26
25
|
Requires-Dist: bpython~=0.24; extra == "full"
|
27
26
|
Requires-Dist: ruff~=0.1.9; extra == "full"
|
28
27
|
Requires-Dist: python-jose~=3.3; extra == "full"
|
29
28
|
Requires-Dist: websockets~=12.0; extra == "full"
|
30
|
-
Requires-Dist: cryptography~=
|
29
|
+
Requires-Dist: cryptography~=42.0; extra == "full"
|
30
|
+
Requires-Dist: watchfiles~=0.21.0; extra == "full"
|
31
31
|
|
32
32
|
|
33
33
|
[](https://pypi.org/project/panther/) [](https://pypi.org/project/panther/) [](https://codecov.io/github/AliRn76/panther) [](https://pepy.tech/project/panther) [](https://github.com/alirn76/panther/blob/main/LICENSE)
|
@@ -45,14 +45,18 @@ Requires-Dist: cryptography~=41.0; extra == "full"
|
|
45
45
|
---
|
46
46
|
|
47
47
|
### Why Use Panther ?
|
48
|
-
-
|
49
|
-
- Built-in
|
50
|
-
-
|
51
|
-
- Built-in
|
52
|
-
- Built-in
|
53
|
-
-
|
54
|
-
-
|
55
|
-
-
|
48
|
+
- Include Simple **File-Base** Database ([PantherDB](https://pypi.org/project/pantherdb/))
|
49
|
+
- Built-in Document-oriented Databases **ODM** (**MongoDB**, PantherDB)
|
50
|
+
- Built-in **Websocket** Support
|
51
|
+
- Built-in API **Caching** System (In Memory, **Redis**)
|
52
|
+
- Built-in **Authentication** Classes
|
53
|
+
- Built-in **Permission** Classes
|
54
|
+
- Built-in Visual API **Monitoring** (In Terminal)
|
55
|
+
- Support Custom **Background Tasks**
|
56
|
+
- Support Custom **Middlewares**
|
57
|
+
- Support Custom **Throttling**
|
58
|
+
- Support **Function-Base** and **Class-Base** APIs
|
59
|
+
- It's One Of The **Fastest Python Frameworks**
|
56
60
|
---
|
57
61
|
|
58
62
|
### Supported by
|
@@ -84,111 +88,129 @@ Requires-Dist: cryptography~=41.0; extra == "full"
|
|
84
88
|
---
|
85
89
|
|
86
90
|
### Installation
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
</details>
|
92
|
-
|
93
|
-
- <details>
|
94
|
-
<summary>2. Active The Environment</summary>
|
95
|
-
* Linux & Mac
|
96
|
-
<pre>$ source .venv/bin/activate</pre>
|
97
|
-
* Windows
|
98
|
-
<pre>$ .\.venv\Scripts\activate</pre>
|
99
|
-
|
100
|
-
</details>
|
101
|
-
|
102
|
-
- <details open>
|
103
|
-
<summary>3. <b>Install Panther</b></summary>
|
104
|
-
- ⬇ Normal Installation
|
105
|
-
<pre><b>$ pip install panther</b></pre>
|
106
|
-
- ⬇ Include full requirements (MongoDB, JWTAuth, Ruff, Redis, bpython)
|
107
|
-
<pre>$ pip install panther[full]</pre>
|
108
|
-
</details>
|
109
|
-
|
110
|
-
---
|
91
|
+
```shell
|
92
|
+
$ pip install panther
|
93
|
+
```
|
111
94
|
|
112
95
|
### Usage
|
113
96
|
|
114
97
|
- #### Create Project
|
115
98
|
|
116
|
-
```
|
99
|
+
```shell
|
117
100
|
$ panther create
|
118
101
|
```
|
119
102
|
|
120
103
|
- #### Run Project
|
121
104
|
|
122
|
-
```
|
105
|
+
```shell
|
123
106
|
$ panther run --reload
|
124
107
|
```
|
125
108
|
_* Panther uses [Uvicorn](https://github.com/encode/uvicorn) as ASGI (Asynchronous Server Gateway Interface) but you can run the project with [Granian](https://pypi.org/project/granian/), [daphne](https://pypi.org/project/daphne/) or any ASGI server too_
|
126
109
|
|
127
110
|
- #### Monitoring Requests
|
128
111
|
|
129
|
-
```
|
112
|
+
```shell
|
130
113
|
$ panther monitor
|
131
114
|
```
|
132
115
|
|
133
116
|
- #### Python Shell
|
134
117
|
|
135
|
-
```
|
118
|
+
```shell
|
136
119
|
$ panther shell
|
137
120
|
```
|
138
121
|
|
139
122
|
---
|
140
123
|
|
141
|
-
###
|
124
|
+
### API Example
|
142
125
|
- Create `main.py`
|
143
126
|
|
144
127
|
```python
|
145
128
|
from datetime import datetime, timedelta
|
146
129
|
|
147
|
-
from panther import
|
148
|
-
from panther.app import
|
149
|
-
from panther.request import Request
|
130
|
+
from panther import status, Panther
|
131
|
+
from panther.app import GenericAPI
|
150
132
|
from panther.response import Response
|
151
|
-
from panther.throttling import Throttling
|
152
133
|
|
153
|
-
InfoThrottling = Throttling(rate=5, duration=timedelta(minutes=1))
|
154
134
|
|
135
|
+
class FirstAPI(GenericAPI):
|
136
|
+
# Cache Response For 10 Seconds
|
137
|
+
cache = True
|
138
|
+
cache_exp_time = timedelta(seconds=10)
|
139
|
+
|
140
|
+
def get(self):
|
141
|
+
date_time = datetime.now().isoformat()
|
142
|
+
data = {'detail': f'Hello World | {date_time}'}
|
143
|
+
return Response(data=data, status_code=status.HTTP_202_ACCEPTED)
|
155
144
|
|
156
|
-
|
157
|
-
|
158
|
-
|
145
|
+
|
146
|
+
url_routing = {'': FirstAPI}
|
147
|
+
app = Panther(__name__, configs=__name__, urls=url_routing)
|
148
|
+
```
|
149
|
+
|
150
|
+
- Run the project:
|
151
|
+
- `$ panther run --reload`
|
152
|
+
|
153
|
+
- Checkout the [http://127.0.0.1:8000/](http://127.0.0.1:8000/)
|
154
|
+
|
155
|
+
### WebSocket Echo Example
|
156
|
+
- Create `main.py`
|
157
|
+
|
158
|
+
```python
|
159
|
+
from panther import Panther
|
160
|
+
from panther.app import GenericAPI
|
161
|
+
from panther.response import HTMLResponse
|
162
|
+
from panther.websocket import GenericWebsocket
|
159
163
|
|
160
164
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
'panther_version': version(),
|
165
|
-
'datetime_now': datetime.now().isoformat(),
|
166
|
-
'user_agent': request.headers.user_agent
|
167
|
-
}
|
168
|
-
return Response(data=data, status_code=status.HTTP_202_ACCEPTED)
|
165
|
+
class FirstWebsocket(GenericWebsocket):
|
166
|
+
async def connect(self, **kwargs):
|
167
|
+
await self.accept()
|
169
168
|
|
169
|
+
async def receive(self, data: str | bytes):
|
170
|
+
await self.send(data)
|
171
|
+
|
172
|
+
|
173
|
+
class MainPage(GenericAPI):
|
174
|
+
def get(self):
|
175
|
+
template = """
|
176
|
+
<input type="text" id="messageInput">
|
177
|
+
<button id="sendButton">Send Message</button>
|
178
|
+
<ul id="messages"></ul>
|
179
|
+
<script>
|
180
|
+
var socket = new WebSocket('ws://127.0.0.1:8000/ws');
|
181
|
+
socket.addEventListener('message', function (event) {
|
182
|
+
var li = document.createElement('li');
|
183
|
+
document.getElementById('messages').appendChild(li).textContent = 'Server: ' + event.data;
|
184
|
+
});
|
185
|
+
function sendMessage() {
|
186
|
+
socket.send(document.getElementById('messageInput').value);
|
187
|
+
}
|
188
|
+
document.getElementById('sendButton').addEventListener('click', sendMessage);
|
189
|
+
</script>
|
190
|
+
"""
|
191
|
+
return HTMLResponse(template)
|
170
192
|
|
171
193
|
url_routing = {
|
172
|
-
'':
|
173
|
-
'
|
194
|
+
'': MainPage,
|
195
|
+
'ws': FirstWebsocket,
|
174
196
|
}
|
175
|
-
|
176
197
|
app = Panther(__name__, configs=__name__, urls=url_routing)
|
198
|
+
|
177
199
|
```
|
178
200
|
|
179
201
|
- Run the project:
|
180
202
|
- `$ panther run --reload`
|
181
|
-
|
182
|
-
|
183
|
-
- Now you can see these two urls:</b>
|
184
|
-
- [http://127.0.0.1:8000/](http://127.0.0.1:8000/)
|
185
|
-
- [http://127.0.0.1:8000/info/](http://127.0.0.1:8000/info/)
|
203
|
+
- Go to [http://127.0.0.1:8000/](http://127.0.0.1:8000/) and work with your `websocket`
|
186
204
|
|
187
205
|
|
188
206
|
|
189
207
|
> **Next Step: [First CRUD](https://pantherpy.github.io/function_first_crud)**
|
190
208
|
|
191
|
-
|
209
|
+
---
|
210
|
+
|
211
|
+
### How Panther Works!
|
212
|
+
|
213
|
+

|
192
214
|
|
193
215
|
---
|
194
216
|
|
panther-4.0.1/README.md
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
|
2
|
+
[](https://pypi.org/project/panther/) [](https://pypi.org/project/panther/) [](https://codecov.io/github/AliRn76/panther) [](https://pepy.tech/project/panther) [](https://github.com/alirn76/panther/blob/main/LICENSE)
|
3
|
+
|
4
|
+
|
5
|
+
## Panther
|
6
|
+
<b>Is A Fast & Friendly Web Framework For Building Async APIs With Python 3.10+</b>
|
7
|
+
|
8
|
+
<p align="center">
|
9
|
+
<img src="https://github.com/AliRn76/panther/raw/master/docs/docs/images/logo-vertical.png" alt="logo" style="width: 450px">
|
10
|
+
</p>
|
11
|
+
|
12
|
+
**_📚 Full Documentation:_** [PantherPy.GitHub.io](https://pantherpy.github.io)
|
13
|
+
|
14
|
+
---
|
15
|
+
|
16
|
+
### Why Use Panther ?
|
17
|
+
- Include Simple **File-Base** Database ([PantherDB](https://pypi.org/project/pantherdb/))
|
18
|
+
- Built-in Document-oriented Databases **ODM** (**MongoDB**, PantherDB)
|
19
|
+
- Built-in **Websocket** Support
|
20
|
+
- Built-in API **Caching** System (In Memory, **Redis**)
|
21
|
+
- Built-in **Authentication** Classes
|
22
|
+
- Built-in **Permission** Classes
|
23
|
+
- Built-in Visual API **Monitoring** (In Terminal)
|
24
|
+
- Support Custom **Background Tasks**
|
25
|
+
- Support Custom **Middlewares**
|
26
|
+
- Support Custom **Throttling**
|
27
|
+
- Support **Function-Base** and **Class-Base** APIs
|
28
|
+
- It's One Of The **Fastest Python Frameworks**
|
29
|
+
---
|
30
|
+
|
31
|
+
### Supported by
|
32
|
+
<center>
|
33
|
+
<a href="https://drive.google.com/file/d/17xe1hicIiRF7SQ-clg9SETdc19SktCbV/view?usp=sharing">
|
34
|
+
<img alt="jetbrains" src="https://github.com/AliRn76/panther/raw/master/docs/docs/images/jb_beam_50x50.png">
|
35
|
+
</a>
|
36
|
+
</center>
|
37
|
+
|
38
|
+
---
|
39
|
+
|
40
|
+
### Benchmark
|
41
|
+
|
42
|
+
| Framework | Throughput (Request/Second) |
|
43
|
+
|------------|-----------------------------|
|
44
|
+
| Blacksheep | 5,339 |
|
45
|
+
| Muffin | 5,320 |
|
46
|
+
| Panther | 5,112 |
|
47
|
+
| Sanic | 3,660 |
|
48
|
+
| FastAPI | 3,260 |
|
49
|
+
| Tornado | 2,081 |
|
50
|
+
| Bottle | 2,045 |
|
51
|
+
| Django | 821 |
|
52
|
+
| Flask | 749 |
|
53
|
+
|
54
|
+
|
55
|
+
> **More Detail:** https://GitHub.com/PantherPy/frameworks-benchmark
|
56
|
+
|
57
|
+
---
|
58
|
+
|
59
|
+
### Installation
|
60
|
+
```shell
|
61
|
+
$ pip install panther
|
62
|
+
```
|
63
|
+
|
64
|
+
### Usage
|
65
|
+
|
66
|
+
- #### Create Project
|
67
|
+
|
68
|
+
```shell
|
69
|
+
$ panther create
|
70
|
+
```
|
71
|
+
|
72
|
+
- #### Run Project
|
73
|
+
|
74
|
+
```shell
|
75
|
+
$ panther run --reload
|
76
|
+
```
|
77
|
+
_* Panther uses [Uvicorn](https://github.com/encode/uvicorn) as ASGI (Asynchronous Server Gateway Interface) but you can run the project with [Granian](https://pypi.org/project/granian/), [daphne](https://pypi.org/project/daphne/) or any ASGI server too_
|
78
|
+
|
79
|
+
- #### Monitoring Requests
|
80
|
+
|
81
|
+
```shell
|
82
|
+
$ panther monitor
|
83
|
+
```
|
84
|
+
|
85
|
+
- #### Python Shell
|
86
|
+
|
87
|
+
```shell
|
88
|
+
$ panther shell
|
89
|
+
```
|
90
|
+
|
91
|
+
---
|
92
|
+
|
93
|
+
### API Example
|
94
|
+
- Create `main.py`
|
95
|
+
|
96
|
+
```python
|
97
|
+
from datetime import datetime, timedelta
|
98
|
+
|
99
|
+
from panther import status, Panther
|
100
|
+
from panther.app import GenericAPI
|
101
|
+
from panther.response import Response
|
102
|
+
|
103
|
+
|
104
|
+
class FirstAPI(GenericAPI):
|
105
|
+
# Cache Response For 10 Seconds
|
106
|
+
cache = True
|
107
|
+
cache_exp_time = timedelta(seconds=10)
|
108
|
+
|
109
|
+
def get(self):
|
110
|
+
date_time = datetime.now().isoformat()
|
111
|
+
data = {'detail': f'Hello World | {date_time}'}
|
112
|
+
return Response(data=data, status_code=status.HTTP_202_ACCEPTED)
|
113
|
+
|
114
|
+
|
115
|
+
url_routing = {'': FirstAPI}
|
116
|
+
app = Panther(__name__, configs=__name__, urls=url_routing)
|
117
|
+
```
|
118
|
+
|
119
|
+
- Run the project:
|
120
|
+
- `$ panther run --reload`
|
121
|
+
|
122
|
+
- Checkout the [http://127.0.0.1:8000/](http://127.0.0.1:8000/)
|
123
|
+
|
124
|
+
### WebSocket Echo Example
|
125
|
+
- Create `main.py`
|
126
|
+
|
127
|
+
```python
|
128
|
+
from panther import Panther
|
129
|
+
from panther.app import GenericAPI
|
130
|
+
from panther.response import HTMLResponse
|
131
|
+
from panther.websocket import GenericWebsocket
|
132
|
+
|
133
|
+
|
134
|
+
class FirstWebsocket(GenericWebsocket):
|
135
|
+
async def connect(self, **kwargs):
|
136
|
+
await self.accept()
|
137
|
+
|
138
|
+
async def receive(self, data: str | bytes):
|
139
|
+
await self.send(data)
|
140
|
+
|
141
|
+
|
142
|
+
class MainPage(GenericAPI):
|
143
|
+
def get(self):
|
144
|
+
template = """
|
145
|
+
<input type="text" id="messageInput">
|
146
|
+
<button id="sendButton">Send Message</button>
|
147
|
+
<ul id="messages"></ul>
|
148
|
+
<script>
|
149
|
+
var socket = new WebSocket('ws://127.0.0.1:8000/ws');
|
150
|
+
socket.addEventListener('message', function (event) {
|
151
|
+
var li = document.createElement('li');
|
152
|
+
document.getElementById('messages').appendChild(li).textContent = 'Server: ' + event.data;
|
153
|
+
});
|
154
|
+
function sendMessage() {
|
155
|
+
socket.send(document.getElementById('messageInput').value);
|
156
|
+
}
|
157
|
+
document.getElementById('sendButton').addEventListener('click', sendMessage);
|
158
|
+
</script>
|
159
|
+
"""
|
160
|
+
return HTMLResponse(template)
|
161
|
+
|
162
|
+
url_routing = {
|
163
|
+
'': MainPage,
|
164
|
+
'ws': FirstWebsocket,
|
165
|
+
}
|
166
|
+
app = Panther(__name__, configs=__name__, urls=url_routing)
|
167
|
+
|
168
|
+
```
|
169
|
+
|
170
|
+
- Run the project:
|
171
|
+
- `$ panther run --reload`
|
172
|
+
- Go to [http://127.0.0.1:8000/](http://127.0.0.1:8000/) and work with your `websocket`
|
173
|
+
|
174
|
+
|
175
|
+
|
176
|
+
> **Next Step: [First CRUD](https://pantherpy.github.io/function_first_crud)**
|
177
|
+
|
178
|
+
---
|
179
|
+
|
180
|
+
### How Panther Works!
|
181
|
+
|
182
|
+

|
183
|
+
|
184
|
+
---
|
185
|
+
|
186
|
+
### Roadmap
|
187
|
+
|
188
|
+

|
189
|
+
|
190
|
+
---
|
191
|
+
|
192
|
+
**If you find this project useful, please give it a star ⭐️.**
|