serpy-rest 0.1.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.
@@ -0,0 +1,187 @@
1
+ Metadata-Version: 2.4
2
+ Name: serpy-rest
3
+ Version: 0.1.0
4
+ Summary: A minimal ASGI web framework for Python.
5
+ Home-page: https://github.com/ragav2005/SerPy
6
+ Author: Ragav Vignes
7
+ Author-email: ragavvignesviswanathan@gmail.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Framework :: AsyncIO
12
+ Requires-Python: >=3.7
13
+ Description-Content-Type: text/markdown
14
+ Dynamic: author
15
+ Dynamic: author-email
16
+ Dynamic: classifier
17
+ Dynamic: description
18
+ Dynamic: description-content-type
19
+ Dynamic: home-page
20
+ Dynamic: requires-python
21
+ Dynamic: summary
22
+
23
+ # SerPy
24
+
25
+ SerPy is a minimal, modern, and lightning-fast ASGI web framework for Python. It is designed for simplicity, flexibility, and performance, making it ideal for building APIs, microservices, and web applications with minimal overhead.
26
+
27
+ ---
28
+
29
+ ## Table of Contents
30
+
31
+ - [Features](#features)
32
+ - [Installation](#installation)
33
+ - [Quick Start](#quick-start)
34
+ - [Example Project](#example-project)
35
+ - [Middleware](#middleware)
36
+ - [Advanced Routing](#advanced-routing)
37
+ - [Contributing](#contributing)
38
+ - [Running Locally](#running-locally)
39
+ - [License](#license)
40
+ - [Contact](#contact)
41
+
42
+ ---
43
+
44
+ ## Features
45
+
46
+ - **ASGI compatible**: Works seamlessly with ASGI servers like Uvicorn and Hypercorn
47
+ - **Simple routing**: Path parameters, method-based routing, and easy route registration
48
+ - **Middleware support**: Add custom middleware for logging, authentication, CORS, etc.
49
+ - **Request/Response abstraction**: Clean API for handling requests and responses
50
+ - **Modular**: Use routers to organize your application
51
+ - **Type hints**: Modern Pythonic code with type hints
52
+
53
+ ---
54
+
55
+ ## Installation
56
+
57
+ Install the latest release from PyPI:
58
+
59
+ ```bash
60
+ pip install serpy-asgi
61
+ ```
62
+
63
+ Or, to use the latest development version, clone this repository:
64
+
65
+ ```bash
66
+ git clone https://github.com/ragav2005/SerPy.git
67
+ cd SerPy
68
+ pip install .
69
+ ```
70
+
71
+ ---
72
+
73
+ ## Quick Start
74
+
75
+ Create a file called `main.py`:
76
+
77
+ ```python
78
+ from serpy import SerPy, Response
79
+
80
+ app = SerPy()
81
+
82
+ @app.route("/hello/{name}", methods=["GET"])
83
+ async def hello(request, name):
84
+ return Response({"message": f"Hello, {name}!"})
85
+
86
+ # Run with: uvicorn main:app
87
+ ```
88
+
89
+ Start the server:
90
+
91
+ ```bash
92
+ uvicorn main:app --reload
93
+ ```
94
+
95
+ ---
96
+
97
+ ## Example Project Structure
98
+
99
+ ```
100
+ myproject/
101
+ ├── main.py
102
+ ├── requirements.txt
103
+ └── ...
104
+ ```
105
+
106
+ ---
107
+
108
+ ## Middleware
109
+
110
+ Add global middleware to your app:
111
+
112
+ ```python
113
+ async def log_middleware(request, call_next):
114
+ print(f"Request: {request.method} {request.path}")
115
+ response = await call_next(request)
116
+ return response
117
+
118
+ app.add_middleware(log_middleware)
119
+ ```
120
+
121
+ ---
122
+
123
+ ## Advanced Routing
124
+
125
+ Use routers to organize endpoints:
126
+
127
+ ```python
128
+ from serpy import Router
129
+
130
+ user_router = Router()
131
+
132
+ @user_router.route("/users/{user_id}", methods=["GET"])
133
+ async def get_user(request, user_id):
134
+ # Fetch user logic here
135
+ return Response({"user_id": user_id})
136
+
137
+ app.include_router(user_router, prefix="/api")
138
+ ```
139
+
140
+ ---
141
+
142
+ ## Contributing
143
+
144
+ Contributions are welcome! To contribute:
145
+
146
+ 1. Fork the repository
147
+ 2. Create a new branch (`git checkout -b feature/your-feature`)
148
+ 3. Commit your changes
149
+ 4. Push to your fork and submit a pull request
150
+
151
+ Please ensure your code follows PEP8 and includes tests where appropriate.
152
+
153
+ ---
154
+
155
+ ## Running Locally (Development)
156
+
157
+ 1. Clone the repository:
158
+ ```bash
159
+ git clone https://github.com/ragav2005/SerPy.git
160
+ cd SerPy
161
+ ```
162
+ 2. (Optional) Create a virtual environment:
163
+ ```bash
164
+ python3 -m venv .venv
165
+ source .venv/bin/activate
166
+ ```
167
+ 3. Install dependencies:
168
+ ```bash
169
+ pip install -r requirements.txt
170
+ ```
171
+ 4. Run the example app or your own app with Uvicorn:
172
+ ```bash
173
+ uvicorn main:app --reload
174
+ ```
175
+
176
+ ---
177
+
178
+ ## License
179
+
180
+ This project is licensed under the MIT License.
181
+
182
+ ---
183
+
184
+ ## Contact
185
+
186
+ Author: [ragav2005](https://github.com/ragav2005)
187
+ For questions, suggestions, or issues, please open an issue on GitHub.
@@ -0,0 +1,165 @@
1
+ # SerPy
2
+
3
+ SerPy is a minimal, modern, and lightning-fast ASGI web framework for Python. It is designed for simplicity, flexibility, and performance, making it ideal for building APIs, microservices, and web applications with minimal overhead.
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ - [Features](#features)
10
+ - [Installation](#installation)
11
+ - [Quick Start](#quick-start)
12
+ - [Example Project](#example-project)
13
+ - [Middleware](#middleware)
14
+ - [Advanced Routing](#advanced-routing)
15
+ - [Contributing](#contributing)
16
+ - [Running Locally](#running-locally)
17
+ - [License](#license)
18
+ - [Contact](#contact)
19
+
20
+ ---
21
+
22
+ ## Features
23
+
24
+ - **ASGI compatible**: Works seamlessly with ASGI servers like Uvicorn and Hypercorn
25
+ - **Simple routing**: Path parameters, method-based routing, and easy route registration
26
+ - **Middleware support**: Add custom middleware for logging, authentication, CORS, etc.
27
+ - **Request/Response abstraction**: Clean API for handling requests and responses
28
+ - **Modular**: Use routers to organize your application
29
+ - **Type hints**: Modern Pythonic code with type hints
30
+
31
+ ---
32
+
33
+ ## Installation
34
+
35
+ Install the latest release from PyPI:
36
+
37
+ ```bash
38
+ pip install serpy-asgi
39
+ ```
40
+
41
+ Or, to use the latest development version, clone this repository:
42
+
43
+ ```bash
44
+ git clone https://github.com/ragav2005/SerPy.git
45
+ cd SerPy
46
+ pip install .
47
+ ```
48
+
49
+ ---
50
+
51
+ ## Quick Start
52
+
53
+ Create a file called `main.py`:
54
+
55
+ ```python
56
+ from serpy import SerPy, Response
57
+
58
+ app = SerPy()
59
+
60
+ @app.route("/hello/{name}", methods=["GET"])
61
+ async def hello(request, name):
62
+ return Response({"message": f"Hello, {name}!"})
63
+
64
+ # Run with: uvicorn main:app
65
+ ```
66
+
67
+ Start the server:
68
+
69
+ ```bash
70
+ uvicorn main:app --reload
71
+ ```
72
+
73
+ ---
74
+
75
+ ## Example Project Structure
76
+
77
+ ```
78
+ myproject/
79
+ ├── main.py
80
+ ├── requirements.txt
81
+ └── ...
82
+ ```
83
+
84
+ ---
85
+
86
+ ## Middleware
87
+
88
+ Add global middleware to your app:
89
+
90
+ ```python
91
+ async def log_middleware(request, call_next):
92
+ print(f"Request: {request.method} {request.path}")
93
+ response = await call_next(request)
94
+ return response
95
+
96
+ app.add_middleware(log_middleware)
97
+ ```
98
+
99
+ ---
100
+
101
+ ## Advanced Routing
102
+
103
+ Use routers to organize endpoints:
104
+
105
+ ```python
106
+ from serpy import Router
107
+
108
+ user_router = Router()
109
+
110
+ @user_router.route("/users/{user_id}", methods=["GET"])
111
+ async def get_user(request, user_id):
112
+ # Fetch user logic here
113
+ return Response({"user_id": user_id})
114
+
115
+ app.include_router(user_router, prefix="/api")
116
+ ```
117
+
118
+ ---
119
+
120
+ ## Contributing
121
+
122
+ Contributions are welcome! To contribute:
123
+
124
+ 1. Fork the repository
125
+ 2. Create a new branch (`git checkout -b feature/your-feature`)
126
+ 3. Commit your changes
127
+ 4. Push to your fork and submit a pull request
128
+
129
+ Please ensure your code follows PEP8 and includes tests where appropriate.
130
+
131
+ ---
132
+
133
+ ## Running Locally (Development)
134
+
135
+ 1. Clone the repository:
136
+ ```bash
137
+ git clone https://github.com/ragav2005/SerPy.git
138
+ cd SerPy
139
+ ```
140
+ 2. (Optional) Create a virtual environment:
141
+ ```bash
142
+ python3 -m venv .venv
143
+ source .venv/bin/activate
144
+ ```
145
+ 3. Install dependencies:
146
+ ```bash
147
+ pip install -r requirements.txt
148
+ ```
149
+ 4. Run the example app or your own app with Uvicorn:
150
+ ```bash
151
+ uvicorn main:app --reload
152
+ ```
153
+
154
+ ---
155
+
156
+ ## License
157
+
158
+ This project is licensed under the MIT License.
159
+
160
+ ---
161
+
162
+ ## Contact
163
+
164
+ Author: [ragav2005](https://github.com/ragav2005)
165
+ For questions, suggestions, or issues, please open an issue on GitHub.
@@ -0,0 +1,190 @@
1
+ import json
2
+ from urllib.parse import parse_qs
3
+
4
+ class Request:
5
+ def __init__(self, scope, receive):
6
+ self.scope = scope
7
+ self._query_params = None
8
+ self.receive = receive
9
+ self._headers = None
10
+
11
+ async def json(self):
12
+ body = b''
13
+ more_body = True
14
+ while more_body:
15
+ message = await self.receive()
16
+ body += message.get('body', b'')
17
+ more_body = message.get('more_body', False)
18
+
19
+ if not body:
20
+ return None
21
+ return json.loads(body)
22
+
23
+ @property
24
+ def path(self):
25
+ return self.scope['path']
26
+
27
+
28
+ @property
29
+ def method(self):
30
+ return self.scope['method']
31
+
32
+
33
+ @property
34
+ def headers(self):
35
+ if self._headers is None:
36
+ self._headers = {
37
+ key.decode('utf-8'): value.decode('utf-8')
38
+ for key, value in self.scope['headers']
39
+ }
40
+ return self._headers
41
+
42
+
43
+ @property
44
+ def query(self):
45
+ if self._query_params is None:
46
+ query_string = self.scope['query_string'].decode("utf-8")
47
+ self._query_params = QueryParams(query_string)
48
+ return self._query_params
49
+
50
+
51
+
52
+ class QueryParams:
53
+ def __init__(self, query_string):
54
+ self._params = parse_qs(query_string)
55
+
56
+ def get(self, key, default=None):
57
+ values = self._params.get(key, [])
58
+ return values[0] if values else default
59
+
60
+ def getall(self, key, default=None):
61
+ return self._params.get(key, default or [])
62
+
63
+
64
+
65
+ class Response:
66
+ def __init__(self, content, status_code=200):
67
+ self.content = content
68
+ self.status_code = status_code
69
+ self.headers = {}
70
+
71
+ async def send_to_asgi(self, send):
72
+ body = json.dumps(self.content).encode("utf-8")
73
+
74
+ headers_list = [[b"content-type", b"application/json"]]
75
+ for key, value in self.headers.items():
76
+ headers_list.append([key.encode("utf-8"), value.encode("utf-8")])
77
+
78
+ await send({
79
+ "type": "http.response.start",
80
+ "status": self.status_code,
81
+ "headers": headers_list,
82
+ })
83
+ await send({"type": "http.response.body", "body": body})
84
+
85
+
86
+
87
+ class Router:
88
+ def __init__(self):
89
+ self.routes = {}
90
+
91
+ def route(self, path, methods=None):
92
+ if methods is None: methods = ["GET"]
93
+ def wrapper(handler):
94
+ for method in methods:
95
+ self.routes[(method.upper(), path)] = handler
96
+ return handler
97
+ return wrapper
98
+
99
+
100
+
101
+ class MiddlewareWrapper:
102
+ def __init__(self, app, middleware_func):
103
+ self.app = app
104
+ self.middleware_func = middleware_func
105
+
106
+ async def __call__(self, scope, receive):
107
+ async def call_next(request):
108
+ response = await self.app(scope, receive)
109
+ return response
110
+
111
+ request = Request(scope, receive)
112
+ response = await self.middleware_func(request, call_next)
113
+ return response
114
+
115
+
116
+
117
+ class SerPy:
118
+ def __init__(self):
119
+ self.routes = {}
120
+ self.app = self._dispatch_request
121
+
122
+ def add_middleware(self, middleware_func):
123
+ self.app = MiddlewareWrapper(self.app, middleware_func)
124
+
125
+ def include_router(self, router: Router, prefix=""):
126
+ for (method, path), handler in router.routes.items():
127
+ self.routes[(method, prefix + path)] = handler
128
+
129
+ def route(self, path, methods=None, middleware=None):
130
+ if methods is None: methods = ["GET"]
131
+ if middleware is None: middleware = []
132
+
133
+ def wrapper(handler):
134
+ for method in methods:
135
+ self.routes[(method.upper(), path)] = (handler, middleware)
136
+ return handler
137
+ return wrapper
138
+
139
+ def find_route(self, method, path):
140
+ for (route_method, route_path), (handler, middleware) in self.routes.items():
141
+
142
+ if route_method != method: continue
143
+
144
+ route_parts = route_path.split("/")
145
+ path_parts = path.split("/")
146
+
147
+ if len(route_parts) != len(path_parts): continue
148
+
149
+ params = {}
150
+ match = True
151
+
152
+ for route_part, path_part in zip(route_parts, path_parts):
153
+ if route_part.startswith('{') and route_part.endswith('}'):
154
+ param_name = route_part[1:-1]
155
+ params[param_name] = path_part
156
+ elif route_part != path_part:
157
+ match = False
158
+ break
159
+ if match:
160
+ return handler, params, middleware
161
+ return None, None, []
162
+
163
+ async def _dispatch_request(self, scope, receive):
164
+
165
+ request = Request(scope, receive)
166
+ handler, params, route_middleware = self.find_route(request.method, request.path)
167
+
168
+ if not handler:
169
+ return Response(content={"error": "Route Not Found"}, status_code=404)
170
+
171
+ async def handler_call(req):
172
+ return await handler(req, **params)
173
+
174
+ chain = handler_call
175
+ for mw in reversed(route_middleware):
176
+ chain = self._wrap_middleware_for_dispatch(mw, chain)
177
+
178
+ response = await chain(request)
179
+ return response
180
+
181
+ def _wrap_middleware_for_dispatch(self, middleware_func, next_in_chain):
182
+ async def new_chain_link(request):
183
+ return await middleware_func(request, next_in_chain)
184
+ return new_chain_link
185
+
186
+
187
+ async def __call__(self, scope, receive, send):
188
+ if scope["type"] != "http": return
189
+ response = await self.app(scope, receive)
190
+ await response.send_to_asgi(send)
@@ -0,0 +1,187 @@
1
+ Metadata-Version: 2.4
2
+ Name: serpy-rest
3
+ Version: 0.1.0
4
+ Summary: A minimal ASGI web framework for Python.
5
+ Home-page: https://github.com/ragav2005/SerPy
6
+ Author: Ragav Vignes
7
+ Author-email: ragavvignesviswanathan@gmail.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Framework :: AsyncIO
12
+ Requires-Python: >=3.7
13
+ Description-Content-Type: text/markdown
14
+ Dynamic: author
15
+ Dynamic: author-email
16
+ Dynamic: classifier
17
+ Dynamic: description
18
+ Dynamic: description-content-type
19
+ Dynamic: home-page
20
+ Dynamic: requires-python
21
+ Dynamic: summary
22
+
23
+ # SerPy
24
+
25
+ SerPy is a minimal, modern, and lightning-fast ASGI web framework for Python. It is designed for simplicity, flexibility, and performance, making it ideal for building APIs, microservices, and web applications with minimal overhead.
26
+
27
+ ---
28
+
29
+ ## Table of Contents
30
+
31
+ - [Features](#features)
32
+ - [Installation](#installation)
33
+ - [Quick Start](#quick-start)
34
+ - [Example Project](#example-project)
35
+ - [Middleware](#middleware)
36
+ - [Advanced Routing](#advanced-routing)
37
+ - [Contributing](#contributing)
38
+ - [Running Locally](#running-locally)
39
+ - [License](#license)
40
+ - [Contact](#contact)
41
+
42
+ ---
43
+
44
+ ## Features
45
+
46
+ - **ASGI compatible**: Works seamlessly with ASGI servers like Uvicorn and Hypercorn
47
+ - **Simple routing**: Path parameters, method-based routing, and easy route registration
48
+ - **Middleware support**: Add custom middleware for logging, authentication, CORS, etc.
49
+ - **Request/Response abstraction**: Clean API for handling requests and responses
50
+ - **Modular**: Use routers to organize your application
51
+ - **Type hints**: Modern Pythonic code with type hints
52
+
53
+ ---
54
+
55
+ ## Installation
56
+
57
+ Install the latest release from PyPI:
58
+
59
+ ```bash
60
+ pip install serpy-asgi
61
+ ```
62
+
63
+ Or, to use the latest development version, clone this repository:
64
+
65
+ ```bash
66
+ git clone https://github.com/ragav2005/SerPy.git
67
+ cd SerPy
68
+ pip install .
69
+ ```
70
+
71
+ ---
72
+
73
+ ## Quick Start
74
+
75
+ Create a file called `main.py`:
76
+
77
+ ```python
78
+ from serpy import SerPy, Response
79
+
80
+ app = SerPy()
81
+
82
+ @app.route("/hello/{name}", methods=["GET"])
83
+ async def hello(request, name):
84
+ return Response({"message": f"Hello, {name}!"})
85
+
86
+ # Run with: uvicorn main:app
87
+ ```
88
+
89
+ Start the server:
90
+
91
+ ```bash
92
+ uvicorn main:app --reload
93
+ ```
94
+
95
+ ---
96
+
97
+ ## Example Project Structure
98
+
99
+ ```
100
+ myproject/
101
+ ├── main.py
102
+ ├── requirements.txt
103
+ └── ...
104
+ ```
105
+
106
+ ---
107
+
108
+ ## Middleware
109
+
110
+ Add global middleware to your app:
111
+
112
+ ```python
113
+ async def log_middleware(request, call_next):
114
+ print(f"Request: {request.method} {request.path}")
115
+ response = await call_next(request)
116
+ return response
117
+
118
+ app.add_middleware(log_middleware)
119
+ ```
120
+
121
+ ---
122
+
123
+ ## Advanced Routing
124
+
125
+ Use routers to organize endpoints:
126
+
127
+ ```python
128
+ from serpy import Router
129
+
130
+ user_router = Router()
131
+
132
+ @user_router.route("/users/{user_id}", methods=["GET"])
133
+ async def get_user(request, user_id):
134
+ # Fetch user logic here
135
+ return Response({"user_id": user_id})
136
+
137
+ app.include_router(user_router, prefix="/api")
138
+ ```
139
+
140
+ ---
141
+
142
+ ## Contributing
143
+
144
+ Contributions are welcome! To contribute:
145
+
146
+ 1. Fork the repository
147
+ 2. Create a new branch (`git checkout -b feature/your-feature`)
148
+ 3. Commit your changes
149
+ 4. Push to your fork and submit a pull request
150
+
151
+ Please ensure your code follows PEP8 and includes tests where appropriate.
152
+
153
+ ---
154
+
155
+ ## Running Locally (Development)
156
+
157
+ 1. Clone the repository:
158
+ ```bash
159
+ git clone https://github.com/ragav2005/SerPy.git
160
+ cd SerPy
161
+ ```
162
+ 2. (Optional) Create a virtual environment:
163
+ ```bash
164
+ python3 -m venv .venv
165
+ source .venv/bin/activate
166
+ ```
167
+ 3. Install dependencies:
168
+ ```bash
169
+ pip install -r requirements.txt
170
+ ```
171
+ 4. Run the example app or your own app with Uvicorn:
172
+ ```bash
173
+ uvicorn main:app --reload
174
+ ```
175
+
176
+ ---
177
+
178
+ ## License
179
+
180
+ This project is licensed under the MIT License.
181
+
182
+ ---
183
+
184
+ ## Contact
185
+
186
+ Author: [ragav2005](https://github.com/ragav2005)
187
+ For questions, suggestions, or issues, please open an issue on GitHub.
@@ -0,0 +1,7 @@
1
+ README.md
2
+ setup.py
3
+ serpy/__init__.py
4
+ serpy_rest.egg-info/PKG-INFO
5
+ serpy_rest.egg-info/SOURCES.txt
6
+ serpy_rest.egg-info/dependency_links.txt
7
+ serpy_rest.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ serpy
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,22 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="serpy-rest",
5
+ version="0.1.0",
6
+ description="A minimal ASGI web framework for Python.",
7
+ long_description=open("README.md").read(),
8
+ long_description_content_type="text/markdown",
9
+ author="Ragav Vignes",
10
+ author_email="ragavvignesviswanathan@gmail.com",
11
+ packages=find_packages(),
12
+ install_requires=[],
13
+ python_requires=">=3.7",
14
+ url="https://github.com/ragav2005/SerPy",
15
+ classifiers=[
16
+ "Programming Language :: Python :: 3",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Operating System :: OS Independent",
19
+ "Framework :: AsyncIO",
20
+ ],
21
+ include_package_data=True,
22
+ )