cuducos / minha-receita Goto Github PK
View Code? Open in Web Editor NEW🏢 Sua API web para consulta de informações do CNPJ da Receita Federal
Home Page: https://minhareceita.org
License: MIT License
🏢 Sua API web para consulta de informações do CNPJ da Receita Federal
Home Page: https://minhareceita.org
License: MIT License
Bom dia!
Parabéns pelo projeto, muito bacana.
Percebi que o valor do capital social está vindo sempre multiplicado por um fator de 100x (para qualquer CNPJ).
Originalmente o dado é do tipo decimal/float, mas no projeto ele é convertido para inteiro e pode estar incorporando os dois zeros após a vírgula.
Para fins de comparação, deixo aqui o valor retornado para o capital social do CNPJ e o que consta em outros mecanismos de consulta (e também o que consta na base de dados da receita):
"cnpj": "10942831000136", "identificador_matriz_filial": 1, "descricao_matriz_filial": "Matriz", "razao_social": "COMERCIAL VANGUARDEIRA EIRELI", "nome_fantasia": "VANGUARDEIRA", "capital_social": 6220000,
Informações de Registro
CNPJ: 10.942.831/0001-36 - 10942831000136
Razão Social: Comercial Vanguardeira Eireli
Nome Fantasia: Vanguardeira
Data da Abertura: 29/06/2009
Capital Social: R$ 62.200,00
Tipo: MATRIZ
Situação: ATIVA
Fonte: https://cnpj.biz/10942831000136
Obrigado (:
Em Go, essas são sempre em maiúsculas.
Algumas que notei que precisam ser atualizadas: Cnpj
, Cep
, Uf
, Ddd
e Mei
.
Atualmente o erro aparece depois de um tempo de espera, e é:
Error: error saving companies: error saving companies: error while importing data to postgres : exec: "psql": executable file not found in $PATH
Usage:
minha-receita transform [flags]
Flags:
-b, --batch-size int size of the batch to save to the database (default 8192)
-c, --clean-up drop & recreate the database table before starting
-u, --database-uri string PostgreSQL URI (default POSTGRES_URI environment variable)
-d, --directory string directory of the downloaded CSV files (default "data")
-h, --help help for transform
-m, --max-parallel-db-queries int maximum parallel database queries (default 32)
-s, --postgres-schema string PostgreSQL schema (default "public")
error saving companies: error saving companies: error while importing data to postgres : exec: "psql": executable file not found in $PATH
exit status 1
No site oficial da Receita Federal existe a informação sobre quando os dados foram atualizados:
Seria interessante essa informação fazer parte do ETL e da API.
Uma sugestão de implementação (depende de #95):
No comando download
já lemos essa página para extrair as URLs dos arquivos CSV, então poderíamos identificar essa data e salvá-la junto com os dados. No PostgreSQL esse comando pode ser uma query única que cria uma tabela (caso ela não exista, apenas) e faz upsert no único registro dessa tabela com o conteúdo desse arquivo.
last_update.txt
já no formato YYYY-MM-DD
no comando download
413fbf2SaveLastUpdate() error
na interface transform.database
create.sql
, drop.sql
e o novo método, algo como SaveLastUpdate(date string)
transform
/last_updated
na APIdocs/cliente.md
Exemplos de SQL:
CREATE TABLE IF NOT EXISTS public.last_update (
id INTEGER PRIMARY KEY,
last_updated_on date
);
INSERT INTO public.last_update (id, last_updated_on)
VALUES(1, '2021-10-20')
ON CONFLICT (id)
DO UPDATE SET last_updated_on = '2021-10-20';
Exemplo de resposta para GET /last_updated
{"last_updated_on": "2021-10-20"}
Oi,
Gostaria de saber se existe um motivo em específico por não ser feito o parse dos emails dos contribuintes e tê-los adicionado na tabela final de empresas.
Caso não tenha, seria possível adicionar esta informação visto que elas vem junto nos arquivos da receita?
Fora isso, obrigado pelo repo :)
Como dito em #27 (comment):
Enão entendo por que o endpoint é uma chamada POST ao invés de GET
Acho que isso não está documentado em nenhum lugar mesmo — falha minha. A ideia era priorizar a privacidade. Passando o CNPJ como parte do corpo da requisição HTTPS, ele fica encriptado e as camadas intermediárias (provedor, proxies, VPN) não precisam saber qual CNPJ você está consultando.
O código do município devolvido pela API é um código chamado "TOM", que possui 4 dígitos e, aparentemente, é um padrão interno da SERPRO. Neste link encontrei uma referência a isto.
Com a finalidade de padronizar a cidade com código IBGE e facilitar a integração, poderíamos criar um arquivo com a referência do código TOM em relação ao código IBGE e expor, também, o código IBGE do município na API?
Olá,
Estou tentando subir a aplicação e está apresentando um erro ao carregar o container feed com 'docker-compose up feed'.
Já fiz várias tentativas e ainda sem sucesso.
De acordo com #27 (comment), não há necessidade de manter a interface como POST.
Atualmente o projedo depende do go-pg
, mas esse projeto diz no README.md
:
go-pg is in a maintenance mode and only critical issues are addressed. New development happens in Bun repo which offers similar functionality but works with PostgreSQL, MySQL, MariaDB, and SQLite.
Talvez seja remover essa dependência que agora é minimamente mantida.
Algumas alternativas:
Usar o Bun
Prós: provavelmente API semelhante, compatibilidade com outros bancos de dados
Contra: como usamos arquivos .sql
(ou seja, queries customizadas) ao invés do ORM, a sintaxe do PostgreSQL (que temos agora) pode não ser compateivel com os outros bancos — especialmente pensando nas possibilidades, no potencial que temos com JSON no PostgreSQL
Usar apenas um drive de PostgreSQL
Prós: KISS, remoção de um ORM que não utilizamos
Contrta: talvez teremos que lidar com conexão do banco de dados de uma forma mais explícita
Na branch go
o CSV gerado contém erros que quebram a importação pelo Postgres.
Como reproduzir
docker-compose up -d postgres
(ou inicie o PostgreSQL da maneira que preferir)POSTGRES_URI
com as crdenciais do PostgreSQL (por exemplo, postgres://minhareceita:minhareceita@localhost:5432/minhareceita?sslmode=disable
)go run main.go drop
(caso o banco de dados já exista e tenha dados, vamos limpar e começar do zero)go run main.go create
go run main.go download
(sugiro usar o --mirror
)go run main.go parse
Isso vai gerar os arquivos data/empresa.csv.gz
e data/socio.csv.gz
(entre outros), mas o PostgreSQL não consegue importar esses dois arquivos. O comando import
não mostra erros, mas manualmente é possível verificá-los:
$ gunzip -c data/empresa.csv.gz | psql $POSTGRES_URI -c "\copy public.empresas FROM STDIN DELIMITER ',' CSV HEADER;"
ERROR: invalid byte sequence for encoding "UTF8": 0xc2 0x4e
CONTEXT: COPY empresas, line 1793
$ gunzip -c data/socio.csv.gz | psql $POSTGRES_URI -c "\copy public.socios FROM STDIN DELIMITER ',' CSV HEADER;"
ERROR: invalid byte sequence for encoding "UTF8": 0xc7 0xd5
CONTEXT: COPY socios, line 12174
Critérios de aceitação
import
mostra os error do PostgreSQL (ao invés de falhar silenciosamente)import
importa os dados do arquivo empresa.csv.gz
import
importa os dados do arquivo socio.csv.gz
Ideias
Penso em implementar um novo comando, validate
para validar os CSVs criados. Podemos usar, por exemplo, o tableschema
e adicionar o esquema dos dados em um diretório schemas
. Creio que isso dá mais segurança sobre os resultados do parse
e ajude a debugar o que está errado nos CSVs.
Step 1/12 : FROM golang:1.15.3-buster as build
1.15.3-buster: Pulling from library/golang
e4c3d3e4f7b0: Pull complete
101c41d0463b: Pull complete
8275efcd805f: Pull complete
751620502a7a: Pull complete
aaabf962c4fc: Pull complete
7883babec904: Pull complete
1791d366c848: Pull complete
Digest: sha256:fb04edf20446eed8af9eb6137d02fdf607f47028a0a806131f8b175a09620aab
Status: Downloaded newer image for golang:1.15.3-buster
---> 4a581cd6feb1
Step 2/12 : WORKDIR /minha-receita
---> Running in 8111a1f54dd8
Removing intermediate container 8111a1f54dd8
---> 01c1a1de18f8
Step 3/12 : ADD go.* ./
---> 00ccaecb6162
Step 4/12 : ADD main.go .
---> 70fded06025f
Step 5/12 : ADD api/ ./api/
---> 19a6101ddff0
Step 6/12 : ADD db/ ./db/
---> 010197122f19
Step 7/12 : RUN go get && go test ./... && go build -o /usr/bin/minha-receita
---> Running in 74a7cefe2a9a
go: finding module for package github.com/cuducos/minha-receita/cmd
go: finding module for package github.com/cuducos/minha-receita/cmd
main.go:7:2: no matching versions for query "latest"
ERROR: Service 'minha-receita' failed to build : The command '/bin/sh -c go get && go test ./... && go build -o /usr/bin/minha-receita' returned a non-zero code: 1
Depende da #71:
db/fs.go
utilizando apenas o sistema de arquivos (sem banco de dados real)docs/servidor.md
Implementar opções como:
Opção | Abreviada com | Descrição |
---|---|---|
--input-directory |
-i |
Diretório onde ficam os arquivos CSV originais da Receita Federal |
--output-directory |
-o |
Diretório onde ficam os arquivos JSON gerador pela Minha Receita |
Apenas temos o código, no campo socios.codigo_qualificacao_socio
. Podemos importar os dados da Receita Federal:
Temos também essa planilha linkada aqui: https://receita.economia.gov.br/orientacao/tributaria/cadastros/cadastro-nacional-de-pessoas-juridicas-cnpj/dados-publicos-cnpj
seria possível ter versão em sqlite ?
Segundo o layout da Receita Federal:
Atualmente no banco de dados e no JSON só temos os códigos numéricos dessa informação, seria legal incluir a descrição (text) também.
Create a test architecture in which a new database is created and provisioned before tests, so we can properly write tests for the search.py
module.
A possible roadmap:
minhareceita_test
database (instead of minhareceita
)minhareceita_test
database with no tablesfeed/import.py
with fixtures on minhareceita_test
Discutindo com o @cuducos sobre isso, a sugestão dele foi algo como minha-receita checksum
:
download
mesmo)--urls-only
Isso pode facilitar dois cenários:
Alguns CNPJs mais recentes estão retornando como não encontrado.
Os dados são disponibilizados (e já baixados pela Minha Receita) no Dados Abertos Sítio RFB Extracao 20.10.2021.zip.
Creio que o ideal seria:
Atualmente, quando a requisição contém um CNPJ válido, mas que não existe, a Minha Receita retorna 204
.
Contexto
Isso surgiu num papo paralelo em outro projeto, mas o resumo é:
A classe de status 2xx (Sucesso) indica que a requisição do cliente foi recebida, compreendida e aceita com sucesso.
(…)
A classe de status 4xx (Erro do cliente) indica que o cliente parece ter se equivocado.
Dúvida
Quais casos de usos vocês experimentaram nos quais uma resposta 204 vazia realmente quebrou um fluxo de trabalho ou impossibilitou a automação com uma API, e que, nessa mesma situação, um 404 com um corpo como {"message": "CNPJ 00.000.000/000-00 não encontrado."}
resolveria?
Boa tarde, tudo bem?
Primeiramente gostaria de agradecer pela disponibilizacao da API.
Gostaria de utilizar a API para buscar um CNAE ao inves de um CNPJ, e como retorno da consulta gostaria da lista das empresas que possuem o mesmo CNAE.
Como tenho pouco conhecimento com docker/programacao nao sei como adaptar. Poderia me auxiliar?
Obrigado,
Sei que temos o README, mas pensando em deixar o uso do projeto minha-receita mais amigável seria importante ter uma página (html) falando sobre o projeto e como consumir a api
Apenas um simples erro de digitação.
O dicionário de resposta está retornando a chave com o nome codigio_municipio
(com um "i" depois do "g") ao invés de codigo_municipio
.
Ao tentar fazer o build do container na branch dev, os testes falham:
--- FAIL: TestGetURLs (0.41s)
download_test.go:221: "http://200.152.38.155/CNPJ/K3241.K03200Y4.D10911.SOCIOCSV.zip" appears 1 in the first array, but 0 in the second array
download_test.go:221: "http://200.152.38.155/CNPJ/K3241.K03200Y7.D10911.SOCIOCSV.zip" appears 1 in the first array, but 0 in the second array
download_test.go:221: "http://200.152.38.155/CNPJ/K3241.K03200Y7.D10710.ESTABELE.zip" appears 0 in the first array, but 1 in the second array
download_test.go:221: "http://200.152.38.155/CNPJ/K3241.K03200Y4.D10710.ESTABELE.zip" appears 0 in the first array, but 1 in the second array
download_test.go:221: "http://200.152.38.155/CNPJ/K3241.K03200Y5.D10710.SOCIOCSV.zip" appears 0 in the first array, but 1 in the second array
download_test.go:221: "http://200.152.38.155/CNPJ/K3241.K03200Y2.D10710.SOCIOCSV.zip" appears 0 in the first array, but 1 in the second array
download_test.go:221: "http://200.152.38.155/CNPJ/K3241.K03200Y0.D10710.SOCIOCSV.zip" appears 0 in the first array, but 1 in the second array
(... truncated ...)
--- FAIL: TestGetFiles (0.26s)
download_test.go:98: Unexpected URL in getFiles result: http://200.152.38.155/CNPJ/K3241.K03200Y0.D10911.EMPRECSV.zip
download_test.go:98: Unexpected URL in getFiles result: http://200.152.38.155/CNPJ/K3241.K03200Y1.D10911.EMPRECSV.zip
download_test.go:98: Unexpected URL in getFiles result: http://200.152.38.155/CNPJ/K3241.K03200Y2.D10911.EMPRECSV.zip
download_test.go:98: Unexpected URL in getFiles result: http://200.152.38.155/CNPJ/K3241.K03200Y3.D10911.EMPRECSV.zip
download_test.go:98: Unexpected URL in getFiles result: http://200.152.38.155/CNPJ/K3241.K03200Y4.D10911.EMPRECSV.zip
download_test.go:98: Unexpected URL in getFiles result: http://200.152.38.155/CNPJ/K3241.K03200Y5.D10911.EMPRECSV.zip
download_test.go:98: Unexpected URL in getFiles result: http://200.152.38.155/CNPJ/K3241.K03200Y6.D10911.EMPRECSV.zip
download_test.go:98: Unexpected URL in getFiles result: http://200.152.38.155/CNPJ/K3241.K03200Y7.D10911.EMPRECSV.zip
(... truncated ...)
Downloading 100% |█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| (428/428 kB, 11.476 MB/s)
FAIL
exit status 1
FAIL github.com/cuducos/minha-receita/download 0.705s
Aparentemente o cliente http de httptest.Server, ao receber uma URL "válida", está fazendo uma conexão com os servidores oficiais ao invés de "baixar" o HTML de teste em "testdata/dados-publicos-cnpj.html". Alterando a função TestGetURLs():
//got, err := getURLs(ts.Client(), federalRevenue)
got, err := getURLs(ts.Client(), ts.URL)
Os testes em "TestGetURLs" passam, mas os testes em "TestGetFiles" falham, porque internamente, a função getFiles() utiliza a constante federalRevenue, que é a URL do site oficial.
Em um computador com Ubuntu eu instalei o Go e depois o postgresql - nunca usei eles
Parti das orientações aqui - https://docs.minhareceita.org/instalacao/
No terminal depois tentei isso:
$ go get
go: go.mod file not found in current directory or any parent directory; see 'go help modules'
Por favor, eu preciso instalar mais algo? Ou fazer outra configuração?
É possível, por exemplo, baixar dois CSVs com a base inteira da Receita? Assim:
1 - Um CSV com um CNPJ por linha, com dados básicos da empresa - com key o CNPJ
2 - Um CSV com os sócios de cada empresa em cada linha, então o mesmo CNPJ pode se repetir nas linhas - depende do número de sócios. Aqui as chaves seriam o CNPJ, mas também depois para orientação o nome completo dos sócios e o CPF mascarado
Originally posted by @reichaves in #118 (comment)
Ao invés de retornar o CPF dos sócios vazio, pelo menos o CPF mascarado
##Nestes casos abaixo nenhum deles retornam CPF dos sócios, pode ter sido azar meu, ou não é retornado hoje?
https://minhareceita.org/90400888000142
https://minhareceita.org/33014556000196
https://minhareceita.org/00000000000191
Instalar e rodar o go-staticchecker
na tarefa lint do CI.
Olá!
Seguindo os passos descritos descritos em https://docs.minhareceita.org/instalacao/ estou tendo o seguinte erro ao tentar rodar o projeto:
[I] minha-receita (docs/env-setup): docker-compose run --rm minha-receita
Creating network "minha-receita_default" with the default driver
Creating minha-receita_postgres_1 ... done
Creating minha-receita_minha-receita_run ... done
2021/02/24 11:32:24 No POSTGRES_SCHEMA environment variable found, using public.
Could not connect to PostgreSQL: dial tcp 172.20.0.2:5432: connect: connection refused
O mesmo acontece caso rode com:
docker-compose up
Devo especificar a variável de ambiente POSTGRES_SCHEMA ou o schema public já deveria funcionar?
Agora que existem testes de integração dependentes de um PostgreSQL rodando, não faz sentido rodar os testes no build.
Using docker-compose.
After run command bellow:
$ docker-compose run --rm minha-receita download --directory /mnt/data/
The following error is presented:
2020/12/18 21:51:47 Preparing to downlaod from the Federal Revenue official website…
Downloading 0% | | (60 kB/6.7 GB, 173.613 kB/s) [0s:11h10m17s] panic: Get "https://cnae.ibge.gov.br/images/concla/documentacao/CNAE_Subclasses_2_3_Estrutura_Detalhada.xlsx": x509: certificate signed by unknown authority
Traceback (most recent call last):
feed_1 | File "import.py", line 130, in <module>
feed_1 | main()
feed_1 | File "import.py", line 104, in main
feed_1 | if wait_for_postgres() and tables_exist():
feed_1 | File "import.py", line 88, in wait_for_postgres
feed_1 | return wait_for_postgres(retries)
feed_1 | File "import.py", line 88, in wait_for_postgres
feed_1 | return wait_for_postgres(retries)
feed_1 | File "import.py", line 88, in wait_for_postgres
feed_1 | return wait_for_postgres(retries)
feed_1 | [Previous line repeated 984 more times]
feed_1 | File "import.py", line 81, in wait_for_postgres
feed_1 | result = psql("SELECT 1", capture_output=True)
feed_1 | File "import.py", line 25, in psql
feed_1 | return run(["psql", POSTGRES_URI, "-c", sql], capture_output=capture_output)
feed_1 | File "/usr/local/lib/python3.7/subprocess.py", line 488, in run
feed_1 | with Popen(*popenargs, **kwargs) as process:
feed_1 | File "/usr/local/lib/python3.7/subprocess.py", line 800, in __init__
feed_1 | restore_signals, start_new_session)
feed_1 | File "/usr/local/lib/python3.7/subprocess.py", line 1472, in _execute_child
feed_1 | for dir in os.get_exec_path(env))
feed_1 | File "/usr/local/lib/python3.7/os.py", line 635, in get_exec_path
feed_1 | warnings.simplefilter("ignore", BytesWarning)
feed_1 | File "/usr/local/lib/python3.7/warnings.py", line 179, in simplefilter
feed_1 | _add_filter(action, None, category, None, lineno, append=append)
feed_1 | File "/usr/local/lib/python3.7/warnings.py", line 186, in _add_filter
feed_1 | filters.remove(item)
feed_1 | RecursionError: maximum recursion depth exceeded in comparison
Usando ubuntu 20.4, com python 3.8
does it make sense to provide docker images directly on dockerhub?
we could automate this workflow using github actions
Meu servidor do postgres tem um HD. Está pedindo 10 dias para incluir os registros. Alguma dica de como acelerar o processo de escrita no postgresql?
Depende da #92:
docker-compose.yml
db/mongo.go
docs/servidor.md
CONTRIBUTING.md
doscs/servidor.md
minha-receita/db/postgres_sql.go
Line 115 in 73610bf
minha-receita/db/postgres_sql.go
Line 119 in 73610bf
Fazendo o build com docker-compose localmente esbarrei nesse erro abaixo:
github.com/cuducos/minha-receita/cmd imports
github.com/cuducos/minha-receita/sample: cannot find module providing package github.com/cuducos/minha-receita/sample
The command '/bin/sh -c go get && go build -o /usr/bin/minha-receita' returned a non-zero code: 1
ERROR: Service 'minha-receita' failed to build : Build failed
Percebi que o diretório /sample não é adicionado no Dockerfile, e quando o feito, resolve o problema.
Abro um PR para isso ou ignorei alguma coisa?
A RFB informa aos usuários das informações disponibilizadas sobre os dados cadastrais do CNPJ - DADOS ABERTOS, que a partir da divulgação do mês de março de 2021, passará a contar as seguintes novidades:
- A atualização será mensal;
- Contará com novo layout;
- …
Etiquetas
Solução proposta
Ver detalhes da implementação no CONTRIBUTING.md
do #70
Roadmap
Essa refatoração levará muito mais tempo do que eu imaginava, então deixo aqui o planejando e o andamento:
11.222.333/0001-81
, a estratégia é criar arquivo como tmp/11222333/11222333000181.json
e ir enriquecendo esse arquivo com os dados de cada CSV
K3241.K03200Y0.D10612.ESTABELE.zip
) e criar o .json
de cada CNPJF.K03200$Z.D10612.CNAECSV.zip
) e enriquecer o company
antes de escrever o JSONF.K03200$Z.D10612.CNAECSV.zip
) e enriquecer o company
antes de escrever o JSONF.K03200$Z.D10612.MOTICSV.zip
) e enriquecer o company
antes de escrever o JSONF.K03200$Z.D10612.MUNICCSV.zip
) e enriquecer o company
antes de escrever o JSONF.K03200$Z.D10612.PAISCSV.zip
) e enriquecer o company
antes de escrever o JSONK3241.K03200Y0.D10612.EMPRECSV.zip
) e enriquecer o .json
de cada CNPJe Ler CSV de natureza jurídica (ex. F.K03200$Z.D10612.NATJUCSV.zip
) e enriquecer o .json
de cada CNPJK3241.K03200Y1.D10612.SOCIOCSV.zip
) e enriquecer o .json
de cada CNPJF.K03200$W.SIMPLES.CSV.D10612.zip
) e enriquecer o .json
de cada CNPJImportData
para não depender de arquivo CSVPRs auxiliares
(Desconsiderem o #40: o desenvolvimento será feito em PRs menores direcionados à branch dev
.)
De acordo com a decisão tomada na issue #29 e implementada no PR #35, a API web utiliza o método GET como principal. Como temos usos que podem não acompanhar essa mudança, se faz necessário, ainda que de forma temporária, dar suporte aos dois métodos — o POST utilizado anteriormente, e o GET, implementado recentemente — antes de fazer o merge na main
e gerar um novo deploy.
Como sugeri no #35, a ideia seria:
em caso de POST:
- Receber e verificar se veio com CNPJ
- Caso não seja, retornar 405
- Se vier com CNPJ, ter certeza de que é um CNPJ válido
- Caso não seja, retornar 405
- Retornar 303 redirecionando para um GET com a URL correta
Assim mantemos retrocompatibilidade, e damos um tempo para tirar o suporte a POST.
Sometimes the progress bar for the download
command in the dev
branch goes beyond the expected total:
Downloading 100% |██████████████████████████████████████| (5.8/4.9 GB, 370.135 kB/s)
Note the 5.8 GB out of 4.9 GB.
Probably this is because some downloads fail, then we restart them from the beginning but keep the downloaded bytes in the progress bar counter.
I won't fix that or review PRs related to that until #37 is over, though — either way, feel free to contribute and I get back to code or code review once the priority is covered : )
Após rodar docker-compose exec minha-receita minha-receita import -d /mnt/data o script não importa dados das empresas e sócios na tabela do banco Postgre, embora as tabelas de cnaes fiquem preenchidas.
Alguém já passou por isso? como resolver? O que poderia gerar esse problema?
Apenas temos o código, no campo empresas.codigo_natureza_juridica
. Podemos importar os dados da Receita Federal:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.