Latest PyPI versionBuild StatusDocumentation StatusJoin the chat at https://gitter.im/IvanMalison/okcupyd

okcupyd

Latest PyPI version Build Status Documentation Status Join the chat at https://gitter.im/IvanMalison/okcupyd

Development Status

okcupyd was broken when okcupid.com released their redesign of their website which included a change in the way their private api worked. This was first reported on July 5th by @mosesmc52 in #61, and later by @dubiousjim in #63. A migration to this new API is underway, and since 0f6b8df9905d29bddce6ee9d9978b73d9905f514, this new code path has been in use. The search functionality does seem to be working now, but almost all of the filters DO NOT WORK. Work on getting these filters working can be tracked in #70 and the more general work for getting okcupyd back to a stable state can be tracked in milestone v1.0.0.

Alpha Installation

Because the old version of okcupyd does not work at all, I have released an alpha version that uses the new private api. You can get this version using pip by running:

pip install --pre -U okcupyd

Or by explicitly specifying the version you would like to obtain:

pip install okcupyd==1.0.0a3

Please be aware that these alpha builds will likely have many bugs and they should not be expected to be stable in any way.

Getting Started

Installation/Setup

pip/PyPI

okcupyd is available for install from PyPI. If you have pip you can simply run:

pip install okcupyd

to make okcupyd available for import in python.

From Source

You can install from source by running the setup.py script included as part of this repository as follows:

python setup.py install

This can be useful if you want to install a version that has not yet been released on PyPI.

From Docker

okcupyd is available on docker (see https://registry.hub.docker.com/u/imalison/okcupyd/)

If you have docker installed on your machine, you can run

docker run -t -i imalison/okcupyd okcupyd

to get an interactive okcupyd shell.

Use

Interactive

Installing the okcupyd package should add an executable script to a directory in your $PATH that will allow you to type okcupyd into your shell of choice to enter an interactive ipython shell that has been prepared for use with okcupyd. Before the shell starts, you will be prompted for your username and password. This executable script accepts the flags –enable-logger which enables a logger of the given name, and –credentials whose action is described below.

It is highly recommended that you use the –enable-logger=requests and –enable-logger=okcupyd flags if you encounter any problems.

Credentials

If you wish to avoid entering your password each time you start a new session you can do one of the following things:

  1. Create a python module (.py file) with your username and password set to the variables USERNAME and PASSWORD respectively. You can start an interactive session with the USERNAME and PASSWORD stored in my_credentials.py by running
PYTHONPATH=. okcupyd --credentials my_credentials

from the directory that my_credentials.py is stored in

The PYTHONPATH=. at the front of this command is necessary to ensure that the current directory is searched for modules.

If you wish to use a version of this library that you have cloned but not installed, you can use the tox environment venv to do the same thing with such a version of the code:

PYTHONPATH=. tox -e venv -- okcupyd --credentials my_credentials
  1. Set the shell environment variables OKC_USERNAME and OKC_PASSWORD to your username and password respectively. Make sure to export the variables so they are visible in processes started from the shell. You can make a credentials.sh file to do this using the following template:
export OKC_USERNAME='your_username'
export OKC_PASSWORD='your_password'

Simply run source credentials.sh to set the environment variables and your shell should be properly configured. Note that this approach requires that the relevant environment variables be set before okcupyd.settings is imported.

3. Manually override the values in okcupyd/settings.py. This method is not recommended because it requires you to find the installation location of the package. Also, If you are working with a source controlled version, you could accidentally commit your credentials.

Using --credentials in a custom script

The ~okcupyd.util.misc.add_command_line_options and ~okcupyd.util.misc.handle_command_line_options can be used to make a custom script support the --credentials and --enable-loggers command line flags. The interface to these functions is admittedly a little bit strange. Refer to the example below for details concerning how to use them:

import argparse
parser = argparse.ArgumentParser()
util.add_command_line_options(parser.add_argument)
args = parser.parse_args()
util.handle_command_line_options(args)

Basic Examples

All examples in this section assume that the variable u has been initialized as follows:

import okcupyd
user = okcupyd.User()

Searching profiles

To search through the user:

profiles = user.search(age_min=26, age_max=32)
for profile in profiles[:10]:
    profile.message("Pumpkins are just okay.")

To search for users that have answered a particular question in a way that is consistent with the user’s preferences for that question:

user_question = user.questions.very_important[0]
profiles = user.search(question=user_question)
for profile in profiles[:10]:
    their_question = profile.find_question(user_question.id)
    profile.message("I'm really glad that you answered {0} to {1}".format(
        their_question.their_answer, their_question.question.text
    ))

The search functionality can be accessed without a User instance:

from okcupyd.json_search import SearchFetchable

for profile in SearchFetchable(attractiveness_min=8000)[:5]:
    profile.message("hawt...")

This is particularly useful if you want to explicitly provide the session that should be used to search:

from okcupyd.session import Session
from okcupyd.json_search import SearchFetchable

session = Session.login('username', 'password')
for profile in SearchFetchable(session=session, attractiveness_min=8000)[:5]:
    profile.message("hawt...")

For more details about what filter arguments can be used with these search functions, see the doucmentation for SearchFetchable()

Messaging another user

user.message('foxylady899', 'Do you have a map?')
# This has slightly different semantics; it will not look through the user's
# inbox for an existing thread.
user.get_profile('foxylady889').message('Do you have a map?')

Rating a profile

user.get_profile('foxylady899').rate(5)

Mailbox

first_thread = user.inbox[0]
print(first_thread.messages)

Quickmatch, Essays, Looking For, Details

You can access the essays, looking for attributes and detail attributes of a profile very easily

profile = user.quickmatch()
print(profile.essays.self_summary)
print(profile.looking_for.ages)
print(profile.details.orientation)

The data for these attributes is loaded from the profile page, but it should be noted that this page is only loaded on demand, so the first of these attribute access calls will make an http request.

A logged in user can update their own details using these objects:

user.profile.essays.self_summary = "I'm pretty boring."
user.profile.looking_for.ages = 18, 19
user.profile.details.ethnicities = ['asian', 'black', 'hispanic']

These assignments will result in updates to the okcupid website. When these updates happen, subsequent access to any profile attribute will result in a new http request to reload the profile page.

Fetchable

Most of the collection objects that are returned from function invocations in the okcupyd library are instances of Fetchable. In most cases, it is fine to treat these objects as though they are lists because they can be iterated over, sliced and accessed by index, just like lists:

for question in user.profile.questions:
    print(question.answer.text)

a_random_question = user.profile.questions[2]
for question in questions[2:4]:
    print(question.answer_options[0])

However, in some cases, it is important to be aware of the subtle differences between Fetchable objects and python lists. Fetchable construct the elements that they “contain” lazily. In most of its uses in the okcupyd library, this means that http requests can be made to populate Fetchable instances as its elments are requested.

The questions Fetchable that is used in the example above fetches the pages that are used to construct its contents in batches of 10 questions. This means that the actual call to retrieve data is made when iteration starts. If you enable the request logger when you run this code snippet, you get output that illustrates this fact:

2014-10-29 04:25:04 Livien-MacbookAir requests.packages.urllib3.connectionpool[82461] DEBUG "GET /profile/ShrewdDrew/questions?leanmode=1&low=11 HTTP/1.1" 200 None
 Yes
 Yes
 Kiss someone.
 Yes.
 Yes
 Sex.
 Both equally
 No, I wouldn't give it as a gift.
 Maybe, I want to know all the important stuff.
 Once or twice a week
 2014-10-29 04:25:04 Livien-MacbookAir requests.packages.urllib3.connectionpool[82461] DEBUG "GET /profile/ShrewdDrew/questions?leanmode=1&low=21 HTTP/1.1" 200 None
 No.
 No
 No
 Yes
 Rarely / never
 Always.
 Discovering your shared interests
 The sun
 Acceptable.
 No.

Some fetchables will continue fetching content for quite a long time. The search fetchable, for example, will fetch content until okcupid runs out of search results. As such, things like:

for profile in user.search():
    profile.message("hey!")

should be avoided, as they are likely to generate a massive number of requests to okcupid.com.

Another subtlety of the Fetchable class is that its instances cache its contained results. This means that the second iteration over okcupyd.profile.Profile.questions in the example below does not result in any http requests:

for question in user.profile.questions:
    print(question.text)

for question in user.profile.questions:
    print(question.answer)

It is important to understand that this means that the contents of a Fetchable are not guarenteed to be in sync with okcupid.com the second time they are requested. Calling refresh() will cause the Fetchable to request new data from okcupid.com when its contents are requested. The code snippet that follows prints out all the questions that the logged in user has answered roughly once per hour, including ones that are answered while the program is running.

import time

while True:
    for question in user.profile.questions:
        print(question.text)
    user.profile.questions.refresh()
    time.sleep(3600)

Without the call to user.profile.questions.refresh(), this program would never update the user.profile.questions instance, and thus what would be printed to the screen with each iteration of the for loop.

Development

tox

If you wish to contribute to this project, it is recommended that you use tox to run tests and enter the interactive environment. You can get tox by running

pip install tox

if you do not already have it.

Once you have cloned the project and installed tox, run:

tox -e py27

This will create a virtualenv that has all dependencies as well as the useful ipython and ipdb libraries installed, and run all okcupyds test suite.

If you want to run a command with access to a virtualenv that was created by tox you can run

tox -e venv -- your_command

To use the development version of the interactive shell (and avoid any conflicts with versions installed in site-packages) you would run the following command:

tox -e venv -- okcupyd

git hooks

If you plan on editing this file (getting_started.rst) you must install the provided git hooks that are included in this repository by running:

bin/create-githook-symlinks.sh

from the root directory of the repository.

API Objects

The classes and functions documented on this page constitute the public API to the okcupyd library.

User

User serves as the primary entry point to the okcupyd library. Most of the objects mentioned on this page are accessible in some way or another from instances of User.

class okcupyd.user.User(session=None)[source]

Encapsulate a logged in okcupid user.

classmethod from_credentials(username, password)[source]
Parameters:
  • username (str) – The username to log in with.
  • password (str) – The password to log in with.
__init__(session=None)[source]
Parameters:session (Session) – The session which will be used for interacting with okcupid.com If none is provided, one will be instantiated automatically with the credentials in settings
profile = None

A Profile object belonging to the logged in user.

inbox = None

A Fetchable of MessageThread objects corresponding to messages that are currently in the user’s inbox.

outbox = None

A Fetchable of MessageThread objects corresponding to messages that are currently in the user’s outbox.

drafts = None

A Fetchable of MessageThread objects corresponding to messages that are currently in the user’s drafts folder.

visitors = None

A Fetchable of Profile objects of okcupid.com users that have visited the user’s profile.

questions = None

A Questions object that is instantiated with the owning User instance’s session.

attractiveness_finder = None

An _AttractivenessFinder object that is instantiated with the owning User instance’s session.

photo = None

A PhotoUploader that is instantiated with the owning User instance’s session.

location_cache = None

A LocationQueryCache instance

get_profile(username)[source]

Get the Profile associated with the supplied username.

Parameters:username – The username of the profile to retrieve.
username

Return the username associated with the User.

message(username, message_text)[source]

Message an okcupid user. If an existing conversation between the logged in user and the target user can be found, reply to that thread instead of starting a new one.

Parameters:
  • username (str) – The username of the user to which the message should be sent.
  • message_text (str) – The body of the message.
search(**kwargs)[source]

Call SearchFetchable() to get a Fetchable object that will lazily perform okcupid searches to provide Profile objects matching the search criteria.

Defaults for gender, gentation, location and radius will be provided if none are given.

Parameters:kwargs – See the SearchFetchable() docstring for details about what parameters are available.
delete_threads(thread_ids_or_threads)[source]

Call delete_threads().

Parameters:thread_ids_or_threads – A list whose members are either MessageThread instances or okc_ids of message threads.
get_user_question(question, fast=False, bust_questions_cache=False)[source]

Get a UserQuestion corresponding to the given Question.

HUGE CAVEATS: If the logged in user has not answered the relevant question, it will automatically be answered with whatever the first answer to the question is.

For the sake of reducing the number of requests made when this function is called repeatedly this function does not bust the cache of this User‘s okcupyd.profile.Profile.questions attribute. That means that a question that HAS been answered could still be answered by this function if this User‘s questions was populated previously (This population happens automatically – See Fetchable for details about when and how this happens).

Parameters:
  • question (BaseQuestion) – The question for which a UserQuestion should be retrieved.
  • fast (bool) – Don’t try to look through the users existing questions to see if arbitrarily answering the question can be avoided.
  • bust_questions_cache (bool) – clear the questions attribute of this users Profile before looking for an existing answer. Be aware that even this does not eliminate all race conditions.
get_question_answer_id(question, fast=False, bust_questions_cache=False)[source]

Get the index of the answer that was given to question

See the documentation for get_user_question() for important caveats about the use of this function.

Parameters:
  • question (BaseQuestion) – The question whose answer_id should be retrieved.
  • fast (bool) – Don’t try to look through the users existing questions to see if arbitrarily answering the question can be avoided.
  • bust_questions_cache (bool) –
    param bust_questions_cache:
     clear the

    questions attribute of this users Profile before looking for an existing answer. Be aware that even this does not eliminate all race conditions.

quickmatch()[source]

Return a Profile obtained by visiting the quickmatch page.

copy(profile_or_user)[source]

Create a Copy instance with the provided object as the source and this User as the destination.

Parameters:profile_or_user – A User or Profile object.

Profile

class okcupyd.profile.Profile(session, username, **kwargs)[source]

Represent the profile of an okcupid user.

Many of the attributes on this object are cached_property instances which lazily load their values, and cache them once they have been accessed. This makes it so that this object avoids making unnecessary HTTP requests to retrieve the same piece of information twice.

Because of this caching behavior, care must be taken to invalidate cached attributes on the object if an up to date view of the profile is needed. It is recommended that you call refresh() to accomplish this, but it is also possible to use bust_self() to bust individual properties if necessary.

username = None

The username of the user to whom this profile belongs.

questions = None

A Fetchable of Question instances, each corresponding to a question that has been answered by the user to whom this profile belongs. The fetchable consists of UserQuestion instead when the profile belongs to the logged in user.

details = None

A Details instance belonging to the same user that this profile belongs to.

refresh(reload=False)[source]
Parameters:reload – Make the request to return a new profile tree. This will result in the caching of the profile_tree attribute. The new profile_tree will be returned.
is_logged_in_user
Returns:True if this profile and the session it was created with belong to the same user and False otherwise.
profile_tree
Returns:a lxml.etree created from the html of the profile page of the account associated with the username that this profile was insantiated with.
photo_infos
Returns:list of Info instances for each photo displayed on okcupid.
looking_for
Returns:A LookingFor instance associated with this profile.
rating

Deprecated. Use liked() instead.

Returns:the rating that the logged in user has given this user or 0 if no rating has been given.
liked
Returns:Whether or not the logged in user liked this profile
contacted
Retuns:A boolean indicating whether the logged in user has contacted the owner of this profile.
responds
Returns:The frequency with which the user associated with this profile responds to messages.
id
Returns:The id that okcupid.com associates with this profile.
essays
Returns:A Essays instance that is associated with this profile.
age
Returns:The age of the user associated with this profile.
match_percentage
Returns:The match percentage of the logged in user and the user associated with this object.
enemy_percentage
Returns:The enemy percentage of the logged in user and the user associated with this object.
location
Returns:The location of the user associated with this profile.
gender

The gender of the user associated with this profile.

orientation

The sexual orientation of the user associated with this profile.

message

Message the user associated with this profile.

Parameters:
  • message – The message to send to this user.
  • thread_id – The id of the thread to respond to, if any.
attractiveness
Returns:The average attractiveness rating given to this profile by the okcupid.com community.
toggle_like()[source]

Toggle whether or not the logged in user likes this profile.

like()[source]

Like this profile.

unlike()[source]

Unlike this profile.

rate(rating)[source]

Rate this profile as the user that was logged in with the session that this object was instantiated with.

Parameters:rating – The rating to give this user.
find_question(question_id, question_fetchable=None)[source]
Parameters:
  • question_id – The id of the question to search for
  • question_fetchable – The question fetchable to iterate through if none is provided self.questions will be used.
question_fetchable(**kwargs)[source]
Returns:A Fetchable instance that contains objects representing the answers that the user associated with this profile has given to okcupid.com match questions.
authcode_get(path, **kwargs)[source]

Perform an HTTP GET to okcupid.com using this profiles session where the authcode is automatically added as a query parameter.

authcode_post(path, **kwargs)[source]

Perform an HTTP POST to okcupid.com using this profiles session where the authcode is automatically added as a form item.

LookingFor

class okcupyd.looking_for.LookingFor(profile)[source]

Represent the looking for attributes belonging to an okcupid.com profile.

gentation

The sex/orientation that the user is looking for.

ages

The age range that the user is interested in.

single

Whether or not the user is only interested in people that are single.

near_me

Whether the user is only interested in people that are close to them.

kinds

The kinds of relationship tha the user is looking for.

update(ages=None, single=None, near_me=None, kinds=None, gentation=None)[source]

Update the looking for attributes of the logged in user.

Parameters:
  • ages (tuple) – The ages that the logged in user is interested in.
  • single (bool) – Whether or not the user is only interested in people that are single.
  • near_me (bool) – Whether or not the user is only interested in people that are near them.
  • kinds (list) – What kinds of relationships the user should be updated to be interested in.
  • gentation (str) – The sex/orientation of people the user is interested in.
class Ages(min, max)
max

Alias for field number 1

min

Alias for field number 0

Details

class okcupyd.details.Details(profile)[source]

Represent the details belonging to an okcupid.com profile.

classmethod name_detail_pairs()[source]
refresh()[source]
id_to_display_name_value
as_dict
convert_and_update(data)[source]
update(data)[source]
bodytype

The bodytype detail of an okcupid.com user’s profile.

orientation

The orientation detail of an okcupid.com user’s profile.

smokes

The smoking detail of an okcupid.com user’s profile.

drugs

The drugs detail of an okcupid.com user’s profile.

drinks

The drinking detail of an okcupid.com user’s profile.

job

The job detail of an okcupid.com user’s profile.

status

The status detail of an okcupid.com user’s profile.

monogamy

The monogamous detail of an okcupid.com user’s profile.

children

The children detail of an okcupid.com user’s profile.

education

The education detail of an okcupid.com user’s profile.

pets

The pets detail of an okcupid.com user’s profile.

diet

The diet detail of an okcupid.com user’s profile.

religion

The religion detail of an okcupid.com user’s profile.

sign

The sign detail of an okcupid.com user’s profile.

height

The height detail of an okcupid.com user’s profile.

ethnicities[source]

The ethnicities detail of an okcupid.com user’s profile.

income[source]

The income detail of an okcupid.com user’s profile.

languages[source]

The languages detail of an okcupid.com user’s profile.

Essays

class okcupyd.essay.Essays(profile)[source]

Interface to reading and writing essays.

self_summary

The contents of the essay labeled ‘Self Summary’. Write to this attribute to change its value for the logged in user.

my_life

The contents of the essay labeled ‘What I’m doing with my life’. Write to this attribute to change its value for the logged in user.

good_at

The contents of the essay labeled ‘I’m really good at’. Write to this attribute to change its value for the logged in user.

people_first_notice

The contents of the essay labeled ‘The first thing people notice about me’. Write to this attribute to change its value for the logged in user.

favorites

The contents of the essay labeled ‘Favorite books, movies, shows, music, and food’. Write to this attribute to change its value for the logged in user.

six_things

The contents of the essay labeled ‘Six things I could never live without’. Write to this attribute to change its value for the logged in user.

think_about

The contents of the essay labeled ‘I spend a lot of time thinking about’. Write to this attribute to change its value for the logged in user.

friday_night

The contents of the essay labeled ‘On a typical friday night I am’. Write to this attribute to change its value for the logged in user.

private_admission

The contents of the essay labeled ‘The most private thing I’m willing to admit’. Write to this attribute to change its value for the logged in user.

message_me_if

The contents of the essay labeled ‘You should message me if’. Write to this attribute to change its value for the logged in user.

essay_names = ['self_summary', 'my_life', 'good_at', 'people_first_notice', 'favorites', 'six_things', 'think_about', 'friday_night', 'private_admission', 'message_me_if']

A list of the attribute names that are used to store the text of of essays on instances of this class.

PhotoUploader

class okcupyd.photo.PhotoUploader(session=None, user_id=None, authcode=None)[source]

Upload photos to okcupid.com.

upload_and_confirm(incoming, **kwargs)[source]

Upload the file to okcupid and confirm, among other things, its thumbnail position.

Parameters:
  • incoming – A filepath string, Info object or a file like object to upload to okcupid.com. If an info object is provided, its thumbnail positioning will be used by default.
  • caption – The caption to add to the photo.
  • thumb_nail_left – For thumb nail positioning.
  • thumb_nail_top – For thumb nail positioning.
  • thumb_nail_right – For thumb nail positioning.
  • thumb_nail_bottom – For thumb nail positioning.
delete(photo_id, album_id=0)[source]

Delete a photo from the logged in users account.

Parameters:
  • photo_id – The okcupid id of the photo to delete.
  • album_id – The album from which to delete the photo.

Info

class okcupyd.photo.Info(photo_id, tnl, tnt, tnr, tnb)[source]

Represent a photo that appears on a okcupid.com user’s profile.

thumb_nail_left = None

The horizontal position of the left side of this photo’s thumbnail.

thumb_nail_top = None

The vertical position of the top side of this photo’s thumbnail.

thumb_nail_right = None

The horizontal position of the right side of this photo’s thumbnail.

thumb_nail_bottom = None

The vertical position of the bottom side of this photo’s thumbnail.

jpg_uri
Returns:A uri from which this photo can be downloaded in jpg format.

MessageThread

class okcupyd.messaging.MessageThread(session, thread_element)[source]

Represent a message thread between two users.

classmethod delete_threads(session, thread_ids_or_threads, authcode=None)[source]
Parameters:
  • session – A logged in Session.
  • thread_ids_or_threads – A list whose members are either MessageThread instances or okc_ids of message threads.
  • authcode – Authcode to use for this request. If none is provided A request to the logged in user’s messages page will be made to retrieve one.
messages = None

A Fetchable of Message objects.

id
Returns:The id assigned to this message by okcupid.com.
correspondent_id
Returns:The id assigned to the correspondent of this message.
correspondent
Returns:The username of the user with whom the logged in user is conversing in this MessageThread.
read
Returns:Whether or not the user has read all the messages in this MessageThread.
initiator
Returns:A Profile instance belonging to the initiator of this MessageThread.
respondent
Returns:A Profile instance belonging to the respondent of this MessageThread.
correspondent_profile
Returns:The Profile of the user with whom the logged in user is conversing in this MessageThread.
user_profile
Returns:A Profile belonging to the logged in user.
got_response
Returns:Whether or not the MessageThread. has received a response.
delete()[source]

Delete this thread for the logged in user.

Message

class okcupyd.messaging.Message(message_element, message_thread)[source]

Represent a message sent on okcupid.com

id
Returns:The id assigned to this message by okcupid.com.
sender
Returns:A Profile instance belonging to the sender of this message.
recipient
Returns:A Profile instance belonging to the recipient of this message.
content
Returns:The text body of the message.

Questions

class okcupyd.question.Questions(session, importances=('not_important', 'little_important', 'somewhat_important', 'very_important', 'mandatory'), user_id=None)[source]

Interface to accessing and answering questions belonging to the logged in user.

mandatory

A Fetchable of UserQuestion instances that correspond to questions that have been answered by the logged in user and assigned the ‘mandatory’ importance.

very_important

A Fetchable of UserQuestion instances that correspond to questions that have been answered by the logged in user and assigned the ‘very_important’ importance.

somewhat_important

A Fetchable of UserQuestion instances that correspond to questions that have been answered by the logged in user and assigned the ‘somewhat_important’ importance.

little_important

A Fetchable of UserQuestion instances that correspond to questions that have been answered by the logged in user and assigned the ‘little_important’ importance.

not_important

A Fetchable of UserQuestion instances that correspond to questions that have been answered by the logged in user and assigned the ‘not_important’ importance.

importance_name_to_number = {'not_important': 5, 'little_important': 4, 'somewhat_important': 3, 'very_important': 1, 'mandatory': 0}

Human readable importance name to integer used to represent them on okcupid.com

respond_from_user_question(user_question, importance)[source]

Respond to a question in exactly the way that is described by the given user_question.

Parameters:
  • user_question (UserQuestion) – The user question to respond with.
  • importance (int see importance_name_to_number) – The importance that should be used in responding to the question.
respond_from_question(question, user_question, importance)[source]

Copy the answer given in question to the logged in user’s profile.

Parameters:
  • question – A Question instance to copy.
  • user_question – An instance of UserQuestion that corresponds to the same question as question. This is needed to retrieve the answer id from the question text answer on question.
  • importance – The importance to assign to the response to the answered question.
respond(question_id, user_response_ids, match_response_ids, importance, note='', is_public=1, is_new=1)[source]

Respond to an okcupid.com question.

Parameters:
  • question_id – The okcupid id used to identify this question.
  • user_response_ids – The answer id(s) to provide to this question.
  • match_response_ids – The answer id(s) that the user considers acceptable.
  • importance – The importance to attribute to this question. See importance_name_to_number for details.
  • note – The explanation note to add to this question.
  • is_public – Whether or not the question answer should be made public.
clear()[source]

USE WITH CAUTION. Delete the answer to every question that the logged in user has responded to.

Question

class okcupyd.question.Question(question_element)[source]

Represent a question answered by a user other than the logged in user.

Note: Because of the way that okcupid presents question data it is actually not very easy to get the index of the answer to a question that belongs to a user other than the logged in user. It is possible to retrieve this value (see okcupyd.user.User.get_question_answer_id() and get_answer_id_for_question()), but it can take quite a few requests to do so. For this reason, the answer_id is NOT included as an attribute on this object, despite its inclusion in UserQuestion.

their_answer

The answer that the user whose Profile this question was retrieved from provided to this Question.

my_answer

The answer that the user whose Session was used to create this Question provided.

their_answer_matches
Returns:whether or not the answer provided by the user answering the question is acceptable to the logged in user.
Return type:rbool
my_answer_matches
Returns:bool indicating whether or not the answer provided by the logged in user is acceptable to the user answering the question.
their_note
Returns:The note the answering user provided as explanation for their answer to this question.
my_note
Returns:The note the logged in user provided as an explanation for their answer to this question.

UserQuestion

class okcupyd.question.UserQuestion(question_element)[source]

Represent a question answered by the logged in user.

get_answer_id_for_question(question)[source]

Get the answer_id corresponding to the answer given for question by looking at this UserQuestion‘s answer_options. The given Question instance must have the same id as this UserQuestion.

That this method exists is admittedly somewhat weird. Unfortunately, it seems to be the only way to retrieve this information.

answer_options
Returns:A list of AnswerOption instances representing the available answers to this question.
explanation
Returns:The explanation written by the logged in user for this question (if any).
answer
Returns:A AnswerOption instance corresponding to the answer the user gave to this question.

AnswerOption

class okcupyd.question.AnswerOption(option_element)[source]
is_users
Returns:Whether or not this was the answer selected by the logged in user.
is_match
Returns:Whether or not this was the answer is acceptable to the logged in user.
text
Returns:The text of this answer.
id
Returns:The integer index associated with this answer.

SearchFetchable()

okcupyd.json_search.SearchFetchable(session=None, **kwargs)[source]

Search okcupid.com with the given parameters. Parameters are registered to this function through register_filter_builder() of search_filters.

Returns:

A Fetchable of Profile instances.

Parameters:
  • session (Session) – A logged in session.
  • gentation (list) – A list of the allowable gentations of returned search results. expected values: ‘’, ‘girls who like girls’, ‘bi guys and girls’, ‘men who like women’, ‘bi guys only’, ‘straight men only’, ‘gay girls only’, ‘women who like men’, ‘straight guys only’, ‘guys who like guys’, ‘girls who like guys’, ‘bi men only’, ‘both who like bi guys’, ‘bi men and women’, ‘guys and girls who like bi guys’, ‘everybody’, ‘both who like bi men’, ‘guys who like girls’, ‘guys and girls who like bi girls’, ‘straight girls only’, ‘both who like bi women’, ‘both who like bi girls’, ‘gay guys only’, ‘men who like men’, ‘gay women only’, ‘straight women only’, ‘bi girls only’, ‘men and women who like bi women’, ‘women’, ‘men and women who like bi men’, ‘bi women only’, ‘women who like women’, ‘gay men only’
  • location – A query that will be used to look up a locid for the search, location_cache must also be passed in in order for this parameter to work. User automatically passes the location_cache in.
  • location_cache – A LocationQueryCache instance.
  • locid (int) –
  • maximum_age (int) – Filter profiles with ages below the provided value.
  • minimum_age (int) – Filter profiles with ages above the provided value.
  • order_by
  • radius ((<class 'int'>, <class 'NoneType'>)) – The maximum distance (in miles) from the specified location of returned search results.

_AttractivenessFinder

class okcupyd.attractiveness_finder._AttractivenessFinder(session=None)[source]

Find the attractiveness of okcupid.com users.

This class is typically wrapped in several different attractiveness finder decorators that allow for cacheing of results and rounding.

find_attractiveness(username, accuracy=1000, _lower=0, _higher=10000)[source]
Parameters:
  • username – The username to lookup attractiveness for.
  • accuracy – The accuracy required to return a result.
  • _lower – The lower bound of the search.
  • _higher – The upper bound of the search.

Copy

class okcupyd.profile_copy.Copy(source_profile_or_user, dest_user)[source]

Copy photos, essays and other attributes from one profile to another.

__init__(source_profile_or_user, dest_user)[source]
Parameters:
  • source_profile_or_user – A User or Profile object from which to copy attributes. questions() will not will not preserve the importance of copied questions if a Profile instance is provided.
  • dest_user – A User to which data will be copied
questions()[source]

Copy questions to the destination user. When this class was initialized with a Profile, this will delete any existing questions answers on the destination account.

photos()[source]

Copy photos to the destination user.

essays()[source]

Copy essays from the source profile to the destination profile.

looking_for()[source]

Copy looking for attributes from the source profile to the destination profile.

details()[source]

Copy details from the source profile to the destination profile.

all()[source]

Invoke all of questions(), details(), essays(), photos(), looking_for()

Statistics

class okcupyd.statistics.Statistics(user, message_threads=None, filters=(), attractiveness_finder=None)[source]

add_command_line_options()

okcupyd.util.misc.add_command_line_options(add_argument, use_short_options=True)[source]
Parameters:
  • add_argument – The add_argument method of an ArgParser.
  • use_short_options – Whether or not to add short options.

handle_command_line_options()

okcupyd.util.misc.handle_command_line_options(args)[source]
Parameters:args – The args returned from an ArgParser

Core Objects

util

class okcupyd.util.cached_property(func)[source]

Descriptor that caches the result of the first call to resolve its contents.

bust_self(obj)[source]

Remove the value that is being stored on obj for this cached_property object.

Parameters:obj – The instance on which to bust the cache.
classmethod bust_caches(obj, excludes=())[source]

Bust the cache for all cached_property objects on obj

Parameters:obj – The instance on which to bust the caches.
class okcupyd.util.REMap(re_value_pairs=(), default=<object object>)[source]

A mapping object that matches regular expressions to values.

classmethod from_string_pairs(string_value_pairs, **kwargs)[source]

Build an REMap from str, value pairs by applying re.compile to each string and calling the __init__ of REMap

okcupyd.util.IndexedREMap(*re_strings, **kwargs)[source]

Build a REMap from the provided regular expression string. Each string will be associated with the index corresponding to its position in the argument list.

Parameters:
  • re_strings – The re_strings that will serve as keys in the map.
  • default – The value to return if none of the regular expressions match
  • offset – The offset at which to start indexing for regular expressions defaults to 1.

curry

class okcupyd.util.currying.curry[source]

Curry a function or method.

Applying curry to a function creates a callable with the same functionality that can be invoked with an incomplete argument list to create a partial application of the original function.

@curry
def greater_than(x, y):
   return x > y

>>> less_than_40 = greater_than(40)
>>> less_than_40(39)
True
>>> less_than_40(50)
False

curry allows functions to be partially invoked an arbitary number of times:

@curry
def add_5_things(a, b, c, d, e):
    return a + b + c + d + e

# All of the following invocations of add_5_things
>>> add_5_things(1)(1)(1)(1)(1)
5

one_left = add_5_things(1, 1)(3)(4) # A one place function that will
# add 1 + 1 + 3 + 4 = 9 to whatever is provided as its argument.

>>>> one_left(5)
14
>>> one_left(6)
15

A particular compelling use case for curry is the creation of decorators that take optional arguments:

@curry
def add_n(function, n=1):
    def wrapped(*args, **kwargs):
        return function(*args, **kwargs) + n
    return wrapped

@add_n(n=12)
def multiply_plus_twelve(x, y):
    return x * y

@add_n
def multiply_plus_one(x, y):
    return x * y

>>> multiply_plus_one(1, 1)
2
>>> multiply_plus_twelve(1, 1)
13

Notice that we were able to apply add_n regardless of whether or not an optional argument had been supplied earlier.

The version of curry that is available for import has been curried itself. That is, its constructor can be invoked partially:

@curry(evaluation_checker=lambda *args, **kwargs: len(args) > 2)
def args_taking_function(*args):
    return reduce(lambda x, y: x*y, args)

>>> args_taking_function(1, 2)
2
>>> args_taking_function(2)(3)
6
>>> args_taking_function(2, 2, 2, 2)
16
function

alias of curry

fetchable

Most of the collection objects that are returned from function invocations in the okcupyd library are instances of Fetchable. In most cases, it is fine to treat these objects as though they are lists because they can be iterated over, sliced and accessed by index, just like lists:

for question in user.profile.questions:
    print(question.answer.text)

a_random_question = user.profile.questions[2]
for question in questions[2:4]:
    print(question.answer_options[0])

However, in some cases, it is important to be aware of the subtle differences between Fetchable objects and python lists. Fetchable construct the elements that they “contain” lazily. In most of its uses in the okcupyd library, this means that http requests can be made to populate Fetchable instances as its elments are requested.

The questions Fetchable that is used in the example above fetches the pages that are used to construct its contents in batches of 10 questions. This means that the actual call to retrieve data is made when iteration starts. If you enable the request logger when you run this code snippet, you get output that illustrates this fact:

2014-10-29 04:25:04 Livien-MacbookAir requests.packages.urllib3.connectionpool[82461] DEBUG "GET /profile/ShrewdDrew/questions?leanmode=1&low=11 HTTP/1.1" 200 None
 Yes
 Yes
 Kiss someone.
 Yes.
 Yes
 Sex.
 Both equally
 No, I wouldn't give it as a gift.
 Maybe, I want to know all the important stuff.
 Once or twice a week
 2014-10-29 04:25:04 Livien-MacbookAir requests.packages.urllib3.connectionpool[82461] DEBUG "GET /profile/ShrewdDrew/questions?leanmode=1&low=21 HTTP/1.1" 200 None
 No.
 No
 No
 Yes
 Rarely / never
 Always.
 Discovering your shared interests
 The sun
 Acceptable.
 No.

Some fetchables will continue fetching content for quite a long time. The search fetchable, for example, will fetch content until okcupid runs out of search results. As such, things like:

for profile in user.search():
    profile.message("hey!")

should be avoided, as they are likely to generate a massive number of requests to okcupid.com.

Another subtlety of the Fetchable class is that its instances cache its contained results. This means that the second iteration over okcupyd.profile.Profile.questions in the example below does not result in any http requests:

for question in user.profile.questions:
    print(question.text)

for question in user.profile.questions:
    print(question.answer)

It is important to understand that this means that the contents of a Fetchable are not guarenteed to be in sync with okcupid.com the second time they are requested. Calling refresh() will cause the Fetchable to request new data from okcupid.com when its contents are requested. The code snippet that follows prints out all the questions that the logged in user has answered roughly once per hour, including ones that are answered while the program is running.

import time

while True:
    for question in user.profile.questions:
        print(question.text)
    user.profile.questions.refresh()
    time.sleep(3600)

Without the call to user.profile.questions.refresh(), this program would never update the user.profile.questions instance, and thus what would be printed to the screen with each iteration of the for loop.

class okcupyd.util.fetchable.Fetchable(fetcher, **kwargs)[source]

List-like container object that lazily loads its contained items.

__init__(fetcher, **kwargs)[source]
Parameters:
  • fetcher – An object with a fetch generator method that retrieves items for the fetchable.
  • nice_repr – Append the repr of a list containing the items that have been fetched to this point by the fetcher. Defaults to True.
  • kwargs – Arguments that should be passed to the fetcher when it’s fetch method is called. These are stored on the fetchable so they can be passed to the fetcher whenever refresh() is called.
refresh(nice_repr=True, **kwargs)[source]
Parameters:
  • nice_repr (bool) – Append the repr of a list containing the items that have been fetched to this point by the fetcher.
  • kwargs – kwargs that should be passed to the fetcher when its fetch method is called. These are merged with the values provided to the constructor, with the ones provided here taking precedence if there is a conflict.
class okcupyd.util.fetchable.SimpleProcessor(session, object_factory, element_xpath)[source]

Applies object_factory to each element found with element_xpath

Accepts session merely to be consistent with the FetchMarshall interface.

Session

class okcupyd.session.Session(requests_session, rate_limit=None)[source]

A requests.Session with convenience methods for interacting with okcupid.com

classmethod login(username=None, password=None, requests_session=None, rate_limit=None)[source]

Get a session that has authenticated with okcupid.com. If no username and password is supplied, the ones stored in okcupyd.settings will be used.

Parameters:
  • username (str) – The username to log in with.
  • password (str) – The password to log in with.
  • rate_limit (float) – Average time in seconds to wait between requests to OKC.
get_profile(username)[source]

Get the profile associated with the supplied username :param username: The username of the profile to retrieve.

get_current_user_profile()[source]

Get the okcupyd.profile.Profile associated with the supplied username.

Parameters:username – The username of the profile to retrieve.

Filters

class okcupyd.filter.Filters(strict=True)[source]

Registrar for functions that construct filters for submission in requests to okcupid.com

build_documentation_lines()[source]

Build a parameter documentation string that can appended to the docstring of a function that uses this Filters instance to build filters.

register_filter_builder

Register a filter function with this Filters instance. This function is curried with curry – that is, it can be invoked partially before it is fully evaluated. This allows us to pass kwargs to this function when it is used as a decorator:

@register_filter_builder(keys=('real_name',),
                         decider=Filters.any_decider)
def my_filter_function(argument):
    return '4,{0}'.format(argument)
Parameters:
  • function – The filter function to register.
  • keys – Keys that should be used as the argument names for function, if none are provided, the filter functions argument names will be used instead.
  • decider – a function of signature (function, incoming_keys, accepted_keys) that returns True if the filter function should be called and False otherwise. Defaults to all_not_none_decider()
  • acceptable_values – A list of acceptable values for the parameter of the filter function (or a list of lists if the filter function takes multiple parameters)
  • types – The type of the parameter accepted by the incoming filter function (or a list of types if the function takes multiple parameters)
  • descriptions – A description for the incoming filter function’s argument (or a list of descriptions if the filter function takes multiple arguments)
  • output_key – The key to use to output the provided value. Will default to the only value in keys if keys has length 1.

Project Modules

okcupyd Package

okcupyd Package

okcupyd.__init__.interactive()[source]
class okcupyd.__init__.User(session=None)[source]

Bases: object

Encapsulate a logged in okcupid user.

copy(profile_or_user)[source]

Create a Copy instance with the provided object as the source and this User as the destination.

Parameters:profile_or_user – A User or Profile object.
delete_threads(thread_ids_or_threads)[source]

Call delete_threads().

Parameters:thread_ids_or_threads – A list whose members are either MessageThread instances or okc_ids of message threads.
classmethod from_credentials(username, password)[source]
Parameters:
  • username (str) – The username to log in with.
  • password (str) – The password to log in with.
get_profile(username)[source]

Get the Profile associated with the supplied username.

Parameters:username – The username of the profile to retrieve.
get_question_answer_id(question, fast=False, bust_questions_cache=False)[source]

Get the index of the answer that was given to question

See the documentation for get_user_question() for important caveats about the use of this function.

Parameters:
  • question (BaseQuestion) – The question whose answer_id should be retrieved.
  • fast (bool) – Don’t try to look through the users existing questions to see if arbitrarily answering the question can be avoided.
  • bust_questions_cache (bool) –
    param bust_questions_cache:
     clear the

    questions attribute of this users Profile before looking for an existing answer. Be aware that even this does not eliminate all race conditions.

get_user_question(question, fast=False, bust_questions_cache=False)[source]

Get a UserQuestion corresponding to the given Question.

HUGE CAVEATS: If the logged in user has not answered the relevant question, it will automatically be answered with whatever the first answer to the question is.

For the sake of reducing the number of requests made when this function is called repeatedly this function does not bust the cache of this User‘s okcupyd.profile.Profile.questions attribute. That means that a question that HAS been answered could still be answered by this function if this User‘s questions was populated previously (This population happens automatically – See Fetchable for details about when and how this happens).

Parameters:
  • question (BaseQuestion) – The question for which a UserQuestion should be retrieved.
  • fast (bool) – Don’t try to look through the users existing questions to see if arbitrarily answering the question can be avoided.
  • bust_questions_cache (bool) – clear the questions attribute of this users Profile before looking for an existing answer. Be aware that even this does not eliminate all race conditions.
message(username, message_text)[source]

Message an okcupid user. If an existing conversation between the logged in user and the target user can be found, reply to that thread instead of starting a new one.

Parameters:
  • username (str) – The username of the user to which the message should be sent.
  • message_text (str) – The body of the message.
quickmatch()[source]

Return a Profile obtained by visiting the quickmatch page.

search(**kwargs)[source]

Call SearchFetchable() to get a Fetchable object that will lazily perform okcupid searches to provide Profile objects matching the search criteria.

Defaults for gender, gentation, location and radius will be provided if none are given.

Parameters:kwargs – See the SearchFetchable() docstring for details about what parameters are available.
username

Return the username associated with the User.

okcupyd.__init__.AttractivenessFinder(*args, **kwargs)
class okcupyd.__init__.Statistics(user, message_threads=None, filters=(), attractiveness_finder=None)[source]

Bases: object

attractiveness_filter(attractiveness_finder=None, min_attractiveness=0, max_attractiveness=10000)[source]
average_attractiveness
average_conversation_length
average_first_message_length
count
has_attractiveness
has_messages
has_response
initiated
no_responses
portion_initiated
portion_received
received
response_rate
threads
time_filter(min_date=None, max_date=None)[source]
with_filters(*filters, **kwargs)[source]
okcupyd.__init__.save_file(filename, data)[source]
class okcupyd.__init__.PhotoUploader(session=None, user_id=None, authcode=None)[source]

Bases: object

Upload photos to okcupid.com.

confirm(pic_id, **kwargs)[source]
delete(photo_id, album_id=0)[source]

Delete a photo from the logged in users account.

Parameters:
  • photo_id – The okcupid id of the photo to delete.
  • album_id – The album from which to delete the photo.
upload(incoming)[source]
upload_and_confirm(incoming, **kwargs)[source]

Upload the file to okcupid and confirm, among other things, its thumbnail position.

Parameters:
  • incoming – A filepath string, Info object or a file like object to upload to okcupid.com. If an info object is provided, its thumbnail positioning will be used by default.
  • caption – The caption to add to the photo.
  • thumb_nail_left – For thumb nail positioning.
  • thumb_nail_top – For thumb nail positioning.
  • thumb_nail_right – For thumb nail positioning.
  • thumb_nail_bottom – For thumb nail positioning.
upload_by_filename(filename)[source]
upload_file(file_object, image_type='jpeg')[source]
upload_from_info(info)[source]
class okcupyd.__init__.Session(requests_session, rate_limit=None)[source]

Bases: object

A requests.Session with convenience methods for interacting with okcupid.com

build_path(path, secure=None)[source]
default_login_headers = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.94 Safari/537.36'}
do_login(username, password)[source]
get_current_user_profile()[source]

Get the okcupyd.profile.Profile associated with the supplied username.

Parameters:username – The username of the profile to retrieve.
get_profile(username)[source]

Get the profile associated with the supplied username :param username: The username of the profile to retrieve.

classmethod login(username=None, password=None, requests_session=None, rate_limit=None)[source]

Get a session that has authenticated with okcupid.com. If no username and password is supplied, the ones stored in okcupyd.settings will be used.

Parameters:
  • username (str) – The username to log in with.
  • password (str) – The password to log in with.
  • rate_limit (float) – Average time in seconds to wait between requests to OKC.
okc_delete(path, secure=None, **kwargs)
okc_get(path, secure=None, **kwargs)
okc_post(path, secure=None, **kwargs)
okc_put(path, secure=None, **kwargs)

attractiveness_finder Module

class okcupyd.attractiveness_finder.AttractivenessFinderDecorator(attractiveness_finder=None)[source]

Bases: object

class okcupyd.attractiveness_finder.CheckForExistenceAttractivenessFinder(attractiveness_finder=None)[source]

Bases: okcupyd.attractiveness_finder.AttractivenessFinderDecorator

find_attractiveness(username, *args, **kwargs)[source]
class okcupyd.attractiveness_finder.RoundedAttractivenessFinder(attractiveness_finder=None)[source]

Bases: okcupyd.attractiveness_finder.AttractivenessFinderDecorator

find_attractiveness(*args, **kwargs)[source]
class okcupyd.attractiveness_finder.CachedAttractivenessFinder(attractiveness_finder=None)[source]

Bases: okcupyd.attractiveness_finder.AttractivenessFinderDecorator

find_attractiveness(username, **kwargs)[source]

details Module

class okcupyd.details.Detail(id_name=None, presenter=None, updater=None)[source]

Bases: object

Represent a detail belonging to an okcupid.com profile.

NO_DEFAULT = <object object>
classmethod comma_separated_presenter(text)[source]
classmethod mapping_multi_updater(mapping)[source]
classmethod auto_indexed_updater(*options)[source]
classmethod mapping_updater(mapping, id_name=None)[source]
static default_updater(id_name, value)[source]
id_name
update(value)[source]
class okcupyd.details.DeclarativeDetail[source]

Bases: object

updater = None
presenter = None
class okcupyd.details.Details(profile)[source]

Bases: object

Represent the details belonging to an okcupid.com profile.

classmethod name_detail_pairs()[source]
refresh()[source]
id_to_display_name_value
as_dict
convert_and_update(data)[source]
update(data)[source]
bodytype

The bodytype detail of an okcupid.com user’s profile.

orientation

The orientation detail of an okcupid.com user’s profile.

smokes

The smoking detail of an okcupid.com user’s profile.

drugs

The drugs detail of an okcupid.com user’s profile.

drinks

The drinking detail of an okcupid.com user’s profile.

job

The job detail of an okcupid.com user’s profile.

status

The status detail of an okcupid.com user’s profile.

monogamy

The monogamous detail of an okcupid.com user’s profile.

children

The children detail of an okcupid.com user’s profile.

education

The education detail of an okcupid.com user’s profile.

pets

The pets detail of an okcupid.com user’s profile.

diet

The diet detail of an okcupid.com user’s profile.

religion

The religion detail of an okcupid.com user’s profile.

sign

The sign detail of an okcupid.com user’s profile.

height

The height detail of an okcupid.com user’s profile.

ethnicities[source]

The ethnicities detail of an okcupid.com user’s profile.

income[source]

The income detail of an okcupid.com user’s profile.

languages[source]

The languages detail of an okcupid.com user’s profile.

okcupyd.details.declarative_detail

alias of languages

okcupyd.details.is_declarative_detail(x)
okcupyd.details.detail

The status detail of an okcupid.com user’s profile.

errors Module

exception okcupyd.errors.AuthenticationError[source]

Bases: Exception

exception okcupyd.errors.NoCorrespondentError[source]

Bases: Exception

essay Module

class okcupyd.essay.Essays(profile)[source]

Bases: object

Interface to reading and writing essays.

static build_essay_property(essay_index, essay_name)[source]
essay_names = ['self_summary', 'my_life', 'good_at', 'people_first_notice', 'favorites', 'six_things', 'think_about', 'friday_night', 'private_admission', 'message_me_if']

A list of the attribute names that are used to store the text of of essays on instances of this class.

short_name_to_title
refresh()[source]
favorites
friday_night
good_at
message_me_if
my_life
people_first_notice
private_admission
self_summary
six_things
think_about

filter Module

okcupyd.filter.all_not_none_decider(function, incoming, accepted_keys)[source]
okcupyd.filter.always_decider(*args, **kwargs)[source]
class okcupyd.filter.Filters(strict=True)[source]

Bases: object

Registrar for functions that construct filters for submission in requests to okcupid.com

filter_meta
filter_class
build_documentation_lines()[source]

Build a parameter documentation string that can appended to the docstring of a function that uses this Filters instance to build filters.

build_paramter_string(key)[source]
add_to_docstring_of(target)[source]
static all_not_none_decider(function, incoming, accepted_keys)
static any_decider(function, incoming, accepted_keys)[source]
static all_decider(function, incoming, accepted_keys)[source]
static any_not_none_decider(function, incoming, accepted_keys)[source]
filters(**kwargs)[source]
build(**kwargs)[source]
legacy_build(**kwargs)[source]
register_builder(filter_object)[source]
register_filter_builder

Register a filter function with this Filters instance. This function is curried with curry – that is, it can be invoked partially before it is fully evaluated. This allows us to pass kwargs to this function when it is used as a decorator:

@register_filter_builder(keys=('real_name',),
                         decider=Filters.any_decider)
def my_filter_function(argument):
    return '4,{0}'.format(argument)
Parameters:
  • function – The filter function to register.
  • keys – Keys that should be used as the argument names for function, if none are provided, the filter functions argument names will be used instead.
  • decider – a function of signature (function, incoming_keys, accepted_keys) that returns True if the filter function should be called and False otherwise. Defaults to all_not_none_decider()
  • acceptable_values – A list of acceptable values for the parameter of the filter function (or a list of lists if the filter function takes multiple parameters)
  • types – The type of the parameter accepted by the incoming filter function (or a list of types if the function takes multiple parameters)
  • descriptions – A description for the incoming filter function’s argument (or a list of descriptions if the filter function takes multiple arguments)
  • output_key – The key to use to output the provided value. Will default to the only value in keys if keys has length 1.
okcupyd.filter.gentation_filter(gentation)[source]
okcupyd.filter.age_filter(age_min=18, age_max=99)[source]
okcupyd.filter.location_filter(radius)[source]

helpers Module

class okcupyd.helpers.MessageInfo(thread_id, message_id)

Bases: tuple

message_id

Alias for field number 1

thread_id

Alias for field number 0

class okcupyd.helpers.Messager(session)[source]

Bases: object

Send Messages to an okcupid user.

message_request_parameters(username, message, thread_id, authcode)[source]
send(username, message, authcode=None, thread_id=None)[source]
okcupyd.helpers.parse_fancydate(fancydate_text)[source]
okcupyd.helpers.parse_date_updated(date_updated_text)[source]
okcupyd.helpers.parse_contextual_date(date_updated_text)[source]
okcupyd.helpers.parse_slashed_date(date_updated_text)[source]
okcupyd.helpers.parse_abbreviated_date(date_updated_text)[source]
okcupyd.helpers.parse_time(date_updated_text)[source]
okcupyd.helpers.parse_day_of_the_week(date_updated_text)[source]
okcupyd.helpers.date_from_weekday(weekday)[source]
okcupyd.helpers.datetime_to_string(a_datetime)[source]
okcupyd.helpers.get_locid(session, location)[source]

Make a request to locquery resource to translate a string location search into an int locid. Returns ———- int

An int that OKCupid maps to a particular geographical location.
okcupyd.helpers.format_last_online(last_online)[source]

Return the upper limit in seconds that a profile may have been online. If last_online is an int, return that int. Otherwise if last_online is a str, convert the string into an int. Returns ———- int

okcupyd.helpers.update_looking_for(profile_tree, looking_for)[source]

Update looking_for attribute of a Profile.

okcupyd.helpers.update_details(profile_tree, details)[source]

Update details attribute of a Profile.

okcupyd.helpers.get_default_gentation(gender, orientation)[source]

Return the default gentation for the given gender and orientation.

okcupyd.helpers.replace_chars(astring)[source]

Replace certain unicode characters to avoid errors when trying to read various strings. Returns ———- str

okcupyd.helpers.add_newlines(tree)[source]

Add a newline character to the end of each <br> element.

looking_for Module

class okcupyd.looking_for.LookingFor(profile)[source]

Bases: object

Represent the looking for attributes belonging to an okcupid.com profile.

raw_fields
gentation

The sex/orientation that the user is looking for.

ages

The age range that the user is interested in.

single

Whether or not the user is only interested in people that are single.

near_me

Whether the user is only interested in people that are close to them.

kinds

The kinds of relationship tha the user is looking for.

update(ages=None, single=None, near_me=None, kinds=None, gentation=None)[source]

Update the looking for attributes of the logged in user.

Parameters:
  • ages (tuple) – The ages that the logged in user is interested in.
  • single (bool) – Whether or not the user is only interested in people that are single.
  • near_me (bool) – Whether or not the user is only interested in people that are near them.
  • kinds (list) – What kinds of relationships the user should be updated to be interested in.
  • gentation (str) – The sex/orientation of people the user is interested in.
class Ages(min, max)

Bases: tuple

max

Alias for field number 1

min

Alias for field number 0

magicnumbers Module

class okcupyd.magicnumbers.maps[source]

Bases: object

bodytype = <okcupyd.util.REMap object>
orientation = <okcupyd.util.REMap object>
smokes = <okcupyd.util.REMap object>
drugs = <okcupyd.util.REMap object>
drinks = <okcupyd.util.REMap object>
ethnicities = <okcupyd.util.REMap object>
job = <okcupyd.util.REMap object>
status = <okcupyd.util.REMap object>
monogamy = <okcupyd.util.REMap object>
strictness = <okcupyd.util.REMap object>
has_kids = <okcupyd.util.REMap object>
wants_kids = <okcupyd.util.REMap object>
education_status = <okcupyd.util.REMap object>
education_level = <okcupyd.util.REMap object>
religion = <okcupyd.util.REMap object>
seriousness = <okcupyd.util.REMap object>
sign = <okcupyd.util.REMap object>
importance = <okcupyd.util.REMap object>
dogs = <okcupyd.util.REMap object>
cats = <okcupyd.util.REMap object>
language_level = <okcupyd.util.REMap object>
diet_strictness = <okcupyd.util.REMap object>
diet = <okcupyd.util.REMap object>
income = <okcupyd.util.REMap object>
class okcupyd.magicnumbers.MappingUpdater(mapping)[source]

Bases: object

class okcupyd.magicnumbers.SimpleFilterBuilder(filter_number, mapping, offset=0)[source]

Bases: object

get_number(values)[source]
get_filter(values)[source]
class okcupyd.magicnumbers.filters[source]

Bases: object

bodytype = <okcupyd.magicnumbers.SimpleFilterBuilder object>
smokes = <okcupyd.magicnumbers.SimpleFilterBuilder object>
drinks = <okcupyd.magicnumbers.SimpleFilterBuilder object>
drugs = <okcupyd.magicnumbers.SimpleFilterBuilder object>
education_level = <okcupyd.magicnumbers.SimpleFilterBuilder object>
job = <okcupyd.magicnumbers.SimpleFilterBuilder object>
income = <okcupyd.magicnumbers.SimpleFilterBuilder object>
religion = <okcupyd.magicnumbers.SimpleFilterBuilder object>
monogamy = <okcupyd.magicnumbers.SimpleFilterBuilder object>
diet = <okcupyd.magicnumbers.SimpleFilterBuilder object>
sign = <okcupyd.magicnumbers.SimpleFilterBuilder object>
ethnicities = <okcupyd.magicnumbers.SimpleFilterBuilder object>
dogs = <okcupyd.magicnumbers.SimpleFilterBuilder object>
cats = <okcupyd.magicnumbers.SimpleFilterBuilder object>
okcupyd.magicnumbers.inches_to_centimeters(inches)[source]
okcupyd.magicnumbers.get_height_filter(height_min=None, height_max=None)[source]
okcupyd.magicnumbers.parse_height_string(height_string)[source]
okcupyd.magicnumbers.get_kids_filter(has_kids=(), wants_kids=())[source]
okcupyd.magicnumbers.get_kids_int(has_kids, wants_kids)[source]
okcupyd.magicnumbers.subtract_has_kids_exponents(value)[source]
okcupyd.magicnumbers.yield_exponents_of_two(value)[source]
okcupyd.magicnumbers.get_language_query(language)[source]
okcupyd.magicnumbers.get_join_date_filter(join_date)[source]
okcupyd.magicnumbers.get_question_filter(question, question_answers=None)[source]

messaging Module

okcupyd.messaging.ThreadFetcher(session, mailbox_number)[source]
class okcupyd.messaging.ThreadHTMLFetcher(session, mailbox_number)[source]

Bases: object

fetch(start_at)[source]
class okcupyd.messaging.MessageFetcher(session, message_thread, read_messages=False)[source]

Bases: object

params
messages_tree
refresh()[source]
fetch()[source]
message_elements
class okcupyd.messaging.Message(message_element, message_thread)[source]

Bases: object

Represent a message sent on okcupid.com

id
Returns:The id assigned to this message by okcupid.com.
sender
Returns:A Profile instance belonging to the sender of this message.
recipient
Returns:A Profile instance belonging to the recipient of this message.
content
Returns:The text body of the message.
time_sent
class okcupyd.messaging.MessageThread(session, thread_element)[source]

Bases: object

Represent a message thread between two users.

classmethod delete_threads(session, thread_ids_or_threads, authcode=None)[source]
Parameters:
  • session – A logged in Session.
  • thread_ids_or_threads – A list whose members are either MessageThread instances or okc_ids of message threads.
  • authcode – Authcode to use for this request. If none is provided A request to the logged in user’s messages page will be made to retrieve one.
messages = None

A Fetchable of Message objects.

id
Returns:The id assigned to this message by okcupid.com.
correspondent_id
Returns:The id assigned to the correspondent of this message.
correspondent
Returns:The username of the user with whom the logged in user is conversing in this MessageThread.
read
Returns:Whether or not the user has read all the messages in this MessageThread.
date
datetime
with_deleted_user
initiator
Returns:A Profile instance belonging to the initiator of this MessageThread.
respondent
Returns:A Profile instance belonging to the respondent of this MessageThread.
correspondent_profile
Returns:The Profile of the user with whom the logged in user is conversing in this MessageThread.
user_profile
Returns:A Profile belonging to the logged in user.
message_count
has_messages
got_response
Returns:Whether or not the MessageThread. has received a response.
delete()[source]

Delete this thread for the logged in user.

photo Module

class okcupyd.photo.PhotoUploader(session=None, user_id=None, authcode=None)[source]

Bases: object

Upload photos to okcupid.com.

upload(incoming)[source]
upload_from_info(info)[source]
upload_by_filename(filename)[source]
upload_file(file_object, image_type='jpeg')[source]
confirm(pic_id, **kwargs)[source]
upload_and_confirm(incoming, **kwargs)[source]

Upload the file to okcupid and confirm, among other things, its thumbnail position.

Parameters:
  • incoming – A filepath string, Info object or a file like object to upload to okcupid.com. If an info object is provided, its thumbnail positioning will be used by default.
  • caption – The caption to add to the photo.
  • thumb_nail_left – For thumb nail positioning.
  • thumb_nail_top – For thumb nail positioning.
  • thumb_nail_right – For thumb nail positioning.
  • thumb_nail_bottom – For thumb nail positioning.
delete(photo_id, album_id=0)[source]

Delete a photo from the logged in users account.

Parameters:
  • photo_id – The okcupid id of the photo to delete.
  • album_id – The album from which to delete the photo.
class okcupyd.photo.Info(photo_id, tnl, tnt, tnr, tnb)[source]

Bases: object

Represent a photo that appears on a okcupid.com user’s profile.

base_uri = 'https://k0.okccdn.com/php/load_okc_image.php/images/'
cdn_re = re.compile('http(?P<was_secure>s?)://.*okccdn.com.*images/[0-9]*x[0-9]*/[0-9]*x[0-9]*/(?P<tnl>[0-9]*?)x(?P<tnt>[0-9]*?)/(?P<tnr>[0-9]*)x(?P<tnb>[0-9]*)/0/(?P<id>[0-9]*).(:?webp|jpeg)\\?v=\\d+')
classmethod from_cdn_uri(cdn_uri)[source]
thumb_nail_left = None

The horizontal position of the left side of this photo’s thumbnail.

thumb_nail_top = None

The vertical position of the top side of this photo’s thumbnail.

thumb_nail_right = None

The horizontal position of the right side of this photo’s thumbnail.

thumb_nail_bottom = None

The vertical position of the bottom side of this photo’s thumbnail.

jpg_uri
Returns:A uri from which this photo can be downloaded in jpg format.

profile Module

class okcupyd.profile.Profile(session, username, **kwargs)[source]

Bases: object

Represent the profile of an okcupid user.

Many of the attributes on this object are cached_property instances which lazily load their values, and cache them once they have been accessed. This makes it so that this object avoids making unnecessary HTTP requests to retrieve the same piece of information twice.

Because of this caching behavior, care must be taken to invalidate cached attributes on the object if an up to date view of the profile is needed. It is recommended that you call refresh() to accomplish this, but it is also possible to use bust_self() to bust individual properties if necessary.

username = None

The username of the user to whom this profile belongs.

questions = None

A Fetchable of Question instances, each corresponding to a question that has been answered by the user to whom this profile belongs. The fetchable consists of UserQuestion instead when the profile belongs to the logged in user.

details = None

A Details instance belonging to the same user that this profile belongs to.

refresh(reload=False)[source]
Parameters:reload – Make the request to return a new profile tree. This will result in the caching of the profile_tree attribute. The new profile_tree will be returned.
is_logged_in_user
Returns:True if this profile and the session it was created with belong to the same user and False otherwise.
profile_tree
Returns:a lxml.etree created from the html of the profile page of the account associated with the username that this profile was insantiated with.
message_request_parameters(content, thread_id)[source]
authcode
photo_infos
Returns:list of Info instances for each photo displayed on okcupid.
looking_for
Returns:A LookingFor instance associated with this profile.
rating

Deprecated. Use liked() instead.

Returns:the rating that the logged in user has given this user or 0 if no rating has been given.
liked
Returns:Whether or not the logged in user liked this profile
contacted
Retuns:A boolean indicating whether the logged in user has contacted the owner of this profile.
responds
Returns:The frequency with which the user associated with this profile responds to messages.
id
Returns:The id that okcupid.com associates with this profile.
essays
Returns:A Essays instance that is associated with this profile.
age
Returns:The age of the user associated with this profile.
match_percentage
Returns:The match percentage of the logged in user and the user associated with this object.
enemy_percentage
Returns:The enemy percentage of the logged in user and the user associated with this object.
location
Returns:The location of the user associated with this profile.
gender

The gender of the user associated with this profile.

orientation

The sexual orientation of the user associated with this profile.

message

Message the user associated with this profile.

Parameters:
  • message – The message to send to this user.
  • thread_id – The id of the thread to respond to, if any.
attractiveness
Returns:The average attractiveness rating given to this profile by the okcupid.com community.
toggle_like()[source]

Toggle whether or not the logged in user likes this profile.

like()[source]

Like this profile.

unlike()[source]

Unlike this profile.

rate(rating)[source]

Rate this profile as the user that was logged in with the session that this object was instantiated with.

Parameters:rating – The rating to give this user.
find_question(question_id, question_fetchable=None)[source]
Parameters:
  • question_id – The id of the question to search for
  • question_fetchable – The question fetchable to iterate through if none is provided self.questions will be used.
question_fetchable(**kwargs)[source]
Returns:A Fetchable instance that contains objects representing the answers that the user associated with this profile has given to okcupid.com match questions.
authcode_get(path, **kwargs)[source]

Perform an HTTP GET to okcupid.com using this profiles session where the authcode is automatically added as a query parameter.

authcode_post(path, **kwargs)[source]

Perform an HTTP POST to okcupid.com using this profiles session where the authcode is automatically added as a form item.

profile_copy Module

class okcupyd.profile_copy.Copy(source_profile_or_user, dest_user)[source]

Bases: object

Copy photos, essays and other attributes from one profile to another.

copy_methods = ['photos', 'essays', 'looking_for', 'details', 'questions']
questions()[source]

Copy questions to the destination user. When this class was initialized with a Profile, this will delete any existing questions answers on the destination account.

photos()[source]

Copy photos to the destination user.

essays()[source]

Copy essays from the source profile to the destination profile.

looking_for()[source]

Copy looking for attributes from the source profile to the destination profile.

details()[source]

Copy details from the source profile to the destination profile.

all()[source]

Invoke all of questions(), details(), essays(), photos(), looking_for()

question Module

class okcupyd.question.BaseQuestion(question_element)[source]

Bases: object

The abstract base class of Question and UserQuestion. Contains all the shared functionality of the aforementined classes. The two are quite different in some ways and can not always be used interchangably. See their respective docstrings for more details.

answered
id
Returns:The integer id given to this question by okcupid.com.
text
class okcupyd.question.Question(question_element)[source]

Bases: okcupyd.question.BaseQuestion

Represent a question answered by a user other than the logged in user.

Note: Because of the way that okcupid presents question data it is actually not very easy to get the index of the answer to a question that belongs to a user other than the logged in user. It is possible to retrieve this value (see okcupyd.user.User.get_question_answer_id() and get_answer_id_for_question()), but it can take quite a few requests to do so. For this reason, the answer_id is NOT included as an attribute on this object, despite its inclusion in UserQuestion.

their_answer

The answer that the user whose Profile this question was retrieved from provided to this Question.

my_answer

The answer that the user whose Session was used to create this Question provided.

their_answer_matches
Returns:whether or not the answer provided by the user answering the question is acceptable to the logged in user.
Return type:rbool
my_answer_matches
Returns:bool indicating whether or not the answer provided by the logged in user is acceptable to the user answering the question.
their_note
Returns:The note the answering user provided as explanation for their answer to this question.
my_note
Returns:The note the logged in user provided as an explanation for their answer to this question.
class okcupyd.question.UserQuestion(question_element)[source]

Bases: okcupyd.question.BaseQuestion

Represent a question answered by the logged in user.

get_answer_id_for_question(question)[source]

Get the answer_id corresponding to the answer given for question by looking at this UserQuestion‘s answer_options. The given Question instance must have the same id as this UserQuestion.

That this method exists is admittedly somewhat weird. Unfortunately, it seems to be the only way to retrieve this information.

answer_id
answer_options
Returns:A list of AnswerOption instances representing the available answers to this question.
explanation
Returns:The explanation written by the logged in user for this question (if any).
answer_text_to_option
answer
Returns:A AnswerOption instance corresponding to the answer the user gave to this question.
class okcupyd.question.AnswerOption(option_element)[source]

Bases: object

is_users
Returns:Whether or not this was the answer selected by the logged in user.
is_match
Returns:Whether or not this was the answer is acceptable to the logged in user.
text
Returns:The text of this answer.
id
Returns:The integer index associated with this answer.
class okcupyd.question.Questions(session, importances=('not_important', 'little_important', 'somewhat_important', 'very_important', 'mandatory'), user_id=None)[source]

Bases: object

Interface to accessing and answering questions belonging to the logged in user.

headers = {'accept-language': 'en-US,en;q=0.8', 'referer': 'https://www.okcupid.com/questions', 'x-requested-with': 'XMLHttpRequest', 'accept-encoding': 'gzip,deflate', 'origin': 'https://www.okcupid.com', 'accept': 'application/json, text/javascript, */*; q=0.01', 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8'}
importance_name_to_number = {'not_important': 5, 'little_important': 4, 'somewhat_important': 3, 'very_important': 1, 'mandatory': 0}

Human readable importance name to integer used to represent them on okcupid.com

path = 'questions/ask'
respond_from_user_question(user_question, importance)[source]

Respond to a question in exactly the way that is described by the given user_question.

Parameters:
  • user_question (UserQuestion) – The user question to respond with.
  • importance (int see importance_name_to_number) – The importance that should be used in responding to the question.
respond_from_question(question, user_question, importance)[source]

Copy the answer given in question to the logged in user’s profile.

Parameters:
  • question – A Question instance to copy.
  • user_question – An instance of UserQuestion that corresponds to the same question as question. This is needed to retrieve the answer id from the question text answer on question.
  • importance – The importance to assign to the response to the answered question.
respond(question_id, user_response_ids, match_response_ids, importance, note='', is_public=1, is_new=1)[source]

Respond to an okcupid.com question.

Parameters:
  • question_id – The okcupid id used to identify this question.
  • user_response_ids – The answer id(s) to provide to this question.
  • match_response_ids – The answer id(s) that the user considers acceptable.
  • importance – The importance to attribute to this question. See importance_name_to_number for details.
  • note – The explanation note to add to this question.
  • is_public – Whether or not the question answer should be made public.
clear()[source]

USE WITH CAUTION. Delete the answer to every question that the logged in user has responded to.

okcupyd.question.QuestionProcessor(question_class)[source]
class okcupyd.question.QuestionHTMLFetcher(session, uri, **additional_parameters)[source]

Bases: object

classmethod from_username(session, username, **kwargs)[source]
fetch(start_at)[source]
okcupyd.question.QuestionFetcher(session, username, question_class=<class 'okcupyd.question.Question'>, is_user=False, **kwargs)[source]

session Module

class okcupyd.session.Session(requests_session, rate_limit=None)[source]

Bases: object

A requests.Session with convenience methods for interacting with okcupid.com

default_login_headers = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.94 Safari/537.36'}
classmethod login(username=None, password=None, requests_session=None, rate_limit=None)[source]

Get a session that has authenticated with okcupid.com. If no username and password is supplied, the ones stored in okcupyd.settings will be used.

Parameters:
  • username (str) – The username to log in with.
  • password (str) – The password to log in with.
  • rate_limit (float) – Average time in seconds to wait between requests to OKC.
do_login(username, password)[source]
build_path(path, secure=None)[source]
get_profile(username)[source]

Get the profile associated with the supplied username :param username: The username of the profile to retrieve.

get_current_user_profile()[source]

Get the okcupyd.profile.Profile associated with the supplied username.

Parameters:username – The username of the profile to retrieve.
okc_delete(path, secure=None, **kwargs)
okc_get(path, secure=None, **kwargs)
okc_post(path, secure=None, **kwargs)
okc_put(path, secure=None, **kwargs)
class okcupyd.session.RateLimiter(rate_limit, wait_std_dev=None)[source]

Bases: object

wait()[source]
okcupyd.session.build_okc_method(method_name)[source]

settings Module

Module where the default username and password for logging in to okcupid are housed.

okcupyd.settings.USERNAME = None

The username that will be used to log in to okcupid

okcupyd.settings.PASSWORD = None

The password that will be used to log in to okcupid

okcupyd.settings.okcupyd_config_at_path(path)[source]
okcupyd.settings.generate_paths_to_check()[source]
okcupyd.settings.load_credentials_from_filepath(filepath)[source]
okcupyd.settings.load_credentials_from_files()[source]

statistics Module

class okcupyd.statistics.Statistics(user, message_threads=None, filters=(), attractiveness_finder=None)[source]

Bases: object

threads
has_messages
has_response
no_responses
initiated
received
has_attractiveness
time_filter(min_date=None, max_date=None)[source]
attractiveness_filter(attractiveness_finder=None, min_attractiveness=0, max_attractiveness=10000)[source]
with_filters(*filters, **kwargs)[source]
count
response_rate
average_first_message_length
average_conversation_length
average_attractiveness
portion_initiated
portion_received

user Module

class okcupyd.user.User(session=None)[source]

Bases: object

Encapsulate a logged in okcupid user.

classmethod from_credentials(username, password)[source]
Parameters:
  • username (str) – The username to log in with.
  • password (str) – The password to log in with.
profile = None

A Profile object belonging to the logged in user.

inbox = None

A Fetchable of MessageThread objects corresponding to messages that are currently in the user’s inbox.

outbox = None

A Fetchable of MessageThread objects corresponding to messages that are currently in the user’s outbox.

drafts = None

A Fetchable of MessageThread objects corresponding to messages that are currently in the user’s drafts folder.

visitors = None

A Fetchable of Profile objects of okcupid.com users that have visited the user’s profile.

questions = None

A Questions object that is instantiated with the owning User instance’s session.

attractiveness_finder = None

An _AttractivenessFinder object that is instantiated with the owning User instance’s session.

photo = None

A PhotoUploader that is instantiated with the owning User instance’s session.

location_cache = None

A LocationQueryCache instance

get_profile(username)[source]

Get the Profile associated with the supplied username.

Parameters:username – The username of the profile to retrieve.
username

Return the username associated with the User.

message(username, message_text)[source]

Message an okcupid user. If an existing conversation between the logged in user and the target user can be found, reply to that thread instead of starting a new one.

Parameters:
  • username (str) – The username of the user to which the message should be sent.
  • message_text (str) – The body of the message.
search(**kwargs)[source]

Call SearchFetchable() to get a Fetchable object that will lazily perform okcupid searches to provide Profile objects matching the search criteria.

Defaults for gender, gentation, location and radius will be provided if none are given.

Parameters:kwargs – See the SearchFetchable() docstring for details about what parameters are available.
delete_threads(thread_ids_or_threads)[source]

Call delete_threads().

Parameters:thread_ids_or_threads – A list whose members are either MessageThread instances or okc_ids of message threads.
get_user_question(question, fast=False, bust_questions_cache=False)[source]

Get a UserQuestion corresponding to the given Question.

HUGE CAVEATS: If the logged in user has not answered the relevant question, it will automatically be answered with whatever the first answer to the question is.

For the sake of reducing the number of requests made when this function is called repeatedly this function does not bust the cache of this User‘s okcupyd.profile.Profile.questions attribute. That means that a question that HAS been answered could still be answered by this function if this User‘s questions was populated previously (This population happens automatically – See Fetchable for details about when and how this happens).

Parameters:
  • question (BaseQuestion) – The question for which a UserQuestion should be retrieved.
  • fast (bool) – Don’t try to look through the users existing questions to see if arbitrarily answering the question can be avoided.
  • bust_questions_cache (bool) – clear the questions attribute of this users Profile before looking for an existing answer. Be aware that even this does not eliminate all race conditions.
get_question_answer_id(question, fast=False, bust_questions_cache=False)[source]

Get the index of the answer that was given to question

See the documentation for get_user_question() for important caveats about the use of this function.

Parameters:
  • question (BaseQuestion) – The question whose answer_id should be retrieved.
  • fast (bool) – Don’t try to look through the users existing questions to see if arbitrarily answering the question can be avoided.
  • bust_questions_cache (bool) –
    param bust_questions_cache:
     clear the

    questions attribute of this users Profile before looking for an existing answer. Be aware that even this does not eliminate all race conditions.

quickmatch()[source]

Return a Profile obtained by visiting the quickmatch page.

copy(profile_or_user)[source]

Create a Copy instance with the provided object as the source and this User as the destination.

Parameters:profile_or_user – A User or Profile object.

xpath Module

class okcupyd.xpath.XPathBuilder(nodes=(), relative=True, direct_child=False)[source]

Bases: object

xpath
or_
text_
add_node(**kwargs)[source]
update_final_node(updated_final_node)[source]
attribute_contains(attribute, contains_string)[source]
with_classes(*classes)[source]
select_attribute_(attribute, elem=None)[source]
text_contains_(contained_text)[source]
with_class(*classes)
apply_(tree)[source]
one_(tree)[source]
get_text_(tree)[source]
class okcupyd.xpath.XPathNode(element='*', attributes=None, predicates=None, direct_child=False, use_or=False, selected_attribute=None)[source]

Bases: object

text = <object object>
static contains_class(class_attribute, contained_class)[source]
static contains_attribute(attribute, contained_string)[source]
static attribute_equal(attribute, value)[source]
make_or
separator
xpath
predicate_joiner
predicate_string
selected_attribute_string
with_classes(classes)[source]
add_contains_predicates(kv_pairs)[source]
text_contains(contained_text)[source]
okcupyd.xpath.xpb

Subpackages

db Package
db Package
class okcupyd.db.Query(entities, session=None)[source]

Bases: sqlalchemy.orm.query.Query

class okcupyd.db.txn(session_class=None)[source]

Bases: object

okcupyd.db.with_txn(function, instance, args, kwargs)[source]
class okcupyd.db.OKCBase(**kwargs)[source]

Bases: sqlalchemy.ext.declarative.api.Base

okc_id = Column(None, StringBackedInteger(), table=None, nullable=False)
okcupyd.db.reset_engine(engine)[source]
okcupyd.db.set_sqlite_db_file(file_path)[source]
adapters Module
class okcupyd.db.adapters.UserAdapter(profile)[source]

Bases: object

build(session)[source]
get_no_txn(session)[source]
get(session)
class okcupyd.db.adapters.ThreadAdapter(thread)[source]

Bases: object

add_messages()[source]
get_thread()[source]
mailbox Module
class okcupyd.db.mailbox.Sync(user)[source]

Bases: object

Sync messages from a users inbox to the okc database.

all()[source]
update_mailbox

Update the mailbox associated with the given mailbox name.

inbox

Update the mailbox associated with the given mailbox name.

outbox

Update the mailbox associated with the given mailbox name.

types Module
class okcupyd.db.types.JSONType(*args, **kwargs)[source]

Bases: sqlalchemy.sql.type_api.TypeDecorator

impl

alias of VARCHAR

process_bind_param(value, dialect)[source]
process_result_value(value, dialect)[source]
class okcupyd.db.types.StringBackedInteger(*args, **kwargs)[source]

Bases: sqlalchemy.sql.type_api.TypeDecorator

impl

alias of VARCHAR

process_bind_param(value, dialect)[source]
process_result_value(value, dialect)[source]
user Module
okcupyd.db.user.have_messaged_by_username_no_txn(session, username_one, username_two)[source]
okcupyd.db.user.have_messaged_by_username(session, username_one, username_two)[source]
Subpackages
model Package
model Package
message Module
class okcupyd.db.model.message.Message(**kwargs)[source]

Bases: okcupyd.db.OKCBase

time_sent
message_thread_id
sender_id
sender
recipient_id
recipient
text
thread_index
created_at
id
okc_id
message_thread Module
class okcupyd.db.model.message_thread.MessageThread(**kwargs)[source]

Bases: okcupyd.db.OKCBase

initiator_id
initiator
respondent_id
respondent
messages
created_at
id
okc_id
user Module
class okcupyd.db.model.user.User(**kwargs)[source]

Bases: okcupyd.db.OKCBase

classmethod from_profile(profile)[source]
handle
age
location
created_at
id
okc_id
class okcupyd.db.model.user.OKCupydUser(**kwargs)[source]

Bases: sqlalchemy.ext.declarative.api.Base

inbox_last_updated
outbox_last_updated
user_id
user
created_at
id
tasks Package
tasks Package
copy Module
okcupyd.tasks.copy.build_copy(source_credentials_or_username, dest_credentials)[source]
okcupyd.tasks.copy.build_copy_task(method)[source]
db Module
site Module
util Package
util Package
okcupyd.util.makelist(value)[source]
okcupyd.util.makelist_decorator(function)[source]
class okcupyd.util.cached_property(func)[source]

Bases: object

Descriptor that caches the result of the first call to resolve its contents.

bust_self(obj)[source]

Remove the value that is being stored on obj for this cached_property object.

Parameters:obj – The instance on which to bust the cache.
classmethod bust_caches(obj, excludes=())[source]

Bust the cache for all cached_property objects on obj

Parameters:obj – The instance on which to bust the caches.
classmethod get_cached_properties(obj)[source]
class okcupyd.util.CallableMap(func_value_pairs=())[source]

Bases: object

add(func, value)[source]
class okcupyd.util.REMap(re_value_pairs=(), default=<object object>)[source]

Bases: object

A mapping object that matches regular expressions to values.

NO_DEFAULT = <object object>
classmethod from_string_pairs(string_value_pairs, **kwargs)[source]

Build an REMap from str, value pairs by applying re.compile to each string and calling the __init__ of REMap

add(re, value)[source]
pattern_to_value
values()[source]
class okcupyd.util.GetAttrGetItem[source]

Bases: type

okcupyd.util.IndexedREMap(*re_strings, **kwargs)[source]

Build a REMap from the provided regular expression string. Each string will be associated with the index corresponding to its position in the argument list.

Parameters:
  • re_strings – The re_strings that will serve as keys in the map.
  • default – The value to return if none of the regular expressions match
  • offset – The offset at which to start indexing for regular expressions defaults to 1.
okcupyd.util.decorate_all(decorator)[source]
compose Module
okcupyd.util.compose.make_single_arity(function)[source]
okcupyd.util.compose.force_args_return(function)[source]
okcupyd.util.compose.tee(*functions)[source]
currying Module
okcupyd.util.currying.curry[source]

Curry a function or method.

Applying curry to a function creates a callable with the same functionality that can be invoked with an incomplete argument list to create a partial application of the original function.

@curry
def greater_than(x, y):
   return x > y

>>> less_than_40 = greater_than(40)
>>> less_than_40(39)
True
>>> less_than_40(50)
False

curry allows functions to be partially invoked an arbitary number of times:

@curry
def add_5_things(a, b, c, d, e):
    return a + b + c + d + e

# All of the following invocations of add_5_things
>>> add_5_things(1)(1)(1)(1)(1)
5

one_left = add_5_things(1, 1)(3)(4) # A one place function that will
# add 1 + 1 + 3 + 4 = 9 to whatever is provided as its argument.

>>>> one_left(5)
14
>>> one_left(6)
15

A particular compelling use case for curry is the creation of decorators that take optional arguments:

@curry
def add_n(function, n=1):
    def wrapped(*args, **kwargs):
        return function(*args, **kwargs) + n
    return wrapped

@add_n(n=12)
def multiply_plus_twelve(x, y):
    return x * y

@add_n
def multiply_plus_one(x, y):
    return x * y

>>> multiply_plus_one(1, 1)
2
>>> multiply_plus_twelve(1, 1)
13

Notice that we were able to apply add_n regardless of whether or not an optional argument had been supplied earlier.

The version of curry that is available for import has been curried itself. That is, its constructor can be invoked partially:

@curry(evaluation_checker=lambda *args, **kwargs: len(args) > 2)
def args_taking_function(*args):
    return reduce(lambda x, y: x*y, args)

>>> args_taking_function(1, 2)
2
>>> args_taking_function(2)(3)
6
>>> args_taking_function(2, 2, 2, 2)
16
fetchable Module

Most of the collection objects that are returned from function invocations in the okcupyd library are instances of Fetchable. In most cases, it is fine to treat these objects as though they are lists because they can be iterated over, sliced and accessed by index, just like lists:

for question in user.profile.questions:
    print(question.answer.text)

a_random_question = user.profile.questions[2]
for question in questions[2:4]:
    print(question.answer_options[0])

However, in some cases, it is important to be aware of the subtle differences between Fetchable objects and python lists. Fetchable construct the elements that they “contain” lazily. In most of its uses in the okcupyd library, this means that http requests can be made to populate Fetchable instances as its elments are requested.

The questions Fetchable that is used in the example above fetches the pages that are used to construct its contents in batches of 10 questions. This means that the actual call to retrieve data is made when iteration starts. If you enable the request logger when you run this code snippet, you get output that illustrates this fact:

2014-10-29 04:25:04 Livien-MacbookAir requests.packages.urllib3.connectionpool[82461] DEBUG "GET /profile/ShrewdDrew/questions?leanmode=1&low=11 HTTP/1.1" 200 None
 Yes
 Yes
 Kiss someone.
 Yes.
 Yes
 Sex.
 Both equally
 No, I wouldn't give it as a gift.
 Maybe, I want to know all the important stuff.
 Once or twice a week
 2014-10-29 04:25:04 Livien-MacbookAir requests.packages.urllib3.connectionpool[82461] DEBUG "GET /profile/ShrewdDrew/questions?leanmode=1&low=21 HTTP/1.1" 200 None
 No.
 No
 No
 Yes
 Rarely / never
 Always.
 Discovering your shared interests
 The sun
 Acceptable.
 No.

Some fetchables will continue fetching content for quite a long time. The search fetchable, for example, will fetch content until okcupid runs out of search results. As such, things like:

for profile in user.search():
    profile.message("hey!")

should be avoided, as they are likely to generate a massive number of requests to okcupid.com.

Another subtlety of the Fetchable class is that its instances cache its contained results. This means that the second iteration over okcupyd.profile.Profile.questions in the example below does not result in any http requests:

for question in user.profile.questions:
    print(question.text)

for question in user.profile.questions:
    print(question.answer)

It is important to understand that this means that the contents of a Fetchable are not guarenteed to be in sync with okcupid.com the second time they are requested. Calling refresh() will cause the Fetchable to request new data from okcupid.com when its contents are requested. The code snippet that follows prints out all the questions that the logged in user has answered roughly once per hour, including ones that are answered while the program is running.

import time

while True:
    for question in user.profile.questions:
        print(question.text)
    user.profile.questions.refresh()
    time.sleep(3600)

Without the call to user.profile.questions.refresh(), this program would never update the user.profile.questions instance, and thus what would be printed to the screen with each iteration of the for loop.

class okcupyd.util.fetchable.Fetchable(fetcher, **kwargs)[source]

Bases: object

List-like container object that lazily loads its contained items.

classmethod fetch_marshall(fetcher, processor)[source]
refresh(nice_repr=True, **kwargs)[source]
Parameters:
  • nice_repr (bool) – Append the repr of a list containing the items that have been fetched to this point by the fetcher.
  • kwargs – kwargs that should be passed to the fetcher when its fetch method is called. These are merged with the values provided to the constructor, with the ones provided here taking precedence if there is a conflict.
class okcupyd.util.fetchable.FetchMarshall(fetcher, processor, terminator=None, start_at=1)[source]

Bases: object

static simple_decider(pos, last, text_response)[source]
fetch(start_at=None)[source]
class okcupyd.util.fetchable.SimpleProcessor(session, object_factory, element_xpath)[source]

Bases: object

Applies object_factory to each element found with element_xpath

Accepts session merely to be consistent with the FetchMarshall interface.

process(text_response)[source]
class okcupyd.util.fetchable.PaginationProcessor(object_factory, element_xpb, current_page_xpb, total_page_xpb)[source]

Bases: object

process(text_response)[source]
class okcupyd.util.fetchable.GETFetcher(session, path, query_param_builder=<function GETFetcher.<lambda>>)[source]

Bases: object

fetch(*args, **kwargs)[source]
misc Module
okcupyd.util.misc.enable_logger(log_name, level=10)[source]
okcupyd.util.misc.get_credentials()[source]
okcupyd.util.misc.add_command_line_options(add_argument, use_short_options=True)[source]
Parameters:
  • add_argument – The add_argument method of an ArgParser.
  • use_short_options – Whether or not to add short options.
okcupyd.util.misc.handle_command_line_options(args)[source]
Parameters:args – The args returned from an ArgParser
okcupyd.util.misc.save_file(filename, data)[source]
okcupyd.util.misc.find_all(a_str, sub)[source]
okcupyd.util.misc.replace_all_case_insensitive(a_str, sub, replacement)[source]

Indices and tables