`python-jamf` is a library for connecting to a Jamf Server that maps directly to the Jamf Pro Classic API.

Overview

python-jamf

Programmatic Automation, Access & Control of Jamf Pro

python_jamf_logo

Introduction

python-jamf is a Python 3 module to access the Jamf Pro Classic API. The Classic API is the primary tool for programmatic access to data on a Jamf Pro server to allow integrations with other utilities or systems. The concept behind it is to have a class or simply a collection of data (variables) and methods (functions) that maps directly to the API (https://example.com:8443/api).

The python-jamf API class doesn't hide anything from you. It handles the URL requests, authentication, and converts between XML/JSON to Python dictionaries/lists.

The python-jamf module also provides undocumented access to Jamf Admin functionality used for uploading items to Jamf Distribution Points.

python_jamf workflow

What are python-jamf and jctl?

Originally, it was a "patch" project that was focused on patch management including installer package management, patch management, including assigning package to patch definition, updating versions, version release branching (i.e. development, testing, production), and scripting and automation. Later, it was split into two projects, python-jamf, which is a python library that connects to a Jamf Pro server using Jamf Pro Classic API, including keychain support for Jamf Pro credentials via keyring python project, support for PyPi to support pip installation and currently supports 56 Jamf Pro record types which will expand in number as the project continues.

The second project, jctl,  is a command-line tool that uses the python-jamf library to select objects to create, delete, print and update. It allows performing Jamf Pro repetitive tasks quickly and provides options not available in the web GUI. It is similar to SQL statements, but far less complex. And recently added PyPi to support pip installation.

Please check out the jctl github page for more information.

Supported Jamf Records

Currently, the python-jamf supports about 50 Jamf records like Buildings, Categories, Computers, OSXConfigurationProfiles, and Policies for example.

Each record is a singleton Python object, but they are generic and most functionality comes from the parent Record class. Objects do not have member variables for Jamf data. All Jamf Pro data is stored as a Python dictionary that is accessed with the data() method. All lists of records are singleton subclasses of the Records class.

By being singleton classes, you perform one fetch to the server for each list or record. This prevents multiple fetches for the same object. All changes you make are local until you save or refresh the object.

Quick Start

Installing

For those that want to try python-jamf quickly here are some general steps:

  • Install Module & Requirements: sudo pip3 install python-jamf
  • Create an Jamf Pro API User
  • Enter hostname, username, and password
  • Test: conf-python-jamf -t

Uninstalling

Uninstalling python-jamf is easy if you installed it via pip. pip is the Package Installer for Python.

To uninstall python-jamf run the following command:

sudo pip3 uninstall python-jamf

Getting Help

Wiki

More Documentation

For further in-depth details please check out the wiki.

Searching the wiki

To search this wiki use the "Search" field in the GitHub navigation bar above. Then on the search results page select the "Wiki" option or click here and search.

MacAdmin Slack Channel

If you have additional questions, or need more help getting started, post a question on the MacAdmin's Slack jctl channel.

MacAdmin's Slack Logo

Latest Status

Since we recorded our session over a month ago, some of the information in our presentation is out of date already. We have spent the time between when we recorded the presentation and now (October 14, 2021) getting GitHub actions working so that it will test and publish to pypi.com. It took longer to get this working than we thought. So that's about where we are. But it works now. We also added some Docker containers that you can run locally to try out python-jamf and jctl. There are also some minor differences in pkgctl than what is shown in the presentation.

I should also mention, one of us also had an issue where we assumed that pkgctl was crashing our production Jamf Pro server. But, increasing the amount of RAM and CPU's for that server fixed this issue.

Comments
  • how to format put for specific ID of computer and static group IP

    how to format put for specific ID of computer and static group IP

    so far i get the computers for a user (sometimes singular, sometimes multiple), but im trying to figure out the appropriate api.put command for it.

    i usually work in bash so i know there the command ends with "<computer_group><computer_additions>$serial</computer_additions></computer_group>" https://JSS.jamfcloud.com/JSSResource/computergroups/id/{id} -X PUT >", but now sure how to translate it to python.

    opened by grainofric3 6
  • docker-compose doesn't create network automatically

    docker-compose doesn't create network automatically

    Issue

    Testing the stable docker version of python-jamf and the build process is failing at network creation.

    Steps to reproduce

    Have only tried with python-jamf-github, but suspect it's the same for python-jamf-dev.

    $ cd python-jamf/python-jamf-docker
    $ docker-compose run --rm python-jamf-github
    network jamfpro_jamfnet declared as external, but could not be found
    

    Workaround

    Create the jamfpro_jamfnet docker network manually.

    $ docker network create -d bridge jamfpro_jamfnet
    4576<snip>
    $ docker-compose run --rm python-jamf-github
    [+] Building 106.1s (6/8)
     => [internal] load build definition from Dockerfile                                                                                                                            0.0s
    
    bug 
    opened by pythoninthegrass 5
  • Consider using Python Black for automatic formatting consistency

    Consider using Python Black for automatic formatting consistency

    For your consideration, this pull request applies Python Black formatting.

    Benefits

    In the projects I've worked on, I've found that applying consistent autoformatting (whether Black or something similar like autopep8 or yapf) significantly streamlines contributions. Discussions about code style fade away, allowing contributors to focus on the function.

    Also, Black's tendency to split long lines up slightly reduces the risk of merge conflicts if multiple elements of the same list/tuple/dict are edited by two different PRs.

    Black sometimes also surfaces syntax bugs before commit, since the formatting won't run if the Python doesn't compile.

    Risks

    Because this PR touches almost every Python file in the project, it's likely that it will conflict with changes on contributors' branches downstream. Any contributors will need to rebase their changes on the main branch (and possibly resolve conflicts manually) in order to continue. (At the moment, I don't see any non-merged branches here on GitHub, so it's probably a good time for a change like this.)

    The most streamlined way to use Black is to configure your local development environment with it, so that every time you save, the formatting is applied. In my VSCode prefs, I have settings to facilitate this:

    "python.formatting.provider": "black",
    "python.formatting.blackPath": "/opt/homebrew/bin/black",
    

    This optional streamlining creates a small additional setup burden for people who are regularly contributing, but shouldn't prevent those who wish to contribute more casually.

    Output

    The changes in this PR were produced with black ., resulting in the output below. No changes to actual function were made.

    % black .
    reformatted jamf/convert.py
    reformatted jamf/version.py
    reformatted setup.py
    reformatted jamf/config.py
    reformatted jamf/setconfig.py
    reformatted jamf/api.py
    reformatted tests/api_mock_test.py
    reformatted tests/convert_json_xml_test.py
    reformatted tests/test_package.py
    reformatted tests/test_config.py
    reformatted jamf/admin.py
    reformatted jamf/package.py
    reformatted tests/test_records.py
    reformatted jamf/records.py
    All done! ✨ 🍰 ✨
    14 files reformatted, 2 files left unchanged.
    

    For more context, see this portion of my 2019 PSU MacAdmins talk, which covers Black specifically.

    Thanks for considering!

    opened by homebysix 4
  • Turn README into wiki

    Turn README into wiki

    Not really an issue. Just a point I wanted to raise for discussion. The README is now getting to a length and if I add documentation for my work it will get longer.

    So how do you feel about me taking the existing README and my documentation and turning it onto a shorter README and a wiki? I was thinking of just a top page and only one layer of sub pages corresponding with the current headlines.

    I also have no idea if I can PR the wiki but I'm guessing I can.

    opened by Honestpuck 4
  • FileShare.mount uses macOS binaries and thus does not support linux

    FileShare.mount uses macOS binaries and thus does not support linux

    SMB could be supported using pysmb (without subprocess calls) I'm not sure about AFP though.

    We could also use 'mount' for linux machines (but then im unsure about other bsd distros)

    opened by yairf-s1 3
  • Add pre-commit configuration and corresponding GH Actions job

    Add pre-commit configuration and corresponding GH Actions job

    This pull request creates a pre-commit configuration and GitHub Actions job that runs it upon submitting PRs or pushing to main. The configuration includes two major formatting automations:

    • Python Black: The project already uses Black manually; adding a pre-commit and CI config makes this formatting easier for contributors to adopt and ensures standard style for submitted pull requests
    • iSort: Sorts Python imports in a consistent way, slightly reducing chances of merge conflict

    The above two changes will result in a new commit being made to the codebase automatically once merged. The changes will be to style only, and should not affect function at all. Here is a preview of that commit.

    I've included a few other relatively minor checks. The codebase already complies with all of these, so no changes are needed for these.

    • check-added-large-files: Helps prevent accidentally committing binary or image files to the repo by limiting new files to 100KB.
    • fix-byte-order-marker: Ensures files have consistent byte order markers (e.g. after being edited by a contributor using Windows)
    • check-case-conflict: Ensures no files are committed that would cause a conflict on case-insensitive file systems
    • check-docstring-first: Ensures Python docstrings are in the proper place
    • check-merge-conflict: Ensures no merge conflict markers are present in committed files
    • mixed-line-ending: Forbids CRLF line endings

    Once this is merged, it may be helpful to add a section to the jctl Contribute wiki page, between the "Clone the Forked Repository" and "Create a Feature Branch" sections:

    ### Install and enable pre-commit
    
    Pre-commit is a framework that automatically runs linting and consistency checks before changes
    are committed to the repository locally. For contributors who will be working in Python code, we
    recommend [installing pre-commit](https://pre-commit.com/#install) and running `pre-commit install`
    in the repo to activate these checks.
    

    (Note that even if contributors don't install pre-commit locally, GH Actions will run the checks upon submitting PRs and fix what it can.)

    On the AutoPkg project, we made a similar change recently, and it's worked well.

    opened by homebysix 2
  • Fixed README section on tests and did some more testing in test_records

    Fixed README section on tests and did some more testing in test_records

    The README section on testing was seriously wrong. I also attempted (and failed) to fix a problem where test_records.py won't run the tests if called on its own. It does run the tests if you use discovery. Not sure if it's worth opening an issue on it, but if you do assign it to me.

    opened by Honestpuck 2
  • All tests now running. Currently 9 fail.

    All tests now running. Currently 9 fail.

    I figured out why python3 -m unittest discover -v wasn't working. When we moved tests out of jamf and put them on the same level in python-jamf the imports tried to import from a parent that didn't exist.

    So all the from .. import <package> had to be changed to from jamf import <package>

    Tomorrow I will see about fixing the 9 tests that error.

    opened by Honestpuck 2
  • Add Support for Detecting Jamf Pro Version & Bearer Token Authentication

    Add Support for Detecting Jamf Pro Version & Bearer Token Authentication

    Hi:

    Jamf will deprecate support for Basic Authentication in Jamf Pro v10.35.0 or later. python-jamf will need to add support for Bearer Token authentication by implementing a version check of Jamf Pro, your application can determine whether Bearer Token authentication is supported (v10.35.0 or later) or if use of Basic authentication is required (v10.34.0 and earlier).

    The jamf-pro-version endpoint within the Jamf Pro API returns the version of the Jamf Pro Server, to help your application determine authentication compatibility with a given Jamf Pro Server. Jamf recommends including a preference to allow users to select the authentication schema based on their environment configuration or dynamically determining which authentication mechanism to use based on the Jamf Pro Server version.

    In addition to the recommendations provided above, Jamf has updated the Classic API Postman Collection to now default to the use of Bearer Token authentication. Older versions of the collection will continue to be available for interaction with environments not yet upgraded to 10.35.0 or later, however the new collection will default to using Bearer Token authentication.

    Additional details regarding the changes, including best practices are detailed on the Jamf Developer Portal.

    enhancement 
    opened by uurazzle 1
  • Added subcommands: packages view_included and scripts script_contents

    Added subcommands: packages view_included and scripts script_contents

    Output looks like this.

    ./jctl packages -S view_included

    BBEdit-13.5.5.pkg Policies Install Bare Bones BBEdit PatchSoftwareTitles Bare Bones BBEdit - 13.5.5 PatchPolicies 13.5.5 SS

    BBEdit-13.5.6.pkg

    Xcode-11.3.1.pkg Policies Install Xcode 11.3 (macOS 10.15) ComputerGroups 02 - Needs Xcode-11.3.1.pkg (Staff, Student, Opt-In, 10.15)

    Zoom-5.6.4.765.pkg Policies Install Zoom Client for Meetings

    ./jctl scripts -S script_contents #!/usr/bin/perl -w

    use strict;

    print "Hi mom";

    opened by magnusviri 1
  • Store prefs in Elektra

    Store prefs in Elektra

    "Elektra stores configuration in a global, hierarchical key database."

    https://www.libelektra.org/plugins/python

    Should be this easy.

    import kdb
    kdb.Key("user:/jamf_server")
    kdb.Key("user:/jamf_username")
    
    opened by magnusviri 1
  • test_package - problem with path

    test_package - problem with path

    test_package has six tests failing. All appear to be failing because the path passed to tar in a call to get package information points to the actual package and not the the expanded package so tar barfs on it.

    bug 
    opened by Honestpuck 2
Releases(0.8.2)
Owner
University of Utah, Marriott Library, Apple Support
Apple Support & Integration in a Heterogeneous Environment
University of Utah, Marriott Library, Apple Support
Python script to decode the EU Covid-19 vaccine certificate

vacdec Python script to decode the EU Covid-19 vaccine certificate This script takes an image with a QR code of a vaccine certificate as the parameter

Hanno Böck 244 Nov 30, 2022
Python version of PlaceNL's headless bot with automatic access token refresh

Reddit /r/place 2022 headless bot This headless Python bot will automatically login to reddit, obtain access tokens (and refreshes them when they expi

19 May 21, 2022
Plugin for Sentry which allows sending notification via Telegram messenger.

Sentry Telegram Plugin for Sentry which allows sending notification via Telegram messenger. Presented plugin tested with Sentry from 8.9 to 9.1.1. DIS

Shmele 208 Dec 30, 2022
Asynchronous Guilded API wrapper for Python

Welcome to guilded.py, a discord.py-esque asynchronous Python wrapper for the Guilded API. If you know discord.py, you know guilded.py. Documentation

shay 115 Dec 30, 2022
Discord ToolBox is a discord bot developed by DJD320 created for the purpose of having some convenient tools in the form of a single bot.

Discord ToolBox Discord ToolBox is a discord bot developed by DJD320 created for the purpose of having some convenient tools in the form of a single b

3 Aug 07, 2021
The implementation of Learning Instance and Task-Aware Dynamic Kernels for Few Shot Learning

INSTA: Learning Instance and Task-Aware Dynamic Kernels for Few Shot Learning This repository provides the implementation and demo of Learning Instanc

11 Jan 02, 2023
ClearML - Auto-Magical Suite of tools to streamline your ML workflow. Experiment Manager, MLOps and Data-Management

ClearML - Auto-Magical Suite of tools to streamline your ML workflow Experiment Manager, MLOps and Data-Management ClearML Formerly known as Allegro T

ClearML 3.9k Jan 01, 2023
Python script to harvest tweets with the Twitter API V2 Academic Research Product Track

Tweet harvester Python script to scrape, collect, and/or harvest tweets with the Twitter API V2 Academic Research Product Track. Important note: In or

Thomas Frissen 2 Nov 11, 2021
DankMemer-Farmer - Autofarm Self-Bot for Discord bot Named Dankmemer.

DankMemer-Farmer Autofarm Self-Bot for Discord bot Named Dankmemer. Warning We are not responsible if you got banned, since "self-bots" outside of the

Mole 16 Dec 14, 2022
The modern Lavalink wrapper designed for discord.py

Pomice The modern Lavalink wrapper designed for discord.py This library is heavily based off of/uses code from the following libraries: Wavelink Slate

Gstone 1 Feb 02, 2022
SongLink Discord Bot - Discord bot to share music links easily

SongLink_Discord_Bot Discord bot to share music links easily. Take a link from y

Edgar Lefevre 4 Feb 18, 2022
Easy-apply-bot - A LinkedIn Easy Apply bot to help with my job search.

easy-apply-bot A LinkedIn Easy Apply bot to help with my job search. Getting Started First, clone the repository somewhere onto your computer, or down

Matthew Alunni 5 Dec 09, 2022
Create Discord Accounts Semi-Automatically Without Captcha Solving API Key

Discord-Account-Generator Create Discord Accounts Semi-Automatically without captcha solving api key IMPORTANT: Your chromedriver version should be th

NotSakshyam 11 Mar 21, 2022
google-resumable-media Apache-2google-resumable-media (🥉28 · ⭐ 27) - Utilities for Google Media Downloads and Resumable.. Apache-2

google-resumable-media Utilities for Google Media Downloads and Resumable Uploads See the docs for examples and usage. Experimental asyncio Support Wh

Google APIs 36 Nov 22, 2022
A bot to display per user data from the Twitch Leak

twitch-leak-bot-discord A bot to display per user data from the Twitch Leak by username Where's the data? I can't and don't want to supply the .csv's

SSSEAL-C 0 Nov 08, 2022
4 Oct 28, 2021
HTTP API for TON (The Open Network)

HTTP API for The Open Network Since TON nodes uses its own ADNL binary transport protocol, a intermediate service is needed for an HTTP connection. TO

66 Dec 28, 2022
칼만 필터는 어렵지 않아(저자 김성필) 파이썬 코드(Unofficial)

KalmanFilter_Python 칼만 필터는 어렵지 않아(저자 김성필) 책을 공부하면서, Matlab 코드를 Python으로 변환한 것입니다. Contents Part01. Recursive Filter Chapter01. Average Filter Chapter0

Donghun Park 20 Oct 28, 2022
radiant discord anti nuke src leaked lol.

radiant-anti-wizz-leaked radiant discord anti nuke src leaked lol, the whole anti sucks but idc. sucks to suck thats tuff bro LMAOOOOOO join my server

ok 15 Aug 06, 2022
Script que realiza a identificação de todos os logins e senhas dos wifis conectados em uma máquina e envia os dados para um e-mail especificado.

getWIFIConnection Script que realiza a identificação de todos os logins e senhas dos wifis conectados em uma máquina e envia os dados para um e-mail e

Vinícius Azevedo 3 Nov 27, 2022