diff --git a/README.md b/README.md index 5f33e25..7ed6cbf 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,14 @@ The Optimizely Python client only works for Optimizely Classic (v1 REST API). Th If this library isn't meeting your requirements than we recommend you to fork the library and make the required changes. -#Optimizely Python Client +# Optimizely Python Client -##Getting Started +## Getting Started Optimizely's Python client library is an interface to its [REST API](http://developers.optimizely.com/rest/). The `optimizely` Python module can be installed via `pip` using the command `pip install optimizely`. -###Authentication +### Authentication The constructor takes in a API key and token type. We support two token types: `oauth` and `legacy`. OAuth refers to a token that was generated via OAuth and legacy is a standard API token, which can be generated from [optimizely.com/tokens](https://www.optimizely.com/tokens). `optimizely.Client(api_key, token_type)` @@ -23,7 +23,7 @@ In the following examples, `client` refers to a `Client` object created using th >>> client = optimizely.Client('abcdefghijklmnopqrstuvwxyz:123456', 'oauth') ``` -###Exceptions +### Exceptions If you make a call and it succeeds, data will be included in the returned object(s) (except in the case of deletions, where a `None` response indicates success). If the call fails, we'll raise one of the following exceptions: @@ -42,15 +42,15 @@ If the call fails, we'll raise one of the following exceptions: All of these Exceptions inherit from the `OptimizelyError` class. -##Projects +## Projects A project is a collection of experiments, goals, and audiences. Each project has an associated Javascript file to include on the page. -###Read a Project +### Read a Project Get metadata for a single project. See [the Optimizely REST API documentation](http://developers.optimizely.com/rest/#read-a-project) for response attribute definitions. -####Example Python +#### Example Python ```python >>> project = client.Projects.get(1234) # get Project by Id >>> project.__dict__ @@ -77,10 +77,10 @@ See [the Optimizely REST API documentation](http://developers.optimizely.com/res # [, ] ``` -###Create a Project +### Create a Project Create a new project in your account. The `project_name` is required in the call. The [other editable arguments](#update-a-project) are all optional. -####Example Python +#### Example Python ```python >>> project = client.Projects.create({'project_name': 'My new project name'}) >>> project.__dict__ @@ -104,11 +104,11 @@ Create a new project in your account. The `project_name` is required in the call # } ``` -###Update a Project +### Update a Project Projects can be updated by updating the attributes of a fetched object and calling `save` or by calling `update` on a client and passing in an update dictionary and resource Id. -####Editable Fields +#### Editable Fields * `project_status` * `project_name` * `include_jquery` @@ -119,7 +119,7 @@ Projects can be updated by updating the attributes of a fetched object and calli * `ip_anonymization` * `ip_filter` -####Example Python +#### Example Python ```python >>> project.project_name = 'My even newer project name' >>> project.save() @@ -147,19 +147,19 @@ Projects can be updated by updating the attributes of a fetched object and calli >>> client.Projects.update(5678, {'project_name': 'My even newer project name'}) ``` -###Delete a Project +### Delete a Project Deleting projects is not supported. -###List Projects in Account +### List Projects in Account Get a list of all the projects in your account, with associated metadata. -####Example Python +#### Example Python ```python >>> client.Projects.get() # get all Account's Projects # [, , ] ``` -##Experiments +## Experiments An A/B experiment is a set of rules for matching visitors to content and recording their conversions. Experiments are the hub that connect several other models: * **Goals** measure conversions and determine a winner. @@ -170,12 +170,12 @@ A multivariate experiment also has **Sections**. A section is a collection of va A multipage experiment adds **Pages**, which manipulate different URLs on your site. -###Read an Experiment +### Read an Experiment Get metadata for a single experiment. See [the Optimizely REST API documentation](http://developers.optimizely.com/rest/#read-an-experiment) for response attribute definitions. -####Example Python +#### Example Python ```python >>> experiment = client.Experiments.get(15) >>> experiment.__dict__ @@ -215,7 +215,7 @@ See [the Optimizely REST API documentation](http://developers.optimizely.com/res # } ``` -###Create a New Experiment +### Create a New Experiment A `project_id`, `description`, and `edit_url` are required in the the call. Other editable arguments are all optional. When you create an experiment, Optimizely will also fill in associated data by default. These defaults mimic the behavior of Optimizely's editor and include: @@ -227,7 +227,7 @@ When you create an experiment, Optimizely will also fill in associated data by d * Immediate `activation_mode`, rather than manual. * The `experiment_type` will be a normal A/B test, rather than a multivariate or multipage test. -####Example Python +#### Example Python ```python >>> experiment = client.Experiments.create({'project_id': 1234, 'edit_url': 'https://mysite.com/products/', 'description': 'My Experiment Name'}) >>> experiment.__dict__ @@ -260,10 +260,10 @@ When you create an experiment, Optimizely will also fill in associated data by d # } ``` -###Update an Experiment +### Update an Experiment Experiments can be updated by updating the attributes of a fetched object and calling `save` or by calling `update` on a client and passing in an update dictionary and resource Id. -####Editable Fields +#### Editable Fields Experiments can be updated by updating the attributes of a fetched object and calling `save` or by calling `update` on a client and passing in an update dictionary and resource Id. * `audience_ids` (add or remove an audience ID here to change the experiment's targeting) @@ -278,7 +278,7 @@ Experiments can be updated by updating the attributes of a fetched object and ca * `experiment_type` -####Example Python +#### Example Python ```python >>> experiment.status = 'Running' >>> experiment.save() @@ -315,35 +315,35 @@ Experiments can be updated by updating the attributes of a fetched object and ca >>> client.Experiments.update(15, {'status': 'Running'}) ``` -###Delete an Experiment +### Delete an Experiment Deleting an experiment will **permanently delete the experiment and its results**. In most cases, it's safer to archive the experiment by setting `status = 'Archived'`. This will remove the experiment from the Optimizely snippet and hide it in the project dashboard, but still leave it available under "Archived Experiments" for viewing and recovery later. -####Example Python +#### Example Python ```python >>> experiment = client.Experiments.get(15) >>> experiment.delete() # returns None on success ``` -###List Experiments in Project +### List Experiments in Project Get a list of all the `experiments` in a project by calling experiments on the associated `Project` object. -####Example Python +#### Example Python ```python >>> project = client.Projects.get(1234) >>> project.experiments() # [, ] ``` -###Get Experiment Results +### Get Experiment Results To list all results, call results on the associated `Experiment` object. This function may return a `ServiceUnavailableError` when the associated endpoint is overloaded. If you experience any issues please email us at [developers@optimizely.com](mailto:developers@optimizely.com). See [the Optimizely REST API documentation](http://developers.optimizely.com/rest/#get-experiment-results) for response attribute definitions. -####Example Python +#### Example Python ```python >>> experiment = client.Experiments.get(15) >>> experiment.results() @@ -369,7 +369,7 @@ See [the Optimizely REST API documentation](http://developers.optimizely.com/res # } ``` -###Get Experiment Results (Stats Engine) +### Get Experiment Results (Stats Engine) To list [Stats Engine results](https://help.optimizely.com/hc/en-us/articles/200039895-Stats-Engine-How-Optimizely-calculates-results-to-enable-business-decisions?flash_digest=ffd1e1a116256b019e5e8109aa843548129129ae), call stats on the associated `Experiment` object. This function may return a `ServiceUnavailableError` when the associated endpoint is overloaded. If you experience any issues please email us at [developers@optimizely.com](mailto:developers@optimizely.com). @@ -378,7 +378,7 @@ This function may return a `ServiceUnavailableError` when the associated endpoin See [the Optimizely REST API documentation](http://developers.optimizely.com/rest/reference/index.html#get-stats) for response attribute definitions. -####Example Python +#### Example Python ```python >>> experiment = client.Experiments.get(15) >>> experiment.stats() @@ -408,15 +408,15 @@ See [the Optimizely REST API documentation](http://developers.optimizely.com/res # } ``` -##Schedules +## Schedules Experiments can be scheduled to start or stop at a particular time. A **Schedule** is a specification of a start time, stop time, or both, associated with a particular experiment. To learn more about scheduling experiments, see the [Experiment Scheduler](https://help.optimizely.com/hc/en-us/articles/200039845-Experiment-Scheduler). -###Read a Schedule +### Read a Schedule Get data about a particular schedule, including the start time and stop time of the associated experiment. See [the Optimizely REST API documentation](http://developers.optimizely.com/rest/#read-a-schedule) for response attribute definitions. -####Example Python +#### Example Python ```python >>> schedule = client.Schedules.get(567) >>> schedule.__dict__ @@ -429,10 +429,10 @@ See [the Optimizely REST API documentation](http://developers.optimizely.com/res # } ``` -###Create a Schedule +### Create a Schedule Create a schedule for an experiment. You must specify either a `start_time` or `stop_time`, or both. All times are in UTC and must be specified in the format `2015-01-01T08:00:00Z`. The created schedule will always be marked `ACTIVE`, and any previously created schedules will be marked as `INACTIVE`. -####Example Python +#### Example Python ```python >>> schedule = client.Schedules.create({'experiment_id': 5678, 'start_time': '2015-01-01T08:00:00Z'}) >>> schedule.__dict__ @@ -445,12 +445,12 @@ Create a schedule for an experiment. You must specify either a `start_time` or ` # } ``` -###Update a Schedule +### Update a Schedule Update a schedule. You must specify either a `start_time` or `stop_time`, or both. All times are in UTC and must be specified in the format `2015-01-01T08:00:00Z`. Schedules can be updated by updating the attributes of a fetched object and calling `save` or by calling `update` on a client and passing in an update dictionary and resource Id. -####Example Python +#### Example Python ```python >>> schedule.stop_time = '2015-01-02T08:00:00Z' >>> schedule.save() @@ -467,34 +467,34 @@ Schedules can be updated by updating the attributes of a fetched object and call >>> client.Schedules.update(9012, {'stop_time': '2015-01-02T08:00:00Z'}) ``` -###Delete a Schedule +### Delete a Schedule Permanently delete a schedule. If the schedule being deleted was marked as `ACTIVE`, the associated experiment will no longer be scheduled. -####Example Python +#### Example Python ```python >>> schedule = client.Schedules.get(567) >>> schedule.delete() # returns None on success ``` -###List Schedules for Experiment +### List Schedules for Experiment See a list containing the current schedules for an experiment as well as any previously created `schedules` by calling schedules on the associated `Experiment` object. The current schedule will be marked `ACTIVE` and any previously created schedules will be marked `INACTIVE`. -####Example Python +#### Example Python ```python >>> experiment = client.Experiments.get(15) >>> experiment.schedules() # [, ] ``` -##Variations +## Variations Every experiment contains a set of variations that each change the visitor's experience in a different way. Variations define the code that should be applied on a page to change the experience, and the percentage of visitors who should see that code. A standard "A/B" test has two variations (including the original), and Optimizely supports adding many more variations. -###Read a Variation +### Read a Variation Get metadata for a single variation. See [the Optimizely REST API documentation](http://developers.optimizely.com/rest/#read-a-variation) for response attribute definitions. -####Example Python +#### Example Python ```python >>> variation = client.Variations.get(859611684) >>> variation.__dict__ @@ -511,19 +511,19 @@ See [the Optimizely REST API documentation](http://developers.optimizely.com/res # } ``` -###Create a new Variation +### Create a new Variation An `experiment_id` and `description` are required in the the call. Most variations will also want to include `js_component`, but an Original can use the default value of an empty string. Whenever possible, you should also include the correct `weight` and update the other variations so their weights sum to 10000. Note that newly created experiments come with two variations created automatically, so you may need to update a variation rather than creating it. -####Known Issues +#### Known Issues Traffic allocation may not always be set correctly. Changes to the `weight` or `is_paused` property should be double-checked on optimizely.com. We're working on fixing this issue now. Please contact [developers@optimizely.com](mailto:developers@optimizely.com) to be updated when it is fixed. -####Example Python +#### Example Python ```python >>> variation = client.Variations.create({'experiment_id': 854484703, 'description': 'Variation #1', 'js_component': '$(\'.headline\').text(\'New headline\');', 'weight': 3333}) >>> variation.__dict__ @@ -540,16 +540,16 @@ We're working on fixing this issue now. Please contact [developers@optimizely.co # } ``` -###Update a Variation +### Update a Variation Variations can be updated by updating the attributes of a fetched object and calling `save` or by calling `update` on a client and passing in an update dictionary and resource Id. -####Editable Fields +#### Editable Fields * `description` * `is_paused` (set this to True to stop the variation from getting traffic) * `js_component` * `weight` -####Example Python +#### Example Python ```python >>> variation.js_component = '$(\'.headline\').text(\'Updated headline\');' >>> variation.save() @@ -570,34 +570,34 @@ Variations can be updated by updating the attributes of a fetched object and cal >>> client.Variations.update(859611684, {'js_component': '$(\'.headline\').text(\'Updated headline\');'}) ``` -###Delete a Variation +### Delete a Variation Deleting a variation is the preferred way to remove it from an experiment. Directly editing the `variation_ids` property on experiments is not supported. -####Example Python +#### Example Python ```python >>> variation = client.Variations.get(859611684) >>> variation.delete() # returns None on success ``` -###List Variations in Experiment +### List Variations in Experiment List all variations associated with the experiment. -####Example Python +#### Example Python ```python >>> experiment = client.Experiments.get(854484703) >>> experiment.variations() # [, , ] ``` -##Goals +## Goals Goals are the metrics used to decide which variation in an experiment is the winner. Like audiences, goals are defined at the project level and can be reused across multiple experiments within a project. Each goal is tracked for each experiment it's associated with. An experiment with no goals will still run, but its results page will be empty. -###Read a Goal +### Read a Goal Optimizely has several different goal types, as explained in [our knowledge base](https://help.optimizely.com/hc/en-us/articles/200039915-Goals-Overview). Depending on the goal type, different fields in the response are important. See [the Optimizely REST API documentation](http://developers.optimizely.com/rest/#read-a-goal) for information about Goals and Goal types. -####Example Python +#### Example Python ```python >>> goal = client.Goals.get(543071054) >>> goal.__dict__ @@ -624,14 +624,14 @@ See [the Optimizely REST API documentation](http://developers.optimizely.com/res # } ``` -###Create a Goal +### Create a Goal For all goals, the `title` and `goal_type` are required. For each goal type, other fields are required: * Click goals need a `selector` and a boolean value for `target_to_experiments` to be set. If it's true, the goal will run on the same pages as the experiment it's it attached to. If it's false, you should also provide `target_urls` and `target_url_match_types`. * Pageview goals need a list of `urls` and `url_match_types` and will match nowhere if the lists are empty. * Custom event goals need an `event` name. -####Example Python +#### Example Python ```python >>> goal = client.Goals.create({'project_id': 1234, , 'title': 'Add to cart clicks', 'goal_type': 0, 'selector': 'div.cart > button', 'target_to_experiments': True}) >>> goal.__dict__ @@ -658,22 +658,22 @@ For all goals, the `title` and `goal_type` are required. For each goal type, oth # } ``` -###Add or Remove a Goal +### Add or Remove a Goal To add a goal to an experiment, call `add_goal` on the associated `Experiment` object using the goal's `id`. To remove a goal, call `remove_goal` on the associated `Experiment` object using the goal's `id`. -####Example Python +#### Example Python ```python >>> experiment = client.Experiments.get(15) >>> experiment.add_goal(543071054) # add a goal >>> experiment.remove_goal(543071054) # remove that goal ``` -###Update a Goal +### Update a Goal Goals can be updated by updating the attributes of a fetched object and calling `save` or by calling `update` on a client and passing in an update dictionary and resource Id. -####Editable Fields +#### Editable Fields * `archived` * `description` * `experiment_ids` @@ -688,7 +688,7 @@ Goals can be updated by updating the attributes of a fetched object and calling Please note that [old goals cannot be edited](https://help.optimizely.com/hc/en-us/articles/200039915-Goals-Measure-the-success-of-your-experiment#retroactive_goals), and will have `is_editable` set to `False`. -####Example Python +#### Example Python ```python >>> goal.title = 'Updated goal name' >>> goal.save() @@ -719,36 +719,36 @@ Please note that [old goals cannot be edited](https://help.optimizely.com/hc/en- >>> client.Goals.update(543071054, {'title': 'Updated goal name'}) ``` -###Delete a Goal +### Delete a Goal Delete a goal and remove it from **all associated experiments**. Deleting a goal will also remove it from past experiments, and you won't be able to see results for that goal on those experiments. It's usually better to [remove a goal](#add-or-remove-a-goal) from an experiment than delete it directly. -####Example Python +#### Example Python ```python >>> goal = client.Goals.get(543071054) >>> goal.delete() # returns None on success ``` -###List all Goals in Project +### List all Goals in Project Get a list of all the goals in a project by calling `goals` on the associated `Project` object. -####Example Python +#### Example Python ```python >>> project = client.Projects.get(1234) >>> project.goals() # [, ] ``` -##Audiences +## Audiences An Audience is a group of visitors that match set conditions. You can target an experiment to one or more audiences, or you can segment experiment results to see how different audiences performed. You can [learn more about audiences in our knowledge base](https://help.optimizely.com/hc/en-us/articles/200039685). -###Read an Audience +### Read an Audience Get metadata for a single audience. See [the Optimizely REST API documentation](http://developers.optimizely.com/rest/#read-an-audience) for response attribute definitions. -####Example Python +#### Example Python ```python >>> audience = client.Audiences.get(567) >>> audience.__dict__ @@ -765,14 +765,14 @@ See [the Optimizely REST API documentation](http://developers.optimizely.com/res # } ``` -###Create an Audience +### Create an Audience For all audiences, `name` and `project_id` are required. You can optionally add a `description`. By default, the `conditions` field will just be a string representing an empty list `'[]'`. In this case, the audience won't match anyone automatically. Instead, you can add visitors to it by `id` using the `addToAudience` function in our [Javascript API](http://developers.optimizely.com/javascript/#audiences). See our [audiences API sample](http://developers.optimizely.com/samples/#dmp) for more information. Platinum customers can also set the `segmentation` field. The default value is False, but you can set it to True to track the audience's behavior on the results page. See the section below on [updating audiences](http://developers.optimizely.com/rest/#update-audience) for more information. -####Example Python +#### Example Python ```python >>> audience = client.Audiences.create({'project_id': 1234, , 'name': 'Chinese food buyers'}) >>> audience.__dict__ @@ -789,10 +789,10 @@ Platinum customers can also set the `segmentation` field. The default value is F # } ``` -###Update an Audience +### Update an Audience Audiences can be updated by updating the attributes of a fetched object and calling `save` or by calling `update` on a client and passing in an update dictionary and resource Id. -####Editable Fields +#### Editable Fields * `name * `description * `conditions` (see [Audience Conditions](http://developers.optimizely.com/rest/conditions)) @@ -800,7 +800,7 @@ Audiences can be updated by updating the attributes of a fetched object and call Only Platinum customers can enable segmentation, and you can only enable segmentation on an audience if you have fewer than ten dimensions or other audiences enabled for segmentation. If you don't have sufficient permissions or already have 10 audiences/dimensions, the API will return an error. -####Example Python +#### Example Python ```python >>> audience.description = 'People who bought Chinese food' >>> audience.save() @@ -821,30 +821,30 @@ Only Platinum customers can enable segmentation, and you can only enable segment >>> client.Audiences.update(568, {'description': 'People who bought Chinese food'}) ``` -###Delete an Audience +### Delete an Audience Deleting audiences is not supported. -###List Audiences in Project +### List Audiences in Project Get a list of all the `audiences` in a project by calling audiences on the associated `Project` object. -####Example Python +#### Example Python ```python >>> project = client.Projects.get(1234) >>> project.audiences() # [, ] ``` -##Dimensions +## Dimensions Dimensions are attributes of visitors to your website or mobile app, such as demographic data, behavioral characteristics, or any other information particular to a visitor. Dimensions can be used to construct audiences and segment experiment results. The REST API allows you to create, edit, or delete dimensions. If you want to track visitor data for a dimension you must use a client-side API (for websites, use the [Javascript API](https://developers.optimizely.com/javascript/#dimensions)). To learn more about dimensions, see [Dimensions: Capture visitor data through the API](https://help.optimizely.com/hc/en-us/articles/200040865-Dimensions-Capture-visitor-data-through-the-API). -###Read a Dimension +### Read a Dimension Get metadata for a single dimension. See [the Optimizely REST API documentation](http://developers.optimizely.com/rest/#read-a-dimension) for response attribute definitions. -####Example Python +#### Example Python ```python >>> dimension = client.Dimensions.get(5678) >>> dimension.__dict__ @@ -858,10 +858,10 @@ See [the Optimizely REST API documentation](http://developers.optimizely.com/res # } ``` -###Create a Dimension +### Create a Dimension Create a new dimension with the specified `name`. The `client_api_name` and `description` fields are optional. If there is an existing dimension with a duplicate `name` or `client_api_name` the client will raise a `BadRequestError`. -####Example Python +#### Example Python ```python >>> dimension = client.Dimensions.create({'project_id': 1234, 'name': 'My Dimension', 'client_api_name', 'my_dimension_api_name', 'description': 'Description of my dimension'}) >>> dimension.__dict__ @@ -875,12 +875,12 @@ Create a new dimension with the specified `name`. The `client_api_name` and `des # } ``` -###Update a Dimension +### Update a Dimension Update the `name`, `client_api_name`, or `description` of an existing dimension. Dimensions can be updated by updating the attributes of a fetched object and calling `save` or by calling `update` on a client and passing in an update dictionary and resource Id. -####Example Python +#### Example Python ```python >>> dimension.description = 'A new description of my dimension' >>> dimension.save() @@ -898,19 +898,19 @@ Dimensions can be updated by updating the attributes of a fetched object and cal >>> client.Dimensions.update(5678, {'description': 'A new description of my dimension'}) ``` -###Delete a Dimension +### Delete a Dimension Permanently delete a dimension. By taking this action, any audiences using this dimension will stop getting traffic, and results associated with this dimension will be permanently deleted. -####Example Python +#### Example Python ```python >>> dimension = client.Dimensions.get(5678) >>> dimension.delete() # returns None on success ``` -###List Dimensions in Project +### List Dimensions in Project Get a list of all the dimensions in a project by calling `dimensions` on the associated `Project` object. -####Example Python +#### Example Python ```python >>> project = client.Projects.get(1234) >>> project.dimensions()