Os endpoints de pesquisa do Twitter v2 agora incluem um endpoint de 'contagens' que retorna totais de séries temporais de Tweets correspondentes.
Este projeto serve como um wrapper para as APIs premium e de pesquisa corporativa do Twitter, fornecendo um utilitário de linha de comando e uma biblioteca Python. Documentos bonitos podem ser vistos aqui.
jq
). A biblioteca searchtweets
está no Pypi:
pip install searchtweets
Ou você pode instalar a versão de desenvolvimento localmente via
git clone https://github.com/twitterdev/search-tweets-python
cd search-tweets-python
pip install -e .
As APIs de pesquisa premium e corporativa usam métodos de autenticação diferentes e tentamos fornecer uma maneira perfeita de lidar com a autenticação para todos os clientes. Sabemos que as credenciais podem ser complicadas ou irritantes. Leia isto na íntegra.
Os clientes premium exigirão os campos bearer_token
e endpoint
; Os clientes corporativos exigem username
, password
e endpoint
. Se você não especificar account_type
, tentaremos discernir o tipo de conta e declarar um aviso sobre esse comportamento.
Para produtos de pesquisa premium, usamos autenticação somente de aplicativo e os tokens ao portador não são entregues com prazo de validade. Você pode fornecer: - sua chave e segredo do aplicativo (a biblioteca lidará com a autenticação do token de portador) - um token de portador que você mesmo obtém
Muitos desenvolvedores podem achar mais simples fornecer a chave e o segredo do aplicativo e permitir que esta biblioteca gerencie a geração do token ao portador para você. Consulte aqui uma visão geral do método de autenticação premium.
Oferecemos suporte a métodos baseados em arquivos YAML e variáveis de ambiente para armazenar credenciais e fornecemos manuseio flexível com padrões sensatos.
Para clientes premium, o arquivo de credenciais mais simples deve ser assim:
search_tweets_api :
account_type : premium
endpoint : <FULL_URL_OF_ENDPOINT>
consumer_key : <CONSUMER_KEY>
consumer_secret : <CONSUMER_SECRET>
Para clientes corporativos, o arquivo de credenciais mais simples deve ter esta aparência:
search_tweets_api :
account_type : enterprise
endpoint : <FULL_URL_OF_ENDPOINT>
username : <USERNAME>
password : <PW>
Por padrão, esta biblioteca espera este arquivo em "~/.twitter_keys.yaml"
, mas você pode passar o local relevante conforme necessário, com o sinalizador --credential-file
para o aplicativo de linha de comando ou conforme demonstrado abaixo em um Python programa.
Ambos os exemplos acima não requerem argumentos especiais de linha de comando ou argumentos no programa. Os métodos de análise de credenciais, a menos que especificado de outra forma, procurarão uma chave YAML chamada search_tweets_api
.
Para desenvolvedores que possuem vários endpoints e/ou produtos de pesquisa, você pode manter todas as credenciais no mesmo arquivo e especificar chaves específicas a serem usadas. --credential-file-key
especifica esse comportamento no aplicativo de linha de comando. Um exemplo:
search_tweets_30_day_dev :
account_type : premium
endpoint : <FULL_URL_OF_ENDPOINT>
consumer_key : <KEY>
consumer_secret : <SECRET>
(optional) bearer_token : <TOKEN>
search_tweets_30_day_prod :
account_type : premium
endpoint : <FULL_URL_OF_ENDPOINT>
bearer_token : <TOKEN>
search_tweets_fullarchive_dev :
account_type : premium
endpoint : <FULL_URL_OF_ENDPOINT>
bearer_token : <TOKEN>
search_tweets_fullarchive_prod :
account_type : premium
endpoint : <FULL_URL_OF_ENDPOINT>
bearer_token : <TOKEN>
Se desejar ou precisar passar credenciais por meio de variáveis de ambiente, você poderá definir as variáveis apropriadas para o seu produto do seguinte modo:
exportar SEARCHTWEETS_ENDPOINT= exportar SEARCHTWEETS_USERNAME= exportar SEARCHTWEETS_PASSWORD= exportar SEARCHTWEETS_BEARER_TOKEN= exportar SEARCHTWEETS_ACCOUNT_TYPE= exportar SEARCHTWEETS_CONSUMER_KEY= exportar SEARCHTWEETS_CONSUMER_SECRET=
A função load_credentials
tentará encontrar essas variáveis se não puder carregar campos do arquivo YAML e substituirá quaisquer credenciais do arquivo YAML que estejam presentes como variáveis de ambiente se tiverem sido analisadas. Este comportamento pode ser alterado definindo o parâmetro load_credentials
env_overwrite
como False
.
As células a seguir demonstram o tratamento de credenciais na biblioteca Python.
from searchtweets import load_credentials
load_credentials ( filename = "./search_tweets_creds_example.yaml" ,
yaml_key = "search_tweets_ent_example" ,
env_overwrite = False )
{'nome de usuário': '<MEU_NOME DE USUÁRIO>', 'senha': '<MINHA_SENHA>', 'ponto final': '<MY_ENDPOINT>'}
load_credentials ( filename = "./search_tweets_creds_example.yaml" ,
yaml_key = "search_tweets_premium_example" ,
env_overwrite = False )
{'bearer_token': '<A_VERY_LONG_MAGIC_STRING>', 'ponto final': 'https://api.twitter.com/1.1/tweets/search/30day/dev.json', 'extra_headers_dict': Nenhum}
Se definirmos nossas variáveis de ambiente, o programa irá procurá-las independentemente da validade ou existência de um arquivo YAML.
import os
os . environ [ "SEARCHTWEETS_USERNAME" ] = "<ENV_USERNAME>"
os . environ [ "SEARCHTWEETS_PASSWORD" ] = "<ENV_PW>"
os . environ [ "SEARCHTWEETS_ENDPOINT" ] = "<https://endpoint>"
load_credentials ( filename = "nothing_here.yaml" , yaml_key = "no_key_here" )
não é possível ler o arquivo nada_aqui.yaml Erro ao analisar o arquivo YAML; procurando variáveis de ambiente válidas
{'nome de usuário': '<ENV_USERNAME>', 'senha': '<ENV_PW>', 'ponto final': '<https://ponto final>'}
as bandeiras:
--credential-file <FILENAME>
--credential-file-key <KEY>
--env-overwrite
são usados para controlar o comportamento das credenciais do aplicativo de linha de comando.
A biblioteca inclui um aplicativo, search_tweets.py
, que fornece acesso rápido aos Tweets. Quando você usa pip
para instalar este pacote, search_tweets.py
é instalado globalmente. O arquivo está localizado no diretório tools/
para quem deseja executá-lo localmente.
Observe que o sinalizador --results-per-call
especifica um argumento para a API ( maxResults
, resultados retornados por CALL), não como um máximo rígido para o número de resultados retornados deste programa. O argumento --max-results
define o número máximo de resultados a serem retornados de uma determinada chamada. Todos os exemplos pressupõem que suas credenciais estão configuradas corretamente no local padrão - .twitter_keys.yaml
ou em variáveis de ambiente.
Transmita resultados json para stdout sem salvar
search_tweets.py
--max-results 1000
--results-per-call 100
--filter-rule " beyonce has:hashtags "
--print-stream
Transmita resultados json para stdout e salve em um arquivo
search_tweets.py
--max-results 1000
--results-per-call 100
--filter-rule " beyonce has:hashtags "
--filename-prefix beyonce_geo
--print-stream
Salvar em arquivo sem saída
search_tweets.py
--max-results 100
--results-per-call 100
--filter-rule " beyonce has:hashtags "
--filename-prefix beyonce_geo
--no-print-stream
Um ou mais cabeçalhos personalizados podem ser especificados na linha de comando, usando o argumento --extra-headers
e uma string formatada em JSON representando um dicionário de cabeçalhos extras:
search_tweets.py
--filter-rule " beyonce has:hashtags "
--extra-headers ' {"<MY_HEADER_KEY>":"<MY_HEADER_VALUE>"} '
As opções podem ser passadas através de um arquivo de configuração (ini ou YAML). Arquivos de exemplo podem ser encontrados nos arquivos tools/api_config_example.config
ou ./tools/api_yaml_example.yaml
, que podem ter esta aparência:
[search_rules]
from_date = 2017-06-01
to_date = 2017-09-01
pt_rule = beyonce has:geo
[search_params]
results_per_call = 500
max_results = 500
[output_params]
save_file = True
filename_prefix = beyonce
results_per_file = 10000000
Ou isto:
search_rules :
from-date : 2017-06-01
to-date : 2017-09-01 01:01
pt-rule : kanye
search_params :
results-per-call : 500
max-results : 500
output_params :
save_file : True
filename_prefix : kanye
results_per_file : 10000000
Cabeçalhos personalizados podem ser especificados em um arquivo de configuração, sob uma chave de credenciais específica:
search_tweets_api :
account_type : premium
endpoint : <FULL_URL_OF_ENDPOINT>
username : <USERNAME>
password : <PW>
extra_headers :
<MY_HEADER_KEY> : <MY_HEADER_VALUE>
Ao usar um arquivo de configuração em conjunto com o utilitário de linha de comando, você precisa especificar seu arquivo de configuração por meio do parâmetro --config-file
. Argumentos adicionais de linha de comando serão adicionados aos argumentos do arquivo de configuração ou substituirão os argumentos do arquivo de configuração se ambos estiverem especificados e presentes.
Exemplo:
search_tweets.py --config-arquivo myapiconfig.config --no-print-stream
As opções completas estão listadas abaixo:
$ search_tweets.py -h uso: search_tweets.py [-h] [--arquivo de credenciais CREDENTIAL_FILE] [--chave de arquivo de credencial CREDENTIAL_YAML_KEY] [--env-overwrite ENV_OVERWRITE] [--arquivo de configuração CONFIG_FILENAME] [--tipo de conta {premium,empresa}] [--contagem-balde COUNT_BUCKET] [--start-datetime FROM_DATE] [--end-datetime TO_DATE] [--regra de filtro PT_RULE] [--resultados por chamada RESULTS_PER_CALL] [--max-resultados MAX_RESULTS] [--max-páginas MAX_PAGES] [--resultados por arquivo RESULTS_PER_FILE] [--prefixo do nome do arquivo FILENAME_PREFIX] [--no-print-stream] [--print-stream] [--extra-headers EXTRA_HEADERS] [--debug] argumentos opcionais: -h, --help mostra esta mensagem de ajuda e sai --arquivo de credenciais CREDENTIAL_FILE Localização do arquivo yaml usado para armazenar seu credenciais. --credential-file-key CREDENTIAL_YAML_KEY a chave no arquivo de credenciais usado para esta sessão credenciais. O padrão é search_tweets_api --env-overwrite ENV_OVERWRITE Substitua as credenciais analisadas por YAML por qualquer conjunto variáveis de ambiente. Consulte os documentos da API ou leia-me para detalhes. --config-arquivo CONFIG_FILENAME arquivo de configuração com todos os parâmetros. Longe, mais fácil de usar do que a versão de argumentos da linha de comando., Se um válido for encontrado, todos os argumentos serão preenchidos a partir daí. Os argumentos restantes da linha de comando anularão os argumentos encontrados na configuração, arquivo. --account-type {premium,empresa} O tipo de conta que você está usando --count-bucket COUNT_BUCKET Defina isto para fazer uma solicitação de 'contagens'. Tamanho do intervalo para ponto final de contagem. Opções:, dia, hora, minuto. --start-datetime FROM_DATE Início da janela de data e hora, formato 'AAAA-mm-DDTHH:MM' (padrão: -30 dias) --end-datetime TO_DATE Fim da janela de data e hora, formato 'AAAA-mm-DDTHH:MM' (padrão: data mais recente) --filter-regra PT_RULE Regra de filtro PowerTrack (consulte: http://support.gnip.com/c cliente/portal/artigos/901152-powertrack-operators) --resultados por chamada RESULTS_PER_CALL Número de resultados a serem retornados por chamada (padrão 100; máx. 500) – corresponde a ‘maxResults’ na API. Se estiver fazendo uma solicitação de 'contagens' com '--count-bucket', este parâmetro será ignorado. --max-resultados MAX_RESULTS Número máximo de tweets ou contagens a serem retornados para isso sessão (o padrão é 500) --max-páginas MAX_PAGES Número máximo de páginas/chamadas de API a serem usadas para isso sessão. --resultados por arquivo RESULTS_PER_FILE Máximo de tweets para salvar por arquivo. --filename-prefix FILENAME_PREFIX prefixo para o nome do arquivo onde os dados json do tweet serão armazenado. --no-print-stream desabilita o streaming de impressão --print-stream Imprime fluxo de tweet para stdout --extra-headers EXTRA_HEADERS str formatado em JSON representando um ditado de adicional cabeçalhos de solicitação --debug imprime todas as informações e mensagens de aviso
Trabalhar com a API em um programa Python é simples tanto para clientes Premium quanto para clientes Enterprise.
Assumiremos que as credenciais estão no local padrão, ~/.twitter_keys.yaml
.
from searchtweets import ResultStream , gen_rule_payload , load_credentials
enterprise_search_args = load_credentials ( "~/.twitter_keys.yaml" ,
yaml_key = "search_tweets_enterprise" ,
env_overwrite = False )
premium_search_args = load_credentials ( "~/.twitter_keys.yaml" ,
yaml_key = "search_tweets_premium" ,
env_overwrite = False )
Existe uma função que formata regras de API de pesquisa em consultas JSON válidas chamadas gen_rule_payload
. Ele possui padrões sensatos, como extrair mais Tweets por chamada do que o padrão 100 (mas observe que um ambiente sandbox só pode ter no máximo 100 aqui, portanto, se você receber erros, verifique isso), sem incluir datas. Discutir os detalhes da geração de regras de pesquisa está fora do escopo desses exemplos; Recomendo que você consulte a documentação para aprender suas nuances, mas por enquanto vamos ver como é uma regra.
rule = gen_rule_payload ( "beyonce" , results_per_call = 100 ) # testing with a sandbox account
print ( rule )
{"query":"beyoncé","maxResults":100}
Esta regra corresponderá aos tweets que contêm o texto beyonce
deles.
A partir deste ponto, existem duas maneiras de interagir com a API. Existe um método rápido para coletar pequenas quantidades de Tweets na memória que requer menos reflexão e conhecimento e interação com o objeto ResultStream
que será apresentado posteriormente.
Usaremos a variável search_args
para alimentar o ponto de configuração da API. O objeto também usa uma regra PowerTrack válida e tem opções para interromper a pesquisa ao atingir limites no número de Tweets e chamadas de API.
Estaremos usando a função collect_results
, que possui três parâmetros.
Para os exemplos restantes, altere os argumentos para premium ou empresarial, dependendo do seu uso.
Vamos ver como vai:
from searchtweets import collect_results
tweets = collect_results ( rule ,
max_results = 100 ,
result_stream_args = enterprise_search_args ) # change this if you need to
Por padrão, as cargas úteis do Tweet são analisadas lentamente em um objeto Tweet
. Um grande número de atributos de Tweet são disponibilizados diretamente, como:
[ print ( tweet . all_text , end = ' n n ' ) for tweet in tweets [ 0 : 10 ]];
Jay-Z & Beyoncé sentou-se à nossa frente no jantar esta noite e, a certa altura, fiz contato visual com Beyoncé. Meus membros viraram gelatina e não consigo mais formar uma frase coerente. Eu vi os olhos do senhor. Beyoncé e não está perto. https://t.co/UdOU9oUtuW Como você pode imaginar... Sinais de Beyoncé sempre serão minha merda. Quando Beyoncé adota um cachorro ?? https://t.co/U571HyLG4F Espere, você não pode simplesmente fazer isso com Beyoncé https://t.co/3p14DocGqA Por que vocês continuam usando gifs de Rihanna e Beyoncé para promover o show quando deixaram Bey perder o mesmo prêmio que ela merecia 3 vezes e deixaram Rihanna sair sem nada além das roupas do corpo? https://t.co/w38QpH0wma 30) alguém te disse que você se parece com Beyoncé https://t.co/Vo4Z7bfSCi Minha Beyoncé favorita https://t.co/f9Jp600l2B Beyoncé precisa ver isso. Que diosa @TiniStoessel https://t.co/gadVJbehQZ Joanne Pearce agora está tocando IF I WAS A BOY - BEYONCE.mp3 de ! Estou tentando ver o finsta da Beyoncé antes de morrer
[ print ( tweet . created_at_datetime ) for tweet in tweets [ 0 : 10 ]];
17/01/2018 00:08:50 17/01/2018 00:08:49 17/01/2018 00:08:44 17/01/2018 00:08:42 17/01/2018 00:08:42 17/01/2018 00:08:42 17/01/2018 00:08:40 17/01/2018 00:08:38 17/01/2018 00:08:37 17/01/2018 00:08:37
[ print ( tweet . generator . get ( "name" )) for tweet in tweets [ 0 : 10 ]];
Twitter para iPhone Twitter para iPhone Twitter para iPhone Twitter para iPhone Twitter para iPhone Twitter para iPhone Twitter para Android Twitter para iPhone Tempo de antena profissional Twitter para iPhone
Voila, temos alguns tweets. Para ambientes interativos e outros casos onde você não se preocupa em coletar seus dados em uma única carga ou não precisa operar diretamente no stream de Tweets ou contagens, recomendo usar esta função de conveniência.
O objeto ResultStream será alimentado por search_args
e usa as regras e outros parâmetros de configuração, incluindo uma parada brusca no número de páginas para limitar o uso de chamadas de API.
rs = ResultStream ( rule_payload = rule ,
max_results = 500 ,
max_pages = 1 ,
** premium_search_args )
print ( rs )
Fluxo de resultados: { "nome de usuário":nulo, "endpoint":"https://api.twitter.com/1.1/tweets/search/30day/dev.json", "rule_payload":{ "query":"beyoncé", "maxResultados":100 }, "tweetar": verdadeiro, "max_resultados":500 }
Existe uma função, .stream
, que lida perfeitamente com solicitações e paginação para uma determinada consulta. Ele retorna um gerador, e para pegar nossos 500 Tweets que mencionam beyonce
podemos fazer isso:
tweets = list ( rs . stream ())
Os tweets são analisados preguiçosamente usando nosso Tweet Parser, portanto, os dados do tweet são facilmente extraíveis.
# using unidecode to prevent emoji/accents printing
[ print ( tweet . all_text ) for tweet in tweets [ 0 : 10 ]];
gente socorro kkkkkkkkkk BEYONCE https://t.co/kJ9zubvKuf Jay-Z & Beyoncé sentou-se à nossa frente no jantar esta noite e, a certa altura, fiz contato visual com Beyoncé. Meus membros viraram gelatina e não consigo mais formar uma frase coerente. Eu vi os olhos do senhor. Beyoncé e não está perto. https://t.co/UdOU9oUtuW Como você pode imaginar... Sinais de Beyoncé sempre serão minha merda. Quando Beyoncé adota um cachorro ?? https://t.co/U571HyLG4F Espere, você não pode simplesmente fazer isso com Beyoncé https://t.co/3p14DocGqA Por que vocês continuam usando gifs de Rihanna e Beyoncé para promover o show quando deixaram Bey perder o mesmo prêmio que ela merecia 3 vezes e deixaram Rihanna sair sem nada além das roupas do corpo? https://t.co/w38QpH0wma 30) alguém te disse que você se parece com Beyoncé https://t.co/Vo4Z7bfSCi Minha Beyoncé favorita https://t.co/f9Jp600l2B Beyoncé precisa ver isso. Que diosa @TiniStoessel https://t.co/gadVJbehQZ Joanne Pearce agora está tocando IF I WAS A BOY - BEYONCE.mp3 de !
Também podemos usar o endpoint Search API Counts para obter contagens de Tweets que correspondem à nossa regra. Cada solicitação retornará até 30 dias de resultados, e cada solicitação de contagem pode ser feita minuto a minuto, hora em hora ou diariamente. O objeto ResultStream
subjacente tratará da conversão de seu endpoint para o endpoint de contagem, e você deve especificar o argumento count_bucket
ao criar uma regra para usá-lo.
O processo é muito semelhante ao de obter Tweets, mas tem algumas pequenas diferenças.
Advertência – os ambientes sandbox premium NÃO têm acesso ao endpoint de contagem da API de pesquisa.
count_rule = gen_rule_payload ( "beyonce" , count_bucket = "day" )
counts = collect_results ( count_rule , result_stream_args = enterprise_search_args )
Nossos resultados são bastante diretos e podem ser usados rapidamente.
counts
[{'contagem': 366, 'timePeriod': '201801170000'}, {'contagem': 44580, 'timePeriod': '201801160000'}, {'contagem': 61932, 'timePeriod': '201801150000'}, {'contagem': 59678, 'timePeriod': '201801140000'}, {'contagem': 44014, 'timePeriod': '201801130000'}, {'contagem': 46607, 'timePeriod': '201801120000'}, {'contagem': 41523, 'timePeriod': '201801110000'}, {'contagem': 47056, 'timePeriod': '201801100000'}, {'contagem': 65506, 'timePeriod': '201801090000'}, {'contagem': 95251, 'timePeriod': '201801080000'}, {'contagem': 162883, 'timePeriod': '201801070000'}, {'contagem': 106344, 'timePeriod': '201801060000'}, {'contagem': 93542, 'timePeriod': '201801050000'}, {'contagem': 110415, 'timePeriod': '201801040000'}, {'contagem': 127523, 'timePeriod': '201801030000'}, {'contagem': 131952, 'timePeriod': '201801020000'}, {'contagem': 176157, 'timePeriod': '201801010000'}, {'contagem': 57229, 'timePeriod': '201712310000'}, {'contagem': 72277, 'timePeriod': '201712300000'}, {'contagem': 72051, 'timePeriod': '201712290000'}, {'contagem': 76371, 'timePeriod': '201712280000'}, {'contagem': 61578, 'timePeriod': '201712270000'}, {'contagem': 55118, 'timePeriod': '201712260000'}, {'contagem': 59115, 'timePeriod': '201712250000'}, {'contagem': 106219, 'timePeriod': '201712240000'}, {'contagem': 114732, 'timePeriod': '201712230000'}, {'contagem': 73327, 'timePeriod': '201712220000'}, {'contagem': 89171, 'timePeriod': '201712210000'}, {'contagem': 192381, 'timePeriod': '201712200000'}, {'contagem': 85554, 'timePeriod': '201712190000'}, {'contagem': 57829, 'timePeriod': '201712180000'}]
Observe que isso só funcionará com a opção de pesquisa completa de arquivos , que está disponível para minha conta somente por meio das opções corporativas. A pesquisa completa de arquivos provavelmente exigirá um endpoint ou método de acesso diferente; consulte seu console do desenvolvedor para obter detalhes.
Vamos fazer uma nova regra e passar as datas desta vez.
gen_rule_payload
usa carimbos de data/hora nos seguintes formatos:
YYYYmmDDHHMM
YYYY-mm-DD
(que será convertido para meia-noite UTC (00:00)YYYY-mm-DD HH:MM
YYYY-mm-DDTHH:MM
Observação: todos os Tweets são armazenados no horário UTC.
rule = gen_rule_payload ( "from:jack" ,
from_date = "2017-09-01" , #UTC 2017-09-01 00:00
to_date = "2017-10-30" , #UTC 2017-10-30 00:00
results_per_call = 500 )
print ( rule )
{"query":"from:jack","maxResults":500,"toDate":"201710300000","fromDate":"201709010000"}
tweets = collect_results ( rule , max_results = 500 , result_stream_args = enterprise_search_args )
[ print ( tweet . all_text ) for tweet in tweets [ 0 : 10 ]];
Mais clareza sobre nossa política e aplicação de informações privadas. Trabalhando para construir o máximo de contexto direto no produto também https://t.co/IrwBexPrBA Para fornecer mais clareza sobre nossa política de informações privadas, adicionamos exemplos específicos do que é/não é uma violação e informações sobre o que precisamos para remover esse tipo de conteúdo do serviço. https://t.co/NGx5hh2tTQ Lançamento de grupos violentos e política de imagens/símbolos de ódio em 22 de novembro https://t.co/NaWuBPxyO5 Iremos agora lançar as nossas políticas sobre grupos violentos, imagens e símbolos de ódio no dia 22 de novembro. Durante o processo de desenvolvimento, recebemos feedback valioso que estamos a implementar antes de estas serem publicadas e aplicadas. Veja mais sobre nosso processo de desenvolvimento de políticas aqui? https://t.co/wx3EeH39BI @WillStick @lizkelley Feliz aniversário, Liz! Publicidade de exclusão de todas as contas pertencentes ao Russia Today (RT) e ao Sputnik. Estamos doando todos os ganhos projetados (US$ 1,9 milhão) para apoiar pesquisas externas sobre o uso do Twitter em eleições, incluindo o uso de automação maliciosa e desinformação. https://t.co/zIxfqqXCZr @TMFJMo @anthonynoto Obrigado @gasca @stratechery @Lefsetz carta Observações diárias de @gasca @stratechery Bridgewater Sim!!!! ❤️❤️❤️❤️ #davechappelle https://t.co/ybSGNrQpYF @ndimichino Às vezes Configurando em @CampFlogGnaw https://t.co/nVq8QjkKsf
rule = gen_rule_payload ( "from:jack" ,
from_date = "2017-09-20" ,
to_date = "2017-10-30" ,
count_bucket = "day" ,
results_per_call = 500 )
print ( rule )
{"query":"from:jack","toDate":"201710300000","fromDate":"201709200000","bucket":"dia"}
counts = collect_results ( rule , max_results = 500 , result_stream_args = enterprise_search_args )
[ print ( c ) for c in counts ];
{'timePeriod': '201710290000', 'contagem': 0} {'timePeriod': '201710280000', 'contagem': 0} {'timePeriod': '201710270000', 'contagem': 3} {'timePeriod': '201710260000', 'contagem': 6} {'timePeriod': '201710250000', 'contagem': 4} {'timePeriod': '201710240000', 'contagem': 4} {'timePeriod': '201710230000', 'contagem': 0} {'timePeriod': '201710220000', 'contagem': 0} {'timePeriod': '201710210000', 'contagem': 3} {'timePeriod': '201710200000', 'contagem': 2} {'timePeriod': '201710190000', 'contagem': 1} {'timePeriod': '201710180000', 'contagem': 6} {'timePeriod': '201710170000', 'contagem': 2} {'timePeriod': '201710160000', 'contagem': 2} {'timePeriod': '201710150000', 'contagem': 1} {'timePeriod': '201710140000', 'contagem': 64} {'timePeriod': '201710130000', 'contagem': 3} {'timePeriod': '201710120000', 'contagem': 4} {'timePeriod': '201710110000', 'contagem': 8} {'timePeriod': '201710100000', 'contagem': 4} {'timePeriod': '201710090000', 'contagem': 1} {'timePeriod': '201710080000', 'contagem': 0} {'timePeriod': '201710070000', 'contagem': 0} {'timePeriod': '201710060000', 'contagem': 1} {'timePeriod': '201710050000', 'contagem': 3} {'timePeriod': '201710040000', 'contagem': 5} {'timePeriod': '201710030000', 'contagem': 8} {'timePeriod': '201710020000', 'contagem': 5} {'timePeriod': '201710010000', 'contagem': 0} {'timePeriod': '201709300000', 'contagem': 0} {'timePeriod': '201709290000', 'contagem': 0} {'timePeriod': '201709280000', 'contagem': 9} {'timePeriod': '201709270000', 'contagem': 41} {'timePeriod': '201709260000', 'contagem': 13} {'timePeriod': '201709250000', 'contagem': 6} {'timePeriod': '201709240000', 'contagem': 7} {'timePeriod': '201709230000', 'contagem': 3} {'timePeriod': '201709220000', 'contagem': 0} {'timePeriod': '201709210000', 'contagem': 1} {'timePeriod': '201709200000', 'contagem': 7}
Quaisquer contribuições deverão seguir o seguinte padrão:
git checkout -b my_new_feature
searchtweets/_version.py
para refletir suas alterações. Usamos controle de versão semântico, portanto, melhorias ininterruptas devem incrementar a versão secundária, por exemplo, 1.5.0 -> 1.6.0
, e as correções de bugs irão incrementar a última versão, 1.6.0 -> 1.6.1
.Depois que o processo de solicitação pull for aceito, os mantenedores do pacote cuidarão da documentação de construção e da distribuição para o Pypi.
Para referência, a distribuição para Pypi é realizada pelos seguintes comandos, executados no diretório raiz do repositório:
python setup.py bdist_wheel
python setup.py sdist
twine upload dist/ *
Como construir a documentação:
Construir a documentação requer alguns pacotes Sphinx para construir as páginas web:
pip install sphinx
pip install sphinx_bootstrap_theme
pip install sphinxcontrib-napoleon
Então (depois que suas alterações forem confirmadas no master), você poderá executar o script bash gerador de documentação e seguir as instruções:
bash build_sphinx_docs.sh master searchtweets
Observe que este README também é gerado e, portanto, após qualquer alteração no README, você precisará reconstruir o README (você precisa do pandoc versão 2.1+ para isso) e enviar o resultado:
bash make_readme.sh