Git Product home page Git Product logo

flagsmith / flagsmith Goto Github PK

View Code? Open in Web Editor NEW
4.3K 38.0 322.0 56.59 MB

Open Source Feature Flagging and Remote Config Service. Host on-prem or use our hosted version at https://flagsmith.com/

Home Page: https://flagsmith.com/

License: BSD 3-Clause "New" or "Revised" License

Python 60.29% HTML 0.60% Dockerfile 0.10% Shell 0.07% JavaScript 21.28% Handlebars 0.11% SCSS 2.22% Procfile 0.01% TypeScript 15.21% PLpgSQL 0.07% Makefile 0.05%
feature-flags continuous-integration remote-control ci cd feature-toggles feature-flag remote-config python feature-flagging

flagsmith's Introduction

Feature Flag, Remote Config and A/B Testing platform, Flagsmith

Stars Docker Pulls Docker Image Size Join the Discord chat Coverage Built with Depot

Flagsmith is an open source, fully featured, Feature Flag and Remote Config service. Use our hosted API, deploy to your own private cloud, or run on-premise.

Flagsmith

Flagsmith makes it easy to create and manage features flags across web, mobile, and server side applications. Just wrap a section of code with a flag, and then use Flagsmith to toggle that feature on or off for different environments, users or user segments.

Get up and running in less than a minute:

curl -o docker-compose.yml https://raw.githubusercontent.com/Flagsmith/flagsmith/main/docker-compose.yml
docker-compose -f docker-compose.yml up

The application will bootstrap an admin user, organisation, and project for you. You'll find a link to set your password in your Compose logs:

Superuser "[email protected]" created successfully.
Please go to the following page and choose a password: https://localhost:8000/password-reset/confirm/.../...

Flagsmith Screenshot

Features

  • Feature flags. Release features with confidence through phased roll-outs.
  • Remote config. Easily toggle individual features on and off, and make changes without deploying new code.
  • A/B and Multivariate Testing. Use segments to run A/B and multivariate tests on new features. With segments, you can also introduce beta programs to get early user feedback.
  • Organization Management. Organizations, projects, and roles for team members help keep your deployment organized.
  • Integrations. Easily enhance Flagsmith with your favourite tools.

Trying Flagsmith

Flagsmith hosted SaaS

You can try our hosted version for free at https://flagsmith.com/

Flagsmith Open Source

The Flagsmith API is built using Python 3, Django 2, and DjangoRestFramework 3. You can try the application out using:

We also have options for deploying to AWS, GCP, Azure and On-Premise. If you need help getting up and running, please get in touch!

Overview

This repository is formed of 2 core components, the REST API (found in /api) and the web-based administrator dashboard (found in /frontend) that you can use to manage Flagsmith. Technical documentation for each component can be found at the API and Frontend pages within our Documentation

These two components run as separate applications. The web-based dashboard is a single page app that communicates via REST calls to the API.

Resources

flagsmith's People

Contributors

ajhelsby avatar aliakseilatyp avatar andrewshawcare avatar azaiko-akveo avatar benrometsch avatar dabeeeenster avatar dependabot[bot] avatar dogacel avatar edsnloor avatar gagantrivedi avatar github-actions[bot] avatar gnumoreno avatar imgbot[bot] avatar justinback avatar khvn26 avatar kyle-ssg avatar matheuslasserre avatar matthewelwell avatar nitz14 avatar nogoodusername avatar novakzaballa avatar plumdog avatar rolodato avatar shrutic-git avatar shubham-padia avatar sjdines avatar tushar5526 avatar vrtak-cz avatar zachaysan avatar zefixlluja 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

flagsmith's Issues

Question around chattiness/performance/caching

Do the bullet-train clients do any caching, or have some mechanism to avoid huge amounts of chattiness? If there is caching, is there some expiry mechanism to ensure that the clients are up to date?

I ask because adding a REST call into each hop is a potentially expensive operation if you have a distributed system. I know some feature toggle systems (and things like consul) have mechanisms for mitigating this e.g. launch-darkly opens websockets and each client keeps a cached copy of the current togglestate taht is updated instantly

301 Moved Permanently when following swagger docs

The swagger docs are cool, thanks. When giving it a try on the segments API it generated me the following curl command:

curl -X GET "http://api.flagsmith.com/api/v1/segments/?page=1" -H  "accept: application/json" -H  "X-CSRFToken: GsV6WkSPliMSr2tzWoJpTsbnPPwOHdR7GZmkCO7MtsOzCBEwbDBAsRoaIQuR13aV"

It will return a

<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>CloudFront</center>
</body>
</html>

That is because you guys are using https now (since this doc has generated).

The fix is just replace the http by https in the doc. I can make a PR to fix, just guide me where this is generated.

PHP Support

Hi there,

Just a quick question, will there be support for using PHP at some point. So far, there only seems to be .NET or JAVA in terms of server side languages and PHP is missing.

Thanks,

Emmanuel

support for realtime updates

Will there be plan to expose realtime updates ? Maybe utilise socket.io so that when the values are updated there would be an event that gets dispatched to the clients in realtime ?

This would avoid the clients having to short poll the backend to fetch the latest updates.

CC @matthewelwell @dabeeeenster

Use of Mysql as database

Is it possible to use a Mysql database instead of Postgres?
If not - what are the main Todo's to enable it?

Feature Leakage

When calling getFeatures, the API returns ALL feature flags. I'm proposing we should only return those flags which are enabled for the given user.

I don't see the point in "leaking" feature flags to an inquisitive user that otherwise doesn't need to know they exist ๐Ÿ‘

Proposing the API would return this, instead of the latter:

{
    "gt8_feature_flag_test": {
        "enabled": true,
        "value": null
    },
    "floating_action_button": {
        "enabled": true,
        "value": null
    },
    "oauth_google": {
        "enabled": true,
        "value": null
    },
    "interactive_tutorial": {
        "enabled": true,
        "value": null
    },
    "breadcrumbs": {
        "enabled": true,
        "value": null
    },
    "tasks": {
        "enabled": true,
        "value": null
    }
}

instead of:

{
    "gt8_feature_flag_test": {
        "enabled": true,
        "value": null
    },
    "floating_action_button": {
        "enabled": true,
        "value": null
    },
    "oauth_google": {
        "enabled": true,
        "value": null
    },
    "test_remote": {
        "enabled": false,
        "value": "1"
    },
    "interactive_tutorial": {
        "enabled": true,
        "value": null
    },
    "breadcrumbs": {
        "enabled": true,
        "value": null
    },
    "thought_from_template": {
        "enabled": false,
        "value": null
    },
    "tasks": {
        "enabled": true,
        "value": null
    }
}

docker-compose up does not work.

When I run docker-compose up, after I cloned the repo, from the repo's root directory. I get the following:

... [build logs / postgres starting] ...
api_1  | python: can't open file 'manage.py': [Errno 2] No such file or directory
bullet-train-api_api_1 exited with code 2

My docker-compose version is:

$ docker-compose --version
docker-compose version 1.23.2, build 1110ad01
docker-py version: 3.6.0
CPython version: 3.6.6
OpenSSL version: OpenSSL 1.1.0h  27 Mar 2018

and docker:

$ docker --version
Docker version 18.09.2, build 6247962

I am also running on a mac using Docker Desktop

Docker commands incorrect

In the repo's readme file there's instructions for running this in Docker, but the instructions are incorrect.

Looking at the updated instructions, you have:

git clone [email protected]:flagsmith/flagsmith.git
docker-compose -f docker/docker-compose.yml up

But that's incorrect (it won't/shouldn't work); the instructions should be either:

git clone [email protected]:flagsmith/flagsmith.git
cd flagsmith
docker-compose -f docker/docker-compose.yml up

or

git clone [email protected]:flagsmith/flagsmith.git
docker-compose -f flagsmith/docker/docker-compose.yml up

WebHook doesn't work

Hi,

I'm trying to investigate how to use web hooks.
I've created test ASP.NET Core service and expose endpoint https://localhost:32768/feature-flags/feature-changed
Then I've added WebHook to our Dev environment (Bullet Train server runs on K8s in our corporate network)
When I click on Test WebHook button it is working perfectly.
But when I try to update/create/delete feture flag - nothing happens.
It seems that Flagsmith server doesn't know about web hook I've created.

Add Flagsmith's API to Postman's API Network

Hey there ๐Ÿ‘‹

We'd love to see the Flagsmith API on the Postman API Network along with other companies like Strapi, Microsoft, Twilio etc.
I see you already work out of an OpenAPI spec so it'd be pretty easy to generate documentation from it and let your users fork it so they can start playing with the API.

If that sounds interesting for you, you can read how to get started here or let me know and I can share more about the benefits/help you with it! ๐Ÿ™‚

Unable to use segments

Hi I've been attempting to self host the bullet train api and frontend, and have some success, but am having issues with segments.

After creating a segment with the front end, I can't select a segment override when editing a feature. The dropdown is visible but contains no values and is unresponsive.

image

Setup
I have forked the api and frontend, and deployed them to heroku.
For the api I have set the DATABASE and appropriate DJANGO env vars and it seems to be working as expected.

For the frontend, I modified the api url to point to my backend, and set ENV to prod in the heroku env vars.

I also changed the assetUrl in project_prod.js to point to my deployed heroku app and added a build command to the package json so that heroku will build it. "build": "npm run env && npm run bundle",

Any suggestions or something I'm missing?

Load testing profile

Hi, I was wondering if you have done any load testing profiling to know of any potential scalability issues as well as the performance characteristics?

Segment rules should be able to operate on Identity IDs

Currently segment rule definitions can only be run against Identity traits. Users often expect the rules to operate on Identity ids as well.

We should introduce a reserved trait name, suggest id, which evaluates to the Identity unique identifier when the rules are being evaluated.

Technical Implementation

We can add the id transiently to the segment list with a special name e.g. id or similar before processing the rules.

Issues

It would mean that SDKs could not set a trait with id which would be a breaking change. What would happen to existing traits that have an ID set? Suggest that if they do, this overrides the coercion of the id.

/api/v1/auth/users/reset_password/ does not use the SENDER_EMAIL env variable

For Self Hosting:

Relevant ENV Settings:

  ENVIRONMENT: production
  SENDER_EMAIL: [email protected]
  EMAIL_BACKEND: django_ses.SESBackend
  AWS_SES_REGION_NAME: us-west-2
  AWS_SES_REGION_ENDPOINT: email.us-west-2.amazonaws.com

Using the above settings for a self host solution, I am able to successfully invite new users and recieve those emails. But if I attempt to reset a users password, that api endpoint fails. See the error below

 ERROR 2020-10-01 19:12:39,217 log 13 140656016357120 Internal Server Error: /api/v1/auth/users/reset_password/
 Traceback (most recent call last):
   File "/app/.venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
     response = get_response(request)
   File "/app/.venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 115, in _get_response
     response = self.process_exception_by_middleware(e, request)
   File "/app/.venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 113, in _get_response
     response = wrapped_callback(request, *callback_args, **callback_kwargs)
   File "/app/.venv/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
     return view_func(*args, **kwargs)
   File "/app/.venv/lib/python3.8/site-packages/rest_framework/viewsets.py", line 114, in view
     return self.dispatch(request, *args, **kwargs)
   File "/app/.venv/lib/python3.8/site-packages/rest_framework/views.py", line 505, in dispatch
     response = self.handle_exception(exc)
   File "/app/.venv/lib/python3.8/site-packages/rest_framework/views.py", line 465, in handle_exception
     self.raise_uncaught_exception(exc)
   File "/app/.venv/lib/python3.8/site-packages/rest_framework/views.py", line 476, in raise_uncaught_exception
     raise exc
   File "/app/.venv/lib/python3.8/site-packages/rest_framework/views.py", line 502, in dispatch
     response = handler(request, *args, **kwargs)
   File "/app/.venv/lib/python3.8/site-packages/djoser/views.py", line 238, in reset_password
     settings.EMAIL.password_reset(self.request, context).send(to)
   File "/app/.venv/lib/python3.8/site-packages/templated_mail/mail.py", line 78, in send
     super(BaseEmailMessage, self).send(*args, **kwargs)
   File "/app/.venv/lib/python3.8/site-packages/django/core/mail/message.py", line 306, in send
     return self.get_connection(fail_silently).send_messages([self])
   File "/app/.venv/lib/python3.8/site-packages/django_ses/__init__.py", line 182, in send_messages
     response = self.connection.send_raw_email(
   File "/app/.venv/lib/python3.8/site-packages/botocore/client.py", line 316, in _api_call
     return self._make_api_call(operation_name, kwargs)
   File "/app/.venv/lib/python3.8/site-packages/botocore/client.py", line 635, in _make_api_call
     raise error_class(parsed_response, operation_name)
 botocore.errorfactory.MessageRejected: An error occurred (MessageRejected) when calling the SendRawEmail operation: Email address is not verified. The following identities failed the check in region US-WEST-2: [email protected]  

Integer Traits and Feature State Values should be stored at least 64bit

Currently integer traits and Feature State Values in postgres top out at 2147483647. We need to change the data type that is used to store the value in postgres.

In addition, the front end should bubble up these error messages to the user if the values cannot be stored for whatever reason.

Forbidden (CSRF cookie not set.): /auth/login/

I run Api locally, set up Postgres database localy and run fronted API also locally.

I have communication between fronted and api but every request throw
"Forbidden (CSRF cookie not set.): /auth/login/"
and i don't know if i miss something and i have wrong configuration or i need to add something into the code?

Web Hook sends only one type of event (FLAG_UPDATED)

Hi,

It is quite stupid to have one type for many events.
Suggestion:
On feature_segment update sends : FLAG_SEGMENT_UPDATED
On feature_identity update sends : FLAG_IDENTITY_UPDATED
on feature update sends : FLAG_FEATURE_UPDATED

Bug: In segment override tab, value type not changing from default text to other type.

Hi team,

Great work on the new version of Bullet Train - Flagsmith! Appreciate all the new features and functionalities.
We are back to integrating Flagsmith and came across a bug which looks like a minor issue.

Steps:

  1. Create a flag and add a value with type JSON.
  2. Go to the Overrides tab select a segment
  3. Now in the segment, try to select a different type other than text, it does not reflect as the corresponding input.

Please let me know if I can provide more context or need any more information on this.
Thank you.

Handle special characters in database URI

Hi, while setting up the custom database, I came across this issue where my db uri had an # in the password and it was failing with the following error:

>>> dj_database_url.parse('postgres://root:test#[email protected]:5432/test_db', conn_max_age=60)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/harenlewis/Projects/ff_env/lib/python3.6/site-packages/dj_database_url.py", line 105, in parse
    port = (str(url.port) if url.port and engine == SCHEMES['oracle']
  File "/usr/lib/python3.6/urllib/parse.py", line 169, in port
    port = int(port, 10)
ValueError: invalid literal for int() with base 10: 'test'

On digging a little it looks like it how dj-database-url parses url!
You can read more about it here: jazzband/dj-database-url#39

I've worked on resolving this, will submit a PR soon!

Segment overrides apply before clicking update feature

Hi guys,

I made the following observation today while integrating flagsmith in my project:

Expected behavior:

Adding a segment override to a feature does not change the feature value until "Update Feature" is hit.

Observed behavior:

Immediately after selecting a segment in the "Edit Feature -> Segment Overrides -> Select a segment" drop down and before hitting "Update Feature", the according flag returned by the api becomes "null".

In addition, if I cancel the dialog before hitting "Update Feature" and open it again, the "abandoned" feature is still there.

How to reproduce:

  1. Create a remote config feature "foo" with value "bar"
  2. Create a user "alice" with some trait
  3. In the client, identify as "alice" and call getFlags() => Will correctly return foo: { enabled: true, value: "bar"}
  4. Create a segment "test_segment" that contains user "alice"
  5. Open the "Edit Feature" dialog for feature "foo"
  6. Under "Segment Overrides", select "test_segment"
  7. DON'T hit "Update Feature"
  8. In the client, repeat step 3 => Will falsly return foo: { enabled: false, value: null }

Cannot create segments (Error: Cannot read property 'reduce' of null)

Hello, i'm having an issue when trying to add a new segment. When I click "Create your first Segment". I tried creating the segment from the DB but I get the same error when editing the segment.

Running Flagsmith locally

  • flagsmith/flagsmith-api:v2.7.1
  • flagsmith/flagsmith-frontend:v2.7.0

Screen Shot 2021-06-18 at 2 57 39 PM

react-select.esm.js:4071 Uncaught TypeError: Cannot read property 'reduce' of null
    at t.value (react-select.esm.js:4071)
    at new t (react-select.esm.js:3541)
    at Jo (react-dom.production.min.js:150)
    at ta (react-dom.production.min.js:162)
    at ja (react-dom.production.min.js:192)
    at Aa (react-dom.production.min.js:193)
    at fi (react-dom.production.min.js:205)
    at Ra (react-dom.production.min.js:200)
    at vi (react-dom.production.min.js:218)
    at bi (react-dom.production.min.js:218)

docker-compose race condition

There's a race condition when starting docker-compose up whereby the app server can start before the DB, thus failing to acquire a DB connection. The DB check in Django needs to be made more robust.

Segmentation

Hi guys,

First of all, thanks for making the decision to go full open source on this project!

I saw in the docs that segments are a "Coming Soon" feature. It would be great to get some details on how that is planned to work (and if people can contribute ideas and perhaps help).

Will segments include the ability to segregate distribution by any custom property?
Will random percentage be possible, for A/B testing?
Is it planned to make metrics available about the segmented distribution?

List all /identities/ and filter by trait

The use case for us is to handle subsets of data differently for a group of identities (e.g. for internal tools) while we're rolling out features. Our current workaround is to create a Segment and assign multiple OR conditions (e.g. id=1 OR id=2), then retrieve that Segment and naively transform it into a list.

Would be open to contributing, any particular reason why the identities doesn't have an option to list all / isn't a ModelViewSet? https://github.com/BulletTrainHQ/bullet-train-api/blob/master/src/environments/views.py#L390. The get_or_create also seems a little unusual.

Potential Bug: Can't disable new user registration with OAuth

With Google OAuth enabled, I can't disable the ability for new users to create accounts, organizations, & projects -- primarily accounts.

I've tried setting USER_CREATE_PERMISSIONS=djoser.permissions.CurrentUserOrAdmin like the readme suggests. And FWIW I've tried USER_CREATE_PERMISSIONS=rest_framework.permissions.IsAdminUser

Any ideas on how to do this?

Cannot Deploy Docker Image to a K8s System

I am trying to deploy the docker image to a k8s system, by building on top of you docker images.
It seems that I its not picking up certain DB settings:

Dockerfile:

FROM bullettrain/frontend:release-2.2.4 AS base

FROM base AS test
CMD true # nothing to test

FROM base AS container
COPY entrypoint.sh .
CMD ["./entrypoint.sh"]

entrypoint.sh:

#!/bin/bash

echo "Setting bullet-train variables"
export DJANGO_DB_HOST=$DB_BULLETTRAIN_DB_WRITE_HOST
export DJANGO_DB_PASSWORD=$DB_BULLETTRAIN_DB_WRITE_PASSWORD
export REDIS_URL=redis://$REDIS_HOST:$REDIS_PORT
export ENVIRONMENT=production
export SENDER_EMAIL=<email>
export EMAIL_BACKEND=django_ses.SESBackend
export AWS_SES_REGION_NAME=<region>
export AWS_SES_REGION_ENDPOINT=<endpoint>
export DJANGO_DB_PORT=<port>
export DJANGO_DB_USER=<username>
export DJANGO_DB_NAME=<db-name>
export DJANGO_SETTINGS_MODULE=app.settings.master-docker
export DJANGO_ALLOWED_HOSTS=$DJANGO_ALLOWED_HOSTS

echo "Email Backend: $EMAIL_BACKEND"

echo "Launching bullet-train"
exec ./bin/docker "$@"

With these settings I get the following logged errors:

Setting bullet-train variables
 Email Backend: django_ses.SESBackend
 Launching bullet-train
 /app/src/app/settings/common.py:45: UserWarning: GOOGLE_SERVICE_ACCOUNT not configured, getting organisation usage will not work
   warnings.warn("GOOGLE_SERVICE_ACCOUNT not configured, getting organisation usage will not work")
 /app/src/app/settings/common.py:48: UserWarning: GA_TABLE_ID not configured, getting organisation usage will not work
   warnings.warn("GA_TABLE_ID not configured, getting organisation usage will not work")
 /app/src/app/settings/common.py:258: UserWarning: `SENDGRID_API_KEY` has not been configured. You will not receive emails.
   warnings.warn(
 Traceback (most recent call last):
   File "/app/.venv/lib/python3.8/site-packages/django/db/backends/base/base.py", line 217, in ensure_connection
     self.connect()
   File "/app/.venv/lib/python3.8/site-packages/django/db/backends/base/base.py", line 195, in connect
     self.connection = self.get_new_connection(conn_params)
   File "/app/.venv/lib/python3.8/site-packages/django/db/backends/postgresql/base.py", line 178, in get_new_connection
     connection = Database.connect(**conn_params)
   File "/app/.venv/lib/python3.8/site-packages/psycopg2/__init__.py", line 127, in connect
     conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
 psycopg2.OperationalError: could not connect to server: Connection timed out
     Is the server running on host "db" (100.67.219.210) and accepting
     TCP/IP connections on port 5432?
 The above exception was the direct cause of the following exception:
 Traceback (most recent call last):
   File "src/manage.py", line 11, in <module>
     execute_from_command_line(sys.argv)
   File "/app/.venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
     utility.execute()
   File "/app/.venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 375, in execute
     self.fetch_command(subcommand).run_from_argv(self.argv)
   File "/app/.venv/lib/python3.8/site-packages/django/core/management/base.py", line 323, in run_from_argv
     self.execute(*args, **cmd_options)
   File "/app/.venv/lib/python3.8/site-packages/django/core/management/base.py", line 364, in execute
     output = self.handle(*args, **options)
   File "/app/.venv/lib/python3.8/site-packages/django/core/management/base.py", line 83, in wrapped
     res = handle_func(*args, **kwargs)
   File "/app/.venv/lib/python3.8/site-packages/django/core/management/commands/migrate.py", line 87, in handle
     executor = MigrationExecutor(connection, self.migration_progress_callback)
   File "/app/.venv/lib/python3.8/site-packages/django/db/migrations/executor.py", line 18, in __init__
     self.loader = MigrationLoader(self.connection)
   File "/app/.venv/lib/python3.8/site-packages/django/db/migrations/loader.py", line 49, in __init__
     self.build_graph()
   File "/app/.venv/lib/python3.8/site-packages/django/db/migrations/loader.py", line 212, in build_graph
     self.applied_migrations = recorder.applied_migrations()
   File "/app/.venv/lib/python3.8/site-packages/django/db/migrations/recorder.py", line 73, in applied_migrations
     if self.has_table():
   File "/app/.venv/lib/python3.8/site-packages/django/db/migrations/recorder.py", line 56, in has_table
     return self.Migration._meta.db_table in self.connection.introspection.table_names(self.connection.cursor())
   File "/app/.venv/lib/python3.8/site-packages/django/db/backends/base/base.py", line 256, in cursor
     return self._cursor()
   File "/app/.venv/lib/python3.8/site-packages/django/db/backends/base/base.py", line 233, in _cursor
     self.ensure_connection()
   File "/app/.venv/lib/python3.8/site-packages/django/db/backends/base/base.py", line 217, in ensure_connection
     self.connect()
   File "/app/.venv/lib/python3.8/site-packages/django/db/utils.py", line 89, in __exit__
     raise dj_exc_value.with_traceback(traceback) from exc_value
   File "/app/.venv/lib/python3.8/site-packages/django/db/backends/base/base.py", line 217, in ensure_connection
     self.connect()
   File "/app/.venv/lib/python3.8/site-packages/django/db/backends/base/base.py", line 195, in connect
     self.connection = self.get_new_connection(conn_params)
   File "/app/.venv/lib/python3.8/site-packages/django/db/backends/postgresql/base.py", line 178, in get_new_connection
     connection = Database.connect(**conn_params)
   File "/app/.venv/lib/python3.8/site-packages/psycopg2/__init__.py", line 127, in connect
     conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
 django.db.utils.OperationalError: could not connect to server: Connection timed out
     Is the server running on host "db" (100.67.219.210) and accepting
     TCP/IP connections on port 5432?
 stream closed

if I set ENVIRONMENT=testit, I do get the error 'ENVIRONMENT env variable must be one of local, dev, staging or production'

So I can see my envs are being set, but some are not being ingested.

Is the prefered method to fork this repo, and use that as a deployment. Or should I be able to layer on top of your dockerfile? I am totally lost at this point.

Need help: High level design/architecture

This project looks really interesting, and I tried setting up this locally as well - works like a charm.
However, I am interested to know more about the underlying architecture. Does it handle realtime updates across clients, etc.

Is there a documentation which covers high level architecture? And any developer documentation. I see a lot of documentation is available for consumer of this infra. It would be good to have a place for developer/contributor documentation to enable more developers to contribute.

Overall, great initiative!

Custom SSO provider

Hello and thanks for an awesome open-source product!
I have a question. I saw Google OAuth integration added recently, is there a possibility to write your own authentication provider and configure Bullet train(on-premise) to use it? We have an internal SSO solution based on OAuth. If there is an already implemented functionality for LDAP, it could also be a solution for us.

Segment rules can turn - true > True

Ok, so the reason for this is as follows:

When the FE is creating the segment condition, it silently casts the value to the correct type based on the input and sends this in the json.

e.g. entering 'true' results in the following json:

    "value": true

whereas entering, e.g. 'some string' results in:

    "value": "some string"

The BE simply converts whatever is sent into a string instead (for reasons I explain later in this message), but since the json becomes a python dictionary before storing it in the database, true becomes True. This string value is then what is stored against the segment condition and is what is returned to the FE (hence the discrepancy in what is returned).

When evaluating segments, however, the BE leans on the type of the trait, not the segment condition. So, if the trait is a boolean trait, then the BE will check if the condition value string is a valid python boolean and then compare the trait value against that accordingly. See the (simplified) python logic here:

    def check_boolean_value(self, value: bool) -> bool:
        if self.value in ("True", "true", "1"):
            bool_value = True
        else:
            return False

        if self.operator == EQUAL:
            return value == bool_value
        elif self.operator == NOT_EQUAL:
            return value != bool_value

        return False

Where this logic falls down, which is possibly the issue that the user is having, is when you legitimately want to test a string trait against a value of "true". This will never be possible since the FE will always cast this to a boolean and hence python will store the string "True" instead.

The simple fix here (as far as I can tell) is to prevent the FE from casting these values so that python stores the correct string. The BE will then still evaluate boolean trait values correctly since the logic looks at whether the string value is one of the following:

("True", "true", "1")

Bug: Can't change user group members

Page: project/{id}/environment/{id}/organisation-settings
Suspected reproduction steps:

  • Create a user
  • Add them to a group
  • Delete the user
  • Create another user
  • Try add this user to the group

Outcome:

  • Fails to add user
  • Shows wrong count of users for the group (still including deleted user)

API response:
400. User {id} does not exist in this organisation

Note:
Looks like it's still trying to post back the id for the deleted user

Static CSS files for administration interface seem to be missing

Not sure if this is because the static folder is ignored in .gitignore, but when logging into the Django adminstration interface, there is no styling applied and the CSS files are not located (the server responds with the, "Bullet Train API" page).

I'm attempting to run the API via Docker (this may or may not be relevant to the issue as I haven't tried running outside of Docker).

SDK-side flag evaluations

Overview

There are common use-cases where it is better to run the flag rules engine within the Flagsmith SDK, rather than within the API.

Generally when requesting flags from end clients (e.g. mobile apps, or within a web browser in a single page app), we think it is optimal that the flag rules engine should be run within our API. This ensures that Segment rules are not 'leaked' to the client. It also reduces the burden on the client SDKs both from a development perspective on the Flagsmith side as well as making the SDKs lightweight, requiring fewer dependencies etc. etc.

However, when getting flags within a server-side environment (for example, as part of server rendered web pages or as part of an API) there are latency issues with having the flags evaluated within the Flagsmith API. If the server is requesting the flags for an identity, it has to wait for a round trip to our API in order to retrieve the flags for that user. Often the server will have all the relevant trait data for the identity in memory. If the server is able to cache the Flagsmith environment details which change infrequently (flags, environment flag states, segment rule definitions), it could then be able to run the Flagsmith rules engine by combining the cached environment details with the traits in memory. This would reduce latency to almost zero as the entire process would happen within the server SDK.

Secondary Benefits

  1. Administrators could write a very simple proxy of our SDK API Endpoints, cache the environment flag settings, and then serve the flags very quickly and without concern of not being able to access the Flagsmith API.

Problems

We don't want to have to update all of our SDK libraries every time we want to make an improvement to the flags engine.

Our rules engine has to be reliable and deterministic and not have edge cases that cause inconsistencies across different languages.

Technical Approach

As part of the work for #85 we are factoring out the rules engine into a simple python library with minimal dependencies. If we employed language specific transpilers, we can transpile the python code into the language shared with the SDK implementation and then run the rules engine as part of the transpiled code within the native language of the SDK.

Our testing pipelines can be updated in order to test all of our SDKs against a comprehensive Segment rules test set and ensure that they provide identical outputs.

SDKs to implement:

Server Side SDKs

Have /api/v1/users/init/ return a JSON response or an empty body

I've created a provisioning script and a client wrapper for the Bullet Train API which throws an exception when attempting to parse the response from /api/v1/users/init/ as it seems to only return a text body of, "ADMIN USER CREATED".

Ideally, when the Accept header is set to application/json, the API could return either a 201 Created response with no body or the same message as a JSON payload:

{
  "adminUserCreated": true
}

Mark flags as deprecated

We currently have a use case around features that are being phased out but can't be deleted yet due to old mobile clients still referencing it.

Is there a way to tag/mark the features as deprecated to be able to hide them from the UI without deleting them? Otherwise, I would like to request that feature.

Right now, adding a tag could work, but it only is a positive match filter rather than "anything except this tag".
image

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.