optropic 1.0.0__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.
@@ -0,0 +1,58 @@
1
+ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2
+
3
+ # dependencies
4
+ node_modules/
5
+ /.pnp
6
+ .pnp.*
7
+ .yarn/*
8
+ !.yarn/patches
9
+ !.yarn/plugins
10
+ !.yarn/releases
11
+ !.yarn/versions
12
+
13
+ # testing
14
+ coverage/
15
+ .coverage
16
+ htmlcov/
17
+
18
+ # next.js
19
+ .next/
20
+ out/
21
+
22
+ # production
23
+ build/
24
+ dist/
25
+
26
+ # turbo
27
+ .turbo/
28
+
29
+ # misc
30
+ .DS_Store
31
+ *.pem
32
+
33
+ # debug
34
+ npm-debug.log*
35
+ yarn-debug.log*
36
+ yarn-error.log*
37
+ .pnpm-debug.log*
38
+
39
+ # env files (can opt-in for committing if needed)
40
+ .env*
41
+
42
+ # vercel
43
+ .vercel
44
+
45
+ # typescript
46
+ *.tsbuildinfo
47
+ next-env.d.ts
48
+ crates/
49
+
50
+ # Build outputs
51
+ .next/
52
+ dist/
53
+ lib/
54
+
55
+ # Test outputs
56
+ playwright-report/
57
+ test-results/
58
+ .env*.local
optropic-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Virtrex GmbH
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.
@@ -0,0 +1,221 @@
1
+ Metadata-Version: 2.4
2
+ Name: optropic
3
+ Version: 1.0.0
4
+ Summary: Official Python SDK for Optropic product authentication and verification
5
+ Project-URL: Homepage, https://optropic.com
6
+ Project-URL: Documentation, https://docs.optropic.com/sdk/python
7
+ Project-URL: Repository, https://github.com/optropic/sdk-python
8
+ Project-URL: Bug Tracker, https://github.com/optropic/sdk-python/issues
9
+ Author-email: Virtrex GmbH <dev@optropic.com>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: anti-counterfeit,authentication,optropic,product-verification,verification
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Security
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.9
25
+ Requires-Dist: httpx<1.0.0,>=0.24.0
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
28
+ Requires-Dist: pytest>=7.0; extra == 'dev'
29
+ Description-Content-Type: text/markdown
30
+
31
+ # optropic
32
+
33
+ Official Python SDK for Optropic product authentication.
34
+
35
+ [![PyPI version](https://badge.fury.io/py/optropic.svg)](https://pypi.org/project/optropic/)
36
+ [![Python](https://img.shields.io/pypi/pyversions/optropic.svg)](https://pypi.org/project/optropic/)
37
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
38
+
39
+ ## Features
40
+
41
+ - **Simple Authentication** - Single API key for all operations
42
+ - **Type-Safe** - Full type annotations with `py.typed` support
43
+ - **Fast Integration** - Copy-paste quickstart, production-ready
44
+ - **Vertical Agnostic** - Same API for pharma, luxury, art, and more
45
+ - **Error Transparency** - Clear error codes, actionable messages
46
+
47
+ ## Installation
48
+
49
+ ```bash
50
+ pip install optropic
51
+ ```
52
+
53
+ ## Quick Start
54
+
55
+ ```python
56
+ from optropic import OptropicClient
57
+
58
+ # Initialize the client
59
+ client = OptropicClient(api_key="op_live_xxxxxxxxxxxx")
60
+
61
+ # Verify an asset
62
+ result = client.verify("asset-id-or-short-id")
63
+
64
+ if result.signature_valid:
65
+ print("Product is genuine!")
66
+ print(f"Security level: {result.security_level}")
67
+ else:
68
+ print("Warning: verification failed")
69
+
70
+ # Or use as a context manager
71
+ with OptropicClient(api_key="op_live_xxxxxxxxxxxx") as client:
72
+ result = client.verify("asset-id-or-short-id")
73
+ print(result.status)
74
+ ```
75
+
76
+ ## API Reference
77
+
78
+ ### OptropicClient
79
+
80
+ The main client class for all SDK operations.
81
+
82
+ #### Constructor
83
+
84
+ ```python
85
+ client = OptropicClient(
86
+ api_key="op_live_xxx", # Required: Your API key
87
+ base_url="https://...", # Optional: For self-hosted deployments
88
+ timeout=30.0, # Optional: Request timeout in seconds (default: 30)
89
+ )
90
+ ```
91
+
92
+ ### Methods
93
+
94
+ #### verify(asset_id: str) -> VerifyResult
95
+
96
+ Verify an asset by ID or short_id.
97
+
98
+ ```python
99
+ result = client.verify("asset-id-or-short-id")
100
+
101
+ # Result fields
102
+ result.id # str: Asset ID
103
+ result.status # str: Verification status
104
+ result.security_level # str: 'signed', 'sealed', etc.
105
+ result.signature_valid # bool: Whether signature is valid
106
+ result.verification_count # int: Number of times verified
107
+ result.last_verified_at # str: ISO timestamp of last verification
108
+ result.revocation_status # str: 'active' or 'revoked'
109
+ result.verification_mode # str: 'online' or 'offline'
110
+ result.provenance_valid # Optional[bool]: Provenance chain validity
111
+ result.evidence # Optional[VerificationEvidence]: Detailed evidence
112
+ ```
113
+
114
+ ## Error Handling
115
+
116
+ All errors extend `OptropicError` with clear error codes:
117
+
118
+ ```python
119
+ from optropic import (
120
+ OptropicClient,
121
+ OptropicError,
122
+ AuthenticationError,
123
+ NotFoundError,
124
+ )
125
+
126
+ try:
127
+ result = client.verify("asset-id")
128
+ except NotFoundError:
129
+ print("Asset not found in system.")
130
+ except AuthenticationError:
131
+ print("Invalid API key.")
132
+ except OptropicError as e:
133
+ print(f"Error {e.code}: {e}")
134
+ print(f"HTTP status: {e.status}")
135
+ ```
136
+
137
+ ### Error Types
138
+
139
+ | Error | Code | Description |
140
+ |-------|------|-------------|
141
+ | `AuthenticationError` | `INVALID_API_KEY` | API key is invalid or missing |
142
+ | `NotFoundError` | `NOT_FOUND` | Asset doesn't exist in the system |
143
+ | `OptropicError` | varies | Base error for all other API errors |
144
+
145
+ ## Types
146
+
147
+ All types are frozen dataclasses with full type annotations:
148
+
149
+ ```python
150
+ from optropic import VerifyResult, VerificationEvidence
151
+ ```
152
+
153
+ - `VerifyResult` - Result of verifying an asset
154
+ - `VerificationEvidence` - Structured evidence from verification
155
+
156
+ ## Environment Variables
157
+
158
+ Recommended setup for production:
159
+
160
+ ```bash
161
+ # .env
162
+ OPTROPIC_API_KEY=op_live_xxxxxxxxxxxx
163
+ ```
164
+
165
+ ```python
166
+ import os
167
+ from optropic import OptropicClient
168
+
169
+ client = OptropicClient(api_key=os.environ["OPTROPIC_API_KEY"])
170
+ ```
171
+
172
+ ## Examples
173
+
174
+ ### Flask Backend
175
+
176
+ ```python
177
+ from flask import Flask, request, jsonify
178
+ from optropic import OptropicClient, NotFoundError
179
+
180
+ app = Flask(__name__)
181
+ client = OptropicClient(api_key=os.environ["OPTROPIC_API_KEY"])
182
+
183
+ @app.route("/api/verify", methods=["POST"])
184
+ def verify():
185
+ try:
186
+ result = client.verify(request.json["asset_id"])
187
+ return jsonify({
188
+ "status": result.status,
189
+ "signature_valid": result.signature_valid,
190
+ "security_level": result.security_level,
191
+ })
192
+ except NotFoundError:
193
+ return jsonify({"error": "Asset not found"}), 404
194
+ ```
195
+
196
+ ### Django View
197
+
198
+ ```python
199
+ import os
200
+ from django.http import JsonResponse
201
+ from optropic import OptropicClient
202
+
203
+ client = OptropicClient(api_key=os.environ["OPTROPIC_API_KEY"])
204
+
205
+ def verify_asset(request, asset_id):
206
+ result = client.verify(asset_id)
207
+ return JsonResponse({
208
+ "status": result.status,
209
+ "signature_valid": result.signature_valid,
210
+ })
211
+ ```
212
+
213
+ ## Support
214
+
215
+ - [Documentation](https://docs.optropic.com)
216
+ - [Email Support](mailto:support@optropic.com)
217
+ - [Issue Tracker](https://github.com/optropic/sdk-python/issues)
218
+
219
+ ## License
220
+
221
+ MIT - [Virtrex GmbH](https://optropic.com)
@@ -0,0 +1,191 @@
1
+ # optropic
2
+
3
+ Official Python SDK for Optropic product authentication.
4
+
5
+ [![PyPI version](https://badge.fury.io/py/optropic.svg)](https://pypi.org/project/optropic/)
6
+ [![Python](https://img.shields.io/pypi/pyversions/optropic.svg)](https://pypi.org/project/optropic/)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+
9
+ ## Features
10
+
11
+ - **Simple Authentication** - Single API key for all operations
12
+ - **Type-Safe** - Full type annotations with `py.typed` support
13
+ - **Fast Integration** - Copy-paste quickstart, production-ready
14
+ - **Vertical Agnostic** - Same API for pharma, luxury, art, and more
15
+ - **Error Transparency** - Clear error codes, actionable messages
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ pip install optropic
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ ```python
26
+ from optropic import OptropicClient
27
+
28
+ # Initialize the client
29
+ client = OptropicClient(api_key="op_live_xxxxxxxxxxxx")
30
+
31
+ # Verify an asset
32
+ result = client.verify("asset-id-or-short-id")
33
+
34
+ if result.signature_valid:
35
+ print("Product is genuine!")
36
+ print(f"Security level: {result.security_level}")
37
+ else:
38
+ print("Warning: verification failed")
39
+
40
+ # Or use as a context manager
41
+ with OptropicClient(api_key="op_live_xxxxxxxxxxxx") as client:
42
+ result = client.verify("asset-id-or-short-id")
43
+ print(result.status)
44
+ ```
45
+
46
+ ## API Reference
47
+
48
+ ### OptropicClient
49
+
50
+ The main client class for all SDK operations.
51
+
52
+ #### Constructor
53
+
54
+ ```python
55
+ client = OptropicClient(
56
+ api_key="op_live_xxx", # Required: Your API key
57
+ base_url="https://...", # Optional: For self-hosted deployments
58
+ timeout=30.0, # Optional: Request timeout in seconds (default: 30)
59
+ )
60
+ ```
61
+
62
+ ### Methods
63
+
64
+ #### verify(asset_id: str) -> VerifyResult
65
+
66
+ Verify an asset by ID or short_id.
67
+
68
+ ```python
69
+ result = client.verify("asset-id-or-short-id")
70
+
71
+ # Result fields
72
+ result.id # str: Asset ID
73
+ result.status # str: Verification status
74
+ result.security_level # str: 'signed', 'sealed', etc.
75
+ result.signature_valid # bool: Whether signature is valid
76
+ result.verification_count # int: Number of times verified
77
+ result.last_verified_at # str: ISO timestamp of last verification
78
+ result.revocation_status # str: 'active' or 'revoked'
79
+ result.verification_mode # str: 'online' or 'offline'
80
+ result.provenance_valid # Optional[bool]: Provenance chain validity
81
+ result.evidence # Optional[VerificationEvidence]: Detailed evidence
82
+ ```
83
+
84
+ ## Error Handling
85
+
86
+ All errors extend `OptropicError` with clear error codes:
87
+
88
+ ```python
89
+ from optropic import (
90
+ OptropicClient,
91
+ OptropicError,
92
+ AuthenticationError,
93
+ NotFoundError,
94
+ )
95
+
96
+ try:
97
+ result = client.verify("asset-id")
98
+ except NotFoundError:
99
+ print("Asset not found in system.")
100
+ except AuthenticationError:
101
+ print("Invalid API key.")
102
+ except OptropicError as e:
103
+ print(f"Error {e.code}: {e}")
104
+ print(f"HTTP status: {e.status}")
105
+ ```
106
+
107
+ ### Error Types
108
+
109
+ | Error | Code | Description |
110
+ |-------|------|-------------|
111
+ | `AuthenticationError` | `INVALID_API_KEY` | API key is invalid or missing |
112
+ | `NotFoundError` | `NOT_FOUND` | Asset doesn't exist in the system |
113
+ | `OptropicError` | varies | Base error for all other API errors |
114
+
115
+ ## Types
116
+
117
+ All types are frozen dataclasses with full type annotations:
118
+
119
+ ```python
120
+ from optropic import VerifyResult, VerificationEvidence
121
+ ```
122
+
123
+ - `VerifyResult` - Result of verifying an asset
124
+ - `VerificationEvidence` - Structured evidence from verification
125
+
126
+ ## Environment Variables
127
+
128
+ Recommended setup for production:
129
+
130
+ ```bash
131
+ # .env
132
+ OPTROPIC_API_KEY=op_live_xxxxxxxxxxxx
133
+ ```
134
+
135
+ ```python
136
+ import os
137
+ from optropic import OptropicClient
138
+
139
+ client = OptropicClient(api_key=os.environ["OPTROPIC_API_KEY"])
140
+ ```
141
+
142
+ ## Examples
143
+
144
+ ### Flask Backend
145
+
146
+ ```python
147
+ from flask import Flask, request, jsonify
148
+ from optropic import OptropicClient, NotFoundError
149
+
150
+ app = Flask(__name__)
151
+ client = OptropicClient(api_key=os.environ["OPTROPIC_API_KEY"])
152
+
153
+ @app.route("/api/verify", methods=["POST"])
154
+ def verify():
155
+ try:
156
+ result = client.verify(request.json["asset_id"])
157
+ return jsonify({
158
+ "status": result.status,
159
+ "signature_valid": result.signature_valid,
160
+ "security_level": result.security_level,
161
+ })
162
+ except NotFoundError:
163
+ return jsonify({"error": "Asset not found"}), 404
164
+ ```
165
+
166
+ ### Django View
167
+
168
+ ```python
169
+ import os
170
+ from django.http import JsonResponse
171
+ from optropic import OptropicClient
172
+
173
+ client = OptropicClient(api_key=os.environ["OPTROPIC_API_KEY"])
174
+
175
+ def verify_asset(request, asset_id):
176
+ result = client.verify(asset_id)
177
+ return JsonResponse({
178
+ "status": result.status,
179
+ "signature_valid": result.signature_valid,
180
+ })
181
+ ```
182
+
183
+ ## Support
184
+
185
+ - [Documentation](https://docs.optropic.com)
186
+ - [Email Support](mailto:support@optropic.com)
187
+ - [Issue Tracker](https://github.com/optropic/sdk-python/issues)
188
+
189
+ ## License
190
+
191
+ MIT - [Virtrex GmbH](https://optropic.com)
@@ -0,0 +1,17 @@
1
+ """Optropic Python SDK — asset verification and compliance."""
2
+
3
+ from .client import OptropicClient
4
+ from .types import VerifyResult, VerificationEvidence
5
+ from .errors import OptropicError, AuthenticationError, NotFoundError
6
+
7
+ __version__ = "1.0.0"
8
+
9
+ __all__ = [
10
+ "OptropicClient",
11
+ "VerifyResult",
12
+ "VerificationEvidence",
13
+ "OptropicError",
14
+ "AuthenticationError",
15
+ "NotFoundError",
16
+ "__version__",
17
+ ]
@@ -0,0 +1,95 @@
1
+ """Optropic Python SDK client."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import httpx
6
+
7
+ from .types import VerifyResult, VerificationEvidence
8
+ from .errors import OptropicError, AuthenticationError, NotFoundError
9
+
10
+ DEFAULT_BASE_URL = "https://api.optropic.com"
11
+
12
+
13
+ class OptropicClient:
14
+ """Client for the Optropic API.
15
+
16
+ Usage::
17
+
18
+ client = OptropicClient(api_key="op_live_xxx")
19
+ result = client.verify("asset-id-or-short-id")
20
+ print(result.signature_valid)
21
+ """
22
+
23
+ def __init__(
24
+ self,
25
+ api_key: str,
26
+ base_url: str = DEFAULT_BASE_URL,
27
+ timeout: float = 30.0,
28
+ ):
29
+ self._api_key = api_key
30
+ self._base_url = base_url.rstrip("/")
31
+ self._client = httpx.Client(
32
+ base_url=self._base_url,
33
+ headers={"x-api-key": api_key},
34
+ timeout=timeout,
35
+ )
36
+
37
+ def verify(self, asset_id: str) -> VerifyResult:
38
+ """Verify an asset by ID or short_id.
39
+
40
+ Args:
41
+ asset_id: UUID or short_id of the asset.
42
+
43
+ Returns:
44
+ VerifyResult with signature validity and revocation status.
45
+
46
+ Raises:
47
+ NotFoundError: If the asset does not exist.
48
+ AuthenticationError: If the API key is invalid.
49
+ OptropicError: For other API errors.
50
+ """
51
+ response = self._client.get(f"/v1/assets/{asset_id}/verify")
52
+ data = response.json()
53
+
54
+ if response.status_code == 404:
55
+ raise NotFoundError(data.get("message", "Asset not found"))
56
+ if response.status_code == 401:
57
+ raise AuthenticationError(data.get("message", "Unauthorized"))
58
+ if response.status_code >= 400:
59
+ raise OptropicError(
60
+ message=data.get("message", "Request failed"),
61
+ code=data.get("code", "UNKNOWN_ERROR"),
62
+ status=response.status_code,
63
+ )
64
+
65
+ evidence = VerificationEvidence(
66
+ signature_valid=data.get("signatureValid", False),
67
+ revocation_status=data.get("revocationStatus", "active"),
68
+ verification_mode=data.get("verificationMode", "online"),
69
+ provenance_valid=data.get("provenanceValid"),
70
+ security_level=data.get("securityLevel"),
71
+ verification_count=data.get("verificationCount"),
72
+ )
73
+
74
+ return VerifyResult(
75
+ id=data["id"],
76
+ status=data["status"],
77
+ security_level=data.get("securityLevel", "signed"),
78
+ signature_valid=data.get("signatureValid", False),
79
+ verification_count=data.get("verificationCount", 0),
80
+ last_verified_at=data.get("lastVerifiedAt", ""),
81
+ revocation_status=data.get("revocationStatus", "active"),
82
+ verification_mode=data.get("verificationMode", "online"),
83
+ provenance_valid=data.get("provenanceValid"),
84
+ evidence=evidence,
85
+ )
86
+
87
+ def close(self) -> None:
88
+ """Close the HTTP client."""
89
+ self._client.close()
90
+
91
+ def __enter__(self) -> "OptropicClient":
92
+ return self
93
+
94
+ def __exit__(self, *args: object) -> None:
95
+ self.close()
@@ -0,0 +1,24 @@
1
+ """Error types for the Optropic Python SDK."""
2
+
3
+
4
+ class OptropicError(Exception):
5
+ """Base error for all Optropic SDK errors."""
6
+
7
+ def __init__(self, message: str, code: str = "UNKNOWN_ERROR", status: int = 0):
8
+ super().__init__(message)
9
+ self.code = code
10
+ self.status = status
11
+
12
+
13
+ class AuthenticationError(OptropicError):
14
+ """Raised when API key is invalid or missing."""
15
+
16
+ def __init__(self, message: str = "Invalid or missing API key"):
17
+ super().__init__(message, code="INVALID_API_KEY", status=401)
18
+
19
+
20
+ class NotFoundError(OptropicError):
21
+ """Raised when a resource is not found."""
22
+
23
+ def __init__(self, message: str = "Resource not found"):
24
+ super().__init__(message, code="NOT_FOUND", status=404)
File without changes
@@ -0,0 +1,73 @@
1
+ """Type definitions for the Optropic Python SDK."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from typing import Optional
7
+
8
+
9
+ @dataclass(frozen=True)
10
+ class VerificationEvidence:
11
+ """Structured evidence from an online verification."""
12
+
13
+ signature_valid: bool
14
+ revocation_status: str # 'active' or 'revoked'
15
+ verification_mode: str # 'online' or 'offline'
16
+ provenance_valid: Optional[bool] = None
17
+ security_level: Optional[str] = None
18
+ verification_count: Optional[int] = None
19
+
20
+
21
+ @dataclass(frozen=True)
22
+ class VerifyResult:
23
+ """Result of verifying an asset."""
24
+
25
+ id: str
26
+ status: str
27
+ security_level: str
28
+ signature_valid: bool
29
+ verification_count: int
30
+ last_verified_at: str
31
+ revocation_status: str
32
+ verification_mode: str
33
+ provenance_valid: Optional[bool] = None
34
+ evidence: Optional[VerificationEvidence] = None
35
+
36
+
37
+ @dataclass(frozen=True)
38
+ class RekorAnchor:
39
+ """Rekor transparency log anchor metadata."""
40
+
41
+ log_index: int
42
+ integrated_time: Optional[str] = None
43
+ entry_url: Optional[str] = None
44
+ verification_url: Optional[str] = None
45
+
46
+
47
+ @dataclass(frozen=True)
48
+ class MerkleRootRecord:
49
+ """Daily Merkle root with transparency log anchor status."""
50
+
51
+ id: str
52
+ root_hash: str
53
+ event_count: int
54
+ anchor_status: str # 'pending', 'anchored', 'failed', 'skipped'
55
+ date: str
56
+ created_at: Optional[str] = None
57
+ rekor: Optional[RekorAnchor] = None
58
+
59
+
60
+ @dataclass(frozen=True)
61
+ class ComplianceAttestation:
62
+ """Daily compliance attestation record."""
63
+
64
+ id: str
65
+ attestation_date: str
66
+ total_events: int
67
+ chain_integrity_valid: bool
68
+ rekor_anchored: bool
69
+ signature_hex: str
70
+ attestation_hash: str
71
+ previous_attestation_hash: Optional[str] = None
72
+ tenant_id: Optional[str] = None
73
+ created_at: Optional[str] = None
@@ -0,0 +1,44 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "optropic"
7
+ version = "1.0.0"
8
+ description = "Official Python SDK for Optropic product authentication and verification"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.9"
12
+ authors = [{name = "Virtrex GmbH", email = "dev@optropic.com"}]
13
+ keywords = ["optropic", "authentication", "anti-counterfeit", "product-verification", "verification"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.9",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Typing :: Typed",
25
+ "Topic :: Security",
26
+ ]
27
+ dependencies = [
28
+ "httpx>=0.24.0,<1.0.0",
29
+ ]
30
+
31
+ [project.urls]
32
+ Homepage = "https://optropic.com"
33
+ Documentation = "https://docs.optropic.com/sdk/python"
34
+ Repository = "https://github.com/optropic/sdk-python"
35
+ "Bug Tracker" = "https://github.com/optropic/sdk-python/issues"
36
+
37
+ [project.optional-dependencies]
38
+ dev = [
39
+ "pytest>=7.0",
40
+ "pytest-asyncio>=0.21",
41
+ ]
42
+
43
+ [tool.hatch.build.targets.wheel]
44
+ packages = ["optropic"]