{"_id":"5582059c8625220d00429f30","initVersion":{"_id":"555fbba928249c1900618a85","version":"1.0"},"user":{"_id":"55648cf93b87582b003ab8b1","username":"","name":"Chris Bunting"},"project":"555fbba928249c1900618a82","__v":0,"hidden":false,"createdAt":"2015-06-17T23:41:16.268Z","fullscreen":false,"htmlmode":false,"html":"","body":"The Recurly Python Client library is an open source library to interact with Recurly's subscription management from your Python website. The library interacts with Recurly's REST API.\n\nView the [GitHub project site](https://github.com/recurly/recurly-client-python)\nfor a list of requirements and download/install instructions.\n\n* [Configuration](#configuration)\n* [Handling Dates](#handling-dates)\n* [Using the API](#using-the-api)\n* [Handling Errors](#handling-errors)\n* [Logging](#logging)\n* [Handle Webhooks](#handle-webhooks)\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Configuration\"\n}\n[/block]\nFirst, import the `recurly` library and setup your [authentication credentials](https://dev.recurly.com/docs/getting-started):\n\n```\nimport recurly\n\nrecurly.SUBDOMAIN = 'YOUR-SUBDOMAIN'\nrecurly.API_KEY = 'abcdef01234567890abcdef01234567890'\n\n# Set a default currency for your API requests\nrecurly.DEFAULT_CURRENCY = 'USD'\n```\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"body\": \"All the examples will assume that you have properly set up your configuration.\"\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Handling Dates\"\n}\n[/block]\nDates from Recurly are converted into [DateTime](http://docs.python.org/2/library/datetime.html) objects, which gives your methods to compare or format dates using that Python class. Dates are returned in UTC format.\n\n```\nsub = Subscription.get('1dd2129544f3e57ecf7d84467985eaf6')\nsub.activated_at\n#datetime.datetime(2013, 1, 22, 17, 21, 24, tzinfo=<iso8601.iso8601.Utc object at 0xa06396c>)\n\n#find local time\n\nUTC_OFFSET_TIMEDELTA = datetime.datetime.utcnow() - datetime.datetime.now()\nlocaltime = s.activated_at - UTC_OFFSET_TIMEDELTA\n#datetime.datetime(2013, 1, 22, 11, 21, 24, 11, tzinfo=<iso8601.iso8601.Utc object at 0xa06396c>)\n```\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Using the API\"\n}\n[/block]\nEach endpoint is documented with examples [here](https://dev.recurly.com/docs/getting-started).  Feel free to explore them for more information related to specific endpoints.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Handling Errors\"\n}\n[/block]\nWhen using the Python library, Recurly recommends proper exception handling.  Not handling exceptions properly could result in unexpected results or sudden termination of your code.  Below is a sample example in Python as how to properly catch exceptions thrown by the Recurly Python library.\n\n```\ntry:\n  #will throw a not found error if account does not exist\n  account = Account.get('1')\n\n  subscription = Subscription()\n  subscription.account = account\n\n  #this will throw an error because a plan_code was not set\n  subscription.save()\nexcept recurly.NotFoundError:\n  print \"Account not found.\\n\"\nexcept recurly.ValidationError, errors:\n  for e in errors.itervalues():\n    print \"%s:%s\" % (e.field, e.message)\n```\n\nFor a list of possible exception types review: [https://github.com/recurly/recurly-client-python/blob/master/recurly/errors.py](https://github.com/recurly/recurly-client-python/blob/master/recurly/errors.py)\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Logging\"\n}\n[/block]\nYou can collect logging from Recurly to have more information when you encounter an unexpected error.\n\n```\nimport recurly\nimport logging\n\nlog = logging.getLogger('recurly.http.response')\nlog.setLevel(logging.DEBUG)\n#create console handler and set level to debug\nch = logging.StreamHandler()\nch.setLevel(logging.DEBUG)\n#create formatter\nformatter = logging.Formatter(\"%(asctime)s - %(name)s - %(levelname)s - %(message)s\")\n#add formatter to ch\nch.setFormatter(formatter)\n#add ch to logger\nlog.addHandler(ch)\n```\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Handle Webhooks\"\n}\n[/block]\nThere is a built in class to help handle [webhooks](https://docs.recurly.com/push-notifications). For a list of the different webhooks and their format, you can view the [documentation](https://recurly.readme.io/v2.0/page/webhooks).\n\nHere is an example using Python's [SimpleHTTPServer (http://docs.python.org/2/library/simplehttpserver.html#module-SimpleHTTPServer).\n\nThis example is not meant to be put into production but rather to provide you with a starting point for your integration.</div>\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"body\": \"This example is not meant to be put into production but rather to provide you with a starting point for your integration\"\n}\n[/block]\n```\n#Recurly will POST an XML payload to your URL that you designate\n#in your webhooks configuration\n\nimport SimpleHTTPServer\nimport recurly\nimport SocketServer\n\n\nclass PushNotificationHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):\n\n    def do_POST(self):\n        bytes = int(self.headers[\"content-length\"])\n        data = self.rfile.read(bytes)\n        notification = recurly.objects_for_push_notification(data)\n        #each webhook is defined by a type\n        if notification['type'] == \"successful_payment_notification\":\n            print \"Payment Received\"\n        elif notification['type'] == \"failed_payment_notification\":\n            print \"The payment did not work\"\n        self.send_response(200)\n        self.wfile.write(\"OK\")\n        self.wfile.flush()\n\n\nPORT = 8000\n\nHandler = PushNotificationHandler\n\nhttpd = SocketServer.TCPServer((\"\", PORT), Handler)\n\nprint \"serving at port\", PORT\nhttpd.serve_forever()\n```\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Support\"\n}\n[/block]\nLooking for help? Please contact <support@recurly.com> or visit [support.recurly.com](https://support.recurly.com/).\n[Stackoverflow](http://stackoverflow.com/questions/tagged/recurly) is also a great place to talk to the community and find answers to common questions.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Announcements\"\n}\n[/block]\nFor the latest API and client library announcements follow Recurly on Twitter and join our Google Group:\n\n- [@recurly](https://twitter.com/recurly)\n- [Recurly Google Group](http://groups.google.com/group/recurly-api)","slug":"python","title":"Python"}

Python


The Recurly Python Client library is an open source library to interact with Recurly's subscription management from your Python website. The library interacts with Recurly's REST API. View the [GitHub project site](https://github.com/recurly/recurly-client-python) for a list of requirements and download/install instructions. * [Configuration](#configuration) * [Handling Dates](#handling-dates) * [Using the API](#using-the-api) * [Handling Errors](#handling-errors) * [Logging](#logging) * [Handle Webhooks](#handle-webhooks) [block:api-header] { "type": "basic", "title": "Configuration" } [/block] First, import the `recurly` library and setup your [authentication credentials](https://dev.recurly.com/docs/getting-started): ``` import recurly recurly.SUBDOMAIN = 'YOUR-SUBDOMAIN' recurly.API_KEY = 'abcdef01234567890abcdef01234567890' # Set a default currency for your API requests recurly.DEFAULT_CURRENCY = 'USD' ``` [block:callout] { "type": "warning", "body": "All the examples will assume that you have properly set up your configuration." } [/block] [block:api-header] { "type": "basic", "title": "Handling Dates" } [/block] Dates from Recurly are converted into [DateTime](http://docs.python.org/2/library/datetime.html) objects, which gives your methods to compare or format dates using that Python class. Dates are returned in UTC format. ``` sub = Subscription.get('1dd2129544f3e57ecf7d84467985eaf6') sub.activated_at #datetime.datetime(2013, 1, 22, 17, 21, 24, tzinfo=<iso8601.iso8601.Utc object at 0xa06396c>) #find local time UTC_OFFSET_TIMEDELTA = datetime.datetime.utcnow() - datetime.datetime.now() localtime = s.activated_at - UTC_OFFSET_TIMEDELTA #datetime.datetime(2013, 1, 22, 11, 21, 24, 11, tzinfo=<iso8601.iso8601.Utc object at 0xa06396c>) ``` [block:api-header] { "type": "basic", "title": "Using the API" } [/block] Each endpoint is documented with examples [here](https://dev.recurly.com/docs/getting-started). Feel free to explore them for more information related to specific endpoints. [block:api-header] { "type": "basic", "title": "Handling Errors" } [/block] When using the Python library, Recurly recommends proper exception handling. Not handling exceptions properly could result in unexpected results or sudden termination of your code. Below is a sample example in Python as how to properly catch exceptions thrown by the Recurly Python library. ``` try: #will throw a not found error if account does not exist account = Account.get('1') subscription = Subscription() subscription.account = account #this will throw an error because a plan_code was not set subscription.save() except recurly.NotFoundError: print "Account not found.\n" except recurly.ValidationError, errors: for e in errors.itervalues(): print "%s:%s" % (e.field, e.message) ``` For a list of possible exception types review: [https://github.com/recurly/recurly-client-python/blob/master/recurly/errors.py](https://github.com/recurly/recurly-client-python/blob/master/recurly/errors.py) [block:api-header] { "type": "basic", "title": "Logging" } [/block] You can collect logging from Recurly to have more information when you encounter an unexpected error. ``` import recurly import logging log = logging.getLogger('recurly.http.response') log.setLevel(logging.DEBUG) #create console handler and set level to debug ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) #create formatter formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") #add formatter to ch ch.setFormatter(formatter) #add ch to logger log.addHandler(ch) ``` [block:api-header] { "type": "basic", "title": "Handle Webhooks" } [/block] There is a built in class to help handle [webhooks](https://docs.recurly.com/push-notifications). For a list of the different webhooks and their format, you can view the [documentation](https://recurly.readme.io/v2.0/page/webhooks). Here is an example using Python's [SimpleHTTPServer (http://docs.python.org/2/library/simplehttpserver.html#module-SimpleHTTPServer). This example is not meant to be put into production but rather to provide you with a starting point for your integration.</div> [block:callout] { "type": "warning", "body": "This example is not meant to be put into production but rather to provide you with a starting point for your integration" } [/block] ``` #Recurly will POST an XML payload to your URL that you designate #in your webhooks configuration import SimpleHTTPServer import recurly import SocketServer class PushNotificationHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): def do_POST(self): bytes = int(self.headers["content-length"]) data = self.rfile.read(bytes) notification = recurly.objects_for_push_notification(data) #each webhook is defined by a type if notification['type'] == "successful_payment_notification": print "Payment Received" elif notification['type'] == "failed_payment_notification": print "The payment did not work" self.send_response(200) self.wfile.write("OK") self.wfile.flush() PORT = 8000 Handler = PushNotificationHandler httpd = SocketServer.TCPServer(("", PORT), Handler) print "serving at port", PORT httpd.serve_forever() ``` [block:api-header] { "type": "basic", "title": "Support" } [/block] Looking for help? Please contact <support@recurly.com> or visit [support.recurly.com](https://support.recurly.com/). [Stackoverflow](http://stackoverflow.com/questions/tagged/recurly) is also a great place to talk to the community and find answers to common questions. [block:api-header] { "type": "basic", "title": "Announcements" } [/block] For the latest API and client library announcements follow Recurly on Twitter and join our Google Group: - [@recurly](https://twitter.com/recurly) - [Recurly Google Group](http://groups.google.com/group/recurly-api)