Contributors ============ There are many ways to directly contribute to the project. You can enhance the documentation and user guides, or add additional API models and methods. For both there are guidelines for how to proceed. Pull Requests ------------- Unless you are a project maintainer all pull requests should be made against the ``main`` branch of the project from a fork in your personal GitHub account. It is recommended you work in a feature branch of your fork and periodically pull in changes from ``main``. All pull requests must pass all tests and linting as defined in the `main_pr_tests.yaml `_ GitHub Actions workflow. Your branch must be up to date with the ``main`` branch. Be sure to pull in all change and resolve merge conflicts before you open your PR. Documentation ------------- The Jamf Pro SDK for Python's documentation is written in `reStructuredText `_ and is built using `Sphinx `_. Documentation is a combination of hand written user guides and code references rendering the docstrings. If you are contributing updates to existing user guides, or expanding with new content, try to include easy to follow instructions and explanations interspersed with ``code-block`` examples and/or references to SDK objects. As much as possible keep your contributions consistent with existing content. .. important:: If you have recommendations for major changes to the documentation - whether rewriting sections or reorganizing content - please open a `Feedback issue `_ first for discussion. Code Contributions ------------------ Before writing code and opening a pull request to add to the project, please open a `Feedback issue `_ for discussion of the proposed changes and ensuring duplicate work is not in flight. Code contributors are required to uphold project standards: * Consistency with existing SDK interfaces. * All code conforms to formatting and styling (``ruff`` is used in this project and is enforced at pull request). * All changes are documented in the users guides, references, and docstrings. * Code changes are covered by additional tests (future: this project will not have a full test suite until it comes out of alpha). * Backwards compatibility is not broken by the contributions (with the exception of the alpha period where breaking changes may be allowed on a case-by-case basis). Your pull request may not be accepted if it does not fulfill all of the requirements listed above. Dev Environment Setup ^^^^^^^^^^^^^^^^^^^^^ It is recommended you use a Python virtual environment for local development (see `venv `_. .. tip:: The ``Makefile`` included in the project includes shortcut commands that will be referenced in this document. You must install ``Xcode Command Line Tools`` on macOS to use the ``make`` command. With your virtual environment active run the following from the SDK repository's directory: .. code-block:: console (.venv) % make install This will install the package in editable mode with all dev and optional dependencies. There are two additional ``make`` commands for maintaining your local environment. * ``uninstall`` will remove **ALL** Python packages from your virtual environment allowing you to reinstall cleanly if needed. * ``clean`` will remove any directory that's generated by linting, testing, and building the package. This is useful in the event cached files are causing an issue with running commands. Code Quality ^^^^^^^^^^^^ The ``ruff`` tool will enforce formatting standards for the codebase. The settings are defined in `pyproject.toml `_. * ``make lint`` will check if your code is compliant with the formatting and linting rules without making changes. * ``make format`` will edit your code to comply with the formatting and linting rules. Project code is required to use type hinting from the ``typing`` module for all arguments and returns. These should be documented in the docstring following Sphinx's `signatures `_ syntax. The top of a docstring should include a brief description plus a longer explanation of any special behavior. Any reStructureText can be used in docstrings to better format and emphasize content. .. code-block:: python from typing import Iterable from jamf_pro_sdk.models.classic.computers import ClassicComputersItem def list_all_computers(self, subsets: Iterable[str] = None) -> List[ClassicComputersItem]: """Returns a list of all computers. :param subsets: (optional) This operations accepts the ``basic`` subset to return additional details for every computer record. No other subset values are supported. :type subsets: Iterable :return: List of computers. :rtype: List[ClassicComputersItem] """ API Additions ^^^^^^^^^^^^^ Any Jamf Pro API added to the clients must have the following elements code complete before you open a pull request: * The API method has been added to the appropriate client, has a complete docstring, and has an interface in-line with other methods of that client. * The API must have matching and complete Pydantic models. * Unless your code is covered by another automated test you will need to add tests to ensure coverage. The SDK references in the documentation automatically include all public method on the clients and no documentation changes may be required as a part of the contribution. Pro API Pydantic models can be created by referencing the resources from the `OpenAPI schema available on the Jamf Pro server `_. * All Pro API Pydantic models must subclass from :class:`~jamf_pro_sdk.models.BaseModel`. This version of Pydantic's ``BaseModel`` will render correctly in the documentation. Classic API Pydantic models are more complex as they convert to XML for write operations, and JSON responses from Jamf Pro are known to deviate from the XML representation. If you need to create a Pydantic model for a Classic API resource use the following guidance: * All Classic API Pydantic models must start with ``Classic`` in the name to prevent conflicts with Pro API models. * Use an API response from a running Jamf Pro instance as your reference. * Base your model on the JSON response. Be sure to note and deviations from the XML representation and include those in the doctrings. * The top-level Pydantic model should subclass from :class:`~jamf_pro_sdk.models.classic.ClassicApiModel`. * Override the ``_xml_root_name``. This value should be the top-level key name in the XML (e.g. ``computer``). * Override the ``_xml_array_item_names`` if applicable. This is a dictionary of attribute name to the XML array item key name (e.g. the ``extension_attributes`` array has ``extension_attribute`` items). This mapping is used during XML generation for write operations. * Override ``_xml_write_fields``. This is a Python set of strings that represent the writeable attributes for the object. By default, only these attributes are included when XML is generated from a model. * All other nested Classic API Pydantic models must subclass from :class:`~jamf_pro_sdk.models.BaseModel`. This version of Pydantic's ``BaseModel`` will render correctly in the documentation. All API models must be added in the model documentation pages. Model docs are separated by type or API grouping (e.g. Computers, Mobile Devices, etc.). List the top-level model first, and then the nested models for that type in order after. Here is an example from the Classic API Models page. Follow this pattern for all new model sections. .. code-block:: rst Computer Groups --------------- .. currentmodule:: jamf_pro_sdk.models.classic.computer_groups .. autosummary:: :toctree: _autosummary :nosignatures: ClassicComputerGroup ClassicComputerGroupMember ClassicComputerGroupMembershipUpdate Other ----- .. toctree:: :maxdepth: 1 playground