This tutorial will guide you through the steps to effectively use the PyOpenBadges library to create, validate, and manage digital badges compliant with the OpenBadge v3.0 specification.
- Installation
- Creating an Issuer (Profile)
- Creating a Badge (Achievement)
- Issuing a Badge (OpenBadgeCredential)
- Validating Objects
- Schema Validation
- Serialization and Deserialization
- Creating an Endorsement
- Integration with Django
- Best Practices
To install PyOpenBadges, use pip or poetry:
# With pip
pip install pyopenbadges
# With poetry (recommended)
poetry add pyopenbadgesIn OpenBadge v3, issuers are represented by the Profile model. Let's start by creating an issuer profile:
from pyopenbadges.models import Profile
from pyopenbadges.models.profile import Image
# Creating a minimal issuer profile
issuer_minimal = Profile(
id="https://example.org/issuers/1",
type="Profile",
name="My Organization"
)
# Creating a complete issuer profile
issuer_complete = Profile(
id="https://example.org/issuers/1",
type="Profile",
name="My Organization",
description="Organization issuing programming skills badges",
url="https://example.org",
email="contact@example.org",
telephone="+33123456789",
image=Image(
id="https://example.org/issuers/1/image",
type="Image",
caption="My Organization Logo"
)
)
# Conversion to JSON-LD
issuer_json = issuer_complete.to_json_ld()
print(issuer_json)Once the issuer is created, you can define badges (Achievement):
from pyopenbadges.models import Achievement, Profile
from pyopenbadges.models.achievement import Criteria, Alignment
# Create an issuer first (required)
issuer = Profile(
id="https://example.org/issuers/1",
type="Profile",
name="My Organization"
)
# Creating a minimal badge
badge_minimal = Achievement(
id="https://example.org/badges/1",
type="Achievement",
name="Python Beginner Badge",
issuer=issuer # Using the issuer object
)
# Creating a complete badge
badge_complete = Achievement(
id="https://example.org/badges/2",
type="Achievement",
name="Python Beginner Badge",
description="This badge certifies mastery of Python basics",
issuer=issuer, # Using the issuer object created above
criteria=Criteria(
narrative="To earn this badge, the candidate must demonstrate understanding of fundamental Python concepts, including variables, control structures, functions, and basic modules."
),
image=Image(
id="https://example.org/badges/1/image",
type="Image",
caption="Python Beginner Badge"
),
tags=["python", "programming", "beginner"],
alignment=[
Alignment(
targetName="Programming in Python",
targetUrl="https://example.org/frameworks/python-skills/beginner",
targetDescription="Ability to write simple Python programs",
targetFramework="Digital Skills Framework",
targetCode="PYTHON-BEG-01"
)
]
)
# Conversion to JSON-LD
badge_json = badge_complete.to_json_ld()
print(badge_json)To award a badge to a recipient, create an OpenBadgeCredential:
from pyopenbadges.models import OpenBadgeCredential, AchievementSubject, Evidence
from datetime import datetime, timedelta
# Badge issuance date
issuance_date = datetime.now()
# Expiration date (optional)
expiration_date = issuance_date + timedelta(days=365)
# Creating a minimal credential
credential_minimal = OpenBadgeCredential(
id="https://example.org/credentials/1",
type=["VerifiableCredential", "OpenBadgeCredential"],
issuer="https://example.org/issuers/1",
issuanceDate=issuance_date,
credentialSubject=AchievementSubject(
id="did:example:recipient123",
type="AchievementSubject",
achievement="https://example.org/badges/1"
)
)
# Creating a complete credential
credential_complete = OpenBadgeCredential(
id="https://example.org/credentials/1",
type=["VerifiableCredential", "OpenBadgeCredential"],
name="Python Beginner Certification for John Doe",
description="Certification attesting to beginner-level Python skills",
issuer=issuer_complete,
issuanceDate=issuance_date,
expirationDate=expiration_date,
credentialSubject=AchievementSubject(
id="did:example:recipient123",
type="AchievementSubject",
name="John Doe",
achievement=badge_complete
),
evidence=[
Evidence(
id="https://example.org/evidence/1",
type="Evidence",
name="Python Project",
description="Console application developed in Python",
narrative="John developed a CLI application that demonstrates his understanding of loops, conditionals, and functions in Python."
)
]
)
# Verifying the validity of the credential
is_valid = credential_complete.is_valid()
print(f"The credential is valid: {is_valid}")
# Conversion to JSON-LD
credential_json = credential_complete.to_json_ld()
print(credential_json)PyOpenBadges provides utilities to validate objects according to the OpenBadge v3 specification:
from pyopenbadges.utils.validators import (
validate_profile,
validate_achievement,
validate_credential,
validate_endorsement
)
# Validating a Profile
profile_validation = validate_profile(issuer_complete)
if profile_validation.is_valid:
print("The profile is valid according to the OpenBadge v3 specification")
else:
print("Profile validation errors:", profile_validation.errors)
# Validating an Achievement
achievement_validation = validate_achievement(badge_complete)
if achievement_validation.is_valid:
print("The badge is valid according to the OpenBadge v3 specification")
else:
print("Badge validation errors:", achievement_validation.errors)
# Validating an OpenBadgeCredential
credential_validation = validate_credential(credential_complete)
if credential_validation.is_valid:
print("The credential is valid according to the OpenBadge v3 specification")
else:
print("Credential validation errors:", credential_validation.errors)
# You can also validate objects from JSON-LD dictionaries
json_data = {
"id": "https://example.org/badges/2",
"type": "Achievement",
"name": "Python Intermediate Badge",
"issuer": "https://example.org/issuers/1"
}
validation_result = validate_achievement(json_data)
print(f"JSON validation: {validation_result.is_valid}")PyOpenBadges supports schema validation via the credentialSchema field in the OpenBadgeCredential class. This allows you to ensure that your credentials conform to specific JSON schemas:
from pyopenbadges.models import OpenBadgeCredential, CredentialSchema
# Create a credential with schema validation
credential = OpenBadgeCredential(
id="https://example.org/credentials/1",
type=["VerifiableCredential", "OpenBadgeCredential"],
issuer="https://example.org/issuers/1",
issuanceDate=datetime.now(),
credentialSubject=AchievementSubject(
id="did:example:recipient123",
type="AchievementSubject",
achievement="https://example.org/badges/1"
),
# Add schema validation
credentialSchema=CredentialSchema(
id="https://w3id.org/openbadges/v3/schema/3.0.0",
type="JsonSchemaValidator2019"
)
)
# Validate against the schema
try:
is_valid_schema = credential.validate_schema()
print(f"The credential conforms to the schema: {is_valid_schema}")
except ValueError as e:
print(f"Schema validation error: {e}")
# The is_valid() method also checks schema validation
is_valid = credential.is_valid()
print(f"The credential is valid: {is_valid}")When converting to JSON-LD, the schema information is automatically included:
# Convert to JSON-LD with schema information
json_ld = credential.to_json_ld()
print(json_ld["credentialSchema"])For more details on schema validation, see the schema validation tutorial.
PyOpenBadges allows you to easily convert objects to JSON-LD and vice versa:
from pyopenbadges.utils.serializers import (
save_object_to_file,
load_object_from_file,
json_ld_to_profile,
json_ld_to_achievement,
json_ld_to_credential,
json_ld_to_endorsement
)
# Save an object to a file
save_object_to_file(credential_complete, "credential.json")
# Load an object from a file
loaded_credential = load_object_from_file("credential.json", "OpenBadgeCredential")
# Converting JSON-LD to Python objects
profile_json_ld = {
"@context": "https://w3id.org/openbadges/v3",
"id": "https://example.org/issuers/2",
"type": "Profile",
"name": "Another Organization"
}
profile_obj = json_ld_to_profile(profile_json_ld)
achievement_json_ld = {
"@context": "https://w3id.org/openbadges/v3",
"id": "https://example.org/badges/2",
"type": "Achievement",
"name": "Python Intermediate Badge",
"issuer": "https://example.org/issuers/1"
}
achievement_obj = json_ld_to_achievement(achievement_json_ld)Endorsements allow third parties to validate and recognize badges, issuers, or credentials:
from pyopenbadges.models import EndorsementCredential
from pyopenbadges.models.endorsement import EndorsementSubject
# Creating a profile for the endorsing organization
endorser = Profile(
id="https://endorser.org/profiles/1",
type="Profile",
name="Accreditation Organization",
description="Organization that accredits quality badges"
)
# Creating an endorsement for a badge
badge_endorsement = EndorsementCredential(
id="https://endorser.org/endorsements/1",
type=["VerifiableCredential", "EndorsementCredential"],
name="Python Beginner Badge Endorsement",
description="This badge is recognized by our organization as being of high quality",
issuer=endorser,
issuanceDate=datetime.now(),
credentialSubject=EndorsementSubject(
id="https://example.org/badges/1",
type="Achievement",
endorsementComment="This badge follows all good pedagogical practices and corresponds well to the beginner level in Python."
)
)
# Creating an endorsement for an issuer
issuer_endorsement = EndorsementCredential(
id="https://endorser.org/endorsements/2",
type=["VerifiableCredential", "EndorsementCredential"],
name="My Organization Endorsement",
issuer=endorser,
issuanceDate=datetime.now(),
credentialSubject=EndorsementSubject(
id="https://example.org/issuers/1",
type="Profile",
endorsementComment="This issuer is recognized for the quality of its certification programs."
)
)
# Conversion to JSON-LD
endorsement_json = badge_endorsement.to_json_ld()
print(endorsement_json)Here are some recommendations for effectively using PyOpenBadges:
-
Use persistent identifiers: Ensure that the identifiers (URLs) of your badges, issuers, and credentials are persistent and accessible.
-
Validate your data: Always use the validation functions to ensure that your objects comply with the specification.
-
Date management: Use Python
datetimeobjects for dates and avoid manual string manipulations. -
Public access: Information about badges should be publicly accessible. Make sure that URLs used as identifiers are accessible.
-
Testing: Test your implementations with test cases covering common scenarios and edge cases.
# Test example
import pytest
from pyopenbadges.models import Achievement
from pyopenbadges.utils.validators import validate_achievement
def test_achievement_validation():
# Test with a valid badge
valid_badge = Achievement(
id="https://example.org/badges/1",
type="Achievement",
name="Test Badge",
issuer="https://example.org/issuers/1"
)
result = validate_achievement(valid_badge)
assert result.is_valid
# Test with an invalid badge (without name)
invalid_badge = {
"id": "https://example.org/badges/1",
"type": "Achievement",
"issuer": "https://example.org/issuers/1"
}
result = validate_achievement(invalid_badge)
assert not result.is_validBy following this tutorial, you should now be able to effectively use the PyOpenBadges library to create, validate, and manage digital badges compliant with the IMS Global OpenBadge v3.0 specification.