Comments (24)
The call needs to be with cloudant
not with Cloudant
. cloudant
is the name of the context manager defined in the init.py. Cloudant
is the name of the Cloudant
client in the account module. See https://github.com/cloudant/python-cloudant/blob/master/src/cloudant/__init__.py#L24 and http://python-cloudant.readthedocs.org/en/latest/cloudant.html#cloudant.cloudant
from python-cloudant.
Are you looking for share_database, unshare_database?
from python-cloudant.
No, that's sharing databases with another Cloudant user. The idea is to create an API key using generate_api_key() and then assign permissions to a specific database, or give the API key permission to create a new database itself. Particularly helpful for temporal, per-user, or per-device database use cases.
from python-cloudant.
I may be misunderstanding what you are looking for but you can use share_database from the database module (It uses the /_api/v2/db/$DB/_security endpoint) and pass it the API Key as the username and then set permissions for reader
, writer
, admin
and this would grant permissions to a specific database for that API key. As for giving permission to create databases, what endpoint would that be?
from python-cloudant.
Also a little confused on your first question re: the base64 auth token. Are you looking to do basic authentication or are you looking to base64.urlsafe_b64encode
your passcode and authenticate using the encoded value? Can you provide a curl statement that gives an example of what you mean here? That might help me uderstand a bit better.
from python-cloudant.
Basically, there are two things I'm trying to here, yes, so I'll separate them out and describe with examples.
Number one is to increase the security profile for a script which is meant to run via cron and utilize Cloudant as its database. Having it run as a script without a security gateway means that (like any local program that utilizes a cloud resource) it will have to store its authentication data somewhere. I'd prefer to store the configuration file using hashed credentials so they can't be human-read.
An example using curl would be: curl -s --proto '=https' -g -H 'Authorization: Basic <BASE64HASHOFUSERPASSWORDCREDS>'�
This is easy to do with the python requests library with code such as:
import requests
response = requests.get(
url="https://bradwbonn.cloudant.com/_all_dbs",
headers = {"Content-Type": "application/json", "Authorization": "Basic <BASE64HASHOFUSERPASSWORDCREDS>"}
)
print r.json()
Number two is to use API keys as the stored credentials instead of a Cloudant username, but now I'm thinking this may be moot. I'm planning to use a rolling database model, which means whatever stored credentials are used will need to be able to create and delete databases, and I'm fairly certain API keys only exist on a per-database basis. It's good to know that share_database() can interact with the _security endpoint though.
from python-cloudant.
Thanks for the clarification. Currently we are set up for cookie authentication only when using the connect(...)
method on a client. But fortunately with Python there is usually a workaround. For this case the work around to use Basic authentication you basically would need to "roll your own" connection routine as in the following:
from cloudant import Cloudant
import requests
# Construct a client object but don't provide it with your password.
# However, the password (auth_token) argument must be set to something.
client = Cloudant('bradwbonn', 'not-giving-you-my-password', account='bradwbonn')
# Roll your own connect() routine...
client.r_session = requests.Session()
client.r_session.headers.update({'Authorization': 'Basic <BASE64HASHOFUSERPASSWORDCREDS>'})
client._cloudant_session = client.session()
# Done ...
Unfortunately, you cannot use the Cloudant with context manager using this work around as in your original example. Also, if you were using the url
kwarg along with the x_cloudant_user
kwarg you would need to account for an additional User-Agent
header but you get the gist...
I hope that works out for you.
I'll open a new "Enhancement" Issue for adding Basic authentication and reference this one.
from python-cloudant.
For added context: take a look at client.connect() to see what exactly you would be overriding. Hopefully seeing that would add a bit more context around the proposed the work around.
from python-cloudant.
Now that I've had more time to think about it, there's no reason why you could not create your own context manager to replicate what the cloudant context manager does and then you could do all this via with as well. ref: https://github.com/cloudant/python-cloudant/blob/master/src/cloudant/__init__.py#L59
I hope some of this helps you along... I'll stop beating this horse now. :)
from python-cloudant.
This is really helpful, thank you! I've actually never extended a library in Python before, so this will end up being yet another learning experience for me. ;)
from python-cloudant.
In your example above: client._cloudant_session = c.session()
I'm not sure I understand what the c refers to. Is it supposed to be client.session()
?
from python-cloudant.
not much luck using
from cloudant import Cloudant
import requests
# Construct a client object but don't provide it with your password.
# However, the password (auth_token) argument must be set to something.
client = Cloudant(USERNAME, PASSWORD, account=USERNAME)
Error using Python 3 notebook is after a !pip install --pre cloudant
NameError Traceback (most recent call last)
in ()
----> 1 from cloudant import Cloudant
2 import requests
3
4 # Construct a client object but don't provide it with your password.
5 # However, the password (auth_token) argument must be set to something.
/opt/conda/lib/python3.4/site-packages/cloudant/init.py in ()
20 import contextlib
21
---> 22 from .account import Cloudant, CouchDB
23
24 @contextlib.contextmanager
/opt/conda/lib/python3.4/site-packages/cloudant/account.py in ()
23 import sys
24
---> 25 from .database import CloudantDatabase, CouchDatabase
26 from .changes import Feed
27 from .errors import CloudantException
/opt/conda/lib/python3.4/site-packages/cloudant/database.py in ()
23
24 from .document import Document
---> 25 from .design_document import DesignDocument
26 from .views import View
27 from .errors import CloudantException
/opt/conda/lib/python3.4/site-packages/cloudant/design_document.py in ()
17 """
18 from .document import Document
---> 19 from .views import View
20 from .errors import CloudantArgumentError
21
/opt/conda/lib/python3.4/site-packages/cloudant/views.py in ()
19 import posixpath
20
---> 21 from .result import Result, python_to_couch
22
23 class Code(str):
/opt/conda/lib/python3.4/site-packages/cloudant/result.py in ()
24 ARG_TYPES = {
25 "descending": bool,
---> 26 "endkey": (basestring, Sequence),
27 "endkey_docid": basestring,
28 "group": bool,
NameError: name 'basestring' is not defined
from python-cloudant.
Ideally, I would like to avoid UID/PW credentials and leverage this type of approach for Cloudant:
import couchdb
couch = couchdb.Server("https://%s.cloudant.com" % USERNAME)
couch.resource.credentials = (USERNAME, auth=(API_KEY, API_SECRET))
Any plans for enabling this approach?
from python-cloudant.
There appear to be a few questions and misconceptions here around API keys and security.
base64
Firstly, @bradwbonn remember base64 doesn't make any difference to security. I suggest storing the plain credentials, because it's easier for others and your future self to understand what the security properties of the script are (if the server's insecure, you've bigger issues anyway :) )
I think this negates the need for accessing the authorization header in your case; but clearly it could be useful for other scenarios, such as authenticating against a proxy server rather than Cloudant itself. I think our workaround works for now, but I do quite like @vinomaster's suggestion -- though it appears requests
-specific (though I can't imagine changing!).
Setting permissions
To set the security on a database from an API key and password, you'll need to set up the _security
document. However, looks like you can't do that yet from issue #52.
Using API keys with python-cloudant
@vinomaster I think your question is around using API keys; let me know if I misunderstood, there's a bunch of issues here :)
To use an API key and password, it's important to note that they are just username and password pairs, so you use them as follows (feel free to try it as-is, the key is a valid read key for that db at least for the next few days):
USERNAME = "bouninamendouldnimendepa"
PASSWORD = "e6fda548ce40d21ae675d03068bb0f913f2d99f1"
ACCOUNT_NAME = "mikerhodes"
DATABASE_NAME = "animaldb"
DOC_NAME = "badger"
from cloudant.account import Cloudant
client = Cloudant(USERNAME, PASSWORD, account=ACCOUNT_NAME)
# Connect to the account and establish a session cookie
client.connect()
session = client.session()
database = client[DATABASE_NAME]
document = database[DOC_NAME]
print "Got document: ", document
client.disconnect()
As @bradwbonn said, this appears to not be working with the context manager, that is, this fails:
# With context manager
with Cloudant(USERNAME, PASSWORD, account=ACCOUNT_NAME) as client:
session = client.session()
database = client[DATABASE_NAME]
document = database[DOC_NAME]
print "Got document from context manager: ", document
I filed this as issue #53.
from python-cloudant.
@bradwbonn, I'm not sure where we are at with this conversation. Apparently a lot has happened while I was sleeping. I'll be sure never to sleep again :). But yes you found a typo in #49 (comment). The line in question should read client._cloudant_session = client.session()
. I apologize for that, in my testing I was using c
as the client but wanted to make it more readible in my comments to you so I changed it to client
. Unfortunately I did not change it everywhere.
from python-cloudant.
@vinomaster, this library is not yet supported in Python3. See http://python-cloudant.readthedocs.org/en/latest/compatibility.html. The problem you are seeing is because of the use of basestring
which was removed in Python3. We have plans to make the library Python3 compatible in the near future. See #23.
from python-cloudant.
Below is a summary of "where we are" with this issue, since it seems that we have diverged in a few directions.
@bradwbonn, setting permissions can be done for users as well as API keys by using the database module's share_database
and unshare_database
methods. On the topic of using Basic authentication with this library, you can still follow the work around that I presented but I think I was negligent before in not stating that extending the library is done at your risk. On a somewhat related note, relating to the work around that I presented: I am sure that you are aware that the _
prefix in Python denotes a "private" variable so it is not best practice to access these variables. However in Python you can pretty much do what you want so there are no mechanisms in place to keep you from doing so. I guess the point that I am trying to make here is keep letting us know about gaps in functionality. This will help us bridge those gaps but any work around should be treated as an exception rather than normal practice.
@vinomaster, the problem you are experiencing is simple. This library has not yet been scrubbed to be used with Python3. Unfortunately, I'm not sure that will help you much. Sorry for that.
@mikerhodes, on the topic of the main context manager, I believe the problem you encountered was simply a spelling mistake. Cloudant
should have been cloudant
. So I am pretty sure we can close #53. As far as the _security
document goes, database level security is currently managed via the share_database
and unshare_database
methods found in the database module as I mentioned earlier. So we have means to update the security document. We can use #52 to add functionality that will allow us to manipulate the _security
document directly since it seems as though this is a requirement now.
A lot of this along with other good stuff can be found in our docs.
from python-cloudant.
This whole conversation has been super-insightful, thank you!
from python-cloudant.
@bradwbonn: I have an update on the whole setting of permissions question. See #52 (comment)
from python-cloudant.
So to summarize:
- The
python-cloudant
is not yet supported on Python 3. This should be in-your-face on the readme. - We are using Cloudant on Bluemix which does support API Keys. I seek only an simple pythonic way to authenticate to a db using an API key. Based on this thread, it seems this functionality is available but it is not intuitive that APIKey and USERNAME can be interchanged. Maybe two simple constructors would be more intuitive: UID/PW credentials, APIKey/Passcode credentials.
Remaining questions:
- When will Python3 support be available?
from python-cloudant.
So after further testing... using Python 2 under Project Jupyter we are unable to pip install Cloudant.
!pip install --pre cloudant
Collecting cloudant
Retrying (Retry(total=4, connect=None, read=None, redirect=None)) after connection broken by 'ProtocolError('Connection aborted.', gaierror(-2, 'Name or service not known'))': /simple/cloudant/
To be clear this Python 2 kernel functionality is provided via conda
!python --version
Python 3.4.3 :: Continuum Analytics, Inc.
To test try here.
At this juncture, until Python3 support it seems Project Jupyter integration with Cloudant is a non-starter.
from python-cloudant.
@vinomaster Could you file a separate bug for Project Jupyter support? This bug is overloaded.
from python-cloudant.
@vinomaster, I've moved your issue with the pip install on Project Jupyter to #54.
from python-cloudant.
I think that all issues here have been either answered or moved off to their own separate issue.
from python-cloudant.
Related Issues (20)
- connection to couchdb server via ipv6 address does not work HOT 2
- cloudant/_common_util.py:22: DeprecationWarning: Using or importing the ABCs from 'collections' HOT 2
- Intermittent follow_replication test failure HOT 1
- create_database from CloudDB could silence some errors HOT 3
- Creating a Design Doc with partitioned = false still creates design doc with partitioned enabled HOT 4
- create_query_index() failing on unpartitioned CouchDB database with message invalid_partitioned_option HOT 2
- Support for configuring number of shards and replicas for a couch database HOT 3
- use_index param in get_query_result and get_partitioned_query_result does not support list data HOT 3
- Could not install package via pip HOT 2
- Need help with couchDb replication to do the below use case in the best possible way HOT 2
- A few questions HOT 1
- Allow IAM token URL to be passed as an argument to Cloudant.iam HOT 4
- Backing up HOT 1
- ConnectionResetError: [Errno 104] Connection reset by peer HOT 9
- How can I get revisions? | How to get data back by using id and revision code? HOT 2
- Querying a view with a boolean type key raises a CloudantArgumentError HOT 2
- Some how I am getting a weakreference HOT 1
- Datetime object HOT 3
- Error 403 when trying to access couchDB server that uses SSL certificate. HOT 5
- Getting HTTPError instead of KeyError HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from python-cloudant.