diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index af5083c2..2027062b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,33 +1,49 @@ -Contributing ------------- +# Contributing to the LaunchDarkly Server-side SDK for Python -We encourage pull-requests and other contributions from the community. We've also published an [SDK contributor's guide](http://docs.launchdarkly.com/docs/sdk-contributors-guide) that provides a detailed explanation of how our SDKs work. +LaunchDarkly has published an [SDK contributor's guide](https://docs.launchdarkly.com/docs/sdk-contributors-guide) that provides a detailed explanation of how our SDKs work. See below for additional information on how to contribute to this SDK. -Development information (for developing this module itself) ------------------------------------------------------------ +## Submitting bug reports and feature requests + +The LaunchDarkly SDK team monitors the [issue tracker](https://github.com/launchdarkly/python-server-sdk/issues) in the SDK repository. Bug reports and feature requests specific to this SDK should be filed in this issue tracker. The SDK team will respond to all newly filed issues within two business days. -1. One-time setup: +## Submitting pull requests + +We encourage pull requests and other contributions from the community. Before submitting pull requests, ensure that all temporary or unintended code is removed. Don't worry about adding reviewers to the pull request; the LaunchDarkly SDK team will add themselves. The SDK team will acknowledge all pull requests within two business days. - mkvirtualenv python-client +## Build instructions -1. When working on the project be sure to activate the python-client virtualenv using the technique of your choosing. +### Setup -1. Install requirements (run-time & test): +It's advisable to use [`virtualenv`](https://virtualenv.pypa.io/) to create a development environment within the project directory: - pip install -r requirements.txt - pip install -r test-requirements.txt +``` +mkvirtualenv python-client +source ./python-client/bin/activate +``` -1. When running unit tests, in order for `test_feature_store.py` to run, you'll need all of the supported databases (Redis, Consul, DynamoDB) running locally on their default ports. +To install the runtime and test requirements: -1. If you want integration tests to run, set the ```LD_SDK_KEY``` environment variable to a valid production SDK Key. +``` +pip install -r requirements.txt +pip install -r test-requirements.txt +``` -1. ```$ py.test testing``` +The additional requirements files `consul-requirements.txt`, `dynamodb-requirements.txt`, `redis-requirements.txt`, and `test-filesource-optional-requirements.txt` can also be installed if you need to test the corresponding features. -1. All code must be compatible with all supported Python versions as described in README. Most portability issues are addressed by using the `six` package. We are avoiding the use of `__future__` imports, since they can easily be omitted by mistake causing code in one file to behave differently from another; instead, whenever possible, use an explicit approach that makes it clear what the desired behavior is in all Python versions (e.g. if you want to do floor division, use `//`; if you want to divide as floats, explicitly cast to floats). +### Testing -Developing with different Python versions ------------------------------------------ +To run all unit tests: -Example for switching to Python 3: +``` +pytest +``` -```virtualenv -p `which python3` ~/.virtualenvs/python-client``` \ No newline at end of file +By default, the full unit test suite includes live tests of the integrations for Consul, DynamoDB, and Redis. Those tests expect you to have instances of all of those databases running locally. To skip them, set the environment variable `LD_SKIP_DATABASE_TESTS=1` before running the tests. + +There are also integration tests that can be run against the LaunchDarkly service. To enable them, set the environment variable `LD_SDK_KEY` to a valid production SDK Key. + +### Portability + +Most portability issues are addressed by using the `six` package. We are avoiding the use of `__future__` imports, since they can easily be omitted by mistake causing code in one file to behave differently from another; instead, whenever possible, use an explicit approach that makes it clear what the desired behavior is in all Python versions (e.g. if you want to do floor division, use `//`; if you want to divide as floats, explicitly cast to floats). + +It is preferable to run tests against all supported minor versions of Python (as described in `README.md` under Requirements), or at least the lowest and highest versions, prior to submitting a pull request. However, LaunchDarkly's CI tests will run automatically against all supported versions. diff --git a/README.md b/README.md index 6013179f..be38186a 100644 --- a/README.md +++ b/README.md @@ -1,138 +1,49 @@ -LaunchDarkly SDK for Python -=========================== +# LaunchDarkly Server-side SDK for Python -[![Circle CI](https://img.shields.io/circleci/project/launchdarkly/python-client.png)](https://circleci.com/gh/launchdarkly/python-client) - -[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Flaunchdarkly%2Fpython-client.svg?type=shield)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Flaunchdarkly%2Fpython-client?ref=badge_shield) +[![Circle CI](https://img.shields.io/circleci/project/launchdarkly/python-server-sdk.png)](https://circleci.com/gh/launchdarkly/python-server-sdk) [![PyPI](https://img.shields.io/pypi/v/ldclient-py.svg?maxAge=2592000)](https://pypi.python.org/pypi/ldclient-py) [![PyPI](https://img.shields.io/pypi/pyversions/ldclient-py.svg)](https://pypi.python.org/pypi/ldclient-py) -[![Twitter Follow](https://img.shields.io/twitter/follow/launchdarkly.svg?style=social&label=Follow&maxAge=2592000)](https://twitter.com/intent/follow?screen_name=launchdarkly) - -Supported Python versions -------------------------- - -This version of the LaunchDarkly SDK is compatible with Python 2.7, and Python 3.3 through 3.7. - -Quick setup ------------ - -1. Install the Python SDK with `pip` - - pip install ldclient-py - -2. Configure the library with your sdk key: - - import ldclient - -3. Get the client: - - ldclient.set_sdk_key("your sdk key") - client = ldclient.get() - - -HTTPS proxy ------------- -Python's standard HTTP library provides built-in support for the use of a HTTPS proxy. If the HTTPS_PROXY environment variable is present then the SDK will proxy all network requests through the URL provided. +## LaunchDarkly overview -How to set the HTTPS_PROXY environment variable on Mac/Linux systems: -``` -export HTTPS_PROXY=https://web-proxy.domain.com:8080 -``` - - -How to set the HTTPS_PROXY environment variable on Windows systems: -``` -set HTTPS_PROXY=https://web-proxy.domain.com:8080 -``` - -Or it can be set from within python: -``` -os.environ["https_proxy"] = "https://web-proxy.domain.com:8080" -``` - -If your proxy requires authentication then you can prefix the URN with your login information: -``` -export HTTPS_PROXY=http://user:pass@web-proxy.domain.com:8080 -``` -or -``` -set HTTPS_PROXY=http://user:pass@web-proxy.domain.com:8080 -``` - - -Your first feature flag ------------------------ - -1. Create a new feature flag on your [dashboard](https://app.launchdarkly.com) -2. In your application code, use the feature's key to check whether the flag is on for each user: - - if client.variation("your.flag.key", {"key": "user@test.com"}, False): - # application code to show the feature - else: - # the code to run if the feature is off - -Supported Python versions -------------------------- - -The SDK is tested with the most recent patch releases of Python 2.7, 3.3, 3.4, 3.5, and 3.6. Python 2.6 is no longer supported. - -Database integrations ---------------------- +[LaunchDarkly](https://www.launchdarkly.com) is a feature management platform that serves over 100 billion feature flags daily to help teams build better software, faster. [Get started](https://docs.launchdarkly.com/docs/getting-started) using LaunchDarkly today! + +[![Twitter Follow](https://img.shields.io/twitter/follow/launchdarkly.svg?style=social&label=Follow&maxAge=2592000)](https://twitter.com/intent/follow?screen_name=launchdarkly) -Feature flag data can be kept in a persistent store using Consul, DynamoDB, or Redis. These adapters are implemented in the `Consul`, `DynamoDB` and `Redis` classes in `ldclient.integrations`; to use them, call the `new_feature_store` method in the appropriate class, and put the returned object in the `feature_store` property of your client configuration. See [`ldclient.integrations`](https://launchdarkly-python-sdk.readthedocs.io/en/latest/api-integrations.html#module-ldclient.integrations) and the [SDK reference guide](https://docs.launchdarkly.com/v2.0/docs/using-a-persistent-feature-store) for more information. +## Supported Python versions -Note that Consul is not supported in Python 3.3 or 3.4. +This version of the LaunchDarkly SDK is compatible with Python 2.7 and 3.3 through 3.7. It is tested with the most recent patch releases of those versions. Python 2.6 is no longer supported. -Using flag data from a file ---------------------------- +## Getting started -For testing purposes, the SDK can be made to read feature flag state from a file or files instead of connecting to LaunchDarkly. See [`ldclient.integrations.Files`](https://launchdarkly-python-sdk.readthedocs.io/en/latest/api-integrations.html#ldclient.integrations.Files) and the [SDK reference guide](https://docs.launchdarkly.com/v2.0/docs/reading-flags-from-a-file) for more details. +Refer to the [SDK reference guide](https://docs.launchdarkly.com/docs/python-sdk-reference) for instructions on getting started with using the SDK. -Learn more ----------- +## Learn more Check out our [documentation](http://docs.launchdarkly.com) for in-depth instructions on configuring and using LaunchDarkly. You can also head straight to the [complete reference guide for this SDK](http://docs.launchdarkly.com/docs/python-sdk-reference). Generated API documentation is on [readthedocs.io](https://launchdarkly-python-sdk.readthedocs.io/en/latest/). -Testing -------- +## Testing We run integration tests for all our SDKs using a centralized test harness. This approach gives us the ability to test for consistency across SDKs, as well as test networking behavior in a long-running application. These tests cover each method in the SDK, and verify that event sending, flag evaluation, stream reconnection, and other aspects of the SDK all behave correctly. -[![Test Coverage](https://codeclimate.com/github/launchdarkly/python-client/badges/coverage.svg)](https://codeclimate.com/github/launchdarkly/python-client/coverage) The Code Climate coverage does not include the coverage provided by this integration test harness. - -Contributing ------------- +## Contributing -See [CONTRIBUTING](CONTRIBUTING.md) for more information. +We encourage pull requests and other contributions from the community. Check out our [contributing guidelines](CONTRIBUTING.md) for instructions on how to contribute to this SDK. -About LaunchDarkly ------------------- +## About LaunchDarkly * LaunchDarkly is a continuous delivery platform that provides feature flags as a service and allows developers to iterate quickly and safely. We allow you to easily flag your features and manage them from the LaunchDarkly dashboard. With LaunchDarkly, you can: * Roll out a new feature to a subset of your users (like a group of users who opt-in to a beta tester group), gathering feedback and bug reports from real-world use cases. * Gradually roll out a feature to an increasing percentage of users, and track the effect that the feature has on key metrics (for instance, how likely is a user to complete a purchase if they have feature A versus feature B?). * Turn off a feature that you realize is causing performance problems in production, without needing to re-deploy, or even restart the application with a changed configuration file. * Grant access to certain features based on user attributes, like payment plan (eg: users on the ‘gold’ plan get access to more features than users in the ‘silver’ plan). Disable parts of your application to facilitate maintenance, without taking everything offline. -* LaunchDarkly provides feature flag SDKs for - * [Java](http://docs.launchdarkly.com/docs/java-sdk-reference "LaunchDarkly Java SDK") - * [JavaScript](http://docs.launchdarkly.com/docs/js-sdk-reference "LaunchDarkly JavaScript SDK") - * [PHP](http://docs.launchdarkly.com/docs/php-sdk-reference "LaunchDarkly PHP SDK") - * [Python](http://docs.launchdarkly.com/docs/python-sdk-reference "LaunchDarkly Python SDK") - * [Go](http://docs.launchdarkly.com/docs/go-sdk-reference "LaunchDarkly Go SDK") - * [Node.JS](http://docs.launchdarkly.com/docs/node-sdk-reference "LaunchDarkly Node SDK") - * [Electron](http://docs.launchdarkly.com/docs/electron-sdk-reference "LaunchDarkly Electron SDK") - * [.NET](http://docs.launchdarkly.com/docs/dotnet-sdk-reference "LaunchDarkly .Net SDK") - * [Ruby](http://docs.launchdarkly.com/docs/ruby-sdk-reference "LaunchDarkly Ruby SDK") - * [iOS](http://docs.launchdarkly.com/docs/ios-sdk-reference "LaunchDarkly iOS SDK") - * [Android](http://docs.launchdarkly.com/docs/android-sdk-reference "LaunchDarkly Android SDK") - * [C/C++](http://docs.launchdarkly.com/docs/c-sdk-reference "LaunchDarkly C/C++ SDK") +* LaunchDarkly provides feature flag SDKs for a wide variety of languages and technologies. Check out [our documentation](https://docs.launchdarkly.com/docs) for a complete list. * Explore LaunchDarkly - * [launchdarkly.com](http://www.launchdarkly.com/ "LaunchDarkly Main Website") for more information - * [docs.launchdarkly.com](http://docs.launchdarkly.com/ "LaunchDarkly Documentation") for our documentation and SDKs - * [apidocs.launchdarkly.com](http://apidocs.launchdarkly.com/ "LaunchDarkly API Documentation") for our API documentation - * [blog.launchdarkly.com](http://blog.launchdarkly.com/ "LaunchDarkly Blog Documentation") for the latest product updates + * [launchdarkly.com](https://www.launchdarkly.com/ "LaunchDarkly Main Website") for more information + * [docs.launchdarkly.com](https://docs.launchdarkly.com/ "LaunchDarkly Documentation") for our documentation and SDK reference guides + * [apidocs.launchdarkly.com](https://apidocs.launchdarkly.com/ "LaunchDarkly API Documentation") for our API documentation + * [blog.launchdarkly.com](https://blog.launchdarkly.com/ "LaunchDarkly Blog Documentation") for the latest product updates * [Feature Flagging Guide](https://github.com/launchdarkly/featureflags/ "Feature Flagging Guide") for best practices and strategies diff --git a/scripts/release.sh b/scripts/release.sh index 089dae25..0f1808b7 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -9,7 +9,7 @@ # When done you should commit and push the changes made. set -uxe -echo "Starting python-client release." +echo "Starting python-server-sdk release." VERSION=$1 @@ -28,4 +28,4 @@ python setup.py sdist pip install twine python -m twine upload dist/* -echo "Done with python-client release" +echo "Done with python-server-sdk release" diff --git a/setup.py b/setup.py index 012def24..ee3faef9 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ def run(self): author='LaunchDarkly', author_email='team@launchdarkly.com', packages=find_packages(), - url='https://github.com/launchdarkly/python-client', + url='https://github.com/launchdarkly/python-server-sdk', description='LaunchDarkly SDK for Python', long_description='LaunchDarkly SDK for Python', install_requires=reqs, diff --git a/testing/test_feature_store.py b/testing/test_feature_store.py index ce0150cf..d64a25f8 100644 --- a/testing/test_feature_store.py +++ b/testing/test_feature_store.py @@ -1,5 +1,6 @@ import boto3 import json +import os import pytest import redis import time @@ -165,19 +166,23 @@ def _clear_data(self): class TestFeatureStore: - params = [ - InMemoryTester(), - RedisTester(CacheConfig.default()), - RedisTester(CacheConfig.disabled()), - RedisWithDeprecatedConstructorTester(CacheConfig.default()), - RedisWithDeprecatedConstructorTester(CacheConfig.disabled()), - DynamoDBTester(CacheConfig.default()), - DynamoDBTester(CacheConfig.disabled()) - ] - - if have_consul: - params.append(ConsulTester(CacheConfig.default())) - params.append(ConsulTester(CacheConfig.disabled())) + if os.environ.get('LD_SKIP_DATABASE_TESTS') == '1': + params = [ + InMemoryTester() + ] + else: + params = [ + InMemoryTester(), + RedisTester(CacheConfig.default()), + RedisTester(CacheConfig.disabled()), + RedisWithDeprecatedConstructorTester(CacheConfig.default()), + RedisWithDeprecatedConstructorTester(CacheConfig.disabled()), + DynamoDBTester(CacheConfig.default()), + DynamoDBTester(CacheConfig.disabled()) + ] + if have_consul: + params.append(ConsulTester(CacheConfig.default())) + params.append(ConsulTester(CacheConfig.disabled())) @pytest.fixture(params=params) def tester(self, request):