ParsePy
A relatively up-to-date fork of ParsePy, the Python wrapper for the Parse.com API. Originally maintained by @dgrtwo
Install / Use
/learn @milesrichardson/ParsePyREADME
Note: As of May 13, 2016, this repository (milesrichardson/ParsePy) is the
most up-to-date and active python client for the Parse API. It supports self-hosted
parse-server via the REST API. Note that some features will not work with parse-server,
if they are not supported by the REST API (e.g. push).
See the section below, "using with self-hosted parse-server," for instructions.
parse_rest
parse_rest is a Python client for the Parse REST API. It provides:
- Python object mapping for Parse objects with methods to save, update, and delete objects, as well as an interface for querying stored objects.
- Complex data types provided by Parse with no python equivalent
- User authentication, account creation** (signup) and querying.
- Cloud code integration
- Installation querying
- push
- Roles/ACLs**
- Image/File type support (done 1/14/17)
** for applications with access to the MASTER KEY, see details below.
Installation
The easiest way to install this package is by downloading or cloning this repository:
pip install git+https://github.com/milesrichardson/ParsePy.git
Note: The version on PyPI is not up-to-date. The code is still under lots of changes and the stability of the library API - though improving - is not guaranteed. Please file any issues that you may find if documentation/application.
Using with self-hosted parse-server
To use the library with self-hosted parse-server, set the environment variable
PARSE_API_ROOT before importing the module.
Example:
import os
os.environ["PARSE_API_ROOT"] = "http://your_server.com:1337/parse"
# Everything else same as usual
from parse_rest.datatypes import Function, Object, GeoPoint
from parse_rest.connection import register
from parse_rest.query import QueryResourceDoesNotExist
from parse_rest.connection import ParseBatcher
from parse_rest.core import ResourceRequestBadRequest, ParseError
APPLICATION_ID = '...'
REST_API_KEY = '...'
MASTER_KEY = '...'
register(APPLICATION_ID, REST_API_KEY, master_key=MASTER_KEY)
Testing
To run the tests, you need to:
- create a
settings_local.pyfile in your local directory with three variables that define a sample Parse application to use for testing:
APPLICATION_ID = "APPLICATION_ID_HERE"
REST_API_KEY = "REST_API_KEY_HERE"
MASTER_KEY = "MASTER_KEY_HERE"
Note Do not give the keys of an existing application with data you want to keep: create a new one instead. The test suite will erase any existing CloudCode in the app and may accidentally replace or change existing objects.
- install the Parse CloudCode tool
You can then test the installation by running the following command:
# test all
python -m unittest parse_rest.tests
# or test individually
python -m unittest parse_rest.tests.TestObject.testCanCreateNewObject
Usage
Before the first interaction with the Parse server, you need to
register your access credentials. You can do so by calling
parse_rest.connection.register.
Before getting to code, a word of caution. You need to consider how your application is meant to be deployed. Parse identifies your application through different keys (available from your Parse dashboard) that are used in every request done to their servers.
If your application is supposed to be distributed to third parties (such as a desktop program to be installed), you SHOULD NOT put the master key in your code. If your application is meant to be running in systems that you fully control (e.g, a web app that needs to integrate with Parse to provide functionality to your client), you may also add your master key.
from parse_rest.connection import register
register(<application_id>, <rest_api_key>[, master_key=None])
Once your application calls register, you will be able to read, write
and query for data at Parse.
Data types
Parse allows us to get data in different base types that have a direct
python equivalent (strings, integers, floats, dicts, lists) as well as
some more complex ones (e.g.:File, Image, Date). It also allows
us to define objects with schema-free structure, and save them, as
well to query them later by their attributes. parse_rest is
handy as a way to serialize/deserialize these objects transparently.
The Object type
In theory, you are able to simply instantiate a Object and do
everything that you want with it, save it on Parse, retrieve it later,
etc.
from parse_rest.datatypes import Object
first_object = Object()
In practice, you will probably want different classes for your
application to allow for a better organization in your own code.
So, let's say you want to make an online game, and you want to save
the scoreboard on Parse. For that, you decide to define a class called
GameScore. All you need to do to create such a class is to define a
Python class that inherts from parse_rest.datatypes.Object:
from parse_rest.datatypes import Object
class GameScore(Object):
pass
You can also create an Object subclass by string name, with the Object.factory
method:
from parse_rest.datatypes import Object
myClassName = "GameScore"
myClass = Object.factory(myClassName)
print myClass
# <class 'parse_rest.datatypes.GameScore'>
print myClass.__name__
# GameScore
You can then instantiate your new class with some parameters:
gameScore = GameScore(score=1337, player_name='John Doe', cheat_mode=False)
You can change or set new parameters afterwards:
gameScore.cheat_mode = True
gameScore.level = 20
To save our new object, just call the save() method:
gameScore.save()
If we want to make an update, just call save() again after modifying an attribute to send the changes to the server:
gameScore.score = 2061
gameScore.save()
You can also increment the score in a single API query:
gameScore.increment("score")
Now that we've done all that work creating our first Parse object, let's delete it:
gameScore.delete()
That's it! You're ready to start saving data on Parse.
Object Metadata
The attributes objectId, createdAt, and updatedAt show metadata about a Object that cannot be modified through the API:
gameScore.objectId
# 'xxwXx9eOec'
gameScore.createdAt
# datetime.datetime(2011, 9, 16, 21, 51, 36, 784000)
gameScore.updatedAt
# datetime.datetime(2011, 9, 118, 14, 18, 23, 152000)
Additional Datatypes
We've mentioned that Parse supports more complex types, most of these
types are also supported on Python (dates, files). So these types can
be converted transparently when you use them. For the types that Parse
provided and Python does not support natively, parse_rest provides
the appropiates classes to work with them. One such example is
GeoPoint, where you store latitude and longitude
from parse_rest.datatypes import Object, GeoPoint
class Restaurant(Object):
pass
restaurant = Restaurant(name="Los Pollos Hermanos")
# coordinates as floats.
restaurant.location = GeoPoint(latitude=12.0, longitude=-34.45)
restaurant.save()
We can store a reference to another Object by assigning it to an attribute:
from parse_rest.datatypes import Object
class CollectedItem(Object):
pass
collectedItem = CollectedItem(type="Sword", isAwesome=True)
collectedItem.save() # we have to save it before it can be referenced
gameScore.item = collectedItem
File Support
You can upload files to parse (assuming your parse-server instance supports it).
This has been tested with the default GridStore adapter.
Example:
from parse_rest.datatypes import Object, File
class GameScore(Object):
pass
# 1. Upload file
with open('/path/to/screenshot.png', 'rb') as fh:
rawdata = fh.read()
screenshotFile = File('arbitraryNameOfFile', rawdata, 'image/png')
screenshotFile.save()
print screenshotFile.url
# 2. Attach file to gamescore object and save
gs = GameScore.Query.get(objectId='xxxxxxx')
gs.screenshot = screenshotFile
gs.save()
print gs.file.url
Batch Operations
For the sake of efficiency, Parse also supports creating, updating or deleting objects in batches using a single query, which saves on network round trips. You can perform such batch operations using the connection.ParseBatcher object:
from parse_rest.connection import ParseBatcher
score1 = GameScore(score=1337, player_name='John Doe', cheat_mode=False)
score2 = GameScore(score=1400, player_name='Jane Doe', cheat_mode=False)
score3 = GameScore(score=2000, player_name='Jack Doe', cheat_mode=True)
scores = [score1, score2, score3]
batcher = ParseBatcher()
batcher.batch_save(scores)
batcher.batch_delete(scores)
You can also mix save and delete operations in the same query as follows (note the absence of parentheses after each save or delete):
batcher.batch([score1.save, score2.save, score3.delete])
If an error occurs during one or multiple of the operations, it will not affect
the execution of the remaining operations. Instead, the batcher.batch_save or
batcher.batch_delete or batcher.batch will raise a ParseBatchError
(child of ParseError) exception with .message set to a list of the errors
encountered. For example:
# Batch save a list of two objects:
# dupe_object is a duplicate violating a unique key constraint
# dupe_object2 is a duplicate violating a unique key constraint
# new_object is a new object satisfying the unique key constraint
#
# dupe_object and dupe_object2 wil
Related Skills
node-connect
350.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
claude-opus-4-5-migration
109.9kMigrate prompts and code from Claude Sonnet 4.0, Sonnet 4.5, or Opus 4.1 to Opus 4.5
frontend-design
109.9kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
model-usage
350.1kUse CodexBar CLI local cost usage to summarize per-model usage for Codex or Claude, including the current (most recent) model or a full model breakdown. Trigger when asked for model-level usage/cost data from codexbar, or when you need a scriptable per-model summary from codexbar cost JSON.
