简体   繁体   中英

Set Bluemix VCAP_SERVICES environment variable locally so that I can develop locally?

I am trying to set my Bluemix VCAP_SERVICES environment variable locally, but I'm getting this error in the terminal:

NoSQL: command not found

Steps to reproduce

  1. Login to Bluemix.net
  2. Deploy a hello world flask application
  3. Bind a Bluemix Cloudant Service to the application
  4. Copy the VCAP_SERVICES Environment Variables from the Runtime / Environment Variables on the application for Python
  5. In local editor remove all the line breaks on Mac terminal
  6. vi ~/.bash_profile
  7. Enter insert mode with i
  8. paste in VCAPSERVICES , mine looks like this:

     VCAP_SERVICES="{"VCAP_SERVICES":{"cloudantNoSQLDB": [{"credentials": {"host": "fakehostc-bluemix.cloudant.com","password":"fakepassword4da6de3a12a83362b26a","port": 443,"url": "https://fakeURLc-bluemix:fakeab96175c-bluemix.cloudant.com","username": "fakeusername-b749-399cfbd1175c-bluemix"},"label":"cloudantNoSQLDB","name":"Cloudant NoSQL DB-p2","plan":"Lite","provider":null,"syslog_drain_url":null,"tags":["data_management","ibm_created","ibm_dedicated_public"]}]}}" export VCAP_SERVICES 
  9. Save the file and quit vi with :wq!

  10. Source the modified file with . ~/.bash_profile . ~/.bash_profile to set the terminal window with the new VCAP Environment Variable

What am I doing wrong copying and setting my local Bluemix VCAP_Services Environment Variable?

If I copy the whole thing I get errors that the line is too long. How can I easily copy and paste the entire Bluemix Python Runtime VCAP_SERVICES Variable into my local Mac .bash_profile environment settings without manually massaging JSON and all these line breaks etc?

I don't want to use a local file to store those since it isn't very secure as I move from dev, test, staging and production.

I figured out the answer use single quotes at the beginning and end of VCAP_SERVICES

VCAP_SERVICES='{"cloudantNoSQLDB": [{"credentials": {"host": "fakehostc-bluemix.cloudant.com","password":"fakepassword4da6de3a12a83362b26a","port": 443,"url": " https://fakeURLc-bluemix:fakeab96175c-bluemix.cloudant.com ","username": "fakeusername-b749-399cfbd1175c-bluemix"},"label":"cloudantNoSQLDB","name":"Cloudant NoSQL DB-p2","plan":"Lite","provider":null,"syslog_drain_url":null,"tags":["data_management","ibm_created","ibm_dedicated_public"]}]}'

Here is the corresponding code to retrieve VCAP Services environment variables and do basic operations on Cloudant:

# 1. Parse VCAP_SERVICES Variable and connect to DB         
vcap = json.loads(os.getenv("VCAP_SERVICES"))['cloudantNoSQLDB']        
serviceUsername = vcap[0]['credentials']['username']
servicePassword = vcap[0]['credentials']['password']    
serviceURL = vcap[0]['credentials']['url']

# Create Cloudant DB connection
# This is the name of the database we are working with.
databaseName = "databasedemo"

# This is a simple collection of data,
# to store within the database.
sampleData = [
    [1, "one", "boiling", 100],
    [2, "two", "hot", 40],
    [3, "three", "warm", 20],
    [4, "four", "cold", 10],
    [5, "five", "freezing", 0]
]

# Use the Cloudant library to create a Cloudant client.
client = Cloudant(serviceUsername, servicePassword, url=serviceURL)

# Connect to the server
client.connect()

# 2.  Creating a database within the service instance.

# Create an instance of the database.
myDatabaseDemo = client.create_database(databaseName)

# Check that the database now exists.
if myDatabaseDemo.exists():
    print "'{0}' successfully created.\n".format(databaseName)

# 3.  Storing a small collection of data as documents within the database.

# Create documents using the sample data.
# Go through each row in the array
for document in sampleData:
    # Retrieve the fields in each row.
    number = document[0]
    name = document[1]
    description = document[2]
    temperature = document[3]

    # Create a JSON document that represents
    # all the data in the row.
    jsonDocument = {
        "numberField": number,
        "nameField": name,
        "descriptionField": description,
        "temperatureField": temperature
    }

    # Create a document using the Database API.
    newDocument = myDatabaseDemo.create_document(jsonDocument)

    # Check that the document exists in the database.
    if newDocument.exists():
        print "Document '{0}' successfully created.".format(number)

# 4.  Retrieving a complete list of the documents.

# Simple and minimal retrieval of the first
# document in the database.
result_collection = Result(myDatabaseDemo.all_docs)
print "Retrieved minimal document:\n{0}\n".format(result_collection[0])

# Simple and full retrieval of the first
# document in the database.
result_collection = Result(myDatabaseDemo.all_docs, include_docs=True)
print "Retrieved full document:\n{0}\n".format(result_collection[0])

# Use a Cloudant API endpoint to retrieve
# all the documents in the database,
# including their content.

# Define the end point and parameters
end_point = '{0}/{1}'.format(serviceURL, databaseName + "/_all_docs")
params = {'include_docs': 'true'}

# Issue the request
response = client.r_session.get(end_point, params=params)

# Display the response content
print "{0}\n".format(response.json())

# 5.  Deleting the database.

# Delete the test database.
try :
    client.delete_database(databaseName)
except CloudantException:
    print "There was a problem deleting '{0}'.\n".format(databaseName)
else:
    print "'{0}' successfully deleted.\n".format(databaseName)

# 6.  Closing the connection to the service instance.

# Disconnect from the server
client.disconnect()

It's an anti-pattern to create the VCAP_SERVICES env variable locally. I suggest just using the connecting info when running locally.

Option 1

if 'VCAP_SERVICES' in os.environ:
    services = json.loads(os.getenv('VCAP_SERVICES'))
    cloudant_url = services['cloudantNoSQLDB'][0]['credentials']['url']
else:
    cloudant_url = "https://fakeURLc-bluemix:fakeab96175c-bluemix.cloudant.com"

Option 2

If you don't want to hardcode credentials into your code, then you can create a .env file:

export LOCAL_CLOUDANT_URL=https://fakeURLc-bluemix:fakeab96175c-bluemix.cloudant.com

and in your python code:

if 'VCAP_SERVICES' in os.environ:
    services = json.loads(os.getenv('VCAP_SERVICES'))
    cloudant_url = services['cloudantNoSQLDB'][0]['credentials']['url']
else:
    cloudant_url = os.environ['LOCAL_CLOUDANT_URL']

and then source .env before you run your application.

Be sure to add .env to .gitignore and .cfignore

There is a cf CLI plugin that will get VCAP_SERVICES from your app and help you set it locally. I've used it on my Mac and didn't have to adjust the quotes at all.

Checkout https://github.com/jthomas/copyenv

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM