{"_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\": \"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[block:callout]\n{\n  \"type\": \"danger\",\n  \"body\": \"If you configure your web server to accept webhooks, be sure to consult the [security and configuration section of our docs](https://docs.recurly.com/docs/webhooks#section-configuration-security) to ensure that you follow best practices and protect against attacks.\"\n}\n[/block]\n\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            # If you need to work with the data, pull the latest information\n            trans = recurly.Transaction.get(notification['transaction'].id)\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:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"Be aware that webhooks may be delayed or received out of order. Fetch the full object to ensure you have the latest and most complete data. \\n\\nFor all of the webhook best practices, check out https://docs.recurly.com/docs/webhooks#section-best-practices\"\n}\n[/block]\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": "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). [block:callout] { "type": "danger", "body": "If you configure your web server to accept webhooks, be sure to consult the [security and configuration section of our docs](https://docs.recurly.com/docs/webhooks#section-configuration-security) to ensure that you follow best practices and protect against attacks." } [/block] [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" # If you need to work with the data, pull the latest information trans = recurly.Transaction.get(notification['transaction'].id) 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:callout] { "type": "info", "body": "Be aware that webhooks may be delayed or received out of order. Fetch the full object to ensure you have the latest and most complete data. \n\nFor all of the webhook best practices, check out https://docs.recurly.com/docs/webhooks#section-best-practices" } [/block] [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)