autoassembler 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.
- autoassembler-0.3.1/.gitignore +48 -0
- autoassembler-0.3.1/LICENSE +21 -0
- autoassembler-0.3.1/Makefile +23 -0
- autoassembler-0.3.1/PKG-INFO +209 -0
- autoassembler-0.3.1/README.md +179 -0
- autoassembler-0.3.1/examples/README.md +117 -0
- autoassembler-0.3.1/examples/adapt.py +71 -0
- autoassembler-0.3.1/examples/diff.py +60 -0
- autoassembler-0.3.1/examples/login.py +49 -0
- autoassembler-0.3.1/examples/plan.py +98 -0
- autoassembler-0.3.1/examples/upload.py +61 -0
- autoassembler-0.3.1/examples/upload_async.py +82 -0
- autoassembler-0.3.1/pyproject.toml +110 -0
- autoassembler-0.3.1/reference.md +2636 -0
- autoassembler-0.3.1/src/autoassembler/.fernignore +7 -0
- autoassembler-0.3.1/src/autoassembler/__init__.py +537 -0
- autoassembler-0.3.1/src/autoassembler/_custom/__init__.py +56 -0
- autoassembler-0.3.1/src/autoassembler/_custom/assemblies.py +226 -0
- autoassembler-0.3.1/src/autoassembler/_custom/assemblies_api.py +188 -0
- autoassembler-0.3.1/src/autoassembler/_custom/credentials.py +248 -0
- autoassembler-0.3.1/src/autoassembler/_custom/http.py +42 -0
- autoassembler-0.3.1/src/autoassembler/_custom/operations.py +258 -0
- autoassembler-0.3.1/src/autoassembler/_custom/planning.py +598 -0
- autoassembler-0.3.1/src/autoassembler/_custom/planning_api.py +225 -0
- autoassembler-0.3.1/src/autoassembler/_default_clients.py +32 -0
- autoassembler-0.3.1/src/autoassembler/_version.py +8 -0
- autoassembler-0.3.1/src/autoassembler/alpha/__init__.py +63 -0
- autoassembler-0.3.1/src/autoassembler/alpha/client.py +82 -0
- autoassembler-0.3.1/src/autoassembler/alpha/jobs/__init__.py +39 -0
- autoassembler-0.3.1/src/autoassembler/alpha/jobs/client.py +338 -0
- autoassembler-0.3.1/src/autoassembler/alpha/jobs/raw_client.py +641 -0
- autoassembler-0.3.1/src/autoassembler/alpha/jobs/types/__init__.py +42 -0
- autoassembler-0.3.1/src/autoassembler/alpha/jobs/types/cancel_job_jobs_response.py +12 -0
- autoassembler-0.3.1/src/autoassembler/alpha/jobs/types/list_jobs_jobs_response.py +30 -0
- autoassembler-0.3.1/src/autoassembler/alpha/jobs/types/list_jobs_jobs_response_pagination.py +22 -0
- autoassembler-0.3.1/src/autoassembler/alpha/jobs/types/retry_job_jobs_response.py +16 -0
- autoassembler-0.3.1/src/autoassembler/alpha/planning/__init__.py +49 -0
- autoassembler-0.3.1/src/autoassembler/alpha/planning/client.py +201 -0
- autoassembler-0.3.1/src/autoassembler/alpha/planning/raw_client.py +268 -0
- autoassembler-0.3.1/src/autoassembler/alpha/planning/types/__init__.py +47 -0
- autoassembler-0.3.1/src/autoassembler/alpha/planning/types/apply_ops_planning_request_namespace.py +5 -0
- autoassembler-0.3.1/src/autoassembler/alpha/planning/types/apply_ops_planning_request_ops_item.py +13 -0
- autoassembler-0.3.1/src/autoassembler/alpha/planning/types/apply_ops_planning_request_ops_item_op.py +58 -0
- autoassembler-0.3.1/src/autoassembler/alpha/planning/types/apply_ops_planning_response.py +13 -0
- autoassembler-0.3.1/src/autoassembler/alpha/raw_client.py +13 -0
- autoassembler-0.3.1/src/autoassembler/assemblies/__init__.py +73 -0
- autoassembler-0.3.1/src/autoassembler/assemblies/client.py +1177 -0
- autoassembler-0.3.1/src/autoassembler/assemblies/raw_client.py +1557 -0
- autoassembler-0.3.1/src/autoassembler/assemblies/types/__init__.py +71 -0
- autoassembler-0.3.1/src/autoassembler/assemblies/types/delete_assembly_response.py +12 -0
- autoassembler-0.3.1/src/autoassembler/assemblies/types/download_assembly_cad_request_namespace.py +5 -0
- autoassembler-0.3.1/src/autoassembler/assemblies/types/get_assembly_info_request_namespace.py +5 -0
- autoassembler-0.3.1/src/autoassembler/assemblies/types/get_status_request_namespace.py +5 -0
- autoassembler-0.3.1/src/autoassembler/assemblies/types/get_status_response.py +16 -0
- autoassembler-0.3.1/src/autoassembler/assemblies/types/get_status_response_progress.py +13 -0
- autoassembler-0.3.1/src/autoassembler/assemblies/types/get_status_response_status.py +7 -0
- autoassembler-0.3.1/src/autoassembler/assemblies/types/get_structure_request_namespace.py +5 -0
- autoassembler-0.3.1/src/autoassembler/assemblies/types/list_assembly_versions_request_namespace.py +5 -0
- autoassembler-0.3.1/src/autoassembler/assemblies/types/list_connections_request_namespace.py +5 -0
- autoassembler-0.3.1/src/autoassembler/assemblies/types/process_request_namespace.py +5 -0
- autoassembler-0.3.1/src/autoassembler/assemblies/types/update_assembly_info_request_namespace.py +5 -0
- autoassembler-0.3.1/src/autoassembler/auth/__init__.py +34 -0
- autoassembler-0.3.1/src/autoassembler/auth/client.py +282 -0
- autoassembler-0.3.1/src/autoassembler/auth/raw_client.py +413 -0
- autoassembler-0.3.1/src/autoassembler/auth/types/__init__.py +36 -0
- autoassembler-0.3.1/src/autoassembler/auth/types/create_access_token_request_grant_type.py +7 -0
- autoassembler-0.3.1/src/autoassembler/base_client.py +328 -0
- autoassembler-0.3.1/src/autoassembler/client.py +262 -0
- autoassembler-0.3.1/src/autoassembler/core/__init__.py +127 -0
- autoassembler-0.3.1/src/autoassembler/core/api_error.py +23 -0
- autoassembler-0.3.1/src/autoassembler/core/client_wrapper.py +147 -0
- autoassembler-0.3.1/src/autoassembler/core/datetime_utils.py +70 -0
- autoassembler-0.3.1/src/autoassembler/core/file.py +67 -0
- autoassembler-0.3.1/src/autoassembler/core/force_multipart.py +18 -0
- autoassembler-0.3.1/src/autoassembler/core/http_client.py +965 -0
- autoassembler-0.3.1/src/autoassembler/core/http_response.py +63 -0
- autoassembler-0.3.1/src/autoassembler/core/http_sse/__init__.py +42 -0
- autoassembler-0.3.1/src/autoassembler/core/http_sse/_api.py +455 -0
- autoassembler-0.3.1/src/autoassembler/core/http_sse/_decoders.py +74 -0
- autoassembler-0.3.1/src/autoassembler/core/http_sse/_exceptions.py +7 -0
- autoassembler-0.3.1/src/autoassembler/core/http_sse/_models.py +17 -0
- autoassembler-0.3.1/src/autoassembler/core/jsonable_encoder.py +133 -0
- autoassembler-0.3.1/src/autoassembler/core/logging.py +107 -0
- autoassembler-0.3.1/src/autoassembler/core/parse_error.py +36 -0
- autoassembler-0.3.1/src/autoassembler/core/pydantic_utilities.py +486 -0
- autoassembler-0.3.1/src/autoassembler/core/query_encoder.py +58 -0
- autoassembler-0.3.1/src/autoassembler/core/remove_none_from_dict.py +11 -0
- autoassembler-0.3.1/src/autoassembler/core/request_options.py +40 -0
- autoassembler-0.3.1/src/autoassembler/core/serialization.py +347 -0
- autoassembler-0.3.1/src/autoassembler/environment.py +7 -0
- autoassembler-0.3.1/src/autoassembler/errors/__init__.py +56 -0
- autoassembler-0.3.1/src/autoassembler/errors/bad_request_error.py +10 -0
- autoassembler-0.3.1/src/autoassembler/errors/conflict_error.py +10 -0
- autoassembler-0.3.1/src/autoassembler/errors/forbidden_error.py +11 -0
- autoassembler-0.3.1/src/autoassembler/errors/internal_server_error.py +11 -0
- autoassembler-0.3.1/src/autoassembler/errors/not_found_error.py +11 -0
- autoassembler-0.3.1/src/autoassembler/errors/unauthorized_error.py +10 -0
- autoassembler-0.3.1/src/autoassembler/errors/unprocessable_entity_error.py +11 -0
- autoassembler-0.3.1/src/autoassembler/operation.py +196 -0
- autoassembler-0.3.1/src/autoassembler/operations/__init__.py +4 -0
- autoassembler-0.3.1/src/autoassembler/operations/client.py +209 -0
- autoassembler-0.3.1/src/autoassembler/operations/raw_client.py +343 -0
- autoassembler-0.3.1/src/autoassembler/planning/__init__.py +70 -0
- autoassembler-0.3.1/src/autoassembler/planning/client.py +1174 -0
- autoassembler-0.3.1/src/autoassembler/planning/raw_client.py +1349 -0
- autoassembler-0.3.1/src/autoassembler/planning/types/__init__.py +68 -0
- autoassembler-0.3.1/src/autoassembler/planning/types/adapt_request_namespace.py +5 -0
- autoassembler-0.3.1/src/autoassembler/planning/types/create_mpp_request_body.py +8 -0
- autoassembler-0.3.1/src/autoassembler/planning/types/create_mpp_request_namespace.py +5 -0
- autoassembler-0.3.1/src/autoassembler/planning/types/delete_mpp_request_namespace.py +5 -0
- autoassembler-0.3.1/src/autoassembler/planning/types/delete_mpp_response.py +12 -0
- autoassembler-0.3.1/src/autoassembler/planning/types/evaluate_dfa_request_namespace.py +5 -0
- autoassembler-0.3.1/src/autoassembler/planning/types/get_mpp_request_namespace.py +5 -0
- autoassembler-0.3.1/src/autoassembler/planning/types/get_mpp_response.py +27 -0
- autoassembler-0.3.1/src/autoassembler/planning/types/list_mpps_request_namespace.py +5 -0
- autoassembler-0.3.1/src/autoassembler/planning/types/plan_request_namespace.py +5 -0
- autoassembler-0.3.1/src/autoassembler/planning/types/validate_request_namespace.py +5 -0
- autoassembler-0.3.1/src/autoassembler/py.typed +0 -0
- autoassembler-0.3.1/src/autoassembler/sessions/__init__.py +4 -0
- autoassembler-0.3.1/src/autoassembler/sessions/client.py +102 -0
- autoassembler-0.3.1/src/autoassembler/sessions/raw_client.py +126 -0
- autoassembler-0.3.1/src/autoassembler/tests/conftest.py +21 -0
- autoassembler-0.3.1/src/autoassembler/tests/test_aiohttp_autodetect.py +113 -0
- autoassembler-0.3.1/src/autoassembler/types/__init__.py +344 -0
- autoassembler-0.3.1/src/autoassembler/types/access_token_response.py +14 -0
- autoassembler-0.3.1/src/autoassembler/types/active_session.py +25 -0
- autoassembler-0.3.1/src/autoassembler/types/active_session_namespace.py +5 -0
- autoassembler-0.3.1/src/autoassembler/types/adapt_mpp_accepted.py +26 -0
- autoassembler-0.3.1/src/autoassembler/types/assembly.py +30 -0
- autoassembler-0.3.1/src/autoassembler/types/assembly_connection.py +21 -0
- autoassembler-0.3.1/src/autoassembler/types/assembly_connection_relationship.py +5 -0
- autoassembler-0.3.1/src/autoassembler/types/assembly_connections_response.py +13 -0
- autoassembler-0.3.1/src/autoassembler/types/assembly_diff_metadata.py +35 -0
- autoassembler-0.3.1/src/autoassembler/types/assembly_diff_response.py +34 -0
- autoassembler-0.3.1/src/autoassembler/types/assembly_info.py +36 -0
- autoassembler-0.3.1/src/autoassembler/types/assembly_json_response.py +15 -0
- autoassembler-0.3.1/src/autoassembler/types/assembly_process_metadata.py +32 -0
- autoassembler-0.3.1/src/autoassembler/types/assembly_process_response.py +18 -0
- autoassembler-0.3.1/src/autoassembler/types/assembly_search_hit.py +31 -0
- autoassembler-0.3.1/src/autoassembler/types/assembly_version_summary.py +27 -0
- autoassembler-0.3.1/src/autoassembler/types/conflict_error_body.py +19 -0
- autoassembler-0.3.1/src/autoassembler/types/conflict_error_body_error.py +5 -0
- autoassembler-0.3.1/src/autoassembler/types/create_mpp_request.py +13 -0
- autoassembler-0.3.1/src/autoassembler/types/device_authorization_response.py +17 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_accepted.py +42 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_context_node.py +20 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_details.py +73 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_error_response.py +38 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_flags.py +74 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_ml_semantics.py +55 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_node.py +26 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_node_pair_with_parts.py +90 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_node_with_parent.py +15 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_reference_target_nodes.py +25 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_report.py +24 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_rigid_alignment.py +30 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_summary.py +121 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_summary_assembly_labels.py +44 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_summary_geometric_diffs.py +24 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_summary_persistent_edges_congruence.py +24 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_summary_persistent_edges_congruence_pose.py +24 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_summary_persistent_nodes_congruence.py +24 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_summary_persistent_nodes_congruence_pose.py +24 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_summary_total_parts.py +24 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_swap.py +65 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_swap_confidence.py +5 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_swap_group.py +92 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_validation_issue.py +38 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_validation_issue_severity.py +5 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_validation_result.py +35 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_warning.py +79 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_warning_reason.py +18 -0
- autoassembler-0.3.1/src/autoassembler/types/diff_warning_severity.py +5 -0
- autoassembler-0.3.1/src/autoassembler/types/error_response.py +30 -0
- autoassembler-0.3.1/src/autoassembler/types/filter.py +19 -0
- autoassembler-0.3.1/src/autoassembler/types/filter_field.py +7 -0
- autoassembler-0.3.1/src/autoassembler/types/filter_operator.py +5 -0
- autoassembler-0.3.1/src/autoassembler/types/job.py +123 -0
- autoassembler-0.3.1/src/autoassembler/types/job_progress.py +24 -0
- autoassembler-0.3.1/src/autoassembler/types/job_status.py +5 -0
- autoassembler-0.3.1/src/autoassembler/types/list_operations_response.py +25 -0
- autoassembler-0.3.1/src/autoassembler/types/manufacturing_process_plan.py +57 -0
- autoassembler-0.3.1/src/autoassembler/types/mpp_adapt_metadata.py +48 -0
- autoassembler-0.3.1/src/autoassembler/types/mpp_adapt_response.py +22 -0
- autoassembler-0.3.1/src/autoassembler/types/mpp_evaluate_dfa_metadata.py +47 -0
- autoassembler-0.3.1/src/autoassembler/types/mpp_evaluate_dfa_response.py +22 -0
- autoassembler-0.3.1/src/autoassembler/types/mpp_plan_metadata.py +47 -0
- autoassembler-0.3.1/src/autoassembler/types/mpp_plan_response.py +22 -0
- autoassembler-0.3.1/src/autoassembler/types/mpp_summary.py +20 -0
- autoassembler-0.3.1/src/autoassembler/types/mpp_validate_metadata.py +47 -0
- autoassembler-0.3.1/src/autoassembler/types/mpp_validate_response.py +22 -0
- autoassembler-0.3.1/src/autoassembler/types/o_auth_error_response.py +14 -0
- autoassembler-0.3.1/src/autoassembler/types/o_auth_error_response_error.py +18 -0
- autoassembler-0.3.1/src/autoassembler/types/operation.py +27 -0
- autoassembler-0.3.1/src/autoassembler/types/operation_error.py +21 -0
- autoassembler-0.3.1/src/autoassembler/types/operation_metadata.py +148 -0
- autoassembler-0.3.1/src/autoassembler/types/operation_response.py +94 -0
- autoassembler-0.3.1/src/autoassembler/types/process_assembly_accepted.py +14 -0
- autoassembler-0.3.1/src/autoassembler/types/process_assembly_response.py +55 -0
- autoassembler-0.3.1/src/autoassembler/types/process_assembly_skipped.py +14 -0
- autoassembler-0.3.1/src/autoassembler/types/search_assemblies_response.py +14 -0
- autoassembler-0.3.1/src/autoassembler/types/seq_plan_accepted.py +24 -0
- autoassembler-0.3.1/src/autoassembler/types/sever.py +33 -0
- autoassembler-0.3.1/src/autoassembler/types/sever_kind.py +5 -0
- autoassembler-0.3.1/src/autoassembler/types/sever_source.py +5 -0
- autoassembler-0.3.1/src/autoassembler/types/sort.py +8 -0
- autoassembler-0.3.1/src/autoassembler/types/upload_response.py +19 -0
- autoassembler-0.3.1/src/autoassembler/types/user_info.py +19 -0
- autoassembler-0.3.1/src/autoassembler/types/user_info_response.py +23 -0
- autoassembler-0.3.1/src/autoassembler/types/user_info_response_providers.py +14 -0
- autoassembler-0.3.1/tests/test_client.py +66 -0
- autoassembler-0.3.1/tests/test_contract.py +659 -0
- autoassembler-0.3.1/tests/test_credentials.py +270 -0
- autoassembler-0.3.1/tests/test_examples.py +483 -0
- autoassembler-0.3.1/tests/test_handles.py +843 -0
- autoassembler-0.3.1/tests/test_operation.py +162 -0
- autoassembler-0.3.1/tests/test_package.py +60 -0
- autoassembler-0.3.1/tests/test_public_api.py +126 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
.venv/
|
|
8
|
+
|
|
9
|
+
# Tooling caches
|
|
10
|
+
.pytest_cache/
|
|
11
|
+
.ruff_cache/
|
|
12
|
+
.mypy_cache/
|
|
13
|
+
|
|
14
|
+
# Fern local artifacts
|
|
15
|
+
**/.preview
|
|
16
|
+
**/.definition
|
|
17
|
+
|
|
18
|
+
# Fern generator provenance (contains volatile git SHA/dirty flag)
|
|
19
|
+
**/.fern/
|
|
20
|
+
|
|
21
|
+
# uv lock — not committed for a library SDK
|
|
22
|
+
uv.lock
|
|
23
|
+
|
|
24
|
+
# IDE
|
|
25
|
+
.idea/
|
|
26
|
+
|
|
27
|
+
# The API service checkout the spec sync builds from
|
|
28
|
+
.api-service/
|
|
29
|
+
|
|
30
|
+
# Local credentials and environment overrides (sanitized templates may be committed)
|
|
31
|
+
.env
|
|
32
|
+
.env.*
|
|
33
|
+
!.env.example
|
|
34
|
+
!.env.*.example
|
|
35
|
+
credentials.json
|
|
36
|
+
credentials.json.tmp
|
|
37
|
+
.credentials-*.tmp
|
|
38
|
+
*.pem
|
|
39
|
+
*.key
|
|
40
|
+
.aws/
|
|
41
|
+
|
|
42
|
+
# Local CAD inputs: use synthetic, reviewed fixtures if a test needs one
|
|
43
|
+
*.step
|
|
44
|
+
*.stp
|
|
45
|
+
*.pvz
|
|
46
|
+
*.STEP
|
|
47
|
+
*.STP
|
|
48
|
+
*.PVZ
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 C-Infinity
|
|
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,23 @@
|
|
|
1
|
+
# AutoAssembler Python SDK — dev tasks. Regeneration is shared: see the root Makefile.
|
|
2
|
+
|
|
3
|
+
# Files, not the _custom directory: ruff's extend-exclude on src/autoassembler/** would skip a directory.
|
|
4
|
+
CUSTOM := src/autoassembler/client.py src/autoassembler/operation.py src/autoassembler/_version.py $(wildcard src/autoassembler/_custom/*.py) tests examples
|
|
5
|
+
|
|
6
|
+
.PHONY: help post-generate lint typecheck test
|
|
7
|
+
|
|
8
|
+
help: ## Show this help
|
|
9
|
+
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
|
|
10
|
+
awk 'BEGIN {FS = ":.*?## "}; {printf " %-14s %s\n", $$1, $$2}'
|
|
11
|
+
|
|
12
|
+
post-generate: ## Surface Fern's reference.md and drop its README/CONTRIBUTING (run by the root `make generate`)
|
|
13
|
+
mv -f src/autoassembler/reference.md reference.md
|
|
14
|
+
rm -f src/autoassembler/CONTRIBUTING.md src/autoassembler/README.md # Fern's; ours are python/README.md and the root's
|
|
15
|
+
|
|
16
|
+
lint: ## Ruff-check the hand-written custom code + tests
|
|
17
|
+
uv run ruff check $(CUSTOM)
|
|
18
|
+
|
|
19
|
+
typecheck: ## Pyright type-check the hand-written surface (config in pyproject)
|
|
20
|
+
uv run pyright
|
|
21
|
+
|
|
22
|
+
test: ## Run the test suite
|
|
23
|
+
uv run pytest -q
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: autoassembler
|
|
3
|
+
Version: 0.3.1
|
|
4
|
+
Summary: Autoassembler Python SDK for AI Process Planning
|
|
5
|
+
Project-URL: Homepage, https://autoassembler.com/
|
|
6
|
+
Project-URL: Repository, https://github.com/cinf-org/autoassembler-sdk
|
|
7
|
+
Project-URL: Documentation, https://github.com/cinf-org/autoassembler-sdk/blob/main/python/reference.md
|
|
8
|
+
Project-URL: Issues, https://github.com/cinf-org/autoassembler-sdk/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/cinf-org/autoassembler-sdk/releases
|
|
10
|
+
Author-email: C-Infinity <info@c-infinity.ai>
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: assembly planning,autoassembler,cad,dfa,manufacturing,process planning,sdk
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Classifier: Typing :: Typed
|
|
25
|
+
Requires-Python: >=3.12
|
|
26
|
+
Requires-Dist: httpx>=0.21.2
|
|
27
|
+
Requires-Dist: pydantic>=2.5
|
|
28
|
+
Requires-Dist: typing-extensions>=4.6.1
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# AutoAssembler Python SDK
|
|
32
|
+
|
|
33
|
+
[AutoAssembler](https://autoassembler.com) is [C-Infinity](https://c-infinity.ai)'s foundational AI for
|
|
34
|
+
assembly process planning: read a CAD assembly, analyze its geometry, motion and production logic,
|
|
35
|
+
and turn that into manufacturing process plans, diff analysis, DFA analysis, work instructions and more.
|
|
36
|
+
This package is the official Python client for the AutoAssembler API. From a script or a notebook you can:
|
|
37
|
+
|
|
38
|
+
- **Upload** a CAD assembly (STEP, PVZ) and get a processed `Assembly` back.
|
|
39
|
+
- **Plan** it: create a process plan, assign parts to stations, let the planner work out the
|
|
40
|
+
assembly sequence, then **validate** that every station is physically buildable.
|
|
41
|
+
- **Diff** two revisions of an assembly and **adapt** an existing plan to the new one.
|
|
42
|
+
|
|
43
|
+
> **Status: 0.x.** The surface may still change between minor releases; see
|
|
44
|
+
> [Versioning](#versioning). The v4 API is stable, except the operations under `client.alpha`.
|
|
45
|
+
|
|
46
|
+
## Documentation
|
|
47
|
+
|
|
48
|
+
- Check the [Quickstart](#quickstart) below, then the runnable scripts in [`examples/`](https://github.com/cinf-org/autoassembler-sdk/tree/main/python/examples).
|
|
49
|
+
- [`reference.md`](https://github.com/cinf-org/autoassembler-sdk/blob/main/python/reference.md): every endpoint of the API as exposed by `client.api`.
|
|
50
|
+
- [Release notes](https://github.com/cinf-org/autoassembler-sdk/releases).
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
pip install autoassembler # or: uv add autoassembler
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Requires **Python 3.12+**. The only runtime dependencies are `httpx`, `pydantic>=2.5` and
|
|
59
|
+
`typing-extensions`.
|
|
60
|
+
|
|
61
|
+
## Authentication
|
|
62
|
+
|
|
63
|
+
Create an API key in the AutoAssembler app under
|
|
64
|
+
**Settings → API keys → Create API key**, then either pass it explicitly, set
|
|
65
|
+
`AA_TOKEN`, or log in interactively once:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from autoassembler import AutoAssembler
|
|
69
|
+
|
|
70
|
+
client = AutoAssembler(token="aa_...") # explicit (CI, scripts)
|
|
71
|
+
client = AutoAssembler() # reads AA_TOKEN, or the token stored by login()
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
import autoassembler
|
|
76
|
+
_ = autoassembler.login() # confirm in your browser; stores the token for 30 days
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`login()` stores tokens in `~/.config/autoassembler/credentials.json`; `logout()` forgets them.
|
|
80
|
+
`login()` also returns the token: assign its result as above to avoid displaying it in a
|
|
81
|
+
notebook or interactive shell. Do not commit credentials or include them in reports.
|
|
82
|
+
`logout()` removes the local copy; it does not revoke the token on the server.
|
|
83
|
+
Pass `base_url=` to both `login()` and `AutoAssembler()` for anything but `https://app.autoassembler.com`,
|
|
84
|
+
including your own deployment.
|
|
85
|
+
|
|
86
|
+
## Quickstart
|
|
87
|
+
|
|
88
|
+
Use your own CAD files in place of the example filenames below; no CAD data is bundled.
|
|
89
|
+
These calls upload the files to the configured service and create resources in your account.
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from autoassembler import AutoAssembler
|
|
93
|
+
|
|
94
|
+
client = AutoAssembler()
|
|
95
|
+
|
|
96
|
+
# Upload two revisions of a design. Processing overlaps on the server; wait for both.
|
|
97
|
+
v1, v2 = (op.result() for op in (client.assemblies.upload("gearbox_v1.step"),
|
|
98
|
+
client.assemblies.upload("gearbox_v2.step")))
|
|
99
|
+
|
|
100
|
+
# Plan v1 from scratch: one station with every part, plan it, check it is buildable.
|
|
101
|
+
mpp = client.planning.create_mpp(v1, name="Gearbox v1") # a manufacturing process plan
|
|
102
|
+
station = mpp.add_station("Final assembly")
|
|
103
|
+
outcome = mpp.plan(station).result() # complete | partial | failed
|
|
104
|
+
verdict = mpp.validate(station).result() # feasible | infeasible
|
|
105
|
+
print(outcome[station].status, verdict[station].status, mpp.viewer_url)
|
|
106
|
+
|
|
107
|
+
# What changed in v2, and v1's plan carried over to it.
|
|
108
|
+
diff = client.assemblies.diff(v1, v2).result()
|
|
109
|
+
mpp_v2 = client.planning.adapt(mpp, v2, diff=diff).result()
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Runnable versions of each step, with flags and error handling, live in
|
|
113
|
+
[`examples/`](https://github.com/cinf-org/autoassembler-sdk/tree/main/python/examples).
|
|
114
|
+
|
|
115
|
+
## How the SDK is organized
|
|
116
|
+
|
|
117
|
+
- **Concepts.** `Assembly` (a CAD file the service knows) and `ProcessPlan` (a manufacturing
|
|
118
|
+
process plan for one assembly, made of `Station`s).
|
|
119
|
+
- **Actions.** `upload`, `diff`, `plan`, `validate`, `evaluate_dfa`, `adapt`. An action that creates
|
|
120
|
+
a resource lives on a namespace (`client.assemblies.upload`, `client.planning.adapt`); an action
|
|
121
|
+
that acts on an existing resource lives on that resource's handle (`mpp.plan(station)`).
|
|
122
|
+
- **Waiting.** Anything that outlives its HTTP request returns an `Operation[T]`.
|
|
123
|
+
`op.result(timeout=None)` polls with backoff and returns `T`, or raises `OperationFailed` /
|
|
124
|
+
`OperationTimeout`; `op.done()` checks without blocking. Start several, then collect:
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
ops = [client.assemblies.upload(p) for p in cad_files]
|
|
128
|
+
assemblies = [op.result() for op in ops]
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Outcomes use the document's own words: a station's planning status is `pending`, `complete`,
|
|
132
|
+
`partial` (a usable partial plan) or `failed`; its validation verdict is `feasible` or
|
|
133
|
+
`infeasible`, with the issues behind it; an assembly is `processing`, `ready` or `failed`.
|
|
134
|
+
|
|
135
|
+
### The full API: `client.api`
|
|
136
|
+
|
|
137
|
+
The curated layer above is built on a client generated from the v4 OpenAPI spec, available
|
|
138
|
+
as `client.api` (`client.api.assemblies.get_status(...)`, `client.api.planning.get_mpp(...)`).
|
|
139
|
+
Use it when the vocabulary above does not cover what you need, and
|
|
140
|
+
[tell us](https://github.com/cinf-org/autoassembler-sdk/issues) what was missing.
|
|
141
|
+
Every endpoint is documented in
|
|
142
|
+
[`reference.md`](https://github.com/cinf-org/autoassembler-sdk/blob/main/python/reference.md).
|
|
143
|
+
|
|
144
|
+
An operation can be resumed by name from any process:
|
|
145
|
+
`client.operations.handle("operations/…").result()`.
|
|
146
|
+
|
|
147
|
+
### Errors
|
|
148
|
+
|
|
149
|
+
| Failure | Raised as |
|
|
150
|
+
|---|---|
|
|
151
|
+
| The server answered with an error status | `ApiError` (`status_code`, `body`, `headers`), or a typed subclass: `BadRequestError`, `UnauthorizedError`, `ForbiddenError`, `NotFoundError`, `ConflictError`, `UnprocessableEntityError` |
|
|
152
|
+
| The response did not match the expected schema | `ParsingError` (not an `ApiError`) |
|
|
153
|
+
| No response at all (DNS, connection, timeout) | `httpx.HTTPError` subclasses |
|
|
154
|
+
| A long-running operation failed or was cancelled | `OperationFailed` (`code`, `message`, `operation`) |
|
|
155
|
+
| A long-running operation did not finish in time | `OperationTimeout` (a `TimeoutError`) |
|
|
156
|
+
|
|
157
|
+
### Async
|
|
158
|
+
|
|
159
|
+
`AsyncAutoAssembler` currently exposes the generated client (`client.api`) and
|
|
160
|
+
`client.operations`; the curated `assemblies` / `planning` namespaces arrive on the async
|
|
161
|
+
client in a later release under the same names, with `asyncio.gather` as the natural way to
|
|
162
|
+
run work in parallel.
|
|
163
|
+
|
|
164
|
+
### Advanced
|
|
165
|
+
|
|
166
|
+
- **Timeouts.** 60 s per request by default: `AutoAssembler(timeout=20.0)` or
|
|
167
|
+
`request_options={"timeout": 5}` per call.
|
|
168
|
+
- **Retries.** Requests that fail with 408, 409, 429 or 5xx are retried twice with backoff;
|
|
169
|
+
`request_options={"max_retries": 0}` turns it off per call.
|
|
170
|
+
- **Your own `httpx` client**, for proxies or transports:
|
|
171
|
+
`AutoAssembler(httpx_client=httpx.Client(proxy="http://..."))`.
|
|
172
|
+
- **Raw responses.** `client.api.<namespace>.with_raw_response.<method>()` returns headers and
|
|
173
|
+
status alongside the parsed data.
|
|
174
|
+
- **Context managers.** `with AutoAssembler() as client:` closes the connection pool.
|
|
175
|
+
|
|
176
|
+
## Compatibility
|
|
177
|
+
|
|
178
|
+
| | |
|
|
179
|
+
|---|---|
|
|
180
|
+
| API | AutoAssembler **v4** (`autoassembler.API_VERSION == "v4"`). The client is generated from the published v4 OpenAPI spec; `fern/openapi/source.json` records which revision. |
|
|
181
|
+
| Servers | `https://app.autoassembler.com` by default; any AutoAssembler deployment that serves the v4 API via `base_url=`. |
|
|
182
|
+
|
|
183
|
+
## Versioning
|
|
184
|
+
|
|
185
|
+
The package follows [semantic versioning](https://semver.org/), independently of the API
|
|
186
|
+
version. While 0.x, a minor release may change the surface and a patch release only fixes;
|
|
187
|
+
from 1.0, breaking changes need a major release and removals are deprecated for one minor
|
|
188
|
+
release first. Each release's notes are on
|
|
189
|
+
[GitHub Releases](https://github.com/cinf-org/autoassembler-sdk/releases).
|
|
190
|
+
|
|
191
|
+
### Alpha
|
|
192
|
+
|
|
193
|
+
Operations the API offers before they are stable sit under `client.alpha` (also
|
|
194
|
+
`client.api.alpha`): today `client.alpha.jobs` and `client.alpha.planning.apply_ops`. They are
|
|
195
|
+
outside these guarantees: any release may change or remove them. An operation that becomes
|
|
196
|
+
stable moves out of `alpha`, to its namespace's usual place.
|
|
197
|
+
|
|
198
|
+
## Contributing
|
|
199
|
+
|
|
200
|
+
Bug reports and feature requests: [issues](https://github.com/cinf-org/autoassembler-sdk/issues).
|
|
201
|
+
Most of `python/src/autoassembler/` is generated from the OpenAPI spec and regenerated on every API
|
|
202
|
+
change, so changes there cannot be merged directly; the hand-written layer (`client.py`,
|
|
203
|
+
`operation.py`, `_custom/`), the examples and the docs welcome pull requests. See
|
|
204
|
+
[`CONTRIBUTING.md`](https://github.com/cinf-org/autoassembler-sdk/blob/main/CONTRIBUTING.md)
|
|
205
|
+
and, for maintainers, [`DEVELOPMENT.md`](https://github.com/cinf-org/autoassembler-sdk/blob/main/DEVELOPMENT.md).
|
|
206
|
+
|
|
207
|
+
## License
|
|
208
|
+
|
|
209
|
+
[MIT](https://github.com/cinf-org/autoassembler-sdk/blob/main/LICENSE) © C-Infinity.
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# AutoAssembler Python SDK
|
|
2
|
+
|
|
3
|
+
[AutoAssembler](https://autoassembler.com) is [C-Infinity](https://c-infinity.ai)'s foundational AI for
|
|
4
|
+
assembly process planning: read a CAD assembly, analyze its geometry, motion and production logic,
|
|
5
|
+
and turn that into manufacturing process plans, diff analysis, DFA analysis, work instructions and more.
|
|
6
|
+
This package is the official Python client for the AutoAssembler API. From a script or a notebook you can:
|
|
7
|
+
|
|
8
|
+
- **Upload** a CAD assembly (STEP, PVZ) and get a processed `Assembly` back.
|
|
9
|
+
- **Plan** it: create a process plan, assign parts to stations, let the planner work out the
|
|
10
|
+
assembly sequence, then **validate** that every station is physically buildable.
|
|
11
|
+
- **Diff** two revisions of an assembly and **adapt** an existing plan to the new one.
|
|
12
|
+
|
|
13
|
+
> **Status: 0.x.** The surface may still change between minor releases; see
|
|
14
|
+
> [Versioning](#versioning). The v4 API is stable, except the operations under `client.alpha`.
|
|
15
|
+
|
|
16
|
+
## Documentation
|
|
17
|
+
|
|
18
|
+
- Check the [Quickstart](#quickstart) below, then the runnable scripts in [`examples/`](https://github.com/cinf-org/autoassembler-sdk/tree/main/python/examples).
|
|
19
|
+
- [`reference.md`](https://github.com/cinf-org/autoassembler-sdk/blob/main/python/reference.md): every endpoint of the API as exposed by `client.api`.
|
|
20
|
+
- [Release notes](https://github.com/cinf-org/autoassembler-sdk/releases).
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
pip install autoassembler # or: uv add autoassembler
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Requires **Python 3.12+**. The only runtime dependencies are `httpx`, `pydantic>=2.5` and
|
|
29
|
+
`typing-extensions`.
|
|
30
|
+
|
|
31
|
+
## Authentication
|
|
32
|
+
|
|
33
|
+
Create an API key in the AutoAssembler app under
|
|
34
|
+
**Settings → API keys → Create API key**, then either pass it explicitly, set
|
|
35
|
+
`AA_TOKEN`, or log in interactively once:
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from autoassembler import AutoAssembler
|
|
39
|
+
|
|
40
|
+
client = AutoAssembler(token="aa_...") # explicit (CI, scripts)
|
|
41
|
+
client = AutoAssembler() # reads AA_TOKEN, or the token stored by login()
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
import autoassembler
|
|
46
|
+
_ = autoassembler.login() # confirm in your browser; stores the token for 30 days
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`login()` stores tokens in `~/.config/autoassembler/credentials.json`; `logout()` forgets them.
|
|
50
|
+
`login()` also returns the token: assign its result as above to avoid displaying it in a
|
|
51
|
+
notebook or interactive shell. Do not commit credentials or include them in reports.
|
|
52
|
+
`logout()` removes the local copy; it does not revoke the token on the server.
|
|
53
|
+
Pass `base_url=` to both `login()` and `AutoAssembler()` for anything but `https://app.autoassembler.com`,
|
|
54
|
+
including your own deployment.
|
|
55
|
+
|
|
56
|
+
## Quickstart
|
|
57
|
+
|
|
58
|
+
Use your own CAD files in place of the example filenames below; no CAD data is bundled.
|
|
59
|
+
These calls upload the files to the configured service and create resources in your account.
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
from autoassembler import AutoAssembler
|
|
63
|
+
|
|
64
|
+
client = AutoAssembler()
|
|
65
|
+
|
|
66
|
+
# Upload two revisions of a design. Processing overlaps on the server; wait for both.
|
|
67
|
+
v1, v2 = (op.result() for op in (client.assemblies.upload("gearbox_v1.step"),
|
|
68
|
+
client.assemblies.upload("gearbox_v2.step")))
|
|
69
|
+
|
|
70
|
+
# Plan v1 from scratch: one station with every part, plan it, check it is buildable.
|
|
71
|
+
mpp = client.planning.create_mpp(v1, name="Gearbox v1") # a manufacturing process plan
|
|
72
|
+
station = mpp.add_station("Final assembly")
|
|
73
|
+
outcome = mpp.plan(station).result() # complete | partial | failed
|
|
74
|
+
verdict = mpp.validate(station).result() # feasible | infeasible
|
|
75
|
+
print(outcome[station].status, verdict[station].status, mpp.viewer_url)
|
|
76
|
+
|
|
77
|
+
# What changed in v2, and v1's plan carried over to it.
|
|
78
|
+
diff = client.assemblies.diff(v1, v2).result()
|
|
79
|
+
mpp_v2 = client.planning.adapt(mpp, v2, diff=diff).result()
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Runnable versions of each step, with flags and error handling, live in
|
|
83
|
+
[`examples/`](https://github.com/cinf-org/autoassembler-sdk/tree/main/python/examples).
|
|
84
|
+
|
|
85
|
+
## How the SDK is organized
|
|
86
|
+
|
|
87
|
+
- **Concepts.** `Assembly` (a CAD file the service knows) and `ProcessPlan` (a manufacturing
|
|
88
|
+
process plan for one assembly, made of `Station`s).
|
|
89
|
+
- **Actions.** `upload`, `diff`, `plan`, `validate`, `evaluate_dfa`, `adapt`. An action that creates
|
|
90
|
+
a resource lives on a namespace (`client.assemblies.upload`, `client.planning.adapt`); an action
|
|
91
|
+
that acts on an existing resource lives on that resource's handle (`mpp.plan(station)`).
|
|
92
|
+
- **Waiting.** Anything that outlives its HTTP request returns an `Operation[T]`.
|
|
93
|
+
`op.result(timeout=None)` polls with backoff and returns `T`, or raises `OperationFailed` /
|
|
94
|
+
`OperationTimeout`; `op.done()` checks without blocking. Start several, then collect:
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
ops = [client.assemblies.upload(p) for p in cad_files]
|
|
98
|
+
assemblies = [op.result() for op in ops]
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Outcomes use the document's own words: a station's planning status is `pending`, `complete`,
|
|
102
|
+
`partial` (a usable partial plan) or `failed`; its validation verdict is `feasible` or
|
|
103
|
+
`infeasible`, with the issues behind it; an assembly is `processing`, `ready` or `failed`.
|
|
104
|
+
|
|
105
|
+
### The full API: `client.api`
|
|
106
|
+
|
|
107
|
+
The curated layer above is built on a client generated from the v4 OpenAPI spec, available
|
|
108
|
+
as `client.api` (`client.api.assemblies.get_status(...)`, `client.api.planning.get_mpp(...)`).
|
|
109
|
+
Use it when the vocabulary above does not cover what you need, and
|
|
110
|
+
[tell us](https://github.com/cinf-org/autoassembler-sdk/issues) what was missing.
|
|
111
|
+
Every endpoint is documented in
|
|
112
|
+
[`reference.md`](https://github.com/cinf-org/autoassembler-sdk/blob/main/python/reference.md).
|
|
113
|
+
|
|
114
|
+
An operation can be resumed by name from any process:
|
|
115
|
+
`client.operations.handle("operations/…").result()`.
|
|
116
|
+
|
|
117
|
+
### Errors
|
|
118
|
+
|
|
119
|
+
| Failure | Raised as |
|
|
120
|
+
|---|---|
|
|
121
|
+
| The server answered with an error status | `ApiError` (`status_code`, `body`, `headers`), or a typed subclass: `BadRequestError`, `UnauthorizedError`, `ForbiddenError`, `NotFoundError`, `ConflictError`, `UnprocessableEntityError` |
|
|
122
|
+
| The response did not match the expected schema | `ParsingError` (not an `ApiError`) |
|
|
123
|
+
| No response at all (DNS, connection, timeout) | `httpx.HTTPError` subclasses |
|
|
124
|
+
| A long-running operation failed or was cancelled | `OperationFailed` (`code`, `message`, `operation`) |
|
|
125
|
+
| A long-running operation did not finish in time | `OperationTimeout` (a `TimeoutError`) |
|
|
126
|
+
|
|
127
|
+
### Async
|
|
128
|
+
|
|
129
|
+
`AsyncAutoAssembler` currently exposes the generated client (`client.api`) and
|
|
130
|
+
`client.operations`; the curated `assemblies` / `planning` namespaces arrive on the async
|
|
131
|
+
client in a later release under the same names, with `asyncio.gather` as the natural way to
|
|
132
|
+
run work in parallel.
|
|
133
|
+
|
|
134
|
+
### Advanced
|
|
135
|
+
|
|
136
|
+
- **Timeouts.** 60 s per request by default: `AutoAssembler(timeout=20.0)` or
|
|
137
|
+
`request_options={"timeout": 5}` per call.
|
|
138
|
+
- **Retries.** Requests that fail with 408, 409, 429 or 5xx are retried twice with backoff;
|
|
139
|
+
`request_options={"max_retries": 0}` turns it off per call.
|
|
140
|
+
- **Your own `httpx` client**, for proxies or transports:
|
|
141
|
+
`AutoAssembler(httpx_client=httpx.Client(proxy="http://..."))`.
|
|
142
|
+
- **Raw responses.** `client.api.<namespace>.with_raw_response.<method>()` returns headers and
|
|
143
|
+
status alongside the parsed data.
|
|
144
|
+
- **Context managers.** `with AutoAssembler() as client:` closes the connection pool.
|
|
145
|
+
|
|
146
|
+
## Compatibility
|
|
147
|
+
|
|
148
|
+
| | |
|
|
149
|
+
|---|---|
|
|
150
|
+
| API | AutoAssembler **v4** (`autoassembler.API_VERSION == "v4"`). The client is generated from the published v4 OpenAPI spec; `fern/openapi/source.json` records which revision. |
|
|
151
|
+
| Servers | `https://app.autoassembler.com` by default; any AutoAssembler deployment that serves the v4 API via `base_url=`. |
|
|
152
|
+
|
|
153
|
+
## Versioning
|
|
154
|
+
|
|
155
|
+
The package follows [semantic versioning](https://semver.org/), independently of the API
|
|
156
|
+
version. While 0.x, a minor release may change the surface and a patch release only fixes;
|
|
157
|
+
from 1.0, breaking changes need a major release and removals are deprecated for one minor
|
|
158
|
+
release first. Each release's notes are on
|
|
159
|
+
[GitHub Releases](https://github.com/cinf-org/autoassembler-sdk/releases).
|
|
160
|
+
|
|
161
|
+
### Alpha
|
|
162
|
+
|
|
163
|
+
Operations the API offers before they are stable sit under `client.alpha` (also
|
|
164
|
+
`client.api.alpha`): today `client.alpha.jobs` and `client.alpha.planning.apply_ops`. They are
|
|
165
|
+
outside these guarantees: any release may change or remove them. An operation that becomes
|
|
166
|
+
stable moves out of `alpha`, to its namespace's usual place.
|
|
167
|
+
|
|
168
|
+
## Contributing
|
|
169
|
+
|
|
170
|
+
Bug reports and feature requests: [issues](https://github.com/cinf-org/autoassembler-sdk/issues).
|
|
171
|
+
Most of `python/src/autoassembler/` is generated from the OpenAPI spec and regenerated on every API
|
|
172
|
+
change, so changes there cannot be merged directly; the hand-written layer (`client.py`,
|
|
173
|
+
`operation.py`, `_custom/`), the examples and the docs welcome pull requests. See
|
|
174
|
+
[`CONTRIBUTING.md`](https://github.com/cinf-org/autoassembler-sdk/blob/main/CONTRIBUTING.md)
|
|
175
|
+
and, for maintainers, [`DEVELOPMENT.md`](https://github.com/cinf-org/autoassembler-sdk/blob/main/DEVELOPMENT.md).
|
|
176
|
+
|
|
177
|
+
## License
|
|
178
|
+
|
|
179
|
+
[MIT](https://github.com/cinf-org/autoassembler-sdk/blob/main/LICENSE) © C-Infinity.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Examples
|
|
2
|
+
|
|
3
|
+
These scripts are the acceptance test of the SDK's surface: the test suite runs each of
|
|
4
|
+
them offline against a scripted server (`tests/test_examples.py`).
|
|
5
|
+
|
|
6
|
+
One script per example. The module docstring is the explanation (`uv run <script> --help`
|
|
7
|
+
prints it); dependencies are declared inline (PEP 723), so `uv run` fetches them with no
|
|
8
|
+
install.
|
|
9
|
+
|
|
10
|
+
| Script | What it shows |
|
|
11
|
+
|---|---|
|
|
12
|
+
| [`login.py`](./login.py) | Log in once with the device flow; later scripts construct `AutoAssembler()` with no token. |
|
|
13
|
+
| [`upload.py`](./upload.py) | CAD files become `Assembly`s you can use; several at once, no threads. |
|
|
14
|
+
| [`diff.py`](./diff.py) | Compare two assemblies and read the report. |
|
|
15
|
+
| [`plan.py`](./plan.py) | Plan an assembly from scratch, then check the plan is buildable. |
|
|
16
|
+
| [`adapt.py`](./adapt.py) | Carry a process plan over to a revised assembly, from the diff between the two. |
|
|
17
|
+
| [`upload_async.py`](./upload_async.py) | The upload flow on the async client, with `asyncio.gather`. Target for the async release; not runnable yet. |
|
|
18
|
+
|
|
19
|
+
## Running one
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
cd python/examples # from the repository root
|
|
23
|
+
export AA_TOKEN="your-api-key" # Settings → API keys in the app
|
|
24
|
+
export AA_URL="https://app.autoassembler.com" # optional; this is the default
|
|
25
|
+
|
|
26
|
+
uv run login.py # instead of AA_TOKEN: log in once in the browser
|
|
27
|
+
uv run upload.py v1.step v2.step # one or more .step/.stp/.pvz files; prints each assembly id
|
|
28
|
+
uv run diff.py <reference_id> <target_id> # two assembly ids, e.g. from upload.py
|
|
29
|
+
uv run plan.py <assembly_id> [--name NAME] # prints the new plan's id
|
|
30
|
+
uv run adapt.py <reference_id> <reference_mpp_id> <target_id> [--name NAME] # the plan from plan.py, onto a revision
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`upload.py`, `plan.py` and `adapt.py` also take `--timeout SECONDS` (default 1800) for how long
|
|
34
|
+
to wait on the server.
|
|
35
|
+
|
|
36
|
+
Instead of `AA_TOKEN`, log in once with `uv run login.py` (the device flow, confirmed in your
|
|
37
|
+
browser); the token is stored under `~/.config/autoassembler/` and the scripts, which construct
|
|
38
|
+
`AutoAssembler()` without a token, find it.
|
|
39
|
+
|
|
40
|
+
The runnable CAD examples exit non-zero on failure and clean up resources they create.
|
|
41
|
+
`login.py` deliberately keeps the local credential. `upload_async.py` is a preview of
|
|
42
|
+
the future API and is not runnable in the current release.
|
|
43
|
+
|
|
44
|
+
From a checkout of this repository, `uv run python upload.py ...` runs a script against the
|
|
45
|
+
checkout's own code instead of the released package: the project environment has the SDK
|
|
46
|
+
installed in editable mode, and the inline dependency header is not consulted.
|
|
47
|
+
|
|
48
|
+
## The walkthrough: from two CAD revisions to a plan and a diff
|
|
49
|
+
|
|
50
|
+
The examples compose into one end-to-end flow:
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
uploads = [client.assemblies.upload(p) for p in ("gearbox_v1.step", "gearbox_v2.step")]
|
|
54
|
+
v1, v2 = (op.result(timeout=1800) for op in uploads) # both processed in parallel
|
|
55
|
+
|
|
56
|
+
report = client.assemblies.diff(v1, v2).result(timeout=1800)
|
|
57
|
+
print(f"{report.summary.candidate_swaps} candidate swaps")
|
|
58
|
+
|
|
59
|
+
mpp = client.planning.create_mpp(v2, name="Gearbox v2 — greenfield")
|
|
60
|
+
station = mpp.add_station("Final assembly")
|
|
61
|
+
if mpp.plan(station).result(timeout=1800)[station].status == "failed":
|
|
62
|
+
raise SystemExit("no plan")
|
|
63
|
+
print(mpp.viewer_url)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Parallel work, sync and async
|
|
67
|
+
|
|
68
|
+
Starting an operation and waiting for it are separate calls, so the **sync** client runs
|
|
69
|
+
work in parallel without threads: start everything, then collect. The file transfers
|
|
70
|
+
happen one after another, but the processing, which dominates, overlaps on the server, so
|
|
71
|
+
the wall-clock cost is roughly one transfer per file plus the slowest processing.
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
ops = [client.assemblies.upload(p) for p in cad_files] # N uploads, all processing
|
|
75
|
+
assemblies = [op.result(timeout=1800) for op in ops] # ≈ as long as the slowest one
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The **async** client has every verb under the same name. Starting an operation is itself
|
|
79
|
+
an HTTP call, so it is awaited; the handle is then awaited to completion. Two awaits, which
|
|
80
|
+
is exactly what makes `asyncio.gather` natural:
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
import asyncio
|
|
84
|
+
from autoassembler import AsyncAutoAssembler
|
|
85
|
+
|
|
86
|
+
client = AsyncAutoAssembler(token=...)
|
|
87
|
+
ops = await asyncio.gather(*(client.assemblies.upload(p) for p in cad_files))
|
|
88
|
+
assemblies = await asyncio.gather(*(op.result(timeout=1800) for op in ops))
|
|
89
|
+
report = await (await client.assemblies.diff(assemblies[0], assemblies[1])).result()
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Async pollers sleep with `asyncio.sleep`, so a hundred pending operations are a hundred
|
|
93
|
+
coroutines, not a hundred threads. See [`upload_async.py`](./upload_async.py). The curated
|
|
94
|
+
namespaces ship sync-first, so that script is the target for the async release; until
|
|
95
|
+
then `AsyncAutoAssembler` offers the generated client at `client.api`.
|
|
96
|
+
|
|
97
|
+
Both clients can also be used as context managers (`with AutoAssembler(...) as client:`,
|
|
98
|
+
`async with AsyncAutoAssembler(...) as client:`), which closes the HTTP connection pool when
|
|
99
|
+
the block ends. The examples construct the client plainly; both forms are fine.
|
|
100
|
+
|
|
101
|
+
## When you need the wire
|
|
102
|
+
|
|
103
|
+
The generated client is one attribute away and documents every endpoint
|
|
104
|
+
([`reference.md`](../reference.md)): `client.api.assemblies.get_status("user", id)`,
|
|
105
|
+
`client.api.planning.get_mpp(...)`. The curated namespaces above are built on it; use it
|
|
106
|
+
when the vocabulary here does not cover what you need, and tell us what was missing.
|
|
107
|
+
|
|
108
|
+
## Adding an example
|
|
109
|
+
|
|
110
|
+
1. Copy the closest script. Keep the PEP 723 header, the `uv run` shebang and the
|
|
111
|
+
`AA_TOKEN` / `AA_URL` environment contract.
|
|
112
|
+
2. Write the module docstring first: what it does, the key steps as a list, what it assumes.
|
|
113
|
+
That docstring is the documentation; there is no separate README.
|
|
114
|
+
3. Exit non-zero on failure and clean up what you created, so the script can double as a
|
|
115
|
+
smoke test. Add an `_async.py` twin only when the async variant shows something the sync
|
|
116
|
+
one cannot.
|
|
117
|
+
4. Add one row to the table above.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env -S uv run --script
|
|
2
|
+
# /// script
|
|
3
|
+
# requires-python = ">=3.12"
|
|
4
|
+
# dependencies = [
|
|
5
|
+
# "autoassembler>=0.3",
|
|
6
|
+
# ]
|
|
7
|
+
# ///
|
|
8
|
+
"""Carry a process plan over to a revised assembly.
|
|
9
|
+
|
|
10
|
+
export AA_TOKEN="your-api-key" # or log in once: uv run login.py
|
|
11
|
+
uv run adapt.py <reference_assembly_id> <reference_mpp_id> <target_assembly_id> [--name NAME]
|
|
12
|
+
|
|
13
|
+
Given a plan for one revision of an assembly, builds the plan for the next revision from it
|
|
14
|
+
instead of planning from scratch: stations and steps carry over, adjusted for what changed.
|
|
15
|
+
|
|
16
|
+
In this example, we:
|
|
17
|
+
- look the assemblies up with client.assemblies.get(id) and the reference plan with
|
|
18
|
+
client.planning.get_mpp(assembly, mpp_id);
|
|
19
|
+
- call client.assemblies.diff(reference, target).result(): what changed between the two
|
|
20
|
+
revisions, which the adaptation works from;
|
|
21
|
+
- call client.planning.adapt(reference_plan, target, diff=report).result(): the new
|
|
22
|
+
ProcessPlan, once saved;
|
|
23
|
+
- print its stations and mpp.viewer_url, which opens it in the UI.
|
|
24
|
+
|
|
25
|
+
Both assemblies must be `ready` (see upload.py).
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
import argparse
|
|
29
|
+
import os
|
|
30
|
+
import sys
|
|
31
|
+
|
|
32
|
+
from autoassembler import AutoAssembler, OperationFailed
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def main() -> int:
|
|
36
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
37
|
+
parser.add_argument("reference_assembly_id")
|
|
38
|
+
parser.add_argument("reference_mpp_id")
|
|
39
|
+
parser.add_argument("target_assembly_id")
|
|
40
|
+
parser.add_argument("--name", default=None, help="name of the adapted process plan")
|
|
41
|
+
parser.add_argument("--timeout", type=float, default=1800)
|
|
42
|
+
args = parser.parse_args()
|
|
43
|
+
|
|
44
|
+
client = AutoAssembler(
|
|
45
|
+
base_url=os.environ.get("AA_URL", "https://app.autoassembler.com"),
|
|
46
|
+
)
|
|
47
|
+
reference = client.assemblies.get(args.reference_assembly_id)
|
|
48
|
+
target = client.assemblies.get(args.target_assembly_id)
|
|
49
|
+
reference_plan = client.planning.get_mpp(reference, args.reference_mpp_id)
|
|
50
|
+
|
|
51
|
+
print(f"Comparing {reference.name} → {target.name}...", flush=True)
|
|
52
|
+
report = client.assemblies.diff(reference, target).result(timeout=args.timeout)
|
|
53
|
+
|
|
54
|
+
print(f"Adapting {reference_plan.name!r}...", flush=True)
|
|
55
|
+
try:
|
|
56
|
+
mpp = client.planning.adapt(reference_plan, target, diff=report, name=args.name).result(
|
|
57
|
+
timeout=args.timeout
|
|
58
|
+
)
|
|
59
|
+
except OperationFailed as error:
|
|
60
|
+
print(f"Adaptation failed: {error.message}", file=sys.stderr)
|
|
61
|
+
return 1
|
|
62
|
+
|
|
63
|
+
print(f"Created plan {mpp.id!r} with {len(mpp.stations)} station(s)")
|
|
64
|
+
for station in mpp.stations:
|
|
65
|
+
print(f" {station.name}: {station.status}")
|
|
66
|
+
print(f"\n{mpp.viewer_url}")
|
|
67
|
+
return 0
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
if __name__ == "__main__":
|
|
71
|
+
raise SystemExit(main())
|