simplex 1.0.8__tar.gz → 1.0.11__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.

Potentially problematic release.


This version of simplex might be problematic. Click here for more details.

Files changed (26) hide show
  1. simplex-1.0.11/.DS_Store +0 -0
  2. simplex-1.0.11/.gitignore +33 -0
  3. {simplex-1.0.8/simplex.egg-info → simplex-1.0.11}/PKG-INFO +1 -1
  4. simplex-1.0.11/publish.sh +114 -0
  5. {simplex-1.0.8 → simplex-1.0.11}/pyproject.toml +2 -2
  6. simplex-1.0.11/requirements-dev.txt +14 -0
  7. {simplex-1.0.8 → simplex-1.0.11}/setup.py +1 -1
  8. {simplex-1.0.8 → simplex-1.0.11}/simplex/__init__.py +9 -1
  9. simplex-1.0.11/simplex/webhook.py +175 -0
  10. {simplex-1.0.8 → simplex-1.0.11/simplex.egg-info}/PKG-INFO +1 -1
  11. {simplex-1.0.8 → simplex-1.0.11}/simplex.egg-info/SOURCES.txt +5 -0
  12. {simplex-1.0.8 → simplex-1.0.11}/LICENSE +0 -0
  13. {simplex-1.0.8 → simplex-1.0.11}/MANIFEST.in +0 -0
  14. {simplex-1.0.8 → simplex-1.0.11}/README.md +0 -0
  15. {simplex-1.0.8 → simplex-1.0.11}/requirements.txt +0 -0
  16. {simplex-1.0.8 → simplex-1.0.11}/setup.cfg +0 -0
  17. {simplex-1.0.8 → simplex-1.0.11}/simplex/client.py +0 -0
  18. {simplex-1.0.8 → simplex-1.0.11}/simplex/errors.py +0 -0
  19. {simplex-1.0.8 → simplex-1.0.11}/simplex/http_client.py +0 -0
  20. {simplex-1.0.8 → simplex-1.0.11}/simplex/resources/__init__.py +0 -0
  21. {simplex-1.0.8 → simplex-1.0.11}/simplex/resources/workflow.py +0 -0
  22. {simplex-1.0.8 → simplex-1.0.11}/simplex/resources/workflow_session.py +0 -0
  23. {simplex-1.0.8 → simplex-1.0.11}/simplex/types.py +0 -0
  24. {simplex-1.0.8 → simplex-1.0.11}/simplex.egg-info/dependency_links.txt +0 -0
  25. {simplex-1.0.8 → simplex-1.0.11}/simplex.egg-info/requires.txt +0 -0
  26. {simplex-1.0.8 → simplex-1.0.11}/simplex.egg-info/top_level.txt +0 -0
Binary file
@@ -0,0 +1,33 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+
23
+ # Environment
24
+ .env
25
+ .venv
26
+ env/
27
+ venv/
28
+ ENV/
29
+
30
+ # IDE
31
+ .idea/
32
+ .vscode/
33
+ *.json
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simplex
3
- Version: 1.0.8
3
+ Version: 1.0.11
4
4
  Summary: Official Python SDK for the Simplex API
5
5
  Home-page: https://github.com/yourusername/simplex-python-sdk
6
6
  Author: Simplex
@@ -0,0 +1,114 @@
1
+ #!/bin/bash
2
+
3
+ # Exit on error
4
+ set -e
5
+
6
+ echo "Starting Python SDK publish script..."
7
+
8
+ # Load environment variables from .env
9
+ if [ -f .env ]; then
10
+ echo "Found .env file"
11
+ export $(cat .env | grep -v '^#' | xargs)
12
+ echo "Loaded environment variables"
13
+ else
14
+ echo "Error: .env file not found"
15
+ exit 1
16
+ fi
17
+
18
+ # Check if PYPI_API_TOKEN exists
19
+ if [ -z "$PYPI_API_TOKEN" ]; then
20
+ echo "Error: PYPI_API_TOKEN not found in .env file"
21
+ exit 1
22
+ fi
23
+ echo "Found PYPI_API_TOKEN"
24
+
25
+ # Extract current version from setup.py and increment patch version
26
+ echo "Attempting to read version from setup.py..."
27
+ if [ ! -f setup.py ]; then
28
+ echo "Error: setup.py file not found"
29
+ exit 1
30
+ fi
31
+
32
+ echo "Contents of setup.py version line:"
33
+ grep "version=" setup.py || echo "No version line found"
34
+
35
+ # More portable version extraction that works on both Mac and Linux
36
+ current_version=$(grep "version=" setup.py | sed 's/.*version="\([^"]*\)".*/\1/')
37
+ if [ -z "$current_version" ]; then
38
+ echo "Error: Could not extract version from setup.py"
39
+ echo "Make sure setup.py contains a line like: version='1.0.0' or version=\"1.0.0\""
40
+ exit 1
41
+ fi
42
+ echo "Current version: $current_version"
43
+ IFS='.' read -r major minor patch <<< "$current_version"
44
+ new_patch=$((patch + 1))
45
+ new_version="$major.$minor.$new_patch"
46
+
47
+ # Update version in setup.py (Mac-compatible sed syntax)
48
+ if [[ "$OSTYPE" == "darwin"* ]]; then
49
+ # Mac version - escape the quotes and use a different delimiter
50
+ sed -i '' "s|version=\"${current_version}\"|version=\"${new_version}\"|" setup.py
51
+ else
52
+ # Linux version
53
+ sed -i "s/version=\"${current_version}\"/version=\"${new_version}\"/" setup.py
54
+ fi
55
+
56
+ echo "Updated setup.py from $current_version to $new_version"
57
+
58
+ # Update version in pyproject.toml
59
+ if [ -f pyproject.toml ]; then
60
+ echo "Updating version in pyproject.toml..."
61
+ if [[ "$OSTYPE" == "darwin"* ]]; then
62
+ sed -i '' "s|version = \".*\"|version = \"${new_version}\"|" pyproject.toml
63
+ else
64
+ sed -i "s/version = \".*\"/version = \"${new_version}\"/" pyproject.toml
65
+ fi
66
+ echo "Updated pyproject.toml to $new_version"
67
+ fi
68
+
69
+ # Update version in simplex/__init__.py
70
+ if [ -f simplex/__init__.py ]; then
71
+ echo "Updating version in simplex/__init__.py..."
72
+ if [[ "$OSTYPE" == "darwin"* ]]; then
73
+ sed -i '' "s|__version__ = \".*\"|__version__ = \"${new_version}\"|" simplex/__init__.py
74
+ else
75
+ sed -i "s/__version__ = \".*\"/__version__ = \"${new_version}\"/" simplex/__init__.py
76
+ fi
77
+ echo "Updated simplex/__init__.py to $new_version"
78
+ fi
79
+
80
+ echo "All version files updated from $current_version to $new_version"
81
+
82
+ # Check BASE_URL in simplex/client.py
83
+ echo "Checking BASE_URL in simplex/client.py..."
84
+ if ! grep -q 'https://api.simplex.sh' simplex/client.py; then
85
+ echo "Warning: BASE_URL in simplex/client.py may not be set to production URL"
86
+ echo "Continuing anyway..."
87
+ fi
88
+ echo "BASE_URL check passed"
89
+
90
+ # Clean previous builds
91
+ echo "Cleaning previous builds..."
92
+ rm -rf dist/ build/ *.egg-info simplex.egg-info
93
+
94
+ # Build the package using modern build tool
95
+ echo "Building package..."
96
+ python -m build
97
+
98
+ # Upload to PyPI using API token
99
+ echo "Uploading to PyPI..."
100
+ TWINE_USERNAME=__token__ TWINE_PASSWORD=$PYPI_API_TOKEN python -m twine upload dist/*
101
+
102
+ echo "Successfully published version $new_version to PyPI"
103
+
104
+ # Create git commit and tag
105
+ echo "Creating git commit and tag..."
106
+ git add setup.py pyproject.toml simplex/__init__.py
107
+ git commit -m "Bump Python SDK version to $new_version"
108
+ git tag "python-v$new_version"
109
+ git push && git push --tags
110
+
111
+ echo "Created and pushed git tag python-v$new_version"
112
+ echo ""
113
+ echo "🎉 Python SDK v$new_version published successfully!"
114
+ echo "Users can now install with: pip install simplex"
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "simplex"
7
- version = "1.0.8"
7
+ version = "1.0.11"
8
8
  description = "Official Python SDK for the Simplex API"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -53,7 +53,7 @@ target-version = ['py38', 'py39', 'py310', 'py311']
53
53
  include = '\.pyi?$'
54
54
 
55
55
  [tool.mypy]
56
- python_version = "3.8"
56
+ python_version = "1.0.11"
57
57
  warn_return_any = true
58
58
  warn_unused_configs = true
59
59
  disallow_untyped_defs = false
@@ -0,0 +1,14 @@
1
+ # Development dependencies
2
+ -r requirements.txt
3
+
4
+ # Testing
5
+ pytest>=7.0.0
6
+ pytest-cov>=3.0.0
7
+
8
+ # Code quality
9
+ black>=22.0.0
10
+ flake8>=4.0.0
11
+ mypy>=0.950
12
+
13
+ # Utilities
14
+ python-dotenv>=0.19.0
@@ -9,7 +9,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
9
9
 
10
10
  setup(
11
11
  name="simplex",
12
- version="1.0.9",
12
+ version="1.0.11",
13
13
  author="Simplex",
14
14
  author_email="support@simplex.sh",
15
15
  description="Official Python SDK for the Simplex API",
@@ -20,8 +20,13 @@ from simplex.errors import (
20
20
  )
21
21
  from simplex.resources.workflow import Workflow
22
22
  from simplex.resources.workflow_session import WorkflowSession
23
+ from simplex.webhook import (
24
+ verify_simplex_webhook,
25
+ verify_simplex_webhook_dict,
26
+ WebhookVerificationError,
27
+ )
23
28
 
24
- __version__ = "1.0.0"
29
+ __version__ = "1.0.11"
25
30
  __all__ = [
26
31
  "SimplexClient",
27
32
  "SimplexError",
@@ -32,4 +37,7 @@ __all__ = [
32
37
  "WorkflowError",
33
38
  "Workflow",
34
39
  "WorkflowSession",
40
+ "verify_simplex_webhook",
41
+ "verify_simplex_webhook_dict",
42
+ "WebhookVerificationError",
35
43
  ]
@@ -0,0 +1,175 @@
1
+ """
2
+ Webhook verification utilities for Simplex webhooks.
3
+
4
+ This module provides functions to verify the authenticity of webhook requests
5
+ from Simplex using HMAC-SHA256 signature verification.
6
+
7
+ Example usage:
8
+ >>> from simplex import verify_simplex_webhook, WebhookVerificationError
9
+ >>>
10
+ >>> try:
11
+ >>> verify_simplex_webhook(
12
+ >>> body=request.body,
13
+ >>> signature=request.headers.get('X-Simplex-Signature'),
14
+ >>> webhook_secret='your-webhook-secret'
15
+ >>> )
16
+ >>> # Webhook verified, safe to process
17
+ >>> except WebhookVerificationError as e:
18
+ >>> # Invalid webhook
19
+ >>> print(f"Verification failed: {e}")
20
+ """
21
+
22
+ import hmac
23
+ import hashlib
24
+ from typing import Optional, Union, Dict
25
+
26
+
27
+ class WebhookVerificationError(Exception):
28
+ """
29
+ Exception raised when webhook verification fails.
30
+
31
+ This error is raised when:
32
+ - The signature header is missing
33
+ - The signature is invalid
34
+ - The signature doesn't match the expected value
35
+ """
36
+
37
+ def __init__(self, message: str):
38
+ """
39
+ Initialize a WebhookVerificationError.
40
+
41
+ Args:
42
+ message: Description of the verification failure
43
+ """
44
+ super().__init__(message)
45
+ self.message = message
46
+
47
+
48
+ def verify_simplex_webhook(
49
+ body: Union[str, bytes],
50
+ signature: Optional[str],
51
+ webhook_secret: str
52
+ ) -> None:
53
+ """
54
+ Verify a Simplex webhook request using HMAC-SHA256 signature verification.
55
+
56
+ This function ensures that webhook requests are authentic and haven't been
57
+ tampered with in transit. It uses the same pattern as GitHub webhooks.
58
+
59
+ The signature is computed as: HMAC-SHA256(webhook_secret, request_body)
60
+
61
+ Args:
62
+ body: Raw request body as string or bytes (must be the original unparsed body)
63
+ signature: The X-Simplex-Signature header value from the request
64
+ webhook_secret: Your webhook secret from the Simplex dashboard
65
+
66
+ Raises:
67
+ WebhookVerificationError: If signature is missing, invalid, or verification fails
68
+
69
+ Example:
70
+ >>> # Flask example
71
+ >>> from flask import Flask, request, jsonify
72
+ >>> from simplex import verify_simplex_webhook, WebhookVerificationError
73
+ >>>
74
+ >>> app = Flask(__name__)
75
+ >>>
76
+ >>> @app.route('/webhook', methods=['POST'])
77
+ >>> def webhook():
78
+ >>> try:
79
+ >>> verify_simplex_webhook(
80
+ >>> body=request.get_data(as_text=True),
81
+ >>> signature=request.headers.get('X-Simplex-Signature'),
82
+ >>> webhook_secret='your-webhook-secret'
83
+ >>> )
84
+ >>>
85
+ >>> # Webhook verified, safe to process
86
+ >>> payload = request.get_json()
87
+ >>> print(f"Received webhook: {payload['session_id']}")
88
+ >>> return jsonify({'received': True})
89
+ >>>
90
+ >>> except WebhookVerificationError as e:
91
+ >>> return jsonify({'error': str(e)}), 401
92
+
93
+ Example:
94
+ >>> # FastAPI example
95
+ >>> from fastapi import FastAPI, Request, HTTPException
96
+ >>> from simplex import verify_simplex_webhook, WebhookVerificationError
97
+ >>>
98
+ >>> app = FastAPI()
99
+ >>>
100
+ >>> @app.post("/webhook")
101
+ >>> async def webhook(request: Request):
102
+ >>> body = await request.body()
103
+ >>> signature = request.headers.get('X-Simplex-Signature')
104
+ >>>
105
+ >>> try:
106
+ >>> verify_simplex_webhook(
107
+ >>> body=body,
108
+ >>> signature=signature,
109
+ >>> webhook_secret='your-webhook-secret'
110
+ >>> )
111
+ >>>
112
+ >>> payload = await request.json()
113
+ >>> return {'received': True}
114
+ >>>
115
+ >>> except WebhookVerificationError as e:
116
+ >>> raise HTTPException(status_code=401, detail=str(e))
117
+ """
118
+ # 1. Check required signature
119
+ if not signature:
120
+ raise WebhookVerificationError('Missing X-Simplex-Signature header')
121
+
122
+ # 2. Ensure body is bytes for HMAC computation
123
+ if isinstance(body, str):
124
+ body_bytes = body.encode('utf-8')
125
+ else:
126
+ body_bytes = body
127
+
128
+ # 3. Compute expected signature
129
+ expected_signature = hmac.new(
130
+ webhook_secret.encode('utf-8'),
131
+ body_bytes,
132
+ hashlib.sha256
133
+ ).hexdigest()
134
+
135
+ # 4. Compare signatures using constant-time comparison to prevent timing attacks
136
+ if not hmac.compare_digest(expected_signature, signature):
137
+ raise WebhookVerificationError('Invalid webhook signature')
138
+
139
+ # Webhook verified successfully!
140
+
141
+
142
+ def verify_simplex_webhook_dict(
143
+ body: Union[str, bytes],
144
+ headers: Dict[str, str],
145
+ webhook_secret: str
146
+ ) -> None:
147
+ """
148
+ Verify a Simplex webhook request using a headers dictionary.
149
+
150
+ This is a convenience wrapper around verify_simplex_webhook() that accepts
151
+ a headers dictionary and handles case-insensitive header lookup.
152
+
153
+ Args:
154
+ body: Raw request body as string or bytes
155
+ headers: Dictionary of request headers
156
+ webhook_secret: Your webhook secret from the Simplex dashboard
157
+
158
+ Raises:
159
+ WebhookVerificationError: If verification fails
160
+
161
+ Example:
162
+ >>> verify_simplex_webhook_dict(
163
+ >>> body=request.body,
164
+ >>> headers=dict(request.headers),
165
+ >>> webhook_secret='your-secret'
166
+ >>> )
167
+ """
168
+ # Try to find the signature header (case-insensitive)
169
+ signature = None
170
+ for key, value in headers.items():
171
+ if key.lower() == 'x-simplex-signature':
172
+ signature = value
173
+ break
174
+
175
+ verify_simplex_webhook(body, signature, webhook_secret)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simplex
3
- Version: 1.0.8
3
+ Version: 1.0.11
4
4
  Summary: Official Python SDK for the Simplex API
5
5
  Home-page: https://github.com/yourusername/simplex-python-sdk
6
6
  Author: Simplex
@@ -1,7 +1,11 @@
1
+ .DS_Store
2
+ .gitignore
1
3
  LICENSE
2
4
  MANIFEST.in
3
5
  README.md
6
+ publish.sh
4
7
  pyproject.toml
8
+ requirements-dev.txt
5
9
  requirements.txt
6
10
  setup.py
7
11
  simplex/__init__.py
@@ -9,6 +13,7 @@ simplex/client.py
9
13
  simplex/errors.py
10
14
  simplex/http_client.py
11
15
  simplex/types.py
16
+ simplex/webhook.py
12
17
  simplex.egg-info/PKG-INFO
13
18
  simplex.egg-info/SOURCES.txt
14
19
  simplex.egg-info/dependency_links.txt
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