Code Monkey home page Code Monkey logo

openfoodfacts-python's Introduction

Open Food Facts Python SDK

Open Food Facts

Status

Project Status Build Status codecov Latest Version License: MIT

Description

This is the official Python SDK for the Open Food Facts project. It provides a simple interface to the Open Food Facts API and allows you to:

  • Get information about a product
  • Perform text search
  • Create a new product or update an existing one

It also provides some helper functions to make it easier to work with Open Food Facts data and APIs, such as:

  • getting translation of a taxonomized field in a given language
  • downloading and iterating over the Open Food Facts data dump
  • handling OCRs of Open Food Facts images generated by Google Cloud Vision

Please note that this SDK is still in beta and the API is subject to change. Make sure to pin the version in your requirements file.

Installation

The easiest way to install the SDK is through pip:

pip install openfoodfacts

or manually from source:

git clone https://github.com/openfoodfacts/openfoodfacts-python
cd openfoodfacts-python
python setup.py install

Examples

All the examples below assume that you have imported the SDK and instanciated the API object:

import openfoodfacts

# User-Agent is mandatory
api = openfoodfacts.API(user_agent="MyAwesomeApp/1.0")

Get information about a product

code = "3017620422003"
api.product.get(code, fields=["code", "product_name"])
# {'code': '3017620422003', 'product_name': 'Nutella'}

Perform text search

api.product.text_search("mineral water")
# {"count": 3006628, "page": 1, "page_count": 20, "page_size": 20, "products": [{...}], "skip": 0}

Create a new product or update an existing one

results = api.product.update({
    "code": CODE,
    "product_name_en": "blueberry jam",
    "ingredients_text_en": "blueberries, sugar, pectin, citric acid"
})

with CODE the product barcode. The rest of the body should be a dictionary of fields to create/update.

To see all possible capabilities, check out the usage guide.

Third party applications

If you use this SDK, feel free to open a PR to add your application in this list.

Contributing

Any help is welcome, as long as you don't break the continuous integration. Fork the repository and open a Pull Request directly on the "develop" branch. A maintainer will review and integrate your changes.

Maintainers:

Contributors:

Copyright and License

Copyright 2016-2024 Open Food Facts

The Open Food Facts Python SDK is licensed under the MIT License.

openfoodfacts-python's People

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

openfoodfacts-python's Issues

Package for Conda

I saw #41 is pending yet, but I think it might be interesting to have this package in Conda too, because it is used quite a lot, especially in the scientific-linked open data environment. Building a conda doesn't seem very hard. I have never build one, but I could try it. There are many documentation about it.

What do you think?

Add Reuse compliance

https://reuse.software/ is a proposed tool and standard to help people using a software knowing its licenses.

It would be good to try to implement it in this project, as this makes totally sense for a SDK and this project is small enough to test it well.

Edit by pierre: https://reuse.software/dev/

Implementing reuse

KeyError: 'products' when trying to access ingredients

Hi,

I'm trying to access ingredients using the line:
openfoodfacts.facets.get_ingredients()

However, I get the error:
KeyError: 'products'

What could be the causes of this error?

Do I need an account to be able to access the ingredients? I created an account and tried to login using this line:
login_session_object = openfoodfacts.utils.login_into_OFF()

It says mismatched username and passoword - but I'm sure that I've typed them correctly.

I'm using python 3.8.8 and Jupyter notebook.

Updating the pull request template

The current pull request template is very basic and lacks the "Fixes" keyword for closing issues easily.

This template needs to be updated with the above suggestions, as it will be very helpful when a new user wants to contribute. It also allows maintainers to manage PRs and issues easily.

Allow to specify the locale

Results can be returned for different locales by the API. This lib in the current state doesn't allow to take advantage of it.

Addition to the Usage Guide

Hello,

I am developing a smart shopping cart as part of my training to become a state-certified mechatronics technician. And for this I found your opensource data and thought that it is really nice. So I began to browse through the files but they are a bit complicated. Then I found the Usage Guide but it didnt help me really much.
So I would like to suggest some points for the Usage Guide. Some points which maybe are nomal for more experienced programmers but not for everyone.

Something like how you can import the modul and some methods how you handle this then. And what you have to do to connect to the server(api):

I use this one:

api_url = "[https://world.openfoodfacts.org/api/v0/product/{}.json]".format(barcode)
response = requests.get(api_url)
if response.status_code == 200:
data = response.json()
product_name = data["product"]["product_name"]
return product_name
else:
return None


Some examples for the basic functions to get the only the different parameters of a product like the name. Yes i can look into the json data(https://world.openfoodfacts.org/api/v0/product/737628064502.json) but it is very much and how the informations are used, is not clear.

Thank you very much

Greetings

Sascha Fast

Allow to perform a search

Ex: Get data from:
http://world.openfoodfacts.org/cgi/search.pl?search_terms=banania&search_simple=1&action=process&json=1

Require a custom user agent to use the SDK

What

  • Require a custom user agent to use the SDK
  • Using the SDK and the API in general will remain as of today: free and accessible for everyone.
    IN the same way, we don't want to implement an API key mechanism and all that kind of stuff.
  • However, due to misuse of the API through various SDKs, we will now force all language clients to have a valid User Agent so that we can reach out in case of problems.
  • For now, We will only require an app name for the user agent.

Extend ProductDataset to other flavors (obf, opf, opff)

Story

In the code (here) the ProductDataset is hardcoded to fetch only the OFF database.

It would be great to allow choosing other flavors (OBF, OPF, OPFF) as a new parameter.

Btw is there dumps of these datasets or do they behave differently than OFF ?

Implement FacetContainer Class

With reference to Issue #69 and the proposed changes to the method of retrieval of data from facets in #69 (comment) a brief summary of the expected changes is as follows

  • Implementation of Pagination via FacetContainer Class with respect to the data retrieved from facets.
  • Implementation of various methods inside FacetContainer Class so as to provide easy and efficient means of accessing, manipulating and moving data.
  • Implementation of a python based filesystem cache module in order to locally store, and speed up retrieval of previously fetched facet data.
  • Extend FacetContainer Class to include support for the above mentioned cache module.
  • Implement appropriate and thorough tests for each of the above mentioned features.

Quoting Proposed Changes

Even though, we can surely increase the limit on the number of records returned, it will almost certainly lead to a decrease in performance and increased waiting times. A suggested way to solve this issue would be to create a set of new functions which handle pagination. We could have 2 different types of functions : get_all_<facet_name>() and get_page_<facet_name>()
The get_all_<facet_name>() function would internally call the get_page_<facet_name>() function repeatedly until all the pages have been fetched one by one. Since this data can be large we can create a FacetContainer which shall store the entire fetched data while also providing easy and efficient access to functions which can be helpful in manipulating and moving the data around.

Combined, these 2 suggestions if implemented, should be able to solve the following issues

  • #69 : By dividing the entire available data into pages and also providing control over the number of records which should be returned per page.
  • #56 : The second part of this feature implementation involves the use of the FacetContainer class to implement functions to aid in Data Manipulation and movement. This class can be used to add more precise filters to the data stored inside it thereby acting as a powerful tool for working with records.

Originally Post by @Ansh-Sarkar in #69 (comment)

Document or Increase the maximum amount of results using facets

I have the impression that the maximum number of echoes when requesting using facets is 10 000. I don't see that mentionned in the README or in the doc. Is it possible to get more results ? (maybe I am doing something wrong)

Otherwise, mentionning that in the README would be useful.

import openfoodfacts
import pandas as pd

brands = openfoodfacts.facets.get_brands()
brands = pd.json_normalize(brands)
brands.shape
# (10000, 5)
packagings = openfoodfacts.facets.get_packaging()
packagings = pd.json_normalize(packagings)
packagings.shape
# (10000, 6)

Problem with product search, something is certainly hardcoded

What

The App always return the result for "eau mineral" (I guess it's for this because it's always starting with cristaline)
which is basically making the API useless

Steps to reproduce the behavior:

import openfoodfacts
api = openfoodfacts.API(version="v2")
results = api.product.text_search("Tomate")

Expected behavior

Return products data that are in link with Tomate and not "mineral water"

Platform (Desktop, Mobile, Hunger Games)

  • OS: MACOS
  • Platform MacBook AIR

Update a product does not work with code parameter

What

In theory, according to the documentation (https://github.com/openfoodfacts/openfoodfacts-python/blob/develop/docs/usage.md), we can update products with 2 parameters.

results = api.product.update(CODE, body)

In practice, a single parameter is accepted:

    results = api.product.update('8000300404425', body)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: ProductResource.update() takes 2 positional arguments but 3 were given

Steps to reproduce the behavior:

Try to update a product (in DEV!).

Expected behavior

Need to update: https://github.com/openfoodfacts/openfoodfacts-python/blob/develop/openfoodfacts/api.py
This function exactly:

def update(self, body: Dict[str, Any]):
     """Create a new product or create it if it doesn't exist yet."""
     if not body.get("code"):
         raise ValueError("missing code from body")

     url = f"{self.base_url}/cgi/product_jqm2.pl"
     return send_for_urlencoded_post_request(url, body, self.api_config)

Two options:

  • add code as parameter for that function (preferred option because documentation tells that and there is condition if not body.get("code"))
  • update documentation and the condition in the function

Remark: beside this bug, it is possible to update a product by providing only the body as parameter and put the code in the body itself.

We could rephrase that sentence, too:
"""Create a new product or create it if it doesn't exist yet."""

how to get categories by page

i can get how to have categories by page with page_size. running facets.get_categories() is very long, i would like to load page by page my view from a thread...
thank you

🎯 What can I work on ? (Python SDK)

Simplify developer flow

  1. DevOps github_actions
  2. github_actions
    aadarsh-ram
  3. 📦 Packaging

Add new and missing features

  1. API READ Facets documentation
  2. ✨ enhancement
  3. API WRITE - Photos ✨ enhancement
  4. API WRITE

GENERAL

READ

PERSONALIZATION

SEARCH

Search V2 - Tag types

WRITE

ML/OCR

Process

  • Capture the barcode of the product where you want to perform the OCR.
  • The Product Opener server software opens the image (process_image=1)
  • Product Opener returns a JSON response. Processing is done using Tesseract or Google Cloud Vision (recommended). The result is often cripped with errors with Tesseract, less with Google Cloud Vision.

Notes:

  • The OCR may contain errors. Encourage your users to correct the output using the ingredients WRITE API.
  • You can also use your own OCR, especially if to plan to send a high number of queries.

Parameters
Test server: https://world.openfoodfacts.org/cgi/ingredients.pl
code=code
id=imagefield
process_image=1

Roadmap

HISTORY_PRODUCT missing

11-14 18:55:16.889 20401-20401/openfoodfacts.github.scrachx.openfood I/Choreographer: Skipped 36 frames! The application may be doing too much work on its main thread.
11-14 18:55:17.445 20401-20401/openfoodfacts.github.scrachx.openfood E/SQLiteLog: (1) no such table: HISTORY_PRODUCT
11-14 18:55:17.446 20401-20401/openfoodfacts.github.scrachx.openfood D/AndroidRuntime: Shutting down VM
11-14 18:55:17.448 20401-20401/openfoodfacts.github.scrachx.openfood E/AndroidRuntime: FATAL EXCEPTION: main
Process: openfoodfacts.github.scrachx.openfood, PID: 20401
android.database.sqlite.SQLiteException: no such table: HISTORY_PRODUCT (code 1): , while compiling: SELECT * FROM HISTORY_PRODUCT WHERE barcode = ?
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteQuery.(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1318)
at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1165)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1036)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1242)
at com.orm.SugarRecord.find(SugarRecord.java:201)
at com.orm.SugarRecord.find(SugarRecord.java:187)
at openfoodfacts.github.scrachx.openfood.network.OpenFoodAPIClient$1.onResponse(OpenFoodAPIClient.java:109)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:66)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6088)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

Support paging

Currently, the library only returns 20 products, which is the first page of results provided by the API.

Steps to reproduce

>>> import openfoodfacts
>>> len(openfoodfacts.products.get_by_state("nutrition_facts_completed"))
20

Expected result
Option to page through the results. Results count should be > 62k (see https://world.openfoodfacts.org/state/nutrition-facts-completed )

facets.get_ingredients("en") & facets.get_states("en") raises ValueError

get_ingredients() and get_states() raises when called with locale="en"
Moreover, get_ingredients() returns an empty list when called with "fr" and "world"

In [9]: openfoodfacts.facets.get_ingredients("en")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
ipython-input-9-ba2498bfb4a8 in module()
----> 1 openfoodfacts.facets.get_ingredients("en")

/usr/local/lib/python2.7/dist-packages/openfoodfacts/__init__.pyc in func(locale)
     24                                resource_type=facet)
     25
---> 26         return utils.fetch(path)['tags']
     27
     28     func.__name__ = "get_%s" % facet

/usr/local/lib/python2.7/dist-packages/openfoodfacts/utils.pyc in fetch(path, json_file)
    113
    114     response = requests.get(path)
--> 115     return response.json()
    116
    117

/usr/local/lib/python2.7/dist-packages/requests/models.pyc in json(self, **kwargs)
    890                     # used.
    891                     pass
--> 892         return complexjson.loads(self.text, **kwargs)
    893
    894     @property

/usr/lib/python2.7/json/__init__.pyc in loads(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    337             parse_int is None and parse_float is None and
    338             parse_constant is None and object_pairs_hook is None and not kw):
--> 339         return _default_decoder.decode(s)
    340     if cls is None:
    341         cls = JSONDecoder

/usr/lib/python2.7/json/decoder.pyc in decode(self, s, _w)
    365         end = _w(s, end).end()
    366         if end != len(s):
--> 367             raise ValueError(errmsg("Extra data", s, end, len(s)))
    368         return obj
    369

ValueError: Extra data: line 1 column 22 - line 10 column 1 (char 21 - 363)

Travis build failing

@frankrousseau : Travis notifications are now available on Slack, shortly after you commit. The build is currently broken (looks like an encoding issue)

writing manifest file 'openfoodfacts.egg-info/SOURCES.txt'
running build_ext
Traceback (most recent call last):
File "setup.py", line 63, in
extras_require={
File "/opt/python/2.7.9/lib/python2.7/distutils/core.py", line 151, in setup
dist.run_commands()
File "/opt/python/2.7.9/lib/python2.7/distutils/dist.py", line 953, in run_commands
self.run_command(cmd)
File "/opt/python/2.7.9/lib/python2.7/distutils/dist.py", line 972, in run_command
cmd_obj.run()
File "/home/travis/virtualenv/python2.7.9/lib/python2.7/site-packages/setuptools/command/test.py", line 142, in run
self.with_project_on_sys_path(self.run_tests)
File "/home/travis/virtualenv/python2.7.9/lib/python2.7/site-packages/setuptools/command/test.py", line 122, in with_project_on_sys_path
func()
File "/home/travis/virtualenv/python2.7.9/lib/python2.7/site-packages/setuptools/command/test.py", line 163, in run_tests
testRunner=self._resolve_as_ep(self.test_runner),
File "/opt/python/2.7.9/lib/python2.7/unittest/main.py", line 94, in init
self.parseArgs(argv)
File "/opt/python/2.7.9/lib/python2.7/unittest/main.py", line 149, in parseArgs
self.createTests()
File "/opt/python/2.7.9/lib/python2.7/unittest/main.py", line 158, in createTests
self.module)
File "/opt/python/2.7.9/lib/python2.7/unittest/loader.py", line 130, in loadTestsFromNames
suites = [self.loadTestsFromName(name, module) for name in names]
File "/opt/python/2.7.9/lib/python2.7/unittest/loader.py", line 103, in loadTestsFromName
return self.loadTestsFromModule(obj)
File "/home/travis/virtualenv/python2.7.9/lib/python2.7/site-packages/setuptools/command/test.py", line 37, in loadTestsFromModule
tests.append(self.loadTestsFromName(submodule))
File "/opt/python/2.7.9/lib/python2.7/unittest/loader.py", line 91, in loadTestsFromName
module = import('.'.join(parts_copy))
File "/home/travis/build/openfoodfacts/openfoodfacts-python/tests/facets_test.py", line 3, in
import openfoodfacts
File "/home/travis/build/openfoodfacts/openfoodfacts-python/openfoodfacts/init.py", line 4, in
from . import utils
File "/home/travis/build/openfoodfacts/openfoodfacts-python/openfoodfacts/utils.py", line 21
SyntaxError: Non-ASCII character '\xe2' in file /home/travis/build/openfoodfacts/openfoodfacts-python/openfoodfacts/utils.py on line 22, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
The command "python setup.py test" exited with 1.
0.11s$ pep8 openfoodfacts/.py
openfoodfacts/utils.py:19:80: E501 line too long (127 characters)
openfoodfacts/utils.py:19:1: E302 expected 2 blank lines, found 1
openfoodfacts/utils.py:19:94: E231 missing whitespace after ','
openfoodfacts/utils.py:23:1: W191 indentation contains tabs
openfoodfacts/utils.py:23:1: E101 indentation contains mixed spaces and tabs
openfoodfacts/utils.py:23:2: E113 unexpected indentation
openfoodfacts/utils.py:24:95: E225 missing whitespace around operator
The command "pep8 openfoodfacts/
.py" exited with 1.
Done. Your build exited with 1.

Query products with advanced_search providing a list of barcodes

Hi!

I am working in a project where i need to compare products obtained by a search in openfoodfacts database with products that I have in my supermarket. The products of my supermarket are stored in a list with their barcode. My first idea was to generate another list with the barcodes of the products that meet a certain query and do the intersection of both lists to find the products that are in my supermarket and appeared in the query.

I did not find an efficient way to do that. I tried using generators but it takes a lot of seconds to generate the list if the query has lots of results. Getting results by pagination gives me better times but still not enough efficient.

I guess it should be a way to do a query but limit the results to only some barcodes. Adding several barcodes in the "code" field with an operator:

search_list=openfoodfacts.products.advanced_search({
    "search_terms":query,
    "code": "3017620422003"or"5449000000996"or"3229820129488"
})

This code only detects the first barcode, others are ignored. If I am missing something please let me know.

Thanks!

Dogfood the new Python package on our own projects

What

  • Dogfood the new Python package on our own projects

Tasks

Part of

Unable to find my packager code with get_packaging_codes()

Some packaging code existing on the web interface is not returned by the get_packaging_codes() function which obviously uses this url.

An example here: https://world.openfoodfacts.org/product/6842420174016/chocolat. The packaging code is EMB 07113Y but it does not appear in the list of packaging codes.

Moreover, I have the impression that the terms packaging_code, packager_code and emb_code that we find indistinctly in the doc design the same thing.

Run tests on each change (continuous integration)

Hello OFF team,

If my PR is merged, this module will have unit tests. They ensure that everything work as expected for most common cases. It would be nice to run these tests everytime a change occurs in the code.

NB: Travis does the job well and is well integrated with Github. I suggest you this platform.

Inconsistency in User Agent Specification in Documentation

Issue: User Agent Parameter Missing in OpenFoodFacts SDK Despite Documentation

What

A discrepancy has been identified in the OpenFoodFacts SDK documentation regarding the ability to set a user agent. The documentation suggests setting a user agent during API initialization, but the SDK's API class constructor does not support this functionality.

Steps to Observe the Discrepancy

  1. The documentation indicates the use of a user_agent parameter in the API initialization as follows:
    api = API(
        user_agent="<application name>",
        ...
    )
  2. However, the actual API class constructor in the SDK lacks the user_agent parameter:
    class API:
        def __init__(
            self,
            username: Optional[str] = None,
            ...
        ) -> None:
            ...

Expected Behavior

The SDK's documentation should accurately reflect its current functionality. If the SDK is intended to support the user_agent parameter, this should be correctly implemented. If not, the documentation should be updated to avoid such mentions.

Suggested Action

Based on this inconsistency, I recommend either:

  • Updating the SDK to include a user_agent parameter in the API class constructor as per the documentation.
  • Amending the documentation to remove any references to setting a user agent if this feature is not supported.

Platform

  • OpenFoodFacts SDK and its official documentation.

Context of Discovery

  • This issue was discovered during my first use of the OpenFoodFacts SDK, leading to initial confusion.

I look forward to a resolution that aligns the SDK with its documentation, ensuring clarity for all future users.

Tests are failing

What

  • Tests are failing

Run # stop the build if there are Python syntax errors or undefined names
./draft.py:61:6: E999 SyntaxError: invalid syntax
with # with_additives
^
./openfoodfacts/init.py:74:13: F821 undefined name 'products'
setattr(products, func.name, func)
^
./openfoodfacts/init.py:89:13: F821 undefined name 'products'
setattr(products, func_all.name, func_all)
^
1 E999 SyntaxError: invalid syntax
2 F821 undefined name 'products'
3
Error: Process completed with exit code 1.

Part of

Create an Open Food Facts account on Pypi.org

Hello all,

What about publishing this client on Pypi.org? That would allow people to install it through this command:

pip install openfoodfacts

For that we need an account on Pypi.org. @teolemon do you think you can create one for the OFF foundation?

Add Anubhav-Bhargava as maintainer of this repository

To @teolemon,

Recently @Anubhav-Bhargava made great contributions to this repo. He is very active and showed that he was able to adapt his coding style to our requirements. It would be good to allow him to maintain this repository with us: it would allow us to ask him to review our own PR and the maintenance of the repositiory would be more reactive.
So, It sounds natural to me to bring him among the maintainer team (if he accepts it of course). What do you think about it?

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.