Git Product home page Git Product logo

heroku.py's Introduction

Heroku.py

This is an awesome Python wrapper for the Heroku API. The Heroku REST API allows Heroku users to manage their accounts, applications, addons, and other aspects related to Heroku. It allows you to easily utilize the Heroku platform from your applications.

WARNING: This project is out-of-date and is not being actively maintained. We recommend you check out the community project heroku3.py instead.

Usage

Login with your password:

import heroku
cloud = heroku.from_pass('[email protected]', 'xxxxxxx')

Or your API Key (available here):

cloud = heroku.from_key('YOUR_API_KEY')

Interact with your applications:

>>> cloud.apps
[<app 'sharp-night-7758'>, <app 'empty-spring-4049'>, ...]

>>> app = cloud.apps['sharp-night-7758']

Scale them up:

>>> app.processes
[<process 'web.1'>, <process 'worker.1'>]

>>> app.processes['web']
[<process 'web.1'>]

>>> app.processes['web'].scale(3)
[<process 'web.1'>, <process 'web.2'>, <process 'web.3'>]

>>> app.processes[0].stop()
True

Access the logs:

>>> print app.logs(num=2)
2011-12-21T22:53:47+00:00 heroku[web.1]: State changed from down to created
2011-12-21T22:53:47+00:00 heroku[web.1]: State changed from created to starting

>>> print app.logs(num=2, tail=True)
<generator object stream_decode_response_unicode at 0x101151d20>

You can even stream the tail:

>>> for line in app.logs(tail=True):
...     print line

2011-12-21T22:53:47+00:00 heroku[web.1]: State changed from down to created
2011-12-21T22:53:47+00:00 heroku[web.1]: State changed from created to starting
...

Change app configuration:

>>> app.config['DEBUG'] = 1
>>> app.config
{u'DEBUG': 1, u'PATH': u'bin:/usr/local/bin:/usr/bin:/bin', u'PYTHONUNBUFFERED': True}

>>> del app.config['DEBUG']

See release history:

>>> app.releases
[<release 'v1'>, <release 'v2'>, ..., <release 'v84'>]


>>> release = app.releases[-2]
>>> release.name
v84

>>> release.env
{u'PATH': u'bin:/usr/local/bin:/usr/bin:/bin', u'PYTHONUNBUFFERED': True}

>>> release.pstable
{u'web': u'gunicorn httpbin:app -b "0.0.0.0:$PORT"'}

>>> release.addons
[u'blitz:250', u'custom_domains:basic', u'logging:basic', u'releases:advanced']

>>> release.rollback()
<release 'v85'>

Create a new app:

>>> cloud.apps.add('myapp')
<app 'myapp'>

Delete the app completely:

>>> app.destroy()
True

And much more. Detailed docs forthcoming.

Customized Sessions

Heroku.py is powered by Requests and supports all customized sessions:

For example advanced logging for easier debugging:

>>> import sys
>>> import requests
>>> from heroku.api import Heroku

>>> my_config = {'verbose': sys.stderr}
>>> session = requests.session(config=my_config)
>>> cloud = Heroku(session=session)
>>> cloud.authenticate(cloud.request_key('[email protected]', 'xxxxxxx'))
>>> cloud.apps
2011-12-21T22:53:47+00:00   GET   https://api.heroku.com/apps
[<app 'myapp'>]

Installation

To install heroku.py, simply:

$ pip install heroku

Or, if you absolutely must:

$ easy_install heroku

But, you really shouldn't do that.

License

Copyright (c) 2013 Heroku, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

heroku.py's People

Contributors

alexwlchan avatar daveschaefer avatar entequak avatar johtso avatar kennethreitz avatar kristianoellegaard avatar ojii avatar rhyselsmore avatar scottpersinger avatar skoczen avatar sookasa-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

heroku.py's Issues

New release?

Hi there,

Isn't it about time for a new release? There are a few fixes in there more than 8 months old, that everyone would benefit from. I believe #16 and #11 are closed using the latest checkout on master.

Kind regards,

Kristian

Always getting an KeyError when trying to scale down to 0 workers

Hi,

I'm currently trying to scale back to 0 workers after im finished with my task. As the task is run maybe only several times a month.

So what I'm trying to do is the following:

  1. Start the celery worker with scale(1)
  2. Delay the celery task to be executed by the celeryworker
  3. Stop the celeryworker with scale(0) (I currently do this in the celery task at the end of the celery task)

I did some testing in the django shell but noticed that even there it is not working how i want it to work.
It always returns an key error as soon as the worker is scaled down, as you can see it even returns an key error as result when i call scale(0) on the worker process. Am I using the api in the wrong way?

See below shell log:


In [38]: app.processes['celeryd'].scale(1)
Out[38]: [<process 'celeryd.1'>]

In [39]: app.processes['celeryd'].scale(0)
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/<ipython-input-39-6ae980b2874f> in <module>()
----> 1 app.processes['celeryd'].scale(0)

heroku/structures.pyc in scale(self, quantity)
     93 
     94     def scale(self, quantity):
---> 95         return self[0].scale(quantity)
     96 
     97 

eroku/models.pyc in scale(self, quantity)
    541         r.raise_for_status()
    542 
--> 543         return self.app.processes[self.type]
    544 
    545 

thon2.7/site-packages/heroku/structures.pyc in __getitem__(self, key)
     82                 return ProcessTypeListResource(items=c)
     83             else:
---> 84                 raise why
     85 
     86 

KeyError: u'celeryd'

In [40]: app.processes['celeryd'].scale(1)
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
python-input-40-5c5022e042ff> in <module>()
----> 1 app.processes['celeryd'].scale(1)

.7/site-packages/heroku/structures.pyc in __getitem__(self, key)
     82                 return ProcessTypeListResource(items=c)
     83             else:
---> 84                 raise why
     85 
     86 

KeyError: 'celeryd'

Can't Create Add New Addons If None Exist

If you've got an application, and it currently has no addons, eg:

>>> app.addons
[]

You're unable to add any new addons until at least one exists:

>>> new_addon = app.addons.add('heroku-postgresql:dev')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/rdegges/.virtualenvs/postgresly/local/lib/python2.7/site-packages/heroku/structures.py", line 50, in add
    return o.new(*args, **kwargs)
  File "/home/rdegges/.virtualenvs/postgresly/local/lib/python2.7/site-packages/heroku/models.py", line 126, in new
    resource=('apps', self.app.name, 'addons', name)
AttributeError: 'Addon' object has no attribute 'app'

So, the workaround (currently) is to add an addon manually using some other method (eg: the CLI tool), and then everything works as expected.

Support requests >= 1.0

Because of API changes from requests 0.14.2 to 1.0.0, this project currently requires requests < 1.0. This may be a trap for people installing heroku.py via pip. An upgrade to requests 1.1.0 would be much appreciated ;-)

Support scaling processes 0 to n

#14 made it possible to scale processes from 0 to any quantity, but #29 removed this feature. Currently, we can do this by the following hack (assuming there is no worker process running for myapp):

import heroku
from heroku.models import Process
h = heroku.from_key(...)
app = h.apps['myapp']
Process.new_from_dict({'process': 'worker'}, h, app=app).scale(10)

But it would be best to be supported officially.

This package has been sunset

This project has been deprecated for some time, and is now being sunset since the published version currently doesn't work with Python 3 or newer versions of requests.

We recommend that you use the maintained https://github.com/martyzz1/heroku3.py instead.

If you really need to continue to use this library, you will need to specify an explicit version in your pip requirements file (such as heroku==0.1.4 ) or else use the GitHub repository version (using a requirement specifier of git+https://github.com/heroku/heroku.py.git).

No longer functions

I'm trying to automate some of our app management overhead by writing scripts that utilize heroku's Rest API via Python. The package I'm referring to can be found at:
http://pypi.python.org/pypi/heroku/0.1.2

The first part of the tutorial works, whether using password or API key:

import heroku
cloud = heroku.from_pass('[email protected]', 'xxxxxxx')`

or

cloud = heroku.from_key('YOUR_API_KEY')

However, when I run

cloud.apps

I get an empty list []

I submitted this issue to Heroku and they said to create a GitHub issue.

Python 3 support

Does this library officially support Python 3?

If so, it would be nice to designate that on PyPI using classifiers in setup.py (I see that 3.0 and 3.1 are commented out in github, and PyPI lists 3.1 and 3.2, which is confusing...).

If not, what does the path forward look like?

Process.scale() always returns an empty list

This is due to the following code at the end of Process.scale():

if self.type in self.app.processes:
    return self.app.processes[self.type]
else:
    return ProcessListResource()

Here the test always fails because __contains__ is not defined for ProcessListResource and every Process is different from self.type because there is no __eq__ in Process.

The correct implementation would be using try-except block:

try:
    return self.app.processes[self.type]
except KeyError:
    return ProcessListResource()

Should the server or client deal with invalid scaling requests?

There are two cases that could probably be patched and prevented:

  1. Try to create 0 or fewer processes of a new type
    e.g. app.processes.add('web', 0)
  2. Try to scale to a number of dynos that's not an integer (whether that process type is currently running or not)
    e.g. app.processes['web'].scale('aaa')

The Heroku Toolbelt prevents these from happening, so I'm guessing you guys like to prevent this behaviour :) However, both of these calls currently throw a KeyError:

File "/app/.heroku/venv/lib/python2.7/site-packages/heroku/structures.py", line 55, in add
    return self[0].new(*args, **kwargs)
  File "/app/.heroku/venv/lib/python2.7/site-packages/heroku/models.py", line 515, in new
    return self.app.processes[type]
  File "/app/.heroku/venv/lib/python2.7/site-packages/heroku/structures.py", line 106, in __getitem__
    raise why
KeyError: 'web'

Now we could add code inside Process.scale() and Process.new() to check for non-integers and quantities < 1. However it seems like The Heroku Way in this module is to try taking actions and raise errors if they don't work? Also on the HEAD branch if we try to scale a process to a number of dynos that's < 1 we get this response from the server:

File "/app/.heroku/venv/lib/python2.7/site-packages/heroku/structures.py", line 46, in add
return self[0].new(_args, *_kwargs)
File "/app/.heroku/venv/lib/python2.7/site-packages/heroku/models.py", line 505, in new
data={'type': type, 'qty': quantity}
File "/app/.heroku/venv/lib/python2.7/site-packages/heroku/api.py", line 103,in _http_resource
raise http_error
requests.exceptions.HTTPError: 422 Client Error: {"error":"Cannot scale to fewer than 0 dynos per process type."}

So perhaps you'd prefer to write server code to deal with these situations instead, which will then get caught by the calls to r.raise_for_status() in both Process.new() and Process.scale()

Let me know! :)

Add Process example

Hey,

Can you add a Process example to the readme? I believe that class is used for doing one off executions. If that's not what its for, what is the equivalent of a heroku run with this wrapper?

unexpected keyword argument 'session'

The readme says:

cloud = Heroku(session=session)

When I try this, I get:

Traceback (most recent call last):
  File "./merge", line 18, in <module>
    cloud = Heroku(session=session)
TypeError: __init__() got an unexpected keyword argument 'session'

Logs with tail=True hangs after about 100 entries

with the following requirements.txt:

requests==0.14.2
git+git://github.com/heroku/heroku.py.git

(note had to peg requests to get r = requests.get(r.content, verify=False, prefetch=False) to work)

and the following snipit:

 for line in self.app.logs(tail=True):
 print line

the script will print about 100 lines, then hang.

Any ideas on what I am doing wrong?

Thanks!

Heroku.from_key is silently overridden by .netrc

Reproduce Steps

Login using Heroku CLI as user1

gabriel@delta:~$ heroku login
Enter your Heroku credentials.
Email: [email protected]
Password (typing will be hidden): 
Authentication successful.

~/.netrc file is updated per usual.

Use Heroku.py to instantiate a session as user2

>>> h=heroku.from_key('key-for-user2')
>>> h.keys
[<key '[email protected]'>]

D'oh it's using a session from user1 via .netrc even though we provided user2's key.

Worst part is it doesn't warn you. It just silently proceeds as the wrong user.

Process types with 0 running instances cause KeyError

Say I have a pretty standard procfile declaring a "web" and a "worker" process. The default state for my app is to have a single web dyno running, and no workers running, using heroku.py to file up workers on demand.

However, when 0 workers are running,

app.processes['worker'].scale(0)

causes KeyError. In other words the process map only contains information about currently running dynos regardless of the contents of the procfile, making it impossible to automate the transition from 0 to 1 workers.

cloud.apps do not work because the url https://api.heroku.com/apps is deprecated

cloud.apps do not work because the url https://api.heroku.com/apps is deprecated since yesterday. Instead show the exception: "requests.exceptions.HTTPError: 410 Client Error: Gone for url: https://api.heroku.com/apps"

Is possible to have a resolution for this issue?

Thank you.

Possible reason of the issue occurrence:
https://devcenter.heroku.com/changelog-items/1147
“Legacy Platform API Brownouts start May 24th
(...) final shutdown Monday, June 26th.
Please see our original deprecation announcement for further details and our status site for upcoming brownout dates and times.”

Why it was discontinued?

Heroku is such a nice platform and having a Python wrapper around its API just makes it more awesome...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.