
Security News
Google’s OSV Fix Just Added 500+ New Advisories — All Thanks to One Small Policy Change
A data handling bug in OSV.dev caused disputed CVEs to disappear from vulnerability feeds until a recent fix restored over 500 advisories.
A Python wrapper for the FileMaker Data API with Django-style ORM functionality.
python-fmdata
is a comprehensive Python library that provides both low-level access to the FileMaker Data API and a high-level ORM (Object-Relational Mapping) interface similar to Django's ORM. It supports multiple authentication methods and makes it easy to work with FileMaker databases from Python applications.
pip install fmdata
For Claris Cloud support:
pip install fmdata[cloud]
import fmdata
from fmdata.session_providers import UsernamePasswordSessionProvider
# Create session provider
session_provider = UsernamePasswordSessionProvider(
username="your_username",
password="your_password"
)
# Create FileMaker client
fm_client = fmdata.FMClient(
url="https://your-filemaker-server.com",
database="your_database",
login_provider=session_provider
)
from marshmallow import fields
from fmdata.orm import Model, PortalField, PortalModel
class ClassPortal(PortalModel):
name = fields.Str(required=False, data_key="class_portal_name::Name")
description = fields.Str(required=False, data_key="class_portal_name::Description")
class Student(Model):
class Meta:
client = fm_client
layout = 'student_layout'
pk = fields.Str(data_key="PrimaryKey")
full_name = fields.Str(data_key="FullName")
enrollment_date = fields.Date(data_key="EnrollmentDate")
graduation_year = fields.Integer(data_key="GraduationYear", allow_none=True)
# Portal relationship
classes = PortalField(model=ClassPortal, name="class_portal_name")
# Find all students, ordered by primary key
students = Student.objects.order_by("pk").find(full_name__raw="*")
# Find students with exact match (equivalent to __exact)
student_john = Student.objects.find(full_name="John Doe") # Searches for exact match
students_of_2024_but_not_john = Student.objects.find(graduation_year=2024).omit(full_name="John Doe") # Searches for students graduating in 2024 but not named John Doe
# Query with chunking and portal prefetching
result_set = (Student.objects
.order_by("pk")
.find(full_name__raw="*") # __raw means filemaker raw query, so it will search for all students with a non-empty full_name
.chunk_size(1000) # Call the API in chunks of 1000 records (in this example, it will return all students)
.prefetch_portal("classes", limit=100)
)[:1000] # Limit to first 1000 records
for student in result_set:
print(f"Student: {student.pk} - {student.full_name}")
# Access prefetched portal records
for class_record in student.classes.only_prefetched():
print(f" Class: {class_record.name} - {class_record.description}")
# Create a new student
student = Student.objects.create(
full_name="John Doe",
enrollment_date=date(2024, 1, 15),
graduation_year=2028
)
# Update a record
student.full_name = "John Smith"
student.save()
# Create portal records
student.classes.create(name="Mathematics", description="Advanced Math Course")
# Delete records
student.delete()
# Bulk operations
Student.objects.find(graduation_year=2024).delete()
from fmdata.session_providers import UsernamePasswordSessionProvider
session_provider = UsernamePasswordSessionProvider(
username="your_username",
password="your_password"
)
from fmdata.session_providers import OAuthSessionProvider
session_provider = OAuthSessionProvider(
oauth_request_id="your_oauth_request_id",
oauth_identifier="your_oauth_identifier"
)
from fmdata.session_providers import ClarisCloudSessionProvider
session_provider = ClarisCloudSessionProvider(
claris_id_name="your_claris_id",
claris_id_password="your_password"
)
from fmdata.orm import Criteria
# Various query criteria
students = Student.objects.find(
full_name__contains="John",
graduation_year__gte=2024,
enrollment_date__range=(date(2020, 1, 1), date(2024, 12, 31))
)
# Raw FileMaker queries
students = Student.objects.find(full_name__raw="John*")
# Empty and non-empty fields
students = Student.objects.find(graduation_year__not_empty=True)
# Order by multiple fields
students = Student.objects.order_by("graduation_year", "-full_name").find()
# Pagination with slicing
first_10 = Student.objects.find()[0:10]
next_10 = Student.objects.find()[10:20]
# Chunked processing for large datasets
for student in Student.objects.find().chunk_size(1000):
process_student(student)
# Prefetch portal data
students = (Student.objects
.prefetch_portal("classes", limit=50)
.find())
# Work with portal records
for student in students:
# Access portal records. If you are using a [:limit] and they are all prefetched, they will be accessed without additional API calls.
classes = student.classes.all()[:30] # Get the first 30 classes (in this example, all classes are prefetched because of the prefetch_portal with limit=50)
# Access prefetched portals. This will return the full list of prefetched portal records without additional API calls.
classes = student.classes.only_prefetched()
# Or force to fetch fresh portal data
classes = student.classes.avoid_prefetch_cache()
# Create new portal records
student.classes.create(name="New Class", description="Description")
# Update portal records
for class_record in classes:
class_record.description += " (Updated)"
class_record.save()
# Delete portal records
student.classes.filter(name="Old Class").delete()
from fmdata import FMErrorEnum
from fmdata.results import FileMakerErrorException
try:
student = Student.objects.get(pk="nonexistent")
except FileMakerErrorException as e:
if e.error_code in (FMErrorEnum.INSUFFICIENT_PRIVILEGES, FMErrorEnum.FIELD_ACCESS_DENIED):
print("Insufficient privileges, please check your user permissions.")
else:
print(f"FileMaker error: {e.error_code} - {e.message}")
For direct FileMaker Data API access:
# Direct API calls
result = fm_client.create_record(
layout="Students",
field_data={"FullName": "Jane Doe", "EnrollmentDate": "01/15/2024"}
).raise_exception_if_has_error() # Raise FileMakerErrorException if response contains an error message
# Get record by ID
record = fm_client.get_record(layout="Students", record_id="123").raise_exception_if_has_error()
# Perform find
results = fm_client.find(
layout="Students",
query=[{"FullName": "John*"}],
sort=[{"fieldName": "FullName", "sortOrder": "ascend"}]
).raise_exception_if_has_error()
# Execute scripts
script_result = fm_client.perform_script(
layout="Students",
name="MyScript",
param="parameter_value"
).raise_exception_if_has_error()
fm_client = fmdata.FMClient(
url="https://your-server.com",
database="your_database",
login_provider=session_provider,
api_version="v1", # API version
connection_timeout=10, # Connection timeout in seconds
read_timeout=30, # Read timeout in seconds
verify_ssl=True, # SSL certificate verification
auto_manage_session=True # Automatic session management
)
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License.
Lorenzo De Siena (dev.lorenzo.desiena@gmail.com)
We would like to thank:
FAQs
fmdata is a wrapper around the FileMaker Data API.
We found that fmdata demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
A data handling bug in OSV.dev caused disputed CVEs to disappear from vulnerability feeds until a recent fix restored over 500 advisories.
Research
/Security News
175 malicious npm packages (26k+ downloads) used unpkg CDN to host redirect scripts for a credential-phishing campaign targeting 135+ organizations worldwide.
Security News
Python 3.14 adds template strings, deferred annotations, and subinterpreters, plus free-threaded mode, an experimental JIT, and Sigstore verification.