Los puntos finales de búsqueda de Twitter v2 ahora incluyen un punto final de 'recuentos' que devuelve totales de series temporales de Tweets coincidentes.
Este proyecto sirve como contenedor para las API de búsqueda empresarial y premium de Twitter, proporcionando una utilidad de línea de comandos y una biblioteca de Python. Se pueden ver bonitos documentos aquí.
jq
). La biblioteca searchtweets
está en Pypi:
pip install searchtweets
O puede instalar la versión de desarrollo localmente a través de
git clone https://github.com/twitterdev/search-tweets-python
cd search-tweets-python
pip install -e .
Las API de búsqueda premium y empresarial utilizan diferentes métodos de autenticación e intentamos proporcionar una manera fluida de manejar la autenticación para todos los clientes. Sabemos que las credenciales pueden ser complicadas o molestas; lea esto en su totalidad.
Los clientes Premium necesitarán los campos bearer_token
y endpoint
; Los clientes empresariales requieren username
, password
y endpoint
. Si no especifica el account_type
, intentamos discernir el tipo de cuenta y declarar una advertencia sobre este comportamiento.
Para los productos de búsqueda premium, utilizamos autenticación solo de aplicación y los tokens al portador no se entregan con una fecha de vencimiento. Puede proporcionar: - la clave y el secreto de su aplicación (la biblioteca se encargará de la autenticación con token de portador) - un token de portador que usted mismo obtenga
A muchos desarrolladores les puede resultar más sencillo proporcionar la clave y el secreto de su aplicación y dejar que esta biblioteca administre la generación de su token de portador por usted. Consulte aquí para obtener una descripción general del método de autenticación premium.
Admitimos métodos basados en archivos YAML y variables de entorno para almacenar credenciales y brindamos un manejo flexible con valores predeterminados sensatos.
Para los clientes premium, el archivo de credenciales más simple debería verse así:
search_tweets_api :
account_type : premium
endpoint : <FULL_URL_OF_ENDPOINT>
consumer_key : <CONSUMER_KEY>
consumer_secret : <CONSUMER_SECRET>
Para clientes empresariales, el archivo de credenciales más simple debería verse así:
search_tweets_api :
account_type : enterprise
endpoint : <FULL_URL_OF_ENDPOINT>
username : <USERNAME>
password : <PW>
De forma predeterminada, esta biblioteca espera este archivo en "~/.twitter_keys.yaml"
, pero puede pasar la ubicación relevante según sea necesario, ya sea con el indicador --credential-file
para la aplicación de línea de comandos o como se muestra a continuación en Python. programa.
Los dos ejemplos anteriores no requieren argumentos especiales de línea de comandos ni argumentos dentro del programa. Los métodos de análisis de credenciales, a menos que se especifique lo contrario, buscarán una clave YAML llamada search_tweets_api
.
Para los desarrolladores que tienen múltiples puntos finales y/o productos de búsqueda, pueden mantener todas las credenciales en el mismo archivo y especificar claves específicas para usar. --credential-file-key
especifica este comportamiento en la aplicación de línea de comando. Un ejemplo:
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>
Si desea o necesita pasar credenciales a través de variables de entorno, puede configurar las variables apropiadas para su producto de las siguientes:
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=
La función load_credentials
intentará encontrar estas variables si no puede cargar campos del archivo YAML y sobrescribirá cualquier credencial del archivo YAML que esté presente como variable de entorno si se ha analizado. Este comportamiento se puede cambiar configurando el parámetro load_credentials
env_overwrite
en False
.
Las siguientes celdas demuestran el manejo de credenciales en la biblioteca de Python.
from searchtweets import load_credentials
load_credentials ( filename = "./search_tweets_creds_example.yaml" ,
yaml_key = "search_tweets_ent_example" ,
env_overwrite = False )
{'nombre de usuario': '<MI_NOMBRE DE USUARIO>', 'contraseña': '<MI_CONTRASEÑA>', 'punto 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>', 'punto final': 'https://api.twitter.com/1.1/tweets/search/30day/dev.json', 'extra_headers_dict': Ninguno}
Si configuramos nuestras variables de entorno, el programa las buscará independientemente de la validez o existencia de un archivo 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" )
no puedo leer el archivo nada_aquí.yaml Error al analizar el archivo YAML; buscando variables de entorno válidas
{'nombre de usuario': '<ENV_USERNAME>', 'contraseña': '<ENV_PW>', 'punto final': '<https://punto final>'}
las banderas:
--credential-file <FILENAME>
--credential-file-key <KEY>
--env-overwrite
se utilizan para controlar el comportamiento de las credenciales desde la aplicación de línea de comandos.
La biblioteca incluye una aplicación, search_tweets.py
, que proporciona acceso rápido a los Tweets. Cuando usa pip
para instalar este paquete, search_tweets.py
se instala globalmente. El archivo se encuentra en el directorio tools/
para aquellos que quieran ejecutarlo localmente.
Tenga en cuenta que el indicador --results-per-call
especifica un argumento para la API ( maxResults
, resultados devueltos por LLAMADA), no como un máximo estricto para el número de resultados devueltos por este programa. El argumento --max-results
define el número máximo de resultados que se devolverán de una llamada determinada. Todos los ejemplos asumen que sus credenciales están configuradas correctamente en la ubicación predeterminada: .twitter_keys.yaml
o en variables de entorno.
Transmita resultados json a stdout sin guardar
search_tweets.py
--max-results 1000
--results-per-call 100
--filter-rule " beyonce has:hashtags "
--print-stream
Transmita los resultados json a la salida estándar y guárdelos en un archivo
search_tweets.py
--max-results 1000
--results-per-call 100
--filter-rule " beyonce has:hashtags "
--filename-prefix beyonce_geo
--print-stream
Guardar en archivo sin salida
search_tweets.py
--max-results 100
--results-per-call 100
--filter-rule " beyonce has:hashtags "
--filename-prefix beyonce_geo
--no-print-stream
Se pueden especificar uno o más encabezados personalizados desde la línea de comando, usando el argumento --extra-headers
y una cadena con formato JSON que representa un diccionario de encabezados adicionales:
search_tweets.py
--filter-rule " beyonce has:hashtags "
--extra-headers ' {"<MY_HEADER_KEY>":"<MY_HEADER_VALUE>"} '
Las opciones se pueden pasar a través de un archivo de configuración (ya sea ini o YAML). Se pueden encontrar archivos de ejemplo en los archivos tools/api_config_example.config
o ./tools/api_yaml_example.yaml
, que podrían tener este aspecto:
[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
O esto:
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
Se pueden especificar encabezados personalizados en un archivo de configuración, bajo una clave de credenciales 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>
Cuando utilice un archivo de configuración junto con la utilidad de línea de comandos, debe especificar su archivo de configuración mediante el parámetro --config-file
. Se agregarán argumentos adicionales de la línea de comandos a los argumentos del archivo de configuración o se sobrescribirán los argumentos del archivo de configuración si ambos están especificados y presentes.
Ejemplo:
buscar_tweets.py --archivo de configuración myapiconfig.config --sin flujo de impresión
Las opciones completas se enumeran a continuación:
$ buscar_tweets.py -h uso: search_tweets.py [-h] [--credential-file CREDENTIAL_FILE] [--clave-archivo-credencial CREDENTIAL_YAML_KEY] [--env-overwrite ENV_OVERWRITE] [--archivo de configuración CONFIG_FILENAME] [--tipo de cuenta {premium,empresa}] [--count-bucket COUNT_BUCKET] [--fecha-inicio DESDE_DATE] [--fecha-fin hora TO_DATE] [--regla-filtro PT_RULE] [--resultados-por-llamada RESULTS_PER_CALL] [--max-results MAX_RESULTS] [--max-pages MAX_PAGES] [--resultados-por-archivo RESULTS_PER_FILE] [--filename-prefix FILENAME_PREFIX] [--sin-flujo-de-impresión] [--flujo-de-impresión] [--extra-headers EXTRA_HEADERS] [--debug] argumentos opcionales: -h, --help muestra este mensaje de ayuda y sale --archivo-credencial CREDENTIAL_FILE Ubicación del archivo yaml utilizado para contener su cartas credenciales. --clave-archivo-credencial CREDENTIAL_YAML_KEY la clave en el archivo de credenciales utilizado para esta sesión cartas credenciales. El valor predeterminado es search_tweets_api --env-overwrite ENV_OVERWRITE Sobrescriba las credenciales analizadas por YAML con cualquier conjunto variables de entorno. Consulte los documentos API o el archivo Léame para detalles. --archivo de configuración CONFIG_FILENAME Archivo de configuración con todos los parámetros. Mucho más fácil de utilizar que la versión de argumentos de la línea de comandos. Si es válido Se encuentra el archivo, se completarán todos los argumentos, a partir de ahí. Los argumentos restantes de la línea de comandos anularán los argumentos encontrados en la configuración, archivo. --tipo de cuenta {premium,empresa} El tipo de cuenta que estás utilizando --count-bucket COUNT_BUCKET Configure esto para realizar una solicitud de 'recuentos'. Tamaño del depósito para el punto final de recuentos. Opciones: día, hora, minuto. --fecha-iniciohora DESDE_DATE Inicio de la ventana de fecha y hora, formato 'AAAA-mm-DDTHH:MM' (predeterminado: -30 días) --fecha de finalización y hora TO_DATE Fin de la ventana de fecha y hora, formato 'AAAA-mm-DDTHH:MM' (predeterminado: fecha más reciente) --regla-filtro PT_RULE Regla de filtro PowerTrack (consulte: http://support.gnip.com/c cliente/portal/artículos/901152-powertrack-operadores) --resultados-por-llamada RESULTS_PER_CALL Número de resultados a devolver por llamada (predeterminado 100; máx. 500): corresponde a 'maxResults' en la API. Si realiza una solicitud de 'recuentos' con '--count-bucket', este parámetro se ignora. --max-resultados MAX_RESULTS Número máximo de Tweets o recuentos que se devolverán para esto sesión (por defecto 500) --max-páginas MAX_PAGES Número máximo de páginas/llamadas API a utilizar para esto sesión. --resultados-por-archivo RESULTS_PER_FILE Máximo de tweets para guardar por archivo. --filename-prefix FILENAME_PREFIX prefijo para el nombre del archivo donde estarán los datos json del tweet almacenado. --no-print-stream deshabilitar la transmisión de impresión --print-stream Imprime el flujo de tweets en la salida estándar --extra-headers EXTRA_HEADERS Cadena con formato JSON que representa un dict de adicional encabezados de solicitud --debug imprime toda la información y mensajes de advertencia
Trabajar con la API dentro de un programa Python es sencillo tanto para clientes Premium como Enterprise.
Asumiremos que las credenciales están en la ubicación predeterminada, ~/.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 )
Hay una función que formatea las reglas de la API de búsqueda en consultas json válidas llamada gen_rule_payload
. Tiene valores predeterminados sensatos, como extraer más Tweets por llamada que los 100 predeterminados (pero tenga en cuenta que un entorno sandbox solo puede tener un máximo de 100 aquí, por lo que si obtiene errores, verifique esto) sin incluir fechas. La discusión de los puntos más finos de la generación de reglas de búsqueda está fuera del alcance de estos ejemplos; Te animo a que veas los documentos para conocer los matices que contienen, pero por ahora veamos cómo se ve una regla.
rule = gen_rule_payload ( "beyonce" , results_per_call = 100 ) # testing with a sandbox account
print ( rule )
{"query":"beyoncé","maxResults":100}
Esta regla coincidirá con los tweets que tengan el texto beyonce
.
A partir de este punto, existen dos formas de interactuar con la API. Existe un método rápido para recopilar cantidades más pequeñas de Tweets en la memoria que requiere menos pensamiento y conocimiento, e interacción con el objeto ResultStream
que se presentará más adelante.
Usaremos la variable search_args
para impulsar el punto de configuración de la API. El objeto también toma una regla PowerTrack válida y tiene opciones para interrumpir la búsqueda cuando se alcanzan límites tanto en la cantidad de Tweets como en las llamadas API.
Usaremos la función collect_results
, que tiene tres parámetros.
Para los ejemplos restantes, cambie los argumentos a premium o empresarial según su uso.
Veamos cómo va:
from searchtweets import collect_results
tweets = collect_results ( rule ,
max_results = 100 ,
result_stream_args = enterprise_search_args ) # change this if you need to
De forma predeterminada, las cargas útiles de los Tweets se analizan de forma diferida en un objeto Tweet
. Una abrumadora cantidad de atributos de Tweet están disponibles directamente, como los siguientes:
[ print ( tweet . all_text , end = ' n n ' ) for tweet in tweets [ 0 : 10 ]];
Jay Z &erio; Beyoncé se sentó frente a nosotros durante la cena esta noche y, en un momento, hice contacto visual con Beyoncé. Mis extremidades se volvieron gelatina y ya no puedo formar una oración coherente. He visto los ojos del señor. Beyoncé y no está cerca. https://t.co/UdOU9oUtuW Como puedes adivinar... Los carteles de Beyoncé siempre serán mi mierda. ¿Cuándo Beyoncé adopta un perro? https://t.co/U571HyLG4F Espera, no puedes simplemente hacerle eso a Beyoncé. https://t.co/3p14DocGqA ¿Por qué siguen usando gifs de Rihanna y Beyoncé para promocionar el programa cuando dejaron que Bey perdiera el mismo premio que merecía 3 veces y dejaron que Rihanna se fuera sin nada más que la ropa que llevaba puesta? https://t.co/w38QpH0wma 30) alguien te dice que te pareces a Beyoncé https://t.co/Vo4Z7bfSCi Mi Beyoncé favorita https://t.co/f9Jp600l2B Beyoncé necesita ver esto. Que diosa @TiniStoessel https://t.co/gadVJbehQZ Joanne Pearce está reproduciendo IF I WAS A BOY - BEYONCE.mp3 de ! Estoy intentando ver la finsta de Beyoncé antes de morir.
[ print ( tweet . created_at_datetime ) for tweet in tweets [ 0 : 10 ]];
2018-01-17 00:08:50 2018-01-17 00:08:49 2018-01-17 00:08:44 2018-01-17 00:08:42 2018-01-17 00:08:42 2018-01-17 00:08:42 2018-01-17 00:08:40 2018-01-17 00:08:38 2018-01-17 00:08:37 2018-01-17 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 Tiempo aire profesional Twitter para iPhone
Listo, tenemos algunos tweets. Para entornos interactivos y otros casos en los que no le importa recopilar sus datos en una sola carga o no necesita operar en el flujo de Tweets o contar directamente, recomiendo usar esta conveniente función.
El objeto ResultStream funcionará con search_args
y tomará las reglas y otros parámetros de configuración, incluida una parada brusca en el número de páginas para limitar el uso de llamadas API.
rs = ResultStream ( rule_payload = rule ,
max_results = 500 ,
max_pages = 1 ,
** premium_search_args )
print ( rs )
Flujo de resultados: { "nombre de usuario": nulo, "punto final":"https://api.twitter.com/1.1/tweets/search/30day/dev.json", "rule_payload":{ "consulta": "beyoncé", "resultados máximos": 100 }, "tuitear": verdadero, "resultados_max":500 }
Hay una función, .stream
, que maneja sin problemas las solicitudes y la paginación de una consulta determinada. Devuelve un generador, y para capturar nuestros 500 Tweets que mencionan beyonce
podemos hacer esto:
tweets = list ( rs . stream ())
Los tweets se analizan de forma perezosa utilizando nuestro Tweet Parser, por lo que los datos de los tweets se pueden extraer muy fácilmente.
# 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 &erio; Beyoncé se sentó frente a nosotros durante la cena esta noche y, en un momento, hice contacto visual con Beyoncé. Mis extremidades se volvieron gelatina y ya no puedo formar una oración coherente. He visto los ojos del señor. Beyoncé y no está cerca. https://t.co/UdOU9oUtuW Como podrás adivinar... Los carteles de Beyoncé siempre serán mi mierda. ¿Cuándo Beyoncé adopta un perro? https://t.co/U571HyLG4F Espera, no puedes simplemente hacerle eso a Beyoncé. https://t.co/3p14DocGqA ¿Por qué siguen usando gifs de Rihanna y Beyoncé para promocionar el programa cuando dejaron que Bey perdiera el mismo premio que merecía 3 veces y dejaron que Rihanna se fuera sin nada más que la ropa que llevaba puesta? https://t.co/w38QpH0wma 30) alguien te dice que te pareces a Beyoncé https://t.co/Vo4Z7bfSCi Mi Beyoncé favorita https://t.co/f9Jp600l2B Beyoncé necesita ver esto. Que diosa @TiniStoessel https://t.co/gadVJbehQZ Joanne Pearce está reproduciendo IF I WAS A BOY - BEYONCE.mp3 de !
También podemos utilizar el punto final Search API Counts para obtener recuentos de Tweets que coincidan con nuestra regla. Cada solicitud arrojará hasta 30 días de resultados y cada solicitud de conteo se puede realizar por minutos, horas o diariamente. El objeto ResultStream
subyacente se encargará de convertir su punto final en el punto final de recuento, y debe especificar el argumento count_bucket
al crear una regla para usarlo.
El proceso es muy similar al de capturar Tweets, pero tiene algunas diferencias menores.
Advertencia: los entornos sandbox premium NO tienen acceso al punto final de recuentos de la API de búsqueda.
count_rule = gen_rule_payload ( "beyonce" , count_bucket = "day" )
counts = collect_results ( count_rule , result_stream_args = enterprise_search_args )
Nuestros resultados son bastante sencillos y se pueden utilizar rápidamente.
counts
[{'count': 366, 'timePeriod': '201801170000'}, {'count': 44580, 'timePeriod': '201801160000'}, {'count': 61932, 'timePeriod': '201801150000'}, {'count': 59678, 'timePeriod': '201801140000'}, {'count': 44014, 'timePeriod': '201801130000'}, {'count': 46607, 'timePeriod': '201801120000'}, {'count': 41523, 'timePeriod': '201801110000'}, {'count': 47056, 'timePeriod': '201801100000'}, {'count': 65506, 'timePeriod': '201801090000'}, {'count': 95251, 'timePeriod': '201801080000'}, {'count': 162883, 'timePeriod': '201801070000'}, {'count': 106344, 'timePeriod': '201801060000'}, {'count': 93542, 'timePeriod': '201801050000'}, {'count': 110415, 'timePeriod': '201801040000'}, {'count': 127523, 'timePeriod': '201801030000'}, {'count': 131952, 'timePeriod': '201801020000'}, {'count': 176157, 'timePeriod': '201801010000'}, {'count': 57229, 'timePeriod': '201712310000'}, {'count': 72277, 'timePeriod': '201712300000'}, {'count': 72051, 'timePeriod': '201712290000'}, {'count': 76371, 'timePeriod': '201712280000'}, {'count': 61578, 'timePeriod': '201712270000'}, {'count': 55118, 'timePeriod': '201712260000'}, {'count': 59115, 'timePeriod': '201712250000'}, {'count': 106219, 'timePeriod': '201712240000'}, {'count': 114732, 'timePeriod': '201712230000'}, {'count': 73327, 'timePeriod': '201712220000'}, {'count': 89171, 'timePeriod': '201712210000'}, {'count': 192381, 'timePeriod': '201712200000'}, {'count': 85554, 'timePeriod': '201712190000'}, {'count': 57829, 'timePeriod': '201712180000'}]
Tenga en cuenta que esto solo funcionará con la opción de búsqueda completa de archivos , que está disponible para mi cuenta solo a través de las opciones empresariales. La búsqueda completa de archivos probablemente requerirá un punto final o método de acceso diferente; consulte su consola de desarrollador para obtener más detalles.
Hagamos una nueva regla y pasemos fechas esta vez.
gen_rule_payload
toma marcas de tiempo de las siguientes formas:
YYYYmmDDHHMM
YYYY-mm-DD
(que se convertirá a medianoche UTC (00:00)YYYY-mm-DD HH:MM
YYYY-mm-DDTHH:MM
Nota: todos los Tweets se almacenan en hora 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 ]];
Más claridad sobre nuestra política y aplicación de información privada. Trabajando también para incorporar el mayor contexto directo al producto https://t.co/IrwBexPrBA Para brindar más claridad sobre nuestra política de información privada, hemos agregado ejemplos específicos de lo que es/no es una violación e información sobre lo que necesitamos para eliminar este tipo de contenido del servicio. https://t.co/NGx5hh2tTQ Lanzamiento de grupos violentos y política de imágenes/símbolos de odio el 22 de noviembre https://t.co/NaWuBPxyO5 Ahora lanzaremos nuestras políticas sobre grupos violentos e imágenes y símbolos de odio el 22 de noviembre. Durante el proceso de desarrollo, recibimos comentarios valiosos que estamos implementando antes de que se publiquen y apliquen. ¿Vea más sobre nuestro proceso de desarrollo de políticas aquí? https://t.co/wx3EeH39BI @WillStick @lizkelley ¡Feliz cumpleaños Liz! Publicidad fuera de borda de todas las cuentas propiedad de Russia Today (RT) y Sputnik. Estamos donando todas las ganancias proyectadas (1,9 mm de dólares) para respaldar la investigación externa sobre el uso de Twitter en las elecciones, incluido el uso de automatización maliciosa y desinformación. https://t.co/zIxfqqXCZr @TMFJMo @anthonynoto Gracias @gasca @stratechery @Lefsetz carta @gasca @stratechery Observaciones diarias de Bridgewater ¡¡¡¡Sí!!!! ❤️❤️❤️❤️ #davechappelle https://t.co/ybSGNrQpYF @ndimichino A veces Configuración en @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":"día"}
counts = collect_results ( rule , max_results = 500 , result_stream_args = enterprise_search_args )
[ print ( c ) for c in counts ];
{'timePeriod': '201710290000', 'recuento': 0} {'timePeriod': '201710280000', 'recuento': 0} {'timePeriod': '201710270000', 'recuento': 3} {'timePeriod': '201710260000', 'recuento': 6} {'timePeriod': '201710250000', 'recuento': 4} {'timePeriod': '201710240000', 'recuento': 4} {'timePeriod': '201710230000', 'recuento': 0} {'timePeriod': '201710220000', 'recuento': 0} {'timePeriod': '201710210000', 'recuento': 3} {'timePeriod': '201710200000', 'recuento': 2} {'timePeriod': '201710190000', 'recuento': 1} {'timePeriod': '201710180000', 'recuento': 6} {'timePeriod': '201710170000', 'recuento': 2} {'timePeriod': '201710160000', 'recuento': 2} {'timePeriod': '201710150000', 'recuento': 1} {'timePeriod': '201710140000', 'recuento': 64} {'timePeriod': '201710130000', 'recuento': 3} {'timePeriod': '201710120000', 'recuento': 4} {'timePeriod': '201710110000', 'recuento': 8} {'timePeriod': '201710100000', 'recuento': 4} {'timePeriod': '201710090000', 'recuento': 1} {'timePeriod': '201710080000', 'recuento': 0} {'timePeriod': '201710070000', 'recuento': 0} {'timePeriod': '201710060000', 'recuento': 1} {'timePeriod': '201710050000', 'recuento': 3} {'timePeriod': '201710040000', 'recuento': 5} {'timePeriod': '201710030000', 'recuento': 8} {'timePeriod': '201710020000', 'recuento': 5} {'timePeriod': '201710010000', 'recuento': 0} {'timePeriod': '201709300000', 'recuento': 0} {'timePeriod': '201709290000', 'recuento': 0} {'timePeriod': '201709280000', 'recuento': 9} {'timePeriod': '201709270000', 'recuento': 41} {'timePeriod': '201709260000', 'recuento': 13} {'timePeriod': '201709250000', 'recuento': 6} {'timePeriod': '201709240000', 'recuento': 7} {'timePeriod': '201709230000', 'recuento': 3} {'timePeriod': '201709220000', 'recuento': 0} {'timePeriod': '201709210000', 'recuento': 1} {'timePeriod': '201709200000', 'recuento': 7}
Cualquier contribución debe seguir el siguiente patrón:
git checkout -b my_new_feature
searchtweets/_version.py
para reflejar sus cambios. Usamos control de versiones semántico, por lo que las mejoras continuas deberían incrementar la versión secundaria, por ejemplo, 1.5.0 -> 1.6.0
, y las correcciones de errores incrementarán la última versión, 1.6.0 -> 1.6.1
.Una vez aceptado el proceso de solicitud de extracción, los mantenedores del paquete se encargarán de la documentación de creación y la distribución a Pypi.
Como referencia, la distribución a Pypi se logra mediante los siguientes comandos, ejecutados desde el directorio raíz en el repositorio:
python setup.py bdist_wheel
python setup.py sdist
twine upload dist/ *
Cómo construir la documentación:
La creación de la documentación requiere algunos paquetes de Sphinx para crear las páginas web:
pip install sphinx
pip install sphinx_bootstrap_theme
pip install sphinxcontrib-napoleon
Luego (una vez que los cambios se hayan confirmado en master), debería poder ejecutar el script bash que genera la documentación y seguir las instrucciones:
bash build_sphinx_docs.sh master searchtweets
Tenga en cuenta que este archivo README también se genera, por lo que después de cualquier cambio en el archivo README, deberá reconstruir el archivo README (necesita la versión 2.1+ de pandoc para esto) y confirmar el resultado:
bash make_readme.sh