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.
Files changed (218) hide show
  1. autoassembler-0.3.1/.gitignore +48 -0
  2. autoassembler-0.3.1/LICENSE +21 -0
  3. autoassembler-0.3.1/Makefile +23 -0
  4. autoassembler-0.3.1/PKG-INFO +209 -0
  5. autoassembler-0.3.1/README.md +179 -0
  6. autoassembler-0.3.1/examples/README.md +117 -0
  7. autoassembler-0.3.1/examples/adapt.py +71 -0
  8. autoassembler-0.3.1/examples/diff.py +60 -0
  9. autoassembler-0.3.1/examples/login.py +49 -0
  10. autoassembler-0.3.1/examples/plan.py +98 -0
  11. autoassembler-0.3.1/examples/upload.py +61 -0
  12. autoassembler-0.3.1/examples/upload_async.py +82 -0
  13. autoassembler-0.3.1/pyproject.toml +110 -0
  14. autoassembler-0.3.1/reference.md +2636 -0
  15. autoassembler-0.3.1/src/autoassembler/.fernignore +7 -0
  16. autoassembler-0.3.1/src/autoassembler/__init__.py +537 -0
  17. autoassembler-0.3.1/src/autoassembler/_custom/__init__.py +56 -0
  18. autoassembler-0.3.1/src/autoassembler/_custom/assemblies.py +226 -0
  19. autoassembler-0.3.1/src/autoassembler/_custom/assemblies_api.py +188 -0
  20. autoassembler-0.3.1/src/autoassembler/_custom/credentials.py +248 -0
  21. autoassembler-0.3.1/src/autoassembler/_custom/http.py +42 -0
  22. autoassembler-0.3.1/src/autoassembler/_custom/operations.py +258 -0
  23. autoassembler-0.3.1/src/autoassembler/_custom/planning.py +598 -0
  24. autoassembler-0.3.1/src/autoassembler/_custom/planning_api.py +225 -0
  25. autoassembler-0.3.1/src/autoassembler/_default_clients.py +32 -0
  26. autoassembler-0.3.1/src/autoassembler/_version.py +8 -0
  27. autoassembler-0.3.1/src/autoassembler/alpha/__init__.py +63 -0
  28. autoassembler-0.3.1/src/autoassembler/alpha/client.py +82 -0
  29. autoassembler-0.3.1/src/autoassembler/alpha/jobs/__init__.py +39 -0
  30. autoassembler-0.3.1/src/autoassembler/alpha/jobs/client.py +338 -0
  31. autoassembler-0.3.1/src/autoassembler/alpha/jobs/raw_client.py +641 -0
  32. autoassembler-0.3.1/src/autoassembler/alpha/jobs/types/__init__.py +42 -0
  33. autoassembler-0.3.1/src/autoassembler/alpha/jobs/types/cancel_job_jobs_response.py +12 -0
  34. autoassembler-0.3.1/src/autoassembler/alpha/jobs/types/list_jobs_jobs_response.py +30 -0
  35. autoassembler-0.3.1/src/autoassembler/alpha/jobs/types/list_jobs_jobs_response_pagination.py +22 -0
  36. autoassembler-0.3.1/src/autoassembler/alpha/jobs/types/retry_job_jobs_response.py +16 -0
  37. autoassembler-0.3.1/src/autoassembler/alpha/planning/__init__.py +49 -0
  38. autoassembler-0.3.1/src/autoassembler/alpha/planning/client.py +201 -0
  39. autoassembler-0.3.1/src/autoassembler/alpha/planning/raw_client.py +268 -0
  40. autoassembler-0.3.1/src/autoassembler/alpha/planning/types/__init__.py +47 -0
  41. autoassembler-0.3.1/src/autoassembler/alpha/planning/types/apply_ops_planning_request_namespace.py +5 -0
  42. autoassembler-0.3.1/src/autoassembler/alpha/planning/types/apply_ops_planning_request_ops_item.py +13 -0
  43. autoassembler-0.3.1/src/autoassembler/alpha/planning/types/apply_ops_planning_request_ops_item_op.py +58 -0
  44. autoassembler-0.3.1/src/autoassembler/alpha/planning/types/apply_ops_planning_response.py +13 -0
  45. autoassembler-0.3.1/src/autoassembler/alpha/raw_client.py +13 -0
  46. autoassembler-0.3.1/src/autoassembler/assemblies/__init__.py +73 -0
  47. autoassembler-0.3.1/src/autoassembler/assemblies/client.py +1177 -0
  48. autoassembler-0.3.1/src/autoassembler/assemblies/raw_client.py +1557 -0
  49. autoassembler-0.3.1/src/autoassembler/assemblies/types/__init__.py +71 -0
  50. autoassembler-0.3.1/src/autoassembler/assemblies/types/delete_assembly_response.py +12 -0
  51. autoassembler-0.3.1/src/autoassembler/assemblies/types/download_assembly_cad_request_namespace.py +5 -0
  52. autoassembler-0.3.1/src/autoassembler/assemblies/types/get_assembly_info_request_namespace.py +5 -0
  53. autoassembler-0.3.1/src/autoassembler/assemblies/types/get_status_request_namespace.py +5 -0
  54. autoassembler-0.3.1/src/autoassembler/assemblies/types/get_status_response.py +16 -0
  55. autoassembler-0.3.1/src/autoassembler/assemblies/types/get_status_response_progress.py +13 -0
  56. autoassembler-0.3.1/src/autoassembler/assemblies/types/get_status_response_status.py +7 -0
  57. autoassembler-0.3.1/src/autoassembler/assemblies/types/get_structure_request_namespace.py +5 -0
  58. autoassembler-0.3.1/src/autoassembler/assemblies/types/list_assembly_versions_request_namespace.py +5 -0
  59. autoassembler-0.3.1/src/autoassembler/assemblies/types/list_connections_request_namespace.py +5 -0
  60. autoassembler-0.3.1/src/autoassembler/assemblies/types/process_request_namespace.py +5 -0
  61. autoassembler-0.3.1/src/autoassembler/assemblies/types/update_assembly_info_request_namespace.py +5 -0
  62. autoassembler-0.3.1/src/autoassembler/auth/__init__.py +34 -0
  63. autoassembler-0.3.1/src/autoassembler/auth/client.py +282 -0
  64. autoassembler-0.3.1/src/autoassembler/auth/raw_client.py +413 -0
  65. autoassembler-0.3.1/src/autoassembler/auth/types/__init__.py +36 -0
  66. autoassembler-0.3.1/src/autoassembler/auth/types/create_access_token_request_grant_type.py +7 -0
  67. autoassembler-0.3.1/src/autoassembler/base_client.py +328 -0
  68. autoassembler-0.3.1/src/autoassembler/client.py +262 -0
  69. autoassembler-0.3.1/src/autoassembler/core/__init__.py +127 -0
  70. autoassembler-0.3.1/src/autoassembler/core/api_error.py +23 -0
  71. autoassembler-0.3.1/src/autoassembler/core/client_wrapper.py +147 -0
  72. autoassembler-0.3.1/src/autoassembler/core/datetime_utils.py +70 -0
  73. autoassembler-0.3.1/src/autoassembler/core/file.py +67 -0
  74. autoassembler-0.3.1/src/autoassembler/core/force_multipart.py +18 -0
  75. autoassembler-0.3.1/src/autoassembler/core/http_client.py +965 -0
  76. autoassembler-0.3.1/src/autoassembler/core/http_response.py +63 -0
  77. autoassembler-0.3.1/src/autoassembler/core/http_sse/__init__.py +42 -0
  78. autoassembler-0.3.1/src/autoassembler/core/http_sse/_api.py +455 -0
  79. autoassembler-0.3.1/src/autoassembler/core/http_sse/_decoders.py +74 -0
  80. autoassembler-0.3.1/src/autoassembler/core/http_sse/_exceptions.py +7 -0
  81. autoassembler-0.3.1/src/autoassembler/core/http_sse/_models.py +17 -0
  82. autoassembler-0.3.1/src/autoassembler/core/jsonable_encoder.py +133 -0
  83. autoassembler-0.3.1/src/autoassembler/core/logging.py +107 -0
  84. autoassembler-0.3.1/src/autoassembler/core/parse_error.py +36 -0
  85. autoassembler-0.3.1/src/autoassembler/core/pydantic_utilities.py +486 -0
  86. autoassembler-0.3.1/src/autoassembler/core/query_encoder.py +58 -0
  87. autoassembler-0.3.1/src/autoassembler/core/remove_none_from_dict.py +11 -0
  88. autoassembler-0.3.1/src/autoassembler/core/request_options.py +40 -0
  89. autoassembler-0.3.1/src/autoassembler/core/serialization.py +347 -0
  90. autoassembler-0.3.1/src/autoassembler/environment.py +7 -0
  91. autoassembler-0.3.1/src/autoassembler/errors/__init__.py +56 -0
  92. autoassembler-0.3.1/src/autoassembler/errors/bad_request_error.py +10 -0
  93. autoassembler-0.3.1/src/autoassembler/errors/conflict_error.py +10 -0
  94. autoassembler-0.3.1/src/autoassembler/errors/forbidden_error.py +11 -0
  95. autoassembler-0.3.1/src/autoassembler/errors/internal_server_error.py +11 -0
  96. autoassembler-0.3.1/src/autoassembler/errors/not_found_error.py +11 -0
  97. autoassembler-0.3.1/src/autoassembler/errors/unauthorized_error.py +10 -0
  98. autoassembler-0.3.1/src/autoassembler/errors/unprocessable_entity_error.py +11 -0
  99. autoassembler-0.3.1/src/autoassembler/operation.py +196 -0
  100. autoassembler-0.3.1/src/autoassembler/operations/__init__.py +4 -0
  101. autoassembler-0.3.1/src/autoassembler/operations/client.py +209 -0
  102. autoassembler-0.3.1/src/autoassembler/operations/raw_client.py +343 -0
  103. autoassembler-0.3.1/src/autoassembler/planning/__init__.py +70 -0
  104. autoassembler-0.3.1/src/autoassembler/planning/client.py +1174 -0
  105. autoassembler-0.3.1/src/autoassembler/planning/raw_client.py +1349 -0
  106. autoassembler-0.3.1/src/autoassembler/planning/types/__init__.py +68 -0
  107. autoassembler-0.3.1/src/autoassembler/planning/types/adapt_request_namespace.py +5 -0
  108. autoassembler-0.3.1/src/autoassembler/planning/types/create_mpp_request_body.py +8 -0
  109. autoassembler-0.3.1/src/autoassembler/planning/types/create_mpp_request_namespace.py +5 -0
  110. autoassembler-0.3.1/src/autoassembler/planning/types/delete_mpp_request_namespace.py +5 -0
  111. autoassembler-0.3.1/src/autoassembler/planning/types/delete_mpp_response.py +12 -0
  112. autoassembler-0.3.1/src/autoassembler/planning/types/evaluate_dfa_request_namespace.py +5 -0
  113. autoassembler-0.3.1/src/autoassembler/planning/types/get_mpp_request_namespace.py +5 -0
  114. autoassembler-0.3.1/src/autoassembler/planning/types/get_mpp_response.py +27 -0
  115. autoassembler-0.3.1/src/autoassembler/planning/types/list_mpps_request_namespace.py +5 -0
  116. autoassembler-0.3.1/src/autoassembler/planning/types/plan_request_namespace.py +5 -0
  117. autoassembler-0.3.1/src/autoassembler/planning/types/validate_request_namespace.py +5 -0
  118. autoassembler-0.3.1/src/autoassembler/py.typed +0 -0
  119. autoassembler-0.3.1/src/autoassembler/sessions/__init__.py +4 -0
  120. autoassembler-0.3.1/src/autoassembler/sessions/client.py +102 -0
  121. autoassembler-0.3.1/src/autoassembler/sessions/raw_client.py +126 -0
  122. autoassembler-0.3.1/src/autoassembler/tests/conftest.py +21 -0
  123. autoassembler-0.3.1/src/autoassembler/tests/test_aiohttp_autodetect.py +113 -0
  124. autoassembler-0.3.1/src/autoassembler/types/__init__.py +344 -0
  125. autoassembler-0.3.1/src/autoassembler/types/access_token_response.py +14 -0
  126. autoassembler-0.3.1/src/autoassembler/types/active_session.py +25 -0
  127. autoassembler-0.3.1/src/autoassembler/types/active_session_namespace.py +5 -0
  128. autoassembler-0.3.1/src/autoassembler/types/adapt_mpp_accepted.py +26 -0
  129. autoassembler-0.3.1/src/autoassembler/types/assembly.py +30 -0
  130. autoassembler-0.3.1/src/autoassembler/types/assembly_connection.py +21 -0
  131. autoassembler-0.3.1/src/autoassembler/types/assembly_connection_relationship.py +5 -0
  132. autoassembler-0.3.1/src/autoassembler/types/assembly_connections_response.py +13 -0
  133. autoassembler-0.3.1/src/autoassembler/types/assembly_diff_metadata.py +35 -0
  134. autoassembler-0.3.1/src/autoassembler/types/assembly_diff_response.py +34 -0
  135. autoassembler-0.3.1/src/autoassembler/types/assembly_info.py +36 -0
  136. autoassembler-0.3.1/src/autoassembler/types/assembly_json_response.py +15 -0
  137. autoassembler-0.3.1/src/autoassembler/types/assembly_process_metadata.py +32 -0
  138. autoassembler-0.3.1/src/autoassembler/types/assembly_process_response.py +18 -0
  139. autoassembler-0.3.1/src/autoassembler/types/assembly_search_hit.py +31 -0
  140. autoassembler-0.3.1/src/autoassembler/types/assembly_version_summary.py +27 -0
  141. autoassembler-0.3.1/src/autoassembler/types/conflict_error_body.py +19 -0
  142. autoassembler-0.3.1/src/autoassembler/types/conflict_error_body_error.py +5 -0
  143. autoassembler-0.3.1/src/autoassembler/types/create_mpp_request.py +13 -0
  144. autoassembler-0.3.1/src/autoassembler/types/device_authorization_response.py +17 -0
  145. autoassembler-0.3.1/src/autoassembler/types/diff_accepted.py +42 -0
  146. autoassembler-0.3.1/src/autoassembler/types/diff_context_node.py +20 -0
  147. autoassembler-0.3.1/src/autoassembler/types/diff_details.py +73 -0
  148. autoassembler-0.3.1/src/autoassembler/types/diff_error_response.py +38 -0
  149. autoassembler-0.3.1/src/autoassembler/types/diff_flags.py +74 -0
  150. autoassembler-0.3.1/src/autoassembler/types/diff_ml_semantics.py +55 -0
  151. autoassembler-0.3.1/src/autoassembler/types/diff_node.py +26 -0
  152. autoassembler-0.3.1/src/autoassembler/types/diff_node_pair_with_parts.py +90 -0
  153. autoassembler-0.3.1/src/autoassembler/types/diff_node_with_parent.py +15 -0
  154. autoassembler-0.3.1/src/autoassembler/types/diff_reference_target_nodes.py +25 -0
  155. autoassembler-0.3.1/src/autoassembler/types/diff_report.py +24 -0
  156. autoassembler-0.3.1/src/autoassembler/types/diff_rigid_alignment.py +30 -0
  157. autoassembler-0.3.1/src/autoassembler/types/diff_summary.py +121 -0
  158. autoassembler-0.3.1/src/autoassembler/types/diff_summary_assembly_labels.py +44 -0
  159. autoassembler-0.3.1/src/autoassembler/types/diff_summary_geometric_diffs.py +24 -0
  160. autoassembler-0.3.1/src/autoassembler/types/diff_summary_persistent_edges_congruence.py +24 -0
  161. autoassembler-0.3.1/src/autoassembler/types/diff_summary_persistent_edges_congruence_pose.py +24 -0
  162. autoassembler-0.3.1/src/autoassembler/types/diff_summary_persistent_nodes_congruence.py +24 -0
  163. autoassembler-0.3.1/src/autoassembler/types/diff_summary_persistent_nodes_congruence_pose.py +24 -0
  164. autoassembler-0.3.1/src/autoassembler/types/diff_summary_total_parts.py +24 -0
  165. autoassembler-0.3.1/src/autoassembler/types/diff_swap.py +65 -0
  166. autoassembler-0.3.1/src/autoassembler/types/diff_swap_confidence.py +5 -0
  167. autoassembler-0.3.1/src/autoassembler/types/diff_swap_group.py +92 -0
  168. autoassembler-0.3.1/src/autoassembler/types/diff_validation_issue.py +38 -0
  169. autoassembler-0.3.1/src/autoassembler/types/diff_validation_issue_severity.py +5 -0
  170. autoassembler-0.3.1/src/autoassembler/types/diff_validation_result.py +35 -0
  171. autoassembler-0.3.1/src/autoassembler/types/diff_warning.py +79 -0
  172. autoassembler-0.3.1/src/autoassembler/types/diff_warning_reason.py +18 -0
  173. autoassembler-0.3.1/src/autoassembler/types/diff_warning_severity.py +5 -0
  174. autoassembler-0.3.1/src/autoassembler/types/error_response.py +30 -0
  175. autoassembler-0.3.1/src/autoassembler/types/filter.py +19 -0
  176. autoassembler-0.3.1/src/autoassembler/types/filter_field.py +7 -0
  177. autoassembler-0.3.1/src/autoassembler/types/filter_operator.py +5 -0
  178. autoassembler-0.3.1/src/autoassembler/types/job.py +123 -0
  179. autoassembler-0.3.1/src/autoassembler/types/job_progress.py +24 -0
  180. autoassembler-0.3.1/src/autoassembler/types/job_status.py +5 -0
  181. autoassembler-0.3.1/src/autoassembler/types/list_operations_response.py +25 -0
  182. autoassembler-0.3.1/src/autoassembler/types/manufacturing_process_plan.py +57 -0
  183. autoassembler-0.3.1/src/autoassembler/types/mpp_adapt_metadata.py +48 -0
  184. autoassembler-0.3.1/src/autoassembler/types/mpp_adapt_response.py +22 -0
  185. autoassembler-0.3.1/src/autoassembler/types/mpp_evaluate_dfa_metadata.py +47 -0
  186. autoassembler-0.3.1/src/autoassembler/types/mpp_evaluate_dfa_response.py +22 -0
  187. autoassembler-0.3.1/src/autoassembler/types/mpp_plan_metadata.py +47 -0
  188. autoassembler-0.3.1/src/autoassembler/types/mpp_plan_response.py +22 -0
  189. autoassembler-0.3.1/src/autoassembler/types/mpp_summary.py +20 -0
  190. autoassembler-0.3.1/src/autoassembler/types/mpp_validate_metadata.py +47 -0
  191. autoassembler-0.3.1/src/autoassembler/types/mpp_validate_response.py +22 -0
  192. autoassembler-0.3.1/src/autoassembler/types/o_auth_error_response.py +14 -0
  193. autoassembler-0.3.1/src/autoassembler/types/o_auth_error_response_error.py +18 -0
  194. autoassembler-0.3.1/src/autoassembler/types/operation.py +27 -0
  195. autoassembler-0.3.1/src/autoassembler/types/operation_error.py +21 -0
  196. autoassembler-0.3.1/src/autoassembler/types/operation_metadata.py +148 -0
  197. autoassembler-0.3.1/src/autoassembler/types/operation_response.py +94 -0
  198. autoassembler-0.3.1/src/autoassembler/types/process_assembly_accepted.py +14 -0
  199. autoassembler-0.3.1/src/autoassembler/types/process_assembly_response.py +55 -0
  200. autoassembler-0.3.1/src/autoassembler/types/process_assembly_skipped.py +14 -0
  201. autoassembler-0.3.1/src/autoassembler/types/search_assemblies_response.py +14 -0
  202. autoassembler-0.3.1/src/autoassembler/types/seq_plan_accepted.py +24 -0
  203. autoassembler-0.3.1/src/autoassembler/types/sever.py +33 -0
  204. autoassembler-0.3.1/src/autoassembler/types/sever_kind.py +5 -0
  205. autoassembler-0.3.1/src/autoassembler/types/sever_source.py +5 -0
  206. autoassembler-0.3.1/src/autoassembler/types/sort.py +8 -0
  207. autoassembler-0.3.1/src/autoassembler/types/upload_response.py +19 -0
  208. autoassembler-0.3.1/src/autoassembler/types/user_info.py +19 -0
  209. autoassembler-0.3.1/src/autoassembler/types/user_info_response.py +23 -0
  210. autoassembler-0.3.1/src/autoassembler/types/user_info_response_providers.py +14 -0
  211. autoassembler-0.3.1/tests/test_client.py +66 -0
  212. autoassembler-0.3.1/tests/test_contract.py +659 -0
  213. autoassembler-0.3.1/tests/test_credentials.py +270 -0
  214. autoassembler-0.3.1/tests/test_examples.py +483 -0
  215. autoassembler-0.3.1/tests/test_handles.py +843 -0
  216. autoassembler-0.3.1/tests/test_operation.py +162 -0
  217. autoassembler-0.3.1/tests/test_package.py +60 -0
  218. 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())