{"library":"spin","title":"spin","type":"library","description":"spin is a developer tool designed to simplify common tasks for scientific Python libraries, such as environment setup, testing, and documentation builds. It focuses on standardizing development workflows using `pyproject.toml`. Current version is 0.18, with releases occurring periodically to add features and fix bugs.","language":"python","status":"active","last_verified":"Sun May 17","install":{"commands":["pip install spin"],"cli":{"name":"spin","version":"Could not load configuration from one of: .spin.toml, spin.toml, pyproject.toml"}},"imports":["from spin.app import run_spin"],"auth":{"required":false,"env_vars":[]},"links":{"homepage":null,"github":"https://github.com/scientific-python/spin","docs":null,"changelog":null,"pypi":"https://pypi.org/project/spin/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null},"quickstart":{"code":"import os\nimport subprocess\nimport sys\nimport tempfile\nfrom pathlib import Path\n\n# Create a temporary project directory to run spin in\nwith tempfile.TemporaryDirectory() as tmpdir_name:\n    project_path = Path(tmpdir_name)\n    os.chdir(project_path)\n\n    # Define a simple pyproject.toml with a 'hello' task\n    pyproject_content = \"\"\"\n[project]\nname = \"my-spin-project\"\nversion = \"0.1.0\"\n\n[tool.spin]\ntasks.hello = \"echo Hello from spin!\"\n\"\"\"\n    (project_path / \"pyproject.toml\").write_text(pyproject_content)\n\n    print(f\"Temporary project created at: {project_path}\")\n    print(\"Attempting to run 'spin hello' via subprocess...\")\n\n    try:\n        # Invoke spin using `python -m spin` to simulate CLI execution\n        # and allow the Python script to continue after spin completes.\n        result = subprocess.run([sys.executable, '-m', 'spin', 'hello'],\n                                capture_output=True, text=True, check=True)\n        \n        print(\"\\n--- spin output ---\")\n        print(result.stdout.strip())\n        print(\"--- end spin output ---\")\n        \n        assert \"Hello from spin!\" in result.stdout\n        print(\"Quickstart successful: 'spin hello' task executed and verified.\")\n\n    except subprocess.CalledProcessError as e:\n        print(f\"Error running spin command (exit code {e.returncode}):\")\n        print(f\"Stdout: {e.stdout}\")\n        print(f\"Stderr: {e.stderr}\")\n        sys.exit(1)\n    except Exception as e:\n        print(f\"An unexpected error occurred: {e}\")\n        sys.exit(1)\n","lang":"python","description":"This quickstart demonstrates how to set up a minimal `spin` project (a `pyproject.toml` with a task) and then programmatically invoke a `spin` command using `subprocess`. While `spin` has a Python API (`spin.app.run_spin`), direct `subprocess` invocation is often more robust for quickstarts and automation, as `run_spin` can cause `sys.exit()`.","tag":null,"tag_description":null,"last_tested":null,"results":[]},"compatibility":{"tag":null,"tag_description":null,"last_tested":"2026-05-17","installed_version":"0.15","pypi_latest":"0.18","is_stale":true,"summary":{"python_range":"3.10–3.9","success_rate":100,"avg_install_s":1.8,"avg_import_s":null,"wheel_type":"wheel"},"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"spin","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"19.3M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"spin","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":2,"import_time_s":null,"mem_mb":null,"disk_size":"20M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"spin","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"21.3M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"spin","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":1.8,"import_time_s":null,"mem_mb":null,"disk_size":"22M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"spin","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"13.1M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"spin","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":1.6,"import_time_s":null,"mem_mb":null,"disk_size":"14M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"spin","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"12.8M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"spin","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":1.6,"import_time_s":null,"mem_mb":null,"disk_size":"13M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"spin","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"18.7M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"spin","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":2.1,"import_time_s":null,"mem_mb":null,"disk_size":"19M"}]}}