vybesec 0.1.10__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.
- vybesec-0.1.10/PKG-INFO +49 -0
- vybesec-0.1.10/README.md +40 -0
- vybesec-0.1.10/pyproject.toml +16 -0
- vybesec-0.1.10/setup.cfg +4 -0
- vybesec-0.1.10/vybesec/__init__.py +4 -0
- vybesec-0.1.10/vybesec/client.py +111 -0
- vybesec-0.1.10/vybesec/middleware.py +34 -0
- vybesec-0.1.10/vybesec.egg-info/PKG-INFO +49 -0
- vybesec-0.1.10/vybesec.egg-info/SOURCES.txt +10 -0
- vybesec-0.1.10/vybesec.egg-info/dependency_links.txt +1 -0
- vybesec-0.1.10/vybesec.egg-info/requires.txt +1 -0
- vybesec-0.1.10/vybesec.egg-info/top_level.txt +1 -0
vybesec-0.1.10/PKG-INFO
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vybesec
|
|
3
|
+
Version: 0.1.10
|
|
4
|
+
Summary: VybeSec server-side monitoring for Python.
|
|
5
|
+
Project-URL: Homepage, https://vybesec.com
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: requests>=2.31.0
|
|
9
|
+
|
|
10
|
+
# vybesec
|
|
11
|
+
|
|
12
|
+
Server-side error monitoring for Python backends (FastAPI/Flask/Django).
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install vybesec
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Init
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from vybesec import init, capture_exception
|
|
24
|
+
|
|
25
|
+
init(
|
|
26
|
+
key="pk_live_YOUR_KEY",
|
|
27
|
+
platform="other",
|
|
28
|
+
environment="production",
|
|
29
|
+
)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Manual capture
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
try:
|
|
36
|
+
raise ValueError("boom")
|
|
37
|
+
except Exception as exc:
|
|
38
|
+
capture_exception(exc, route="/api/checkout", method="POST", status_code=500)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## FastAPI middleware
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
from fastapi import FastAPI
|
|
45
|
+
from vybesec.middleware import VybesecMiddleware
|
|
46
|
+
|
|
47
|
+
app = FastAPI()
|
|
48
|
+
app.add_middleware(VybesecMiddleware)
|
|
49
|
+
```
|
vybesec-0.1.10/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# vybesec
|
|
2
|
+
|
|
3
|
+
Server-side error monitoring for Python backends (FastAPI/Flask/Django).
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install vybesec
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Init
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from vybesec import init, capture_exception
|
|
15
|
+
|
|
16
|
+
init(
|
|
17
|
+
key="pk_live_YOUR_KEY",
|
|
18
|
+
platform="other",
|
|
19
|
+
environment="production",
|
|
20
|
+
)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Manual capture
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
try:
|
|
27
|
+
raise ValueError("boom")
|
|
28
|
+
except Exception as exc:
|
|
29
|
+
capture_exception(exc, route="/api/checkout", method="POST", status_code=500)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## FastAPI middleware
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
from fastapi import FastAPI
|
|
36
|
+
from vybesec.middleware import VybesecMiddleware
|
|
37
|
+
|
|
38
|
+
app = FastAPI()
|
|
39
|
+
app.add_middleware(VybesecMiddleware)
|
|
40
|
+
```
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "vybesec"
|
|
7
|
+
version = "0.1.10"
|
|
8
|
+
description = "VybeSec server-side monitoring for Python."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"requests>=2.31.0"
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[project.urls]
|
|
16
|
+
Homepage = "https://vybesec.com"
|
vybesec-0.1.10/setup.cfg
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import time
|
|
4
|
+
import uuid
|
|
5
|
+
import traceback
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from typing import Optional, Dict, Any
|
|
8
|
+
|
|
9
|
+
import requests
|
|
10
|
+
|
|
11
|
+
SCRUB_PATTERNS = [
|
|
12
|
+
(r"sk-[a-zA-Z0-9]{20,}", "[api-key]"),
|
|
13
|
+
(r"pk_live_[a-zA-Z0-9]{20,}", "[stripe-key]"),
|
|
14
|
+
(r"whsec_[a-zA-Z0-9]{20,}", "[webhook-secret]"),
|
|
15
|
+
(r"Bearer\s+[a-zA-Z0-9\-_.]{20,}", "Bearer [token]"),
|
|
16
|
+
(r"eyJ[a-zA-Z0-9_-]{10,}\.[a-zA-Z0-9_-]{10,}", "[jwt]"),
|
|
17
|
+
(r"\b[A-Za-z0-9._%+\-]+@[A-Za-z0-9.\-]+\.[A-Za-z]{2,}\b", "[email]"),
|
|
18
|
+
(r"\b\d{4}[\s\-]?\d{4}[\s\-]?\d{4}[\s\-]?\d{4}\b", "[card]"),
|
|
19
|
+
(r"\b\d{3}-\d{2}-\d{4}\b", "[ssn]"),
|
|
20
|
+
(r'"password"\s*:\s*"[^"]+"', '"password":"[redacted]"'),
|
|
21
|
+
(r'"secret"\s*:\s*"[^"]+"', '"secret":"[redacted]"'),
|
|
22
|
+
(r'"token"\s*:\s*"[^"]+"', '"token":"[redacted]"'),
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def scrub_sensitive_data(value: str) -> str:
|
|
27
|
+
if not value:
|
|
28
|
+
return value
|
|
29
|
+
output = value
|
|
30
|
+
for pattern, replacement in SCRUB_PATTERNS:
|
|
31
|
+
output = __import__("re").sub(pattern, replacement, output)
|
|
32
|
+
return output
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass
|
|
36
|
+
class VybesecConfig:
|
|
37
|
+
key: str
|
|
38
|
+
platform: str = "other"
|
|
39
|
+
environment: str = "production"
|
|
40
|
+
release: str = ""
|
|
41
|
+
ingest_url: str = "https://vybesec-ingest.hexeldigitalstudio.workers.dev"
|
|
42
|
+
debug: bool = False
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
_CONFIG: Optional[VybesecConfig] = None
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def init(
|
|
49
|
+
*,
|
|
50
|
+
key: str,
|
|
51
|
+
platform: str = "other",
|
|
52
|
+
environment: str = "production",
|
|
53
|
+
release: str = "",
|
|
54
|
+
ingest_url: str = "https://vybesec-ingest.hexeldigitalstudio.workers.dev",
|
|
55
|
+
debug: bool = False,
|
|
56
|
+
) -> None:
|
|
57
|
+
global _CONFIG
|
|
58
|
+
_CONFIG = VybesecConfig(
|
|
59
|
+
key=key,
|
|
60
|
+
platform=platform,
|
|
61
|
+
environment=environment,
|
|
62
|
+
release=release,
|
|
63
|
+
ingest_url=ingest_url,
|
|
64
|
+
debug=debug,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def capture_exception(
|
|
69
|
+
exc: Exception,
|
|
70
|
+
*,
|
|
71
|
+
route: Optional[str] = None,
|
|
72
|
+
method: Optional[str] = None,
|
|
73
|
+
status_code: Optional[int] = None,
|
|
74
|
+
request_body: Optional[str] = None,
|
|
75
|
+
tags: Optional[Dict[str, str]] = None,
|
|
76
|
+
) -> None:
|
|
77
|
+
if _CONFIG is None:
|
|
78
|
+
print("[Vybesec] capture_exception called before init()")
|
|
79
|
+
return
|
|
80
|
+
|
|
81
|
+
message = scrub_sensitive_data(str(exc))
|
|
82
|
+
stack = scrub_sensitive_data("".join(traceback.format_exception(type(exc), exc, exc.__traceback__)))
|
|
83
|
+
body = scrub_sensitive_data(request_body).strip()[:500] if request_body else None
|
|
84
|
+
|
|
85
|
+
payload: Dict[str, Any] = {
|
|
86
|
+
"type": "error",
|
|
87
|
+
"message": message,
|
|
88
|
+
"stackTrace": stack,
|
|
89
|
+
"errorType": exc.__class__.__name__,
|
|
90
|
+
"source": "server",
|
|
91
|
+
"serverRuntime": "python",
|
|
92
|
+
"serverPlatform": "python",
|
|
93
|
+
"serverRoute": route,
|
|
94
|
+
"serverMethod": method,
|
|
95
|
+
"serverStatusCode": status_code,
|
|
96
|
+
"requestBody": body,
|
|
97
|
+
"platform": _CONFIG.platform,
|
|
98
|
+
"environment": _CONFIG.environment,
|
|
99
|
+
"release": _CONFIG.release,
|
|
100
|
+
"sdkVersion": "0.1.0",
|
|
101
|
+
"timestamp": int(time.time() * 1000),
|
|
102
|
+
"tags": tags or {},
|
|
103
|
+
"sessionId": uuid.uuid4().hex[:16],
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
url = f"{_CONFIG.ingest_url}/v1/server-events/{_CONFIG.key}"
|
|
107
|
+
try:
|
|
108
|
+
requests.post(url, json=[payload], timeout=2)
|
|
109
|
+
except Exception as err:
|
|
110
|
+
if _CONFIG.debug:
|
|
111
|
+
print("[Vybesec] Send failed:", err)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Callable, Awaitable
|
|
4
|
+
|
|
5
|
+
from .client import capture_exception
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
from starlette.middleware.base import BaseHTTPMiddleware
|
|
9
|
+
from starlette.requests import Request
|
|
10
|
+
except Exception: # pragma: no cover
|
|
11
|
+
BaseHTTPMiddleware = object # type: ignore
|
|
12
|
+
Request = object # type: ignore
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class VybesecMiddleware(BaseHTTPMiddleware):
|
|
16
|
+
async def dispatch(self, request: Request, call_next: Callable[[Request], Awaitable]): # type: ignore[override]
|
|
17
|
+
try:
|
|
18
|
+
response = await call_next(request)
|
|
19
|
+
return response
|
|
20
|
+
except Exception as exc:
|
|
21
|
+
body_text = None
|
|
22
|
+
try:
|
|
23
|
+
body = await request.body() # type: ignore[attr-defined]
|
|
24
|
+
body_text = body.decode("utf-8") if body else None
|
|
25
|
+
except Exception:
|
|
26
|
+
body_text = None
|
|
27
|
+
capture_exception(
|
|
28
|
+
exc,
|
|
29
|
+
route=getattr(request, "url", None).path if getattr(request, "url", None) else None,
|
|
30
|
+
method=getattr(request, "method", None),
|
|
31
|
+
status_code=500,
|
|
32
|
+
request_body=body_text,
|
|
33
|
+
)
|
|
34
|
+
raise
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vybesec
|
|
3
|
+
Version: 0.1.10
|
|
4
|
+
Summary: VybeSec server-side monitoring for Python.
|
|
5
|
+
Project-URL: Homepage, https://vybesec.com
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: requests>=2.31.0
|
|
9
|
+
|
|
10
|
+
# vybesec
|
|
11
|
+
|
|
12
|
+
Server-side error monitoring for Python backends (FastAPI/Flask/Django).
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install vybesec
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Init
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from vybesec import init, capture_exception
|
|
24
|
+
|
|
25
|
+
init(
|
|
26
|
+
key="pk_live_YOUR_KEY",
|
|
27
|
+
platform="other",
|
|
28
|
+
environment="production",
|
|
29
|
+
)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Manual capture
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
try:
|
|
36
|
+
raise ValueError("boom")
|
|
37
|
+
except Exception as exc:
|
|
38
|
+
capture_exception(exc, route="/api/checkout", method="POST", status_code=500)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## FastAPI middleware
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
from fastapi import FastAPI
|
|
45
|
+
from vybesec.middleware import VybesecMiddleware
|
|
46
|
+
|
|
47
|
+
app = FastAPI()
|
|
48
|
+
app.add_middleware(VybesecMiddleware)
|
|
49
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
requests>=2.31.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
vybesec
|