Skip to content

Commit

Permalink
Merge branch 'pr/102'
Browse files Browse the repository at this point in the history
  • Loading branch information
sigmavirus24 committed Apr 6, 2016
2 parents be8d7a8 + 8c08215 commit 48d677c
Show file tree
Hide file tree
Showing 82 changed files with 2,792 additions and 138 deletions.
49 changes: 35 additions & 14 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,38 @@
language: python
python:
- 2.6
- 2.7
- 3.2
- 3.3
- 3.4
- pypy
# command to install dependencies, e.g. pip install -r requirements.txt
# --use-mirrors

sudo: false

install:
pip install -r dev-requirements.txt
# # command to run tests, e.g. python setup.py test
script: py.test
pip install tox

script: tox

notifications:
on_success: change
on_failure: change
on_success: change
on_failure: always

matrix:
include:
- python: 2.7
env: TOXENV=py27
- python: 3.3
env: TOXENV=py33
- python: 3.4
env: TOXENV=py34
- python: 3.5
env: TOXENV=py35
- python: 2.7
env: TOXENV=py27 REQUESTS_VERSION="===2.2.1"
- python: 3.3
env: TOXENV=py33 REQUESTS_VERSION="===2.2.1"
- python: 3.4
env: TOXENV=py34 REQUESTS_VERSION="===2.2.1"
- python: 3.5
env: TOXENV=py35 REQUESTS_VERSION="===2.2.1"
- env: TOXENV=py27-flake8
- env: TOXENV=py34-flake8
- env: TOXENV=docstrings
- env: TOXENV=docs
- env: TOXENV=readme
allow_failures:
- env: TOXENV=docstrings
6 changes: 6 additions & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,9 @@ Design Advice
-------------

- Cory Benfield

Contributors
------------

- Marc Abramowitz (@msabramo)
- Bryce Boe <bbzbryce@gmail.com> (@bboe)
49 changes: 49 additions & 0 deletions CODE_OF_CONDUCT.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
Contributor Code of Conduct
---------------------------

As contributors and maintainers of this project, and in the interest of
fostering an open and welcoming community, we pledge to respect all
people who contribute through reporting issues, posting feature
requests, updating documentation, submitting pull requests or patches,
and other activities.

We are committed to making participation in this project a
harassment-free experience for everyone, regardless of level of
experience, gender, gender identity and expression, sexual orientation,
disability, personal appearance, body size, race, ethnicity, age,
religion, or nationality.

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery
* Personal attacks
* Trolling or insulting/derogatory comments
* Public or private harassment
* Publishing other's private information, such as physical or electronic
addresses, without explicit permission
* Other unethical or unprofessional conduct

Project maintainers have the right and responsibility to remove, edit,
or reject comments, commits, code, wiki edits, issues, and other
contributions that are not aligned to this Code of Conduct, or to ban
temporarily or permanently any contributor for other behaviors that they
deem inappropriate, threatening, offensive, or harmful.

By adopting this Code of Conduct, project maintainers commit themselves
to fairly and consistently applying these principles to every aspect of
managing this project. Project maintainers who do not follow or enforce
the Code of Conduct may be permanently removed from the project team.

This code of conduct applies both within project spaces and in public
spaces when an individual is representing the project or its community.

Instances of abusive, harassing, or otherwise unacceptable behavior may
be reported by contacting a project maintainer at [INSERT EMAIL
ADDRESS]. All complaints will be reviewed and investigated and will
result in a response that is deemed necessary and appropriate to the
circumstances. Maintainers are obligated to maintain confidentiality
with regard to the reporter of an incident.

This Code of Conduct is adapted from the Contributor Covenant
(http://contributor-covenant.org), version 1.3.0, available at
http://contributor-covenant.org/version/1/3/0/
46 changes: 46 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,52 @@
History
=======

0.6.0 - 2016-xx-yy
------------------

- Add ``betamax_recorder`` pytest fixture

- Remove CI support for Pythons 2.6 and 3.2

0.5.1 - 2015-10-24
------------------

- Fix bugs with requests 2.8.x integration

- Fix bugs with older versions of requests that were missing an HTTPHeaderDict
implementation

0.5.0 - 2015-07-15
------------------

- Add unittest integration in ``betamax.fixtures.unittest``

- Add pytest integration in ``betamax.fixtures.pytest``

- Add a decorator as a short cut for ``use_cassette``

- Fix bug where body bytes were not always encoded on Python 3.2+

Fixed by @bboe

0.4.2 - 2015-04-18
------------------

- Fix issue #58 reported by @bboe

Multiple cookies were not being properly stored or replayed after being
recorded.

- @leighlondon converted ``__all__`` to a tuple

0.4.1 - 2014-09-24
------------------

- Fix issue #39 reported by @buttscicles

This bug did not properly parse the Set-Cookie header with multiple cookies
when replaying a recorded response.

0.4.0 - 2014-07-29
------------------

Expand Down
4 changes: 2 additions & 2 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ include README.rst
include LICENSE
include HISTORY.rst
include AUTHORS.rst
recursive-include docs/
recursive-include tests/
recursive-include docs Makefile *.py *.rst
recursive-include tests *.json *.py
prune *.pyc
prune docs/_build
6 changes: 3 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ does not have to."
Example Use
-----------

::
.. code-block:: python
from betamax import Betamax
from requests import Session
Expand Down Expand Up @@ -62,8 +62,8 @@ are stored in files called cassettes. (An example cassette can be seen in
the `examples section of the documentation`_.) The directory you store your
cassettes in is called your library, or your `cassette library`_.

VCR Cassette Compatiblity
-------------------------
VCR Cassette Compatibility
--------------------------

Betamax can use any VCR-recorded cassette as of this point in time. The only
caveat is that python-requests returns a URL on each response. VCR does not
Expand Down
13 changes: 8 additions & 5 deletions betamax/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""
betamax
betamax.
=======
See http://betamax.rtfd.org/ for documentation.
Expand All @@ -9,15 +10,17 @@
"""

from .decorator import use_cassette
from .exceptions import BetamaxError
from .recorder import Betamax
from .matchers import BaseMatcher
from .recorder import Betamax
from .serializers import BaseSerializer

__all__ = ('BetamaxError', 'Betamax', 'BaseMatcher', 'BaseSerializer')
__all__ = ('BetamaxError', 'Betamax', 'BaseMatcher', 'BaseSerializer',
'use_cassette')
__author__ = 'Ian Cordasco'
__copyright__ = 'Copyright 2013 Ian Cordasco'
__copyright__ = 'Copyright 2013-2014 Ian Cordasco'
__license__ = 'Apache 2.0'
__title__ = 'betamax'
__version__ = '0.4.0'
__version__ = '0.5.1'
__version_info__ = tuple(int(i) for i in __version__.split('.'))
50 changes: 49 additions & 1 deletion betamax/adapter.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
"""
betamax.adapter.
==============
adapter for betamax
"""
import os

from .cassette import Cassette
Expand All @@ -7,7 +14,6 @@


class BetamaxAdapter(BaseAdapter):

"""This object is an implementation detail of the library.
It is not meant to be a public API and is not exported as such.
Expand All @@ -24,19 +30,33 @@ def __init__(self, **kwargs):
self.options = {}

def cassette_exists(self):
"""Check if cassette exists on file system.
:returns: bool -- True if exists, False otherwise
"""
if self.cassette_name and os.path.exists(self.cassette_name):
return True
return False

def close(self):
"""Propagate close to underlying adapter."""
self.http_adapter.close()

def eject_cassette(self):
"""Eject currently loaded cassette."""
if self.cassette:
self.cassette.eject()
self.cassette = None # Allow self.cassette to be garbage-collected

def load_cassette(self, cassette_name, serialize, options):
"""Load cassette.
Loads a previously serialized http response as a cassette
:param str cassette_name: (required), name of cassette
:param str serialize: (required), type of serialization i.e 'json'
:options dict options: (required), options for cassette
"""
self.cassette_name = cassette_name
self.serialize = serialize
self.options.update(options.items())
Expand Down Expand Up @@ -73,6 +93,11 @@ def load_cassette(self, cassette_name, serialize, options):

def send(self, request, stream=False, timeout=None, verify=True,
cert=None, proxies=None):
"""Send request.
:param request request: request
:returns: A Response object
"""
interaction = None

if not self.cassette:
Expand All @@ -96,6 +121,21 @@ def send(self, request, stream=False, timeout=None, verify=True,

def send_and_record(self, request, stream=False, timeout=None,
verify=True, cert=None, proxies=None):
"""Send request and record response.
The response will be serialized and saved to a
cassette which can be replayed in the future.
:param request request: request
:param bool stream: (optional) defer download until content is accessed
:param float timeout: (optional) time to wait for a response
:param bool verify: (optional) verify SSL certificate
:param str cert: (optional) path to SSL client
:param proxies dict: (optional) mapping protocol to URL of the proxy
:return: Iteraction
:rtype: class:`betamax.cassette.iteraction`
"""
adapter = self.find_adapter(request.url)
response = adapter.send(
request, stream=True, timeout=timeout, verify=verify,
Expand All @@ -105,6 +145,13 @@ def send_and_record(self, request, stream=False, timeout=None,
return self.cassette.interactions[-1]

def find_adapter(self, url):
"""Find adapter.
Searches for an existing adapter where the url and prefix match.
:param url str: (required) url of the adapter
:returns: betamax adapter
"""
for (prefix, adapter) in self.old_adapters.items():

if url.lower().startswith(prefix):
Expand All @@ -125,6 +172,7 @@ def find_adapter(self, url):


def unhandled_request_message(request, cassette):
"""Generate exception for unhandled requests."""
return UNHANDLED_REQUEST_EXCEPTION.format(
url=request.url, cassette_file_path=cassette.cassette_name,
cassette_record_mode=cassette.record_mode,
Expand Down
3 changes: 1 addition & 2 deletions betamax/cassette/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from .cassette import Cassette
from .interaction import Interaction
from .mock_response import MockHTTPResponse

__all__ = ['Cassette', 'Interaction', 'MockHTTPResponse']
__all__ = ('Cassette', 'Interaction')

0 comments on commit 48d677c

Please sign in to comment.