Giter Site home page Giter Site logo

forestadmin / django-forestadmin Goto Github PK

View Code? Open in Web Editor NEW
119.0 19.0 18.0 659 KB

🐍 Django agent for Forest Admin to integrate directly to your existing Django backend application.

Home Page: https://www.forestadmin.com

License: GNU General Public License v3.0

Python 99.50% JavaScript 0.49% Shell 0.01%
admin admin-panel internal-tool django python backend backend-api

django-forestadmin's People

Contributors

arnaudbesnier avatar dependabot[bot] avatar forest-bot avatar guillaumecisco avatar jbarreau avatar lucasob avatar matthv avatar rmartin48 avatar romaincoudour avatar stevebunlon avatar vamonte 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

django-forestadmin's Issues

ModuleNotFoundError: No module named 'pytz'

Expected behavior

Start a new Django 4 project with the forestadmin agent.

Actual behavior

ModuleNotFoundError: No module named 'pytz'

Failure Logs

  from django_forest.utils.scope import ScopeManager
  File "/Users/xxxx/fadmin/pvenv/forestDemo/lib/python3.9/site-packages/django_forest/utils/scope.py", line 6, in <module>
  import pytz
  ModuleNotFoundError: No module named 'pytz'

Context

The new django version use the zoneinfo package instead of the pytz package. (https://docs.djangoproject.com/fr/4.0/releases/4.0/)

Zoneinfo is available in python >= 3.9
One backport is mandatory to use zoneinfo with python < 3.9. Its backport is only available for python >= 3.6

  • Django Version: 4.0.1

Smart fields not being filtered out in list view

Expected behavior

One would expect hidden smart views to not be invoked at all when querying a list of model instances.

Actual behavior

The smart fields are hidden from the response, however, they are all still calculated, but then filtered out of the response.

This is made clear in ListView::get where ListView::hand_smart_fields is called.

Inside this function, all smart fields for the model are appended to the response, only to then be filtered out again by ListView::serialize

Context

Support ticket raised: https://community.forestadmin.com/t/dont-load-smart-field-in-collection-view/5102

  • Package Version: 1.3.3
  • Django Version: 3.2.13

The automated release is failing 🚨

🚨 The automated release from the main branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you can benefit from your bug fixes and new features again.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can fix this 💪.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the main branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here are some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


request to https://hooks.slack.com/services/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 failed, reason: connect ETIMEDOUT 54.211.89.16:443

Unfortunately this error doesn't have any additional information. Feel free to kindly ask the author of the semantic-release-slack-bot plugin to add more helpful information.


Good luck with your project ✨

Your semantic-release bot 📦🚀

Onboarding - CORS configuration can conflict with django-cors-headers app configuration if used

Expected behavior

Using the app django-cors-headers, the onboarding should be smooth.

Actual behavior

Onboarding on a Django backend using the app django-cors-headers seems to conflict with the agent CORS configuration and does not let the Forest Admin client request the backend.
By manually adding app.forestadmin.com, as an authorized domain to the django-cors-headers configuration, we manage to bypass the issue.

Context

  • Package Version: 1.0.5
  • Django Version: unknown

IATError: Issued in the future

Expected behavior

Forest Admin authentication should work consistently.

Actual behavior

Authentication fails on an intermittent basis due to a race condition when issuing the id token. When this happens, the /forest/authentication/callback endpoint will return a 500 error with an oic.oic.message.IATError: Issued in the future exception raised. Clicking Login in again multiple times usually resolves the issue.

Debugging the token verification process in oic reveals a very small discrepancy between _now and _iat. The intermittent nature of the bug suggest this discrepancy is not always present.

# oic/oic/message.py

class IdToken(OpenIDSchema):
    ...
    if _now < (_iat - _skew):  # e.g. 1657294222 < (1657294223 - 0)
        raise IATError("Issued in the future")

Screen Shot 2022-07-09 at 1 36 08 am

Failure Logs

ERROR:django.request:Internal Server Error: /forest/authentication/callback
Traceback (most recent call last):
  File "/app/.venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/app/.venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/app/.venv/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "/app/.venv/lib/python3.9/site-packages/django/views/generic/base.py", line 98, in dispatch
    return handler(request, *args, **kwargs)
  File "/app/.venv/lib/python3.9/site-packages/django_forest/authentication/utils.py", line 21, in wrapper
    return f(*args, **kwargs)
  File "/app/.venv/lib/python3.9/site-packages/django_forest/authentication/views/callback.py", line 149, in get
    token_body = self._verify_code_and_generate_token_body(callback_url, request)
  File "/app/.venv/lib/python3.9/site-packages/django_forest/authentication/views/callback.py", line 131, in _verify_code_and_generate_token_body
    user = self._authenticate(
  File "/app/.venv/lib/python3.9/site-packages/django_forest/authentication/views/callback.py", line 90, in _authenticate
    access_token_request = client.do_access_token_request(
  File "/app/.venv/lib/python3.9/site-packages/oic/oic/__init__.py", line 704, in do_access_token_request
    atr = super().do_access_token_request(
  File "/app/.venv/lib/python3.9/site-packages/oic/oauth2/__init__.py", line 926, in do_access_token_request
    return self.request_and_return(
  File "/app/.venv/lib/python3.9/site-packages/oic/oauth2/__init__.py", line 819, in request_and_return
    return self.parse_request_response(resp, response, body_type, state, **kwargs)
  File "/app/.venv/lib/python3.9/site-packages/oic/oauth2/__init__.py", line 760, in parse_request_response
    return self.parse_response(
  File "/app/.venv/lib/python3.9/site-packages/oic/oauth2/__init__.py", line 679, in parse_response
    verf = resp.verify(**kwargs)
  File "/app/.venv/lib/python3.9/site-packages/oic/oic/message.py", line 360, in verify
    self["id_token"] = verify_id_token(self, **kwargs)
  File "/app/.venv/lib/python3.9/site-packages/oic/oic/message.py", line 311, in verify_id_token
    if not idt.verify(**kwargs):
  File "/app/.venv/lib/python3.9/site-packages/oic/oic/message.py", line 790, in verify
    raise IATError("Issued in the future")
oic.oic.message.IATError: Issued in the future

Proposed fix

Passing in a skew to oic addresses the race condition.

# django_forest/authentication/views/callback.py

class CallbackView(View):
    def _authenticate(self, client, state, code):
        access_token_request = client.do_access_token_request(
            ...,
            skew=10
        )

Context

  • Package Version: 1.3.2
  • Django Version: 3.2.13
  • Python Version: 3.9.9
  • OIC Version: 1.4.0

Getting error while trying Forest Admin

Expected behavior

No error.

Actual behavior

Stack trace when booting django app.

django.core.exceptions.FieldError: The relation has multiple target fields, but only single target field was asked for

Failure Logs

File "/Users/dmarkey/src/xx/src/xx/urls.py", line 15, in
init_forest()
File "/Users/dmarkey/src/xxx/venv/lib/python3.10/site-packages/django_forest/init.py", line 11, in init_forest
Schema.build_schema()
File "/Users/dmarkey/src/xxx/venv/lib/python3.10/site-packages/django_forest/utils/schema/init.py", line 121, in build_schema
cls.add_fields(model, collection)
File "/Users/dmarkey/src/xxx/venv/lib/python3.10/site-packages/django_forest/utils/schema/init.py", line 111, in add_fields
f = cls.handle_relation(field, f)
File "/Users/dmarkey/src/xxx/venv/lib/python3.10/site-packages/django_forest/utils/schema/init.py", line 88, in handle_relation
f['reference'] = f'{field.related_model._meta.db_table}.{field.target_field.column}'
File "/Users/dmarkey/src/xxx/venv/lib/python3.10/site-packages/django/db/models/fields/related.py", line 436, in target_field
raise exceptions.FieldError(
django.core.exceptions.FieldError: The relation has multiple target fields, but only single target field was asked for

Context

  • Package Version: django-forestadmin==1.5.0
  • Django Version: Django==3.2.19

Is there a setting to ignore certain models? I've identified the model and I'm not really that interested in it in Forest Admin

AttributeError: 'DecimalValidator' object has no attribute 'code'

Expected behavior

TODO: display decimal field without problem.

Actual behavior

TODO: AttributeError: 'DecimalValidator' object has no attribute 'code'

Failure Logs

TODO: Please include any relevant log snippets, if necessary.
Captura de Pantalla 2021-11-19 a la(s) 10 04 27 p  m

Context

TODO: My file requirements.txt

aniso8601==7.0.0
asgiref==3.4.1
Beaker==1.11.0
certifi==2021.10.8
cffi==1.15.0
chardet==4.0.0
cryptography==35.0.0
defusedxml==0.7.1
Django==3.2.9
django-cors-headers==3.7.0
django-forestadmin==1.0.5
django-graphql-jwt==0.3.4
django-ipware==3.0.7
ecdsa==0.17.0
future==0.18.2
graphene==2.1.9
graphene-django==2.15.0
graphql-core==2.3.2
graphql-relay==2.0.1
idna==2.10
importlib-metadata==4.6.3
Mako==1.1.6
MarkupSafe==2.0.1
marshmallow==3.14.1
marshmallow-jsonapi==0.24.0
oic==1.2.1
promise==2.3
pyasn1==0.4.8
pycparser==2.21
pycryptodomex==3.11.0
pyjwkest==1.4.2
PyJWT==2.3.0
python-dateutil==2.8.1
python-jose==3.3.0
pytz==2021.3
requests==2.25.1
rsa==4.7.2
Rx==1.6.1
singledispatch==3.7.0
six==1.16.0
sqlparse==0.4.2
text-unidecode==1.3
typing_extensions==4.0.0
urllib3==1.26.7
zipp==3.6.0

  • Package Version: Django==3.2.9
  • Django Version: django-forestadmin==1.0.5

Python 3.10: ImportError: cannot import name 'Mapping' from 'collections'

Expected behavior

Running ./manage.py runserver should not result in any errors.

Actual behavior

Testing django_forest on Django 4.0b1 and Python 3.10 results in an import error: ImportError: cannot import name 'Mapping' from 'collections'

PS: This is most likely stemming from the oic library. Changing the import in question to from collections.abc import Mapping will work on Python 3.10

Failure Logs

> ./manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

Exception in thread django-main-thread:
Traceback (most recent call last):
  File "/usr/local/Cellar/[email protected]/3.10.0_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/threading.py", line 1009, in _bootstrap_inner
    self.run()
  File "/usr/local/Cellar/[email protected]/3.10.0_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/threading.py", line 946, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/django/core/management/commands/runserver.py", line 124, in inner_run
    self.check(display_num_errors=True)
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/django/core/management/base.py", line 438, in check
    all_issues = checks.run_checks(
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/django/core/checks/registry.py", line 77, in run_checks
    new_errors = check(app_configs=app_configs, databases=databases)
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/django/core/checks/urls.py", line 13, in check_url_config
    return check_resolver(resolver)
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/django/core/checks/urls.py", line 23, in check_resolver
    return check_method()
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/django/urls/resolvers.py", line 442, in check
    for pattern in self.url_patterns:
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/django/utils/functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/django/urls/resolvers.py", line 628, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/django/utils/functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/django/urls/resolvers.py", line 621, in urlconf_module
    return import_module(self.urlconf_name)
  File "/usr/local/Cellar/[email protected]/3.10.0_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/Users/<USER>/Projects/ian/<project>/src/tapin/urls.py", line 24, in <module>
    path('forest', include('django_forest.urls')),
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/django/urls/conf.py", line 34, in include
    urlconf_module = import_module(urlconf_module)
  File "/usr/local/Cellar/[email protected]/3.10.0_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/django_forest/urls.py", line 5, in <module>
    from .authentication import urls as authentication_urls
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/django_forest/authentication/urls.py", line 4, in <module>
    from . import views
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/django_forest/authentication/views/__init__.py", line 1, in <module>
    from .callback import CallbackView
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/django_forest/authentication/views/callback.py", line 5, in <module>
    from oic.oauth2 import AuthorizationResponse
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/oic/oauth2/__init__.py", line 18, in <module>
    from oic.oauth2.base import PBase
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/oic/oauth2/base.py", line 10, in <module>
    from oic.oauth2.util import set_cookie
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/oic/oauth2/util.py", line 12, in <module>
    from oic.utils.sanitize import sanitize
  File "/Users/<USER>/.local/share/virtualenvs/<project>-aqsNCo9p/lib/python3.10/site-packages/oic/utils/sanitize.py", line 2, in <module>
    from collections import Mapping
ImportError: cannot import name 'Mapping' from 'collections' (/usr/local/Cellar/[email protected]/3.10.0_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/collections/__init__.py)

Context

  • Python Version: 3.10.0
  • Package Version: django-forestadmin==1.0.5
  • Django Version: django==4.0b1

The automated release is failing 🚨

🚨 The automated release from the main branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you can benefit from your bug fixes and new features again.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can fix this 💪.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the main branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here are some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


No Slack web-hook defined.

A Slack Webhook must be created and set in the SLACK_WEBHOOK environment variable on your CI environment.

Please make sure to create a Slack Webhook and to set it in the SLACK_WEBHOOK environment variable on your CI environment. Alternatively, provide slackWebhook as a configuration option.


Good luck with your project ✨

Your semantic-release bot 📦🚀

Onboarding - No schema synchronisation on server start, developer stuck in the last onboarding page "waiting for your backend to run..."

Expected behavior

The onboarding should be smooth with a schema synchronisation success that let the developer enter its newly generated admin panel.

Actual behavior

The developer is stuck, "waiting for the backend to run...", because the .forestadmin-schema.json is not sent to Forest Admin on backend application start. Is the ̀forestadmin-schema.json` generated? 🤷‍♂️

Failure Logs

  • Did the server started properly and is accessible?
  • Is the .forestadmin-schema.json generated?
  • Can we see the logs generated on start?

Context

  • Package Version: v1.0.5
  • Django Version: ?

JSON schema file name and location should not be hard-coded

Expected behavior

The file .forestadmin-schema.json is very important and, it will trigger an error in production will be triggered.

At least, it should be defined as a constant and properly documented. Related to this issue is the undocumented behavior of how and when it is generated (it depends on the value of settings.DEBUG).

Bonus: customizable name and location through Django settings.

Actual behavior

The filename is hard-coded in two methods of django_forest.utils.schema.Schema

  • handle_schema_file_production
  • handle_schema_file

@classmethod
def handle_schema_file_production(cls, file_path):
try:
with open(file_path, 'r') as f:
data = f.read()
try:
cls.schema_data = json.loads(data)
except Exception:
logger.error('The content of .forestadmin-schema.json file is not a correct JSON.')
logger.error('The schema cannot be synchronized with Forest Admin servers.')
except Exception:
logger.error('The .forestadmin-schema.json file does not exist.')
logger.error('The schema cannot be synchronized with Forest Admin servers.')
@staticmethod
def get_serialized_collection(collection):
for index, field in enumerate(collection['fields']):
fields = list(FIELD.keys()) + ['validations', 'enums']
collection['fields'][index] = {x: field[x] for x in field if x in fields}
return collection
@classmethod
def handle_schema_file(cls):
file_path = os.path.join(os.getcwd(), '.forestadmin-schema.json')

TODO: Please provide any relevant information about your setup.

  • Package Version: 1.5.0
  • Django Version: irrelevant

`get_hook_result` not targeting the specified action

Expected behavior

HookView::get_hook_result does not search for the specific hook. It is expected that the action_name be respected, and only that action's hook be executed.

Actual behavior

The returned value is incorrect, as it could be None, or, the result of another action's hook. In the current implementation, it will be the last registered action's hook's result.

Context

  • Package Version: 1.3.3
  • Django Version: 3.2.13

Replace insecure and unmaintained indirect dependencies of `oic` (`pyjwkest`)

Expected behavior

All the code used for cryptography, authentication or authorization related operations must be top notch, from popular, maintained and robust libraries.

A popular saying applies: "Good friends don't let friends program cryptography"

Actual behavior

Library oic (OIC = OpenID Connect) uses a crypto-related library that is unmaintained, and has been unable to replace it for over 4 years.

  • pyjwkest has a very clear message: "NOTE!! This library is NOT actively maintained anymore." It has not had a release in the last six years.

The ideas of switching to any of these libraries have utterly failed

Not crypto-related but with cybersecurity relevance:

Failure Logs

Check out these alternatives:

  • OAuthLib + Django OAuth Toolkit
    • oauthlib): "Python Framework for OAuth1 & OAuth2". "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic for Python 3.6+."
    • django-oauth-toolkit: "Django OAuth Toolkit can help you providing out of the box all the endpoints, data and logic needed to add OAuth2 capabilities to your Django projects. Django OAuth Toolkit makes extensive use of the excellent OAuthLib, so that everything is rfc-compliant."
  • Authlib (lepture/authlib): "The ultimate Python library in building OAuth and OpenID Connect servers." Includes integrations with Django, Flask, and other Python web frameworks.

Failure Logs

N/A

Context

N/A

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.