### Install Dependencies Source: https://github.com/w24-service-gmbh/werk24-python/blob/main/CONTRIBUTING.md Install project dependencies using pip. Ensure you have a requirements.txt file. ```bash pip install -r requirements.txt ``` -------------------------------- ### Install and Initialize Werk24 Library Source: https://github.com/w24-service-gmbh/werk24-python/blob/main/README.md Install the library using pip and then run the initialization command to obtain a trial license. This is the first step before using the Werk24 client. ```bash pip install werk24 # install the library werk24 init # obtain a trial license ``` -------------------------------- ### Install and Authenticate Werk24 Client Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt Install the library using pip. Obtain a trial license using the CLI or set environment variables for authentication. The client resolves credentials in a specific order. ```bash pip install werk24 # Obtain a trial license (writes ~/.werk24 or .werk24) werk24 init # Or set environment variables directly export W24TECHREAD_AUTH_TOKEN=your_token_here export W24TECHREAD_AUTH_REGION=eu-central-1 ``` -------------------------------- ### Install Werk24 with other packages Source: https://github.com/w24-service-gmbh/werk24-python/blob/main/README.md Install the werk24 package along with other common data science libraries like requests, pandas, and numpy. Ensure you are in a virtual environment. ```bash # werk24 works well with other packages pip install werk24 requests pandas numpy ``` -------------------------------- ### Ask Types (v2) - Redaction Example (Python) Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt Demonstrates the configuration of `AskRedaction` with custom keywords, logo and company data redaction, PNG output format, and a specific fill color. ```python from werk24.models.v2.asks import ( AskMetaData, AskFeatures, AskInsights, AskBalloons, AskRedaction, AskReferencePositions, AskSheetImages, AskViewImages, AskCustom, ) from werk24.models.v2.enums import ThumbnailFileFormat, PostprocessorSlot from werk24.models.v2.models import RedactionKeyword # Redaction with custom keywords and PNG output redact_ask = AskRedaction( redact_logos=True, redact_company_data=True, redact_personal_data=True, redact_keywords=[RedactionKeyword(keyword="CONFIDENTIAL"), RedactionKeyword(keyword="SECRET")], output_format=ThumbnailFileFormat.PNG, fill_color="#000000", ) ``` -------------------------------- ### Read data from a technical drawing using Werk24Client Source: https://github.com/w24-service-gmbh/werk24-python/blob/main/README.md Asynchronously read data from a technical drawing using the Werk24Client. This example demonstrates how to initialize the client, specify the drawing file, and request metadata. Ensure you have the asyncio library available. ```python import asyncio from werk24 import Werk24Client, AskMetaData, get_test_drawing async def read_drawing(asks): fid = get_test_drawing() async with Werk24Client() as client: return [msg async for msg in client.read_drawing(fid, asks)] asyncio.run(read_drawing([AskMetaData()])) ``` -------------------------------- ### Check installed Werk24 versions and dependencies Source: https://github.com/w24-service-gmbh/werk24-python/blob/main/README.md Verify the installed version of the werk24 package and check the versions of key dependencies like cryptography, pydantic, and websockets. Use 'pip show' for specific package details and 'pip list | grep' for filtering. ```bash # See what versions are actually installed pip show werk24 pip list | grep -E "(cryptography|pydantic|websockets)" ``` -------------------------------- ### Configure WebSocket Connection for Unstable Networks Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt This example shows how to configure the Werk24Client for robust WebSocket connections, including setting heartbeat intervals, timeouts, and automatic reconnection attempts. ```python import asyncio from werk24 import Werk24Client from werk24.models.v2.asks import AskFeatures async def main(): # Aggressive reconnect for flaky networks client = Werk24Client( token="your_token", region="eu-central-1", ping_interval=10.0, # heartbeat every 10s ping_timeout=5.0, # fail if no pong within 5s max_reconnect_attempts=5, # retry up to 5 times reconnect_delay=0.5, # start with 0.5s, doubles each attempt ) with open("drawing.pdf", "rb") as f: drawing = f.read() async with client: # If connection drops mid-stream, client auto-reconnects async for msg in client.read_drawing(drawing, [AskFeatures()]): print(f"Received: {msg.message_type}") asyncio.run(main()) ``` -------------------------------- ### Initialize and Use Werk24Client for Drawing Analysis Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt Initialize the Werk24Client as an async context manager. Submit a drawing and a list of 'asks' to the client. Asynchronously iterate over the TechreadMessage responses. ```python import asyncio from werk24 import Werk24Client, AskMetaData, AskFeatures, get_test_drawing async def main(): drawing = get_test_drawing() # returns bytes of a sample drawing async with Werk24Client( token="your_token", region="eu-central-1", ping_interval=30.0, ping_timeout=10.0, max_reconnect_attempts=3, reconnect_delay=1.0, ) as client: async for message in client.read_drawing(drawing, [AskMetaData(), AskFeatures()]): print(f"Type: {message.message_type}, Subtype: {message.message_subtype}") if message.payload_dict: print(message.payload_dict) asyncio.run(main()) ``` -------------------------------- ### Werk24Client Initialization and Usage Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt Demonstrates how to initialize the Werk24Client as an async context manager and use it to process a drawing with specified asks, iterating over the streamed results. ```APIDOC ## Werk24Client ### Description The main entry point for all API interactions. Use as an async context manager; the WebSocket connection is established on `__aenter__` and gracefully shut down on `__aexit__`. ### Usage Example ```python import asyncio from werk24 import Werk24Client, AskMetaData, AskFeatures, get_test_drawing async def main(): drawing = get_test_drawing() # returns bytes of a sample drawing async with Werk24Client( token="your_token", region="eu-central-1", ping_interval=30.0, ping_timeout=10.0, max_reconnect_attempts=3, reconnect_delay=1.0, ) as client: async for message in client.read_drawing(drawing, [AskMetaData(), AskFeatures()]): print(f"Type: {message.message_type}, Subtype: {message.message_subtype}") if message.payload_dict: print(message.payload_dict) asyncio.run(main()) ``` ``` -------------------------------- ### Werk24Client.get_system_status() Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt Static method to fetch live system status without requiring authentication. ```APIDOC ## `Werk24Client.get_system_status()` — Check API Health Static method to fetch live system status without requiring authentication. ```python import asyncio from werk24 import Werk24Client async def check_status(): status = await Werk24Client.get_system_status() print(f"Status: {status.status_indicator}") # e.g. "none" (all good) print(f"Description: {status.status_description}") for component in status.components: print(f" {component.name}: {component.status}") for incident in status.incidents: print(f" INCIDENT: {incident.name} — {incident.status}") asyncio.run(check_status()) # Output: # Status: none # Description: All Systems Operational # API: operational # WebSocket: operational ``` ``` -------------------------------- ### Generate RSA Keys for End-to-End Encryption Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt Shows how to generate RSA private and public key pairs using the cryptography library and use them to initialize Werk24Client for encrypted communication. Requires a 'drawing.pdf' file. ```python import asyncio from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.primitives import serialization from werk24 import Werk24Client, EncryptionKeys from werk24.models.v2.asks import AskMetaData def generate_key_pair(): private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) private_pem = private_key.private_bytes( serialization.Encoding.PEM, serialization.PrivateFormat.TraditionalOpenSSL, serialization.NoEncryption(), ) public_pem = private_key.public_key().public_bytes( serialization.Encoding.PEM, serialization.PublicFormat.SubjectPublicKeyInfo, ) return private_pem, public_pem async def main(): private_pem, public_pem = generate_key_pair() encryption_keys = EncryptionKeys( client_private_key_pem=private_pem, client_public_key_pem=public_pem, ) with open("drawing.pdf", "rb") as f: drawing = f.read() async with Werk24Client() as client: async for msg in client.read_drawing( drawing, [AskMetaData()], encryption_keys=encryption_keys, ): print(msg.message_type) asyncio.run(main()) ``` -------------------------------- ### Werk24 CLI help information Source: https://github.com/w24-service-gmbh/werk24-python/blob/main/README.md Display the help message for the Werk24 command-line interface (CLI). This shows available options and commands, including initialization, health checks, reading drawings, and version information. ```bash $> werk24 --help Usage: python -m werk24.cli.werk24 [OPTIONS] COMMAND [ARGS]... ╭─ Options ─────────────────────────────────────────────────────────────────────────────────╮ │ --log-level TEXT Set the log level [default: WARNING] │ │ --install-completion Install completion for the current shell. │ │ --show-completion Show completion for the current shell, to copy it or... | │ --help Show this message and exit. │ ╰───────────────────────────────────────────────────────────────────────────────────────────╯ ╭─ Commands ────────────────────────────────────────────────────────────────────────────────╮ │ init Initialize Werk24 by providing or creating a license. │ │ health-check Run a comprehensive health check for the CLI. │ │ techread Read a drawing file and extract information. │ │ version Print the version of the Client. │ │ status Fetch and display the Werk24 system status. │ ╰───────────────────────────────────────────────────────────────────────────────────────────╯ ``` -------------------------------- ### Manage Werk24 API Licenses with Utility Functions Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt This Python code demonstrates using utility functions from `werk24.utils.license` to parse license text, save license files, and find licenses from various sources. ```python from werk24.utils.license import find_license, parse_license_text, save_license_file, License # Parse license from text directly (e.g., from a secret manager) license_text = "W24TECHREAD_AUTH_TOKEN=abc123\nW24TECHREAD_AUTH_REGION=eu-central-1\n" license = parse_license_text(license_text) print(license.token, license.region) # Save a license to .werk24 for future use save_license_file(License(token="abc123", region="eu-central-1")) # Resolve license from any source (file, env var, or explicit) resolved = find_license(token="abc123", region="eu-central-1") # Or let it auto-discover: # resolved = find_license() # searches ~/.werk24, envs, etc. ``` -------------------------------- ### Parse Drawing Responses with Features and Insights Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt Demonstrates how to read a drawing file and process both feature and insight components from the API response. Requires a 'drawing.pdf' file in the current directory. ```python import asyncio from werk24 import Werk24Client from werk24.models.v2.asks import AskFeatures, AskInsights from werk24.models.v2.responses import ResponseFeaturesComponentDrawing, ResponseInsightsComponentDrawing from werk24.models.v2.enums import SizeType async def parse_responses(): with open("drawing.pdf", "rb") as f: drawing = f.read() async with Werk24Client() as client: async for msg in client.read_drawing(drawing, [AskFeatures(), AskInsights()]): if not msg.payload_dict: continue subtype = getattr(msg.message_subtype, "value", None) if subtype == "FEATURES": r = ResponseFeaturesComponentDrawing.model_validate(msg.payload_dict) for dim in r.dimensions: print(f"Dim: {dim.size.value}{dim.size.unit} ({dim.size.size_type.value})") if dim.size.tolerance: tol = dim.size.tolerance print(f" Tolerance: {tol.fit or ''} [{tol.deviation_lower}..{tol.deviation_upper}]") for thread in r.threads: print(f"Thread: {thread.label}, handedness={thread.handedness.value}") for bore in r.bores: print(f"Bore Ø{bore.diameter.value}{bore.diameter.unit}, qty={bore.quantity}") for gdnt in r.gdnts: print(f"GD&T: {gdnt.characteristic.value}, datum={[d.label for d in gdnt.datums]}") elif subtype == "INSIGHTS": r = ResponseInsightsComponentDrawing.model_validate(msg.payload_dict) print("Primary processes:", [p.primary_process.value for p in r.primary_process_options]) print("Secondary processes:", [s.label for s in r.secondary_processes]) if r.volume_estimate: print(f"Volume estimate: {r.volume_estimate.value} {r.volume_estimate.unit}") asyncio.run(parse_responses()) ``` -------------------------------- ### Run Tests Source: https://github.com/w24-service-gmbh/werk24-python/blob/main/CONTRIBUTING.md Execute all project tests using pytest. Ensure all tests pass before submitting changes. ```bash pytest ``` -------------------------------- ### Werk24 CLI Commands for Core Operations Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt A collection of bash commands for interacting with the Werk24 service via its CLI. These commands cover initialization, health checks, reading documents, status checks, version display, and log level adjustment. ```bash # Initialize license werk24 init ``` ```bash # Check system health werk24 health-check ``` ```bash # Read a drawing and print extracted data werk24 techread drawing.pdf --ask META_DATA --ask FEATURES ``` ```bash # Check system status werk24 status ``` ```bash # Print client version werk24 version ``` ```bash # Adjust log level for debugging werk24 --log-level DEBUG techread drawing.pdf --ask META_DATA ``` -------------------------------- ### Check API System Status (Python) Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt Use the static method `Werk24Client.get_system_status()` to check the API's health and operational status without authentication. ```python import asyncio from werk24 import Werk24Client async def check_status(): status = await Werk24Client.get_system_status() print(f"Status: {status.status_indicator}") # e.g. "none" (all good) print(f"Description: {status.status_description}") for component in status.components: print(f" {component.name}: {component.status}") for incident in status.incidents: print(f" INCIDENT: {incident.name} — {incident.status}") asyncio.run(check_status()) # Output: # Status: none # Description: All Systems Operational # API: operational # WebSocket: operational ``` -------------------------------- ### Upgrade Werk24 to the latest version Source: https://github.com/w24-service-gmbh/werk24-python/blob/main/README.md Upgrade the werk24 package to the most recent version available. This command should be run within your project's virtual environment. ```bash # Simply upgrade to the latest version pip install --upgrade werk24 ``` -------------------------------- ### Werk24Client.read_drawing_with_callback() Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt Uploads a drawing and registers a webhook URL; the API POSTs results to the URL asynchronously. Returns the UUID request ID for tracking. ```APIDOC ## `Werk24Client.read_drawing_with_callback()` — Async Webhook Callback Uploads a drawing and registers a webhook URL; the API POSTs results to the URL asynchronously. Returns the `UUID` request ID for tracking. ```python import asyncio from werk24 import Werk24Client from werk24.models.v2.asks import AskMetaData, AskFeatures async def submit_with_callback(): with open("drawing.pdf", "rb") as f: drawing = f.read() async with Werk24Client() as client: request_id = await client.read_drawing_with_callback( drawing=drawing, asks=[AskMetaData(), AskFeatures()], callback_url="https://your-server.com/webhook/werk24", callback_headers={"X-API-Key": "secret"}, max_pages=5, drawing_filename="part_12345.pdf", priority="PRIO1", ) print(f"Submitted. Track with request_id: {request_id}") # API will POST TechreadMessage JSON to your callback URL for each result asyncio.run(submit_with_callback()) ``` ``` -------------------------------- ### Handle Werk24 API Exceptions Gracefully Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt This code demonstrates how to catch and handle various exceptions from the Werk24 API, including rate limits and server errors. It implements a retry mechanism for transient errors. ```python import asyncio from werk24 import Werk24Client from werk24.models.v2.asks import AskMetaData from werk24.utils.exceptions import ( UnauthorizedException, RequestTooLargeException, InsufficientCreditsException, PriorityTooHighError, InvalidPriorityError, UnsupportedMediaType, ServerException, W24RateLimitError, W24AuthenticationError, W24ValidationError, W24ServerError, ) import time async def safe_read(drawing_bytes: bytes, max_retries=3): for attempt in range(max_retries): try: async with Werk24Client() as client: async for msg in client.read_drawing(drawing_bytes, [AskMetaData()]): print(msg.message_type) return except UnauthorizedException: print("Invalid or expired credentials. Check your license.") raise except RequestTooLargeException: print("Drawing exceeds 10MB size limit.") raise except InsufficientCreditsException: print("Account has insufficient credits.") raise except PriorityTooHighError as e: print(f"Requested priority {e.requested_priority} exceeds account tier {e.account_tier}.") raise except InvalidPriorityError as e: print(f"Invalid priority value: {e.invalid_value}. Use PRIO1, PRIO2, or PRIO3.") raise except UnsupportedMediaType: print("Drawing format not supported. Use PDF, PNG, JPEG, or TIFF.") raise except W24RateLimitError as e: wait = e.retry_after or 5 if attempt < max_retries - 1: print(f"Rate limited. Retrying in {wait}s...") time.sleep(wait) else: raise except W24ServerError as e: if e.is_transient and attempt < max_retries - 1: print("Transient server error, retrying...") time.sleep(2 ** attempt) else: raise except ServerException as e: print(f"Server error: {e}") raise asyncio.run(safe_read(open("drawing.pdf", "rb").read())) ``` -------------------------------- ### Werk24Client.read_drawing_with_hooks() Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt Associates callback functions with specific ask types using Hook objects. Supports both sync and async callbacks. ```APIDOC ## `Werk24Client.read_drawing_with_hooks()` — Hook-Based Result Handling Associates callback functions with specific ask types using `Hook` objects. Supports both sync and async callbacks. ```python import asyncio from werk24 import Werk24Client, Hook from werk24.models.v2.asks import AskMetaData, AskBalloons from werk24.models.v2.responses import ResponseMetaDataComponentDrawing, ResponseBalloons async def on_metadata(message): meta = ResponseMetaDataComponentDrawing.model_validate(message.payload_dict) print("Weight:", meta.weight) print("Languages:", meta.languages) def on_balloons(message): # sync hooks also supported balloons = ResponseBalloons.model_validate(message.payload_dict) for b in balloons.balloons: print(f"Balloon at {b.center}, ref_id={b.reference_id}") async def main(): with open("drawing.pdf", "rb") as f: drawing = f.read() hooks = [ Hook(ask=AskMetaData(), function=on_metadata), Hook(ask=AskBalloons(), function=on_balloons), ] async with Werk24Client() as client: await client.read_drawing_with_hooks(drawing, hooks, priority="PRIO3") asyncio.run(main()) ``` ``` -------------------------------- ### Read Drawing with Hooks (Python) Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt Use `read_drawing_with_hooks` to process a drawing and associate callback functions with specific ask types for synchronous or asynchronous result handling. ```python import asyncio from werk24 import Werk24Client, Hook from werk24.models.v2.asks import AskMetaData, AskBalloons from werk24.models.v2.responses import ResponseMetaDataComponentDrawing, ResponseBalloons async def on_metadata(message): meta = ResponseMetaDataComponentDrawing.model_validate(message.payload_dict) print("Weight:", meta.weight) print("Languages:", meta.languages) def on_balloons(message): # sync hooks also supported balloons = ResponseBalloons.model_validate(message.payload_dict) for b in balloons.balloons: print(f"Balloon at {b.center}, ref_id={b.reference_id}") async def main(): with open("drawing.pdf", "rb") as f: drawing = f.read() hooks = [ Hook(ask=AskMetaData(), function=on_metadata), Hook(ask=AskBalloons(), function=on_balloons), ] async with Werk24Client() as client: await client.read_drawing_with_hooks(drawing, hooks, priority="PRIO3") asyncio.run(main()) ``` -------------------------------- ### Read Drawing with Async Webhook Callback (Python) Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt Utilize `read_drawing_with_callback` to upload a drawing and receive results asynchronously via a webhook. This method returns a request ID for tracking. ```python import asyncio from werk24 import Werk24Client from werk24.models.v2.asks import AskMetaData, AskFeatures async def submit_with_callback(): with open("drawing.pdf", "rb") as f: drawing = f.read() async with Werk24Client() as client: request_id = await client.read_drawing_with_callback( drawing=drawing, asks=[AskMetaData(), AskFeatures()], callback_url="https://your-server.com/webhook/werk24", callback_headers={"X-API-Key": "secret"}, max_pages=5, drawing_filename="part_12345.pdf", priority="PRIO1", ) print(f"Submitted. Track with request_id: {request_id}") # API will POST TechreadMessage JSON to your callback URL for each result asyncio.run(submit_with_callback()) ``` -------------------------------- ### Validate Ask Types (Python) Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt Employ the static method `Werk24Client.validate_asks()` for pre-flight validation of ask types, ensuring they are correctly formatted before submission. This is also performed automatically by `read_drawing()`. ```python from werk24 import Werk24Client from werk24.models.v2.asks import AskMetaData, AskFeatures, AskBalloons from werk24.models.v1.ask import W24AskTitleBlock from werk24.utils.exceptions import BadRequestException # Mix of v1 and v2 asks — both are valid asks = [AskMetaData(), AskFeatures(), AskBalloons(), W24AskTitleBlock()] try: Werk24Client.validate_asks(asks) print("All asks valid!") except BadRequestException as e: print(f"Invalid asks: {e}") # Validate empty list try: Werk24Client.validate_asks([]) except BadRequestException as e: print(e) # "No ask types provided. At least one ask type is required." ``` -------------------------------- ### Werk24Client.read_drawing() - Stream Drawing Results Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt Details the `read_drawing` method of the `Werk24Client`, which validates asks, uploads a drawing, and yields `TechreadMessage` objects as results are processed. It supports various input types for drawings and allows configuration of processing parameters. ```APIDOC ## Werk24Client.read_drawing() ### Description Validates asks, uploads the drawing, and yields `TechreadMessage` objects as the API returns results. Accepts `bytes`, `BufferedReader`, or `io.BytesIO`. ### Parameters - **drawing**: `bytes` | `BufferedReader` | `io.BytesIO` - The drawing data to process. - **asks**: `list` - A list of ask objects (e.g., `AskMetaData()`, `AskFeatures()`). - **max_pages**: `int` (Optional) - Maximum number of pages to process. - **priority**: `str` (Optional) - Processing priority ('PRIO1', 'PRIO2', 'PRIO3'). ### Usage Example ```python import asyncio, io from werk24 import Werk24Client from werk24.models.v2.asks import AskMetaData, AskFeatures from werk24.models.v2.responses import ResponseMetaDataComponentDrawing, ResponseFeaturesComponentDrawing async def extract(drawing_bytes: bytes): async with Werk24Client() as client: async for msg in client.read_drawing( drawing_bytes, asks=[AskMetaData(), AskFeatures()], max_pages=5, priority="PRIO2", # PRIO1 | PRIO2 | PRIO3 ): if msg.payload_dict: ask_type = msg.message_subtype if ask_type and ask_type.value == "META_DATA": meta = ResponseMetaDataComponentDrawing.model_validate(msg.payload_dict) print("Drawing number:", [i.value for i in meta.identifiers]) print("Material:", [m.material_combination[0].designation for m in meta.material_options]) print("General tolerances:", meta.general_tolerances) elif ask_type and ask_type.value == "FEATURES": feats = ResponseFeaturesComponentDrawing.model_validate(msg.payload_dict) print(f"Dimensions: {len(feats.dimensions)}, Threads: {len(feats.threads)}, Bores: {len(feats.bores)}") with open("drawing.pdf", "rb") as f: asyncio.run(extract(f.read())) ``` ``` -------------------------------- ### Stream Drawing Results with read_drawing Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt Use the `read_drawing` method to stream results from a drawing. This method validates asks, uploads the drawing, and yields `TechreadMessage` objects. It accepts bytes, BufferedReader, or io.BytesIO and allows specifying parameters like `max_pages` and `priority`. ```python import asyncio, io from werk24 import Werk24Client from werk24.models.v2.asks import AskMetaData, AskFeatures from werk24.models.v2.responses import ResponseMetaDataComponentDrawing, ResponseFeaturesComponentDrawing async def extract(drawing_bytes: bytes): async with Werk24Client() as client: async for msg in client.read_drawing( drawing_bytes, asks=[AskMetaData(), AskFeatures()], max_pages=5, priority="PRIO2", # PRIO1 | PRIO2 | PRIO3 ): if msg.payload_dict: ask_type = msg.message_subtype if ask_type and ask_type.value == "META_DATA": meta = ResponseMetaDataComponentDrawing.model_validate(msg.payload_dict) print("Drawing number:", [i.value for i in meta.identifiers]) print("Material:", [m.material_combination[0].designation for m in meta.material_options]) print("General tolerances:", meta.general_tolerances) elif ask_type and ask_type.value == "FEATURES": feats = ResponseFeaturesComponentDrawing.model_validate(msg.payload_dict) print(f"Dimensions: {len(feats.dimensions)}, Threads: {len(feats.threads)}, Bores: {len(feats.bores)}") with open("drawing.pdf", "rb") as f: asyncio.run(extract(f.read())) ``` -------------------------------- ### Werk24Client.validate_asks() Source: https://context7.com/w24-service-gmbh/werk24-python/llms.txt Static method to validate ask types before submitting a request. Called automatically by read_drawing() but can be invoked manually. ```APIDOC ## `Werk24Client.validate_asks()` — Pre-flight Ask Validation Static method to validate ask types before submitting a request. Called automatically by `read_drawing()` but can be invoked manually. ```python from werk24 import Werk24Client from werk24.models.v2.asks import AskMetaData, AskFeatures, AskBalloons from werk24.models.v1.ask import W24AskTitleBlock from werk24.utils.exceptions import BadRequestException # Mix of v1 and v2 asks — both are valid asks = [AskMetaData(), AskFeatures(), AskBalloons(), W24AskTitleBlock()] try: Werk24Client.validate_asks(asks) print("All asks valid!") except BadRequestException as e: print(f"Invalid asks: {e}") # Validate empty list try: Werk24Client.validate_asks([]) except BadRequestException as e: print(e) # "No ask types provided. At least one ask type is required." ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.