fasthttp-client 0.1.0__py3-none-any.whl

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.
fasthttp/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ from fasthttp.app import FastHTTP
2
+
3
+ __all__ = ("FastHTTP",)
fasthttp/app.py ADDED
@@ -0,0 +1,237 @@
1
+ import asyncio
2
+ import time
3
+ from collections.abc import Callable
4
+ from typing import Annotated, Literal
5
+
6
+ import aiohttp
7
+ from annotated_doc import Doc
8
+
9
+ from fasthttp.client import HTTPClient
10
+ from fasthttp.logging import setup_logger
11
+ from fasthttp.routing import Route
12
+ from fasthttp.types import RequestsOptinal
13
+
14
+
15
+ class FastHTTP:
16
+ """
17
+ FastHTTP application entry point.
18
+
19
+ FastHTTP is a lightweight asynchronous HTTP client framework
20
+ built on top of aiohttp. It provides a clean decorator-based API
21
+ for defining HTTP requests and handling responses, similar to
22
+ web frameworks like FastAPI, but for outgoing requests.
23
+
24
+ The application manages:
25
+ - Request routing via decorators (GET, POST, PUT, PATCH, DELETE)
26
+ - Per-method default request configuration
27
+ - Async request execution
28
+ - Structured and colorized logging
29
+ - Unified Response handling
30
+
31
+ Example:
32
+ ```python
33
+ from fasthttp import FastHTTP
34
+ from fasthttp.response import Response
35
+
36
+ app = FastHTTP()
37
+
38
+ @app.get(url="https://httpbin.org/get")
39
+ async def get_data(resp: Response):
40
+ return resp.json()
41
+
42
+ if __name__ == "__main__":
43
+ app.run()
44
+ ```
45
+
46
+ """
47
+ def __init__(
48
+ self,
49
+ *,
50
+ debug: Annotated[
51
+ bool,
52
+ Doc(
53
+ """
54
+ Enable debug mode.
55
+
56
+ When enabled, FastHTTP will print datailed
57
+ tracebacks and requests/response logs.
58
+ """)] = False,
59
+
60
+ get_request: Annotated[
61
+ RequestsOptinal,
62
+ Doc(
63
+ """
64
+ Default configuration for GET requests.
65
+
66
+ Allows setting headers, timeout and other request-level
67
+ options that will be applied to all GET requests
68
+ """
69
+ )] | None = None,
70
+ post_request: Annotated[
71
+ RequestsOptinal,
72
+ Doc(
73
+ """
74
+ Default configuration for POST requests.
75
+
76
+ Used to define headers, timeout and other options
77
+
78
+ applied to all POST requests.
79
+ """
80
+ )] | None = None,
81
+ put_request: Annotated[
82
+ RequestsOptinal,
83
+ Doc(
84
+ """
85
+ Default configuration for PUT requests.
86
+
87
+ Controls request headers, timeout and other
88
+
89
+ options for PUT requests.
90
+ """
91
+ )] | None = None,
92
+ patch_request: Annotated[
93
+ RequestsOptinal,
94
+ Doc(
95
+ """
96
+ # Create the app
97
+ Default configuration for PATCH requests.
98
+
99
+ Used to configure headers, timeout and
100
+ other PATCH-specific options.
101
+ """
102
+ )] | None = None,
103
+ delete_request: Annotated[
104
+ RequestsOptinal,
105
+ Doc(
106
+ """
107
+ Default configuration for DELETE requests.
108
+
109
+ Allows defining haders, timeout,
110
+ and other options for DELETE requests.
111
+ """
112
+ )] | None = None,
113
+ ) -> None:
114
+ self.logger = setup_logger(debug=debug)
115
+ self.routes: list[Route] = []
116
+
117
+ self.request_configs = {
118
+ "GET": get_request or {},
119
+ "POST": post_request or {},
120
+ "PUT": put_request or {},
121
+ "PATCH": patch_request or {},
122
+ "DELETE": delete_request or {},
123
+ }
124
+
125
+ self.client = HTTPClient(self.request_configs, self.logger)
126
+
127
+ def _add_route(
128
+ self,
129
+ *,
130
+ method: Literal["GET", "POST", "PUT", "PATCH", "DELETE"],
131
+ url: str,
132
+ params=None,
133
+ json=None,
134
+ data=None,
135
+ ):
136
+ def decorator(func: Callable):
137
+ self.routes.append(
138
+ Route(
139
+ method=method,
140
+ url=url,
141
+ handler=func,
142
+ params=params,
143
+ json=json,
144
+ data=data,
145
+ )
146
+ )
147
+ self.logger.debug("Registered route: %s %s", method, url)
148
+ return func
149
+ return decorator
150
+
151
+ def get(self, *, url: str, params=None):
152
+ return self._add_route(
153
+ method="GET",
154
+ url=url,
155
+ params=params,
156
+ )
157
+
158
+ def post(self, *, url: str, json=None, data=None):
159
+ return self._add_route(
160
+ method="POST",
161
+ url=url,
162
+ json=json,
163
+ data=data,
164
+ )
165
+
166
+ def put(self, *, url: str, json=None, data=None):
167
+ return self._add_route(
168
+ method="PUT",
169
+ url=url,
170
+ json=json,
171
+ data=data,
172
+ )
173
+
174
+ def patch(self, *, url: str, json=None, data=None):
175
+ return self._add_route(
176
+ method="PATCH",
177
+ url=url,
178
+ json=json,
179
+ data=data,
180
+ )
181
+
182
+ def delete(self, *, url: str, json=None, data=None):
183
+ return self._add_route(
184
+ method="DELETE",
185
+ url=url,
186
+ json=json,
187
+ data=data,
188
+ )
189
+
190
+ async def _run(self) -> None:
191
+ total = len(self.routes)
192
+
193
+ self.logger.info("Sending %d requests", total)
194
+ start_all = time.perf_counter()
195
+
196
+ async with aiohttp.ClientSession() as session:
197
+ for route in self.routes:
198
+ start = time.perf_counter()
199
+
200
+ result = await self.client.send(session, route)
201
+ elapsed = (time.perf_counter() - start) * 1000
202
+
203
+ if result and isinstance(result.status, int):
204
+ self.logger.info(
205
+ "✔️ %-6s %-30s %s %6.2fms",
206
+ route.method,
207
+ route.url,
208
+ result.status,
209
+ elapsed,
210
+ )
211
+
212
+ handler_result = getattr(result, "_handler_result", None)
213
+ if handler_result is not None:
214
+ self.logger.debug("[RESULT] %s", handler_result)
215
+ elif result.text:
216
+ self.logger.debug("[RESULT] %s", result.text)
217
+ else:
218
+ self.logger.error(
219
+ "✖️ %-6s %-30s ERR %6.2fms",
220
+ route.method,
221
+ route.url,
222
+ elapsed,
223
+ )
224
+
225
+ await asyncio.sleep(0.5)
226
+
227
+ total_time = time.perf_counter() - start_all
228
+ self.logger.info("Done in %.2fs", total_time)
229
+
230
+ def run(self) -> None:
231
+ self.logger.info("FastHTTP started")
232
+ try:
233
+ asyncio.run(self._run())
234
+ except aiohttp.ClientConnectionError as e:
235
+ self.logger.error("Connection error: %s", e)
236
+ except KeyboardInterrupt:
237
+ self.logger.warning("Interrupted by user")
fasthttp/client.py ADDED
@@ -0,0 +1,90 @@
1
+ import asyncio
2
+ import time
3
+ from typing import Optional
4
+
5
+ import aiohttp
6
+
7
+ from fasthttp.response import Response
8
+ from fasthttp.routing import Route
9
+
10
+
11
+ class HTTPClient:
12
+ """
13
+ HTTP client responsible for sending HTTP requests.
14
+
15
+ This class manages low-level request execution using aiohttp,
16
+ applies per-method request configuration (headers, timeout, redirects),
17
+ logs request lifecycle events, and returns normalized Response objects.
18
+ """
19
+ def __init__(self, request_configs: dict, logger) -> None:
20
+ self.request_configs = request_configs
21
+ self.logger = logger
22
+
23
+ async def send(self, session: aiohttp.ClientSession, route: Route) -> Optional[Response]:
24
+ """
25
+ Send a single HTTP request based on a Route definition.
26
+
27
+ This method:
28
+ - Applies request configuration based on HTTP method
29
+ - Sends the request using an existing aiohttp ClientSession
30
+ - Measures request execution time
31
+ - Logs outgoing requests and incoming responses
32
+ - Executes the route handler with the Response object
33
+
34
+ Returns:
35
+ - Response instance if the request was successful
36
+ - Modified Response if the handler returned a string or Response
37
+ - None if a connection or timeout error occurred
38
+ """
39
+ config = self.request_configs.get(route.method, {})
40
+
41
+ self.logger.debug(
42
+ "→ %s %s | headers=%s",
43
+ route.method,
44
+ route.url,
45
+ config.get("headers"),
46
+ )
47
+
48
+ start = time.perf_counter()
49
+
50
+ try:
51
+ async with session.request(
52
+ method=route.method,
53
+ url=route.url,
54
+ headers=config.get("headers"),
55
+ params=route.params,
56
+ json=route.json,
57
+ data=route.data,
58
+ timeout=config.get("timeout"),
59
+ ) as resp:
60
+ elapsed = (time.perf_counter() - start) * 1000
61
+ text = await resp.text()
62
+
63
+ self.logger.info(
64
+ "← %s %s [%s] %.2fms",
65
+ route.method,
66
+ route.url,
67
+ resp.status,
68
+ elapsed,
69
+ )
70
+
71
+ response = Response(
72
+ status=resp.status,
73
+ text=text,
74
+ headers=dict(resp.headers),
75
+ )
76
+
77
+ handler_result = await route.handler(response)
78
+ if isinstance(handler_result, Response):
79
+ return handler_result
80
+ if isinstance(handler_result, str):
81
+ response.text = handler_result
82
+
83
+ response._handler_result = handler_result
84
+ return response
85
+
86
+ except (aiohttp.ClientConnectorError, asyncio.TimeoutError):
87
+ return None
88
+
89
+ except Exception:
90
+ return None
fasthttp/logging.py ADDED
@@ -0,0 +1,116 @@
1
+ import logging
2
+ import sys
3
+ from datetime import datetime, timezone
4
+ from typing import ClassVar
5
+
6
+ LOGGER_NAME = "fasthttp"
7
+
8
+
9
+ class ColorFormatter(logging.Formatter):
10
+ """
11
+ Custom logging formatter with colored output.
12
+
13
+ Adds ANSI colors, icons and improved formatting
14
+ to log records based on their log level.
15
+
16
+ Designed for CLI-friendly and readable logs.
17
+ """
18
+ RESET = "\033[0m"
19
+
20
+ BOLD = "\033[1m"
21
+ DIM = "\033[2m"
22
+
23
+ GRAY = "\033[90m"
24
+ CYAN = "\033[36m"
25
+ GREEN = "\033[32m"
26
+ YELLOW = "\033[33m"
27
+ BLUE = "\033[34m"
28
+ RED = "\033[31m"
29
+ RED_BG = "\033[41m"
30
+ PURPLE = "\033[35m"
31
+
32
+ LEVEL_COLORS: ClassVar[dict[int, str]] = {
33
+ logging.DEBUG: YELLOW,
34
+ logging.INFO: GREEN,
35
+ logging.WARNING: BLUE,
36
+ logging.ERROR: RED,
37
+ logging.CRITICAL: RED_BG,
38
+ }
39
+
40
+ LEVEL_ICONS: ClassVar[dict[int, str]] = {
41
+ logging.DEBUG: "🐛",
42
+ logging.INFO: "✔",
43
+ logging.WARNING: "⚠",
44
+ logging.ERROR: "✖",
45
+ logging.CRITICAL: "💀",
46
+ }
47
+
48
+ def formatTime(self, record, datefmt=None) -> str: # noqa N802
49
+ """
50
+ Format the timestamp of a log record.
51
+
52
+ Converts the record creation time to UTC
53
+ and formats it with millisecond precision.
54
+ """
55
+ t = datetime.fromtimestamp(record.created, tz=timezone.utc)
56
+ return f"{self.GRAY}{t.strftime('%H:%M:%S.%f')[:-3]}{self.RESET}"
57
+
58
+ def format(self, record: logging.LogRecord) -> str:
59
+ """
60
+ Format a log record with colors and icons.
61
+
62
+ Applies:
63
+ - Colored log level names
64
+ - Colored logger names
65
+ - Emoji icons based on log level
66
+ - Special formatting for result messages
67
+
68
+ Returns the fully formatted log string.
69
+ """
70
+ color = self.LEVEL_COLORS.get(record.levelno, self.RESET)
71
+ icon = self.LEVEL_ICONS.get(record.levelno, "")
72
+
73
+ record.levelname = (
74
+ f"{color}{self.BOLD}{record.levelname:<8}{self.RESET}"
75
+ )
76
+ record.name = f"{self.CYAN}{record.name}{self.RESET}"
77
+
78
+ msg = str(record.msg)
79
+
80
+ if msg.startswith("[RESULT]"):
81
+ record.msg = f"{self.PURPLE}↳ {msg[8:].strip()}{self.RESET}"
82
+ else:
83
+ record.msg = f"{color}{icon} {msg}{self.RESET}"
84
+
85
+ return super().format(record)
86
+
87
+
88
+ def setup_logger(*, debug: bool = False) -> logging.Logger:
89
+ """
90
+ Configure and return the application logger.
91
+
92
+ Creates a logger with colored output and
93
+ configurable verbosity based on debug mode.
94
+
95
+ If the logger is already configured,
96
+ returns the existing instance.
97
+ """
98
+ logger = logging.getLogger(LOGGER_NAME)
99
+
100
+ if logger.handlers:
101
+ return logger
102
+
103
+ logger.setLevel(logging.DEBUG)
104
+
105
+ handler = logging.StreamHandler(sys.stdout)
106
+ handler.setLevel(logging.DEBUG if debug else logging.INFO)
107
+
108
+ formatter = ColorFormatter(
109
+ "%(asctime)s │ %(levelname)s │ %(name)s │ %(message)s"
110
+ )
111
+
112
+ handler.setFormatter(formatter)
113
+ logger.addHandler(handler)
114
+ logger.propagate = False
115
+
116
+ return logger
fasthttp/response.py ADDED
@@ -0,0 +1,71 @@
1
+ import json
2
+ from typing import Annotated
3
+
4
+ from annotated_doc import Doc
5
+
6
+ from fasthttp.types import JSONResponse
7
+
8
+
9
+ class Response:
10
+ """
11
+ HTTP response object.
12
+
13
+ Represents an HTTP response returned by the server,
14
+ including status code, raw body text, and response headers.
15
+
16
+ Used by FastHTTP to pass response data to route handlers.
17
+ """
18
+ def __init__(
19
+ self,
20
+ status: Annotated[
21
+ int,
22
+ Doc(
23
+ """
24
+ HTTP status code of the response.
25
+
26
+ Indicates the result of the HTTP request
27
+ (e.g. 200 for success, 404 for not found,
28
+ 500 for server error).
29
+ """
30
+ )],
31
+ text: Annotated[
32
+ str,
33
+ Doc(
34
+ """
35
+ Raw response body as a string.
36
+
37
+ Contains the response payload exactly as
38
+ returned by the server.
39
+ """
40
+ )],
41
+ headers: Annotated[
42
+ dict,
43
+ Doc(
44
+ """
45
+ HTTP response headers.
46
+
47
+ A mapping of header names to their values
48
+ returned by the server.
49
+ """
50
+ )]
51
+ ) -> None:
52
+ self.status = status
53
+ self.text = text
54
+ self.headers = headers
55
+ self._handler_result = None
56
+
57
+ def json(self) -> JSONResponse.Value:
58
+ """
59
+ Parse the response body as JSON.
60
+
61
+ Returns the parsed JSON object. Raises a
62
+ ValueError if the response body is not valid JSON.
63
+ """
64
+ return json.loads(self.text)
65
+
66
+ def __repr__(self) -> str:
67
+ """
68
+ Return a debug-friendly string representation
69
+ of the response.
70
+ """
71
+ return f"<Response [{self.status}]>"
fasthttp/routing.py ADDED
@@ -0,0 +1,95 @@
1
+ from collections.abc import Callable
2
+ from typing import Annotated, Any, Literal
3
+
4
+ from annotated_doc import Doc
5
+
6
+
7
+ class Route:
8
+ """
9
+ Definition of an HTTP request route.
10
+
11
+ A Route binds together an HTTP method, a target URL,
12
+ optional request data, and a response handler function.
13
+
14
+ It is used by FastHTTP to send requests and process
15
+ responses in a structured and predictable way.
16
+ """
17
+ def __init__(
18
+ self,
19
+ *,
20
+ method: Annotated[
21
+ Literal["GET", "POST", "PUT", "PATCH", "DELETE"],
22
+ Doc(
23
+ """
24
+ HTTP method for the request.
25
+
26
+ Determines how the request will be sent to the server.
27
+
28
+ Suppoeted methods are:
29
+ GET, POST, PUT, PATCH, DELETE.
30
+ """
31
+ )],
32
+ url: Annotated[
33
+ str,
34
+ Doc(
35
+ """
36
+ Target URL for the HTTP request.
37
+
38
+ Must be a full URL including scheme, host and path
39
+ Example:
40
+ https://api.google.com/
41
+ """
42
+ )],
43
+ handler: Annotated[
44
+ Callable,
45
+ Doc(
46
+ """
47
+ Response handler function.
48
+
49
+ This asyncfunction will be called with a Response object
50
+ and can return:
51
+ - str
52
+ - Response
53
+ - None
54
+ """
55
+ )],
56
+ params: Annotated[
57
+ dict | None,
58
+ Doc(
59
+ """
60
+ Query parameters to be sent with the request.
61
+
62
+ The dictionary will be encoded into the URL query string
63
+ and appended to the request URL.
64
+ """
65
+ )] = None,
66
+ json: Annotated[
67
+ dict | None,
68
+ Doc(
69
+ """
70
+ JSON body to be sent with the request.
71
+
72
+ The data will be serialized to JSON and sent with the
73
+
74
+ application/json Content-Type header.
75
+ """
76
+ )] = None,
77
+ data: Annotated[
78
+ Any | None,
79
+ Doc(
80
+ """
81
+
82
+ Raw request body or form data.
83
+
84
+ Can be used to send form-encoded data, plain text,
85
+
86
+ binary payloads or any custom request body.
87
+ """
88
+ )] = None,
89
+ ) -> None:
90
+ self.method = method
91
+ self.url = url
92
+ self.handler = handler
93
+ self.params = params
94
+ self.json = json
95
+ self.data = data
fasthttp/types.py ADDED
@@ -0,0 +1,55 @@
1
+ from typing import Annotated, TypeAlias, TypedDict
2
+
3
+ from annotated_doc import Doc
4
+
5
+
6
+ class JSONResponse:
7
+ """
8
+ JSON response type definitions.
9
+
10
+ This class groups type aliases that describe valid JSON data
11
+ structures returned by HTTP responses.
12
+
13
+ It is used for type-safe annotations of parsed JSON payloads,
14
+ including primitive values, lists, and nested objects.
15
+ """
16
+ Primutive: TypeAlias = str | int | float | bool | None
17
+ Value: TypeAlias = Primutive | list["Value"] | dict[str, "Value"]
18
+
19
+
20
+ class RequestsOptinal(TypedDict, total=False):
21
+ """
22
+ Optional request configuration.
23
+
24
+ Defines optional parameters that control how HTTP requests
25
+ are sent, such as headers, timeouts, and redirect behavior.
26
+
27
+ All fields are optional and may be omitted if not needed.
28
+ """
29
+ headers: Annotated[
30
+ dict[str, str],
31
+ Doc(
32
+ """
33
+ HTTP headers to be sent with the request.
34
+ A dictionary of header names and values that will be included
35
+ in every request of this method type.
36
+ """
37
+ )]
38
+ timeout: Annotated[
39
+ float,
40
+ Doc(
41
+ """
42
+ Request timeout in seconds.
43
+ Specifies the maximum amount of time to wait for the server
44
+ to respond before the request is cancelled.
45
+ """
46
+ )]
47
+ allow_redirects: Annotated[
48
+ bool,
49
+ Doc(
50
+ """
51
+ Enable or disable HTTP redirects.
52
+ When set to True, the client will automatically follow
53
+ redirect responses (3xx status codes).
54
+ """
55
+ )]
@@ -0,0 +1,179 @@
1
+ Metadata-Version: 2.4
2
+ Name: fasthttp-client
3
+ Version: 0.1.0
4
+ Summary: Fast and simple HTTP client library with async support and beautiful logging
5
+ Project-URL: Homepage, https://github.com/ndugram/fasthttp
6
+ Project-URL: Documentation, https://github.com/ndugram/fasthttp
7
+ Project-URL: Repository, https://github.com/ndugram/fasthttp
8
+ Project-URL: Issues, https://github.com/ndugram/fasthttp/issues
9
+ Author-email: White NEFOR <n7for8572@gmail.com>
10
+ Maintainer-email: White NEFOR <n7for8572@gmail.com>
11
+ License: MIT
12
+ License-File: LICENSE
13
+ Keywords: aiohttp,async,client,fast,http,http-client,python,requests
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Topic :: Internet :: WWW/HTTP
24
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
25
+ Classifier: Topic :: System :: Networking
26
+ Classifier: Typing :: Typed
27
+ Requires-Python: >=3.10
28
+ Requires-Dist: aiohttp>=3.13.3
29
+ Requires-Dist: annotated-doc>=0.0.4
30
+ Provides-Extra: dev
31
+ Requires-Dist: mypy>=1.13.0; extra == 'dev'
32
+ Requires-Dist: pre-commit>=4.0.0; extra == 'dev'
33
+ Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
34
+ Requires-Dist: pytest-cov>=6.0.0; extra == 'dev'
35
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
36
+ Requires-Dist: ruff>=0.14.14; extra == 'dev'
37
+ Description-Content-Type: text/markdown
38
+
39
+ # FastHTTP Client
40
+
41
+ <div align="center">
42
+
43
+ ![PyPI version](https://badge.fury.io/py/fasthttp.svg)
44
+ ![Python Version](https://img.shields.io/pypi/pyversions/fasthttp.svg)
45
+ ![License](https://img.shields.io/pypi/l/fasthttp.svg)
46
+
47
+ **🚀 Simple & Fast HTTP Client for Python**
48
+
49
+ [Documentation](docs/index.md) • [Quick Start](#quick-start) • [Examples](docs/examples.md)
50
+
51
+ </div>
52
+
53
+ ## ⚡ Features
54
+
55
+ - **Simple API** - Minimal boilerplate with decorators
56
+ - **Beautiful Logging** - Colorful request/response logs with timing
57
+ - **Async Support** - Built on aiohttp for high performance
58
+ - **Type Safe** - Full type annotations
59
+ - **All HTTP Methods** - GET, POST, PUT, PATCH, DELETE
60
+
61
+ ## 🚀 Quick Start
62
+
63
+ ### Installation
64
+ ```bash
65
+ pip install fasthttp-client
66
+ ```
67
+
68
+ ### Basic Usage
69
+ ```python
70
+ from fasthttp import FastHTTP
71
+ from fasthttp.response import Response
72
+
73
+ app = FastHTTP()
74
+
75
+
76
+ @app.get(url="https://httpbin.org/get")
77
+ async def get_data(resp: Response):
78
+ return resp.json()
79
+
80
+
81
+ if __name__ == "__main__":
82
+ app.run()
83
+ ```
84
+
85
+ **Output:**
86
+ ```
87
+ 16:09:18.955 │ INFO │ fasthttp │ ✔ FastHTTP started
88
+ 16:09:19.519 │ INFO │ fasthttp │ ✔ ← GET https://httpbin.org/get [200] 458.26ms
89
+ 16:09:20.037 │ INFO │ fasthttp │ ✔ Done in 1.08s
90
+ ```
91
+
92
+ ### With Configuration
93
+ ```python
94
+ from fasthttp import FastHTTP
95
+ from fasthttp.response import Response
96
+
97
+ app = FastHTTP(
98
+ debug=True,
99
+ get_request={
100
+ "headers": {"User-Agent": "MyApp/1.0"},
101
+ "timeout": 10,
102
+ },
103
+ )
104
+
105
+ @app.get(url="https://api.github.com/users/octocat")
106
+ async def get_user(resp: Response):
107
+ return resp.json()
108
+
109
+ if __name__ == "__main__":
110
+ app.run()
111
+ ```
112
+
113
+ ## 🔧 All HTTP Methods
114
+
115
+ ```python
116
+ from fasthttp import FastHTTP
117
+ from fasthttp.response import Response
118
+
119
+ app = FastHTTP()
120
+
121
+ # GET
122
+ @app.get(url="https://jsonplaceholder.typicode.com/posts/1")
123
+ async def get_post(resp: Response):
124
+ return resp.json()
125
+
126
+ # POST
127
+ @app.post(url="https://httpbin.org/post", json={"name": "John"})
128
+ async def create_user(resp: Response):
129
+ return f"Created: {resp.status}"
130
+
131
+ # PUT
132
+ @app.put(url="https://httpbin.org/put", json={"name": "Jane"})
133
+ async def update_user(resp: Response):
134
+ return resp.json()
135
+
136
+ # DELETE
137
+ @app.delete(url="https://httpbin.org/delete")
138
+ async def delete_user(resp: Response):
139
+ return f"Delete: {resp.status}"
140
+ ```
141
+
142
+ ## 📚 Documentation
143
+
144
+ - **[📖 Documentation](docs/index.md)** - Complete guide
145
+ - **[⚡ Quick Start](docs/quick-start.md)** - Get started in 2 minutes
146
+ - **[🔧 API Reference](docs/api-reference.md)** - Full API documentation
147
+ - **[💡 Examples](docs/examples.md)** - Real-world examples
148
+ - **[⚙️ Configuration](docs/configuration.md)** - Advanced settings
149
+
150
+ ## 🛠️ Development
151
+
152
+ ```bash
153
+ git clone https://github.com/ndugram/fasthttp.git
154
+ cd fasthttp
155
+ pip install -e ".[dev]"
156
+
157
+ # Run tests
158
+ pytest
159
+
160
+ # Code quality
161
+ ruff format .
162
+ ruff check .
163
+ ```
164
+
165
+ ## 📄 License
166
+
167
+ MIT License - see [LICENSE](LICENSE) file for details.
168
+
169
+ ## 🤝 Contributing
170
+
171
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines.
172
+
173
+ ## 🔒 Security
174
+
175
+ See [SECURITY.md](SECURITY.md) for security policies.
176
+
177
+ ---
178
+
179
+ **Made with ❤️ by the NDUgram Team**
@@ -0,0 +1,11 @@
1
+ fasthttp/__init__.py,sha256=1Wvp_6J6cxKkwSajw8RTNCexOOp0FcGxW6yf0KJE90s,59
2
+ fasthttp/app.py,sha256=hiD78ceoEqoAyybRZA6lYMpcRrb2F116Q4z_A4uDKSE,6900
3
+ fasthttp/client.py,sha256=4-g_FxujNRR4cUZ4WhB7Wgadz0_RYl_QZCeoT4EIg00,2900
4
+ fasthttp/logging.py,sha256=SUNSSXIR61JDNzduMtM1BIIbDDg1NZUIwfygAlqq-uY,3087
5
+ fasthttp/response.py,sha256=7fueAqAkJoaDDRbW0zRgHBRrxuKfM_TBBAYG8PJ-xrs,1789
6
+ fasthttp/routing.py,sha256=oUGg3Ld2BgllRYcaURdgfaPz9qHZDlYQBeumZnJUBn4,2569
7
+ fasthttp/types.py,sha256=G6przuFoKv2K74kguWk2cznIx2nMC91VyFcvgL3cClk,1623
8
+ fasthttp_client-0.1.0.dist-info/METADATA,sha256=AzchcoK_pL9TVU-Q73RyHyHtyC_yX0HaJqByEQ6cM_w,4805
9
+ fasthttp_client-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
10
+ fasthttp_client-0.1.0.dist-info/licenses/LICENSE,sha256=Vz_vj5RNgcljwWVnBRK23jfM9H9I-Pwn0R7SDVxrOiQ,1086
11
+ fasthttp_client-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 安𝐍ᴇғᴏʀ | ᵈᵉᵛ
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.