analytics-platform 0.3.0__tar.gz → 0.3.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.
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/PKG-INFO +11 -1
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/README.md +10 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform/__init__.py +4 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform/core.py +1 -1
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform/proxy.py +10 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform.egg-info/PKG-INFO +11 -1
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/pyproject.toml +1 -1
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/tests/test_proxy.py +6 -1
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/LICENSE +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform/analytics.py +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform/audit.py +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform/crawlers.py +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform/django.py +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform/errors.py +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform/firewall.py +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform/flags.py +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform/forms.py +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform/inventory.py +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform/maintenance.py +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform/performance.py +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform/posture.py +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform/request_rules.py +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform/resources.py +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform.egg-info/SOURCES.txt +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform.egg-info/dependency_links.txt +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform.egg-info/top_level.txt +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/setup.cfg +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/tests/test_crawlers.py +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/tests/test_errors.py +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/tests/test_firewall.py +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/tests/test_request_rules.py +0 -0
- {analytics_platform-0.3.0 → analytics_platform-0.3.1}/tests/test_resources.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: analytics-platform
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: Firewall, error monitoring and server analytics for your Python server, run from your analytics dashboard.
|
|
5
5
|
Author: steviec87
|
|
6
6
|
License-Expression: MIT
|
|
@@ -179,6 +179,16 @@ Their errors carry the job's name as the route, a job that raises is sent
|
|
|
179
179
|
(status 500) and raised on, and each run is timed (Server speed → Jobs).
|
|
180
180
|
Several services on one site: `Platform(..., server_name="worker")`.
|
|
181
181
|
|
|
182
|
+
**Several apps on one site** (microservices, a worker, a Node service next to
|
|
183
|
+
this one): install the package in each, with the same `site_id`, `secret` and
|
|
184
|
+
`endpoint`, and a `server_name` of its own. Errors, Server speed, Crawlers and
|
|
185
|
+
Security → Updates then tell the apps apart. Without one, each app is named
|
|
186
|
+
after its machine: two apps on one machine are reported as one, and only the
|
|
187
|
+
last package list sent is kept. A service only your other apps call takes
|
|
188
|
+
`firewall=False, proxy=False, maintenance=False` (its requests all come from
|
|
189
|
+
your own apps, so the rate limit would see one visitor); on a machine shared
|
|
190
|
+
by several apps, keep `resources` on in only one of them.
|
|
191
|
+
|
|
182
192
|
Options: `server_name`, `root` (traceback paths relative to it),
|
|
183
193
|
`capture_uncaught`, `capture_logging`, `spool_dir` (where unsent errors wait;
|
|
184
194
|
`False` for none), `before_send(event, error)` (change an error, or return
|
|
@@ -153,6 +153,16 @@ Their errors carry the job's name as the route, a job that raises is sent
|
|
|
153
153
|
(status 500) and raised on, and each run is timed (Server speed → Jobs).
|
|
154
154
|
Several services on one site: `Platform(..., server_name="worker")`.
|
|
155
155
|
|
|
156
|
+
**Several apps on one site** (microservices, a worker, a Node service next to
|
|
157
|
+
this one): install the package in each, with the same `site_id`, `secret` and
|
|
158
|
+
`endpoint`, and a `server_name` of its own. Errors, Server speed, Crawlers and
|
|
159
|
+
Security → Updates then tell the apps apart. Without one, each app is named
|
|
160
|
+
after its machine: two apps on one machine are reported as one, and only the
|
|
161
|
+
last package list sent is kept. A service only your other apps call takes
|
|
162
|
+
`firewall=False, proxy=False, maintenance=False` (its requests all come from
|
|
163
|
+
your own apps, so the rate limit would see one visitor); on a machine shared
|
|
164
|
+
by several apps, keep `resources` on in only one of them.
|
|
165
|
+
|
|
156
166
|
Options: `server_name`, `root` (traceback paths relative to it),
|
|
157
167
|
`capture_uncaught`, `capture_logging`, `spool_dir` (where unsent errors wait;
|
|
158
168
|
`False` for none), `before_send(event, error)` (change an error, or return
|
|
@@ -100,6 +100,10 @@ class Platform:
|
|
|
100
100
|
# so its errors, timings and resources can be told apart.
|
|
101
101
|
if server_name and name in ("errors", "performance", "crawlers", "resources"):
|
|
102
102
|
opts.setdefault("server_name", server_name)
|
|
103
|
+
# Inventory and posture call it host, and are stored one per site
|
|
104
|
+
# and host: without it two services on one machine overwrite each other's.
|
|
105
|
+
if server_name and name in ("inventory", "posture"):
|
|
106
|
+
opts.setdefault("host", server_name)
|
|
103
107
|
try:
|
|
104
108
|
self._modules[name] = _load(name, self.core, opts)
|
|
105
109
|
except Exception as error:
|
|
@@ -47,6 +47,13 @@ def prefix_for(secret):
|
|
|
47
47
|
return hashlib.sha256(("proxy|" + str(secret)).encode("utf-8")).hexdigest()[:8]
|
|
48
48
|
|
|
49
49
|
|
|
50
|
+
# Sent as X-Proxy-Key, so the collector believes the visitor addresses this
|
|
51
|
+
# proxy passes on: anyone can write X-Forwarded-For. Worked out from the secret
|
|
52
|
+
# as the collector does (expresscollect/utils/proxyKey.js).
|
|
53
|
+
def key_for(secret):
|
|
54
|
+
return hashlib.sha256(("proxykey|" + str(secret)).encode("utf-8")).hexdigest()[:32]
|
|
55
|
+
|
|
56
|
+
|
|
50
57
|
class Proxy:
|
|
51
58
|
"""prefix: the path it answers on (default: from the secret)."""
|
|
52
59
|
|
|
@@ -54,6 +61,7 @@ class Proxy:
|
|
|
54
61
|
self.core = core
|
|
55
62
|
self.enabled = enabled
|
|
56
63
|
self.prefix = re.sub(r"[^A-Za-z0-9_-]", "", str(prefix or prefix_for(core.secret)))
|
|
64
|
+
self.key = key_for(core.secret) if core.secret else ""
|
|
57
65
|
# One copy of each tracker file, so a repeat visitor costs no upstream
|
|
58
66
|
# request. A handful of small files: it never grows.
|
|
59
67
|
self._files = {}
|
|
@@ -139,6 +147,8 @@ class Proxy:
|
|
|
139
147
|
# The visitor's address: the collector needs it for the country, the
|
|
140
148
|
# daily visitor ID and the per-visitor rate limit.
|
|
141
149
|
out = {"X-Forwarded-For": client_ip or ""}
|
|
150
|
+
if self.key:
|
|
151
|
+
out["X-Proxy-Key"] = self.key
|
|
142
152
|
for name in PASS_HEADERS:
|
|
143
153
|
value = headers.get(name)
|
|
144
154
|
if value:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: analytics-platform
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: Firewall, error monitoring and server analytics for your Python server, run from your analytics dashboard.
|
|
5
5
|
Author: steviec87
|
|
6
6
|
License-Expression: MIT
|
|
@@ -179,6 +179,16 @@ Their errors carry the job's name as the route, a job that raises is sent
|
|
|
179
179
|
(status 500) and raised on, and each run is timed (Server speed → Jobs).
|
|
180
180
|
Several services on one site: `Platform(..., server_name="worker")`.
|
|
181
181
|
|
|
182
|
+
**Several apps on one site** (microservices, a worker, a Node service next to
|
|
183
|
+
this one): install the package in each, with the same `site_id`, `secret` and
|
|
184
|
+
`endpoint`, and a `server_name` of its own. Errors, Server speed, Crawlers and
|
|
185
|
+
Security → Updates then tell the apps apart. Without one, each app is named
|
|
186
|
+
after its machine: two apps on one machine are reported as one, and only the
|
|
187
|
+
last package list sent is kept. A service only your other apps call takes
|
|
188
|
+
`firewall=False, proxy=False, maintenance=False` (its requests all come from
|
|
189
|
+
your own apps, so the rate limit would see one visitor); on a machine shared
|
|
190
|
+
by several apps, keep `resources` on in only one of them.
|
|
191
|
+
|
|
182
192
|
Options: `server_name`, `root` (traceback paths relative to it),
|
|
183
193
|
`capture_uncaught`, `capture_logging`, `spool_dir` (where unsent errors wait;
|
|
184
194
|
`False` for none), `before_send(event, error)` (change an error, or return
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "analytics-platform"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.1"
|
|
8
8
|
description = "Firewall, error monitoring and server analytics for your Python server, run from your analytics dashboard."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -12,7 +12,7 @@ from http.server import BaseHTTPRequestHandler, HTTPServer
|
|
|
12
12
|
|
|
13
13
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
14
14
|
|
|
15
|
-
from analytics_platform.proxy import Proxy, prefix_for # noqa: E402
|
|
15
|
+
from analytics_platform.proxy import Proxy, key_for, prefix_for # noqa: E402
|
|
16
16
|
|
|
17
17
|
TRACKER = b"// a tracker" + b"x" * 600
|
|
18
18
|
|
|
@@ -77,6 +77,10 @@ class ProxyTest(unittest.TestCase):
|
|
|
77
77
|
Collector.seen = []
|
|
78
78
|
self.proxy = Proxy(FakeCore(self.endpoint))
|
|
79
79
|
|
|
80
|
+
def test_the_proxy_key_is_worked_out_as_the_collector_does(self):
|
|
81
|
+
# The same vector is pinned in the collector, the backend and the other packages.
|
|
82
|
+
self.assertEqual(key_for("0123456789abcdef01234567"), "8fc74dbbd4f088449862841cd29fcaee")
|
|
83
|
+
|
|
80
84
|
def test_the_address_comes_from_the_secret(self):
|
|
81
85
|
self.assertEqual(prefix_for("s3cret"), prefix_for("s3cret"))
|
|
82
86
|
self.assertNotEqual(prefix_for("s3cret"), prefix_for("other"))
|
|
@@ -123,6 +127,7 @@ class ProxyTest(unittest.TestCase):
|
|
|
123
127
|
self.assertEqual(got["path"], "/collectanalytics/e?v=1")
|
|
124
128
|
self.assertEqual(got["body"], b'{"event":"pageview"}')
|
|
125
129
|
self.assertEqual(got["headers"].get("X-Forwarded-For"), "198.51.100.4")
|
|
130
|
+
self.assertEqual(got["headers"].get("X-Proxy-Key"), key_for("s3cret"), "so the collector believes the address")
|
|
126
131
|
self.assertEqual(got["headers"].get("User-Agent"), "Mozilla/5.0")
|
|
127
132
|
self.assertIsNone(got["headers"].get("Cookie"), "the site's own cookies stay on the site")
|
|
128
133
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{analytics_platform-0.3.0 → analytics_platform-0.3.1}/analytics_platform.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|