mbuzz 0.1.0__py3-none-any.whl → 0.1.1__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.
mbuzz/middleware/flask.py CHANGED
@@ -8,6 +8,7 @@ from ..config import config
8
8
  from ..context import RequestContext, set_context, clear_context
9
9
  from ..cookies import VISITOR_COOKIE, SESSION_COOKIE, VISITOR_MAX_AGE, SESSION_MAX_AGE
10
10
  from ..utils.identifier import generate_id
11
+ from ..utils.session_id import generate_deterministic, generate_from_fingerprint
11
12
  from ..client.session import create_session
12
13
 
13
14
 
@@ -55,8 +56,29 @@ def _get_or_create_visitor_id() -> str:
55
56
 
56
57
 
57
58
  def _get_or_create_session_id() -> str:
58
- """Get session ID from cookie or generate new one."""
59
- return request.cookies.get(SESSION_COOKIE) or generate_id()
59
+ """Get session ID from cookie or generate deterministic one."""
60
+ existing = request.cookies.get(SESSION_COOKIE)
61
+ if existing:
62
+ return existing
63
+
64
+ existing_visitor_id = request.cookies.get(VISITOR_COOKIE)
65
+ if existing_visitor_id:
66
+ return generate_deterministic(existing_visitor_id)
67
+ else:
68
+ return generate_from_fingerprint(_get_client_ip(), _get_user_agent())
69
+
70
+
71
+ def _get_client_ip() -> str:
72
+ """Get client IP from request headers."""
73
+ forwarded = request.headers.get("X-Forwarded-For", "")
74
+ if forwarded:
75
+ return forwarded.split(",")[0].strip()
76
+ return request.remote_addr or "unknown"
77
+
78
+
79
+ def _get_user_agent() -> str:
80
+ """Get user agent from request."""
81
+ return request.headers.get("User-Agent", "unknown")
60
82
 
61
83
 
62
84
  def _set_request_context(visitor_id: str, session_id: str) -> None:
@@ -0,0 +1,39 @@
1
+ """Deterministic session ID generation."""
2
+
3
+ import hashlib
4
+ import secrets
5
+ import time
6
+
7
+ SESSION_TIMEOUT_SECONDS = 1800
8
+ SESSION_ID_LENGTH = 64
9
+ FINGERPRINT_LENGTH = 32
10
+
11
+
12
+ def generate_deterministic(visitor_id: str, timestamp: int | None = None) -> str:
13
+ """Generate session ID for returning visitors."""
14
+ if timestamp is None:
15
+ timestamp = int(time.time())
16
+ time_bucket = timestamp // SESSION_TIMEOUT_SECONDS
17
+ raw = f"{visitor_id}_{time_bucket}"
18
+ return hashlib.sha256(raw.encode()).hexdigest()[:SESSION_ID_LENGTH]
19
+
20
+
21
+ def generate_from_fingerprint(
22
+ client_ip: str,
23
+ user_agent: str,
24
+ timestamp: int | None = None
25
+ ) -> str:
26
+ """Generate session ID for new visitors using IP+UA fingerprint."""
27
+ if timestamp is None:
28
+ timestamp = int(time.time())
29
+ fingerprint = hashlib.sha256(
30
+ f"{client_ip}|{user_agent}".encode()
31
+ ).hexdigest()[:FINGERPRINT_LENGTH]
32
+ time_bucket = timestamp // SESSION_TIMEOUT_SECONDS
33
+ raw = f"{fingerprint}_{time_bucket}"
34
+ return hashlib.sha256(raw.encode()).hexdigest()[:SESSION_ID_LENGTH]
35
+
36
+
37
+ def generate_random() -> str:
38
+ """Generate random session ID (fallback)."""
39
+ return secrets.token_hex(32)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mbuzz
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: Multi-touch attribution SDK for Python
5
5
  Project-URL: Homepage, https://mbuzz.co
6
6
  Project-URL: Documentation, https://mbuzz.co/docs/getting-started
@@ -9,9 +9,10 @@ mbuzz/client/identify.py,sha256=duyd-OWdBo4w7-7Nv5X-GeG2IpMI-1G_kYwnDXup0FE,859
9
9
  mbuzz/client/session.py,sha256=mk8v892bvpeW-VNKFQYDsW442w881yfXBiM4sr9a0SU,835
10
10
  mbuzz/client/track.py,sha256=-leW3yJcg9Vm6dL7fLQvFwgUN-nZF-OmDRMeR_9Blz8,3725
11
11
  mbuzz/middleware/__init__.py,sha256=gIjwTArToaQNB2NC0iPE_RcmzuHjH7-7jjd7_Dyq4Pw,37
12
- mbuzz/middleware/flask.py,sha256=dRn8rnOTSrd0w7GjwzjxFFFGuCe7J84MvaNGTT5w4_k,3453
12
+ mbuzz/middleware/flask.py,sha256=s3U77A2986L-KvWUH9MmqSwJwQWzQTYlZPZXH-wzE9o,4182
13
13
  mbuzz/utils/__init__.py,sha256=-ejtRN6CTkV3D8uujDtAPDoMT0DAG-ULpWOF-Ae55dY,103
14
14
  mbuzz/utils/identifier.py,sha256=iAYmd4he2RTtTNlmszb6KQmD9McZbSMgZZdkMuoGOCE,174
15
- mbuzz-0.1.0.dist-info/METADATA,sha256=HvgtdBRMTA3QqdpOrlkMUqIMoeq5LKnYPUuNrnwF9Hs,1849
16
- mbuzz-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
17
- mbuzz-0.1.0.dist-info/RECORD,,
15
+ mbuzz/utils/session_id.py,sha256=3XJkzPg5iUIbRYzz5LThfS8WTAmlmtn60WZTA_TlVhk,1185
16
+ mbuzz-0.1.1.dist-info/METADATA,sha256=bs7g2oYQ3tRv5sHTWyA7wx4J5WC0z0OOTRUmQEdqKcQ,1849
17
+ mbuzz-0.1.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
18
+ mbuzz-0.1.1.dist-info/RECORD,,
File without changes