gicc-datasets 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,12 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .venv/
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+ *.egg-info/
7
+ build/
8
+ dist/
9
+ .env
10
+ .aws/
11
+ .DS_Store
12
+ plah.html
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 pshiguihara
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,121 @@
1
+ Metadata-Version: 2.5
2
+ Name: gicc-datasets
3
+ Version: 0.1.0
4
+ Summary: Versioned datasets in Amazon S3, using your existing AWS permissions.
5
+ Project-URL: Homepage, https://github.com/pshiguihara/gicc-datasets
6
+ Project-URL: Documentation, https://github.com/pshiguihara/gicc-datasets/blob/main/docs/tutorial.md
7
+ Project-URL: Issues, https://github.com/pshiguihara/gicc-datasets/issues
8
+ Author: pshiguihara
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: aws,datasets,research,s3
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Requires-Python: >=3.11
22
+ Requires-Dist: boto3<2,>=1.35.99
23
+ Provides-Extra: dev
24
+ Requires-Dist: build>=1.2; extra == 'dev'
25
+ Requires-Dist: moto[s3]<6,>=5; extra == 'dev'
26
+ Requires-Dist: pytest<10,>=8; extra == 'dev'
27
+ Requires-Dist: ruff>=0.11; extra == 'dev'
28
+ Requires-Dist: twine>=6; extra == 'dev'
29
+ Description-Content-Type: text/markdown
30
+
31
+ # gicc-datasets
32
+
33
+ **Datasets versionados en Amazon S3, desde Python o la terminal.**
34
+
35
+ [![PyPI](https://img.shields.io/pypi/v/gicc-datasets?color=176B87)](https://pypi.org/project/gicc-datasets/)
36
+ [![Python](https://img.shields.io/pypi/pyversions/gicc-datasets)](https://pypi.org/project/gicc-datasets/)
37
+ [![License: MIT](https://img.shields.io/badge/license-MIT-64748B)](https://github.com/pshiguihara/gicc-datasets/blob/main/LICENSE)
38
+
39
+ Sube carpetas, ZIP o archivos. Descarga versiones específicas y verifica su contenido con SHA-256.
40
+ Cada usuario utiliza sus propias credenciales AWS y los permisos asignados a su bucket y prefijo.
41
+
42
+ ## Instalar
43
+
44
+ Python 3.11 o posterior. Se recomienda un entorno virtual.
45
+
46
+ ```bash
47
+ pip install gicc-datasets
48
+ ```
49
+
50
+ ## Empezar
51
+
52
+ Necesitas un perfil AWS con lectura y escritura limitadas al destino asignado. No necesitas ser administrador ni listar todos los buckets.
53
+
54
+ ```bash
55
+ # Sustituye los valores por los que te entregue el responsable de AWS.
56
+ gicc-datasets configure --profile gicc --bucket mi-bucket \
57
+ --prefix datasets/mi-equipo/ --region us-east-1
58
+
59
+ gicc-datasets doctor
60
+
61
+ # Revisa el contenido antes de subirlo.
62
+ gicc-datasets upload ./encuesta --dataset encuesta --version 1.0.0 --dry-run
63
+
64
+ gicc-datasets upload ./encuesta --dataset encuesta --version 1.0.0
65
+
66
+ gicc-datasets download encuesta --version 1.0.0 --output ./descargas/encuesta
67
+ ```
68
+
69
+ `doctor` comprueba el listado del prefijo; no prueba la escritura ni modifica S3.
70
+
71
+ ## Tres formas de subir
72
+
73
+ | Origen | Comando | Resultado |
74
+ | :--- | :--- | :--- |
75
+ | Carpeta | `upload ./datos --dataset muestra --version 1.0.0` | Conserva archivos y subcarpetas. |
76
+ | ZIP | `upload ./datos.zip --dataset muestra --version 1.1.0` | Conserva el ZIP intacto. |
77
+ | ZIP extraído | `upload ./datos.zip --dataset muestra --version 1.2.0 --extract-zip` | Publica los archivos del ZIP. |
78
+ | Archivo | `upload ./datos.csv --dataset muestra --version 1.3.0` | Conserva el archivo original. |
79
+
80
+ Anteponer `gicc-datasets` a cada comando. Una versión publicada no se reemplaza desde el cliente; usa una versión nueva para actualizar datos.
81
+
82
+ ## Python
83
+
84
+ ```python
85
+ from gicc_datasets import DatasetClient
86
+
87
+ client = DatasetClient(
88
+ profile="gicc",
89
+ bucket="mi-bucket",
90
+ prefix="datasets/mi-equipo/",
91
+ region="us-east-1",
92
+ )
93
+
94
+ client.upload("./datos", dataset="muestra", version="1.0.0")
95
+ client.download("muestra", version="1.0.0", output="./descargas/muestra")
96
+ ```
97
+
98
+ En un servicio con rol AWS, omite `profile` para usar la cadena de credenciales de Boto3.
99
+
100
+ ## Consultar
101
+
102
+ ```bash
103
+ gicc-datasets list
104
+ gicc-datasets versions muestra
105
+ gicc-datasets info muestra --version 1.0.0
106
+ gicc-datasets --json list
107
+ ```
108
+
109
+ ## Acceso y alcance
110
+
111
+ - Instalar el paquete no concede acceso a S3. AWS aplica los permisos de cada identidad.
112
+ - La configuración guarda destino y nombre de perfil, sin credenciales.
113
+ - No incluye operaciones de borrado, administración IAM ni modificación de ACL.
114
+ - Las descargas verifican tamaño y SHA-256 antes de copiar los datos al destino.
115
+ - La protección contra sobrescrituras de versiones corresponde al cliente; no sustituye controles de retención en AWS.
116
+
117
+ **[Tutorial](https://github.com/pshiguihara/gicc-datasets/blob/main/docs/tutorial.md)** · **[Permisos](https://github.com/pshiguihara/gicc-datasets/blob/main/docs/permissions.md)** · **[Formato y límites](https://github.com/pshiguihara/gicc-datasets/blob/main/docs/format.md)**
118
+
119
+ Las guías también están en `docs/` del archivo fuente descargable en PyPI. Los enlaces a GitHub requieren acceso al repositorio privado.
120
+
121
+ MIT · [pshiguihara](https://github.com/pshiguihara)
@@ -0,0 +1,91 @@
1
+ # gicc-datasets
2
+
3
+ **Datasets versionados en Amazon S3, desde Python o la terminal.**
4
+
5
+ [![PyPI](https://img.shields.io/pypi/v/gicc-datasets?color=176B87)](https://pypi.org/project/gicc-datasets/)
6
+ [![Python](https://img.shields.io/pypi/pyversions/gicc-datasets)](https://pypi.org/project/gicc-datasets/)
7
+ [![License: MIT](https://img.shields.io/badge/license-MIT-64748B)](https://github.com/pshiguihara/gicc-datasets/blob/main/LICENSE)
8
+
9
+ Sube carpetas, ZIP o archivos. Descarga versiones específicas y verifica su contenido con SHA-256.
10
+ Cada usuario utiliza sus propias credenciales AWS y los permisos asignados a su bucket y prefijo.
11
+
12
+ ## Instalar
13
+
14
+ Python 3.11 o posterior. Se recomienda un entorno virtual.
15
+
16
+ ```bash
17
+ pip install gicc-datasets
18
+ ```
19
+
20
+ ## Empezar
21
+
22
+ Necesitas un perfil AWS con lectura y escritura limitadas al destino asignado. No necesitas ser administrador ni listar todos los buckets.
23
+
24
+ ```bash
25
+ # Sustituye los valores por los que te entregue el responsable de AWS.
26
+ gicc-datasets configure --profile gicc --bucket mi-bucket \
27
+ --prefix datasets/mi-equipo/ --region us-east-1
28
+
29
+ gicc-datasets doctor
30
+
31
+ # Revisa el contenido antes de subirlo.
32
+ gicc-datasets upload ./encuesta --dataset encuesta --version 1.0.0 --dry-run
33
+
34
+ gicc-datasets upload ./encuesta --dataset encuesta --version 1.0.0
35
+
36
+ gicc-datasets download encuesta --version 1.0.0 --output ./descargas/encuesta
37
+ ```
38
+
39
+ `doctor` comprueba el listado del prefijo; no prueba la escritura ni modifica S3.
40
+
41
+ ## Tres formas de subir
42
+
43
+ | Origen | Comando | Resultado |
44
+ | :--- | :--- | :--- |
45
+ | Carpeta | `upload ./datos --dataset muestra --version 1.0.0` | Conserva archivos y subcarpetas. |
46
+ | ZIP | `upload ./datos.zip --dataset muestra --version 1.1.0` | Conserva el ZIP intacto. |
47
+ | ZIP extraído | `upload ./datos.zip --dataset muestra --version 1.2.0 --extract-zip` | Publica los archivos del ZIP. |
48
+ | Archivo | `upload ./datos.csv --dataset muestra --version 1.3.0` | Conserva el archivo original. |
49
+
50
+ Anteponer `gicc-datasets` a cada comando. Una versión publicada no se reemplaza desde el cliente; usa una versión nueva para actualizar datos.
51
+
52
+ ## Python
53
+
54
+ ```python
55
+ from gicc_datasets import DatasetClient
56
+
57
+ client = DatasetClient(
58
+ profile="gicc",
59
+ bucket="mi-bucket",
60
+ prefix="datasets/mi-equipo/",
61
+ region="us-east-1",
62
+ )
63
+
64
+ client.upload("./datos", dataset="muestra", version="1.0.0")
65
+ client.download("muestra", version="1.0.0", output="./descargas/muestra")
66
+ ```
67
+
68
+ En un servicio con rol AWS, omite `profile` para usar la cadena de credenciales de Boto3.
69
+
70
+ ## Consultar
71
+
72
+ ```bash
73
+ gicc-datasets list
74
+ gicc-datasets versions muestra
75
+ gicc-datasets info muestra --version 1.0.0
76
+ gicc-datasets --json list
77
+ ```
78
+
79
+ ## Acceso y alcance
80
+
81
+ - Instalar el paquete no concede acceso a S3. AWS aplica los permisos de cada identidad.
82
+ - La configuración guarda destino y nombre de perfil, sin credenciales.
83
+ - No incluye operaciones de borrado, administración IAM ni modificación de ACL.
84
+ - Las descargas verifican tamaño y SHA-256 antes de copiar los datos al destino.
85
+ - La protección contra sobrescrituras de versiones corresponde al cliente; no sustituye controles de retención en AWS.
86
+
87
+ **[Tutorial](https://github.com/pshiguihara/gicc-datasets/blob/main/docs/tutorial.md)** · **[Permisos](https://github.com/pshiguihara/gicc-datasets/blob/main/docs/permissions.md)** · **[Formato y límites](https://github.com/pshiguihara/gicc-datasets/blob/main/docs/format.md)**
88
+
89
+ Las guías también están en `docs/` del archivo fuente descargable en PyPI. Los enlaces a GitHub requieren acceso al repositorio privado.
90
+
91
+ MIT · [pshiguihara](https://github.com/pshiguihara)
@@ -0,0 +1,32 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+ permissions:
7
+ contents: read
8
+ jobs:
9
+ test:
10
+ strategy:
11
+ fail-fast: false
12
+ matrix:
13
+ os: [ubuntu-latest]
14
+ python: ['3.11', '3.12', '3.13', '3.14']
15
+ include:
16
+ - os: macos-latest
17
+ python: '3.14'
18
+ - os: windows-latest
19
+ python: '3.14'
20
+ runs-on: ${{ matrix.os }}
21
+ steps:
22
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
23
+ with:
24
+ persist-credentials: false
25
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
26
+ with:
27
+ python-version: ${{ matrix.python }}
28
+ - run: python -m pip install -e '.[dev]'
29
+ - run: ruff check src tests
30
+ - run: pytest -q
31
+ - run: python -m build
32
+ - run: python -m twine check dist/*
@@ -0,0 +1,17 @@
1
+ # Desarrollo
2
+
3
+ ```bash
4
+ python -m venv .venv
5
+ source .venv/bin/activate
6
+ python -m pip install -e '.[dev]'
7
+ ruff check src tests
8
+ pytest -q
9
+ python -m build
10
+ python -m twine check dist/*
11
+ ```
12
+
13
+ Las pruebas usan S3 simulado; no requieren claves AWS ni acceden a buckets reales.
14
+ Cubren carpetas, ZIP, archivos, multipart, conflictos de publicación, integridad, rutas y errores de acceso.
15
+ Las políticas IAM deben verificarse por separado en el entorno de cada organización.
16
+
17
+ La plantilla `docs/ci.yml` define comprobaciones para Python 3.11–3.14 en Linux y Python 3.14 en macOS y Windows. Para activarla, muévela a `.github/workflows/ci.yml` con una sesión de GitHub autorizada para gestionar workflows. La plantilla no requiere secretos de PyPI o AWS.
@@ -0,0 +1,28 @@
1
+ # Formato y límites
2
+
3
+ ```text
4
+ <prefix>/<dataset>/versions/<version>/
5
+ ├── manifest.json
6
+ └── uploads/<uuid>/files/<ruta-relativa>
7
+ ```
8
+
9
+ El manifiesto usa `schema: 1`, dataset, versión, fecha UTC, UUID de carga, modo de origen, directorios y una lista de archivos con ruta, clave, tamaño y SHA-256. No contiene credenciales ni rutas locales absolutas.
10
+
11
+ La publicación sube los objetos bajo un UUID independiente y crea el manifiesto al final con `IfNoneMatch="*"`. Dos publicaciones concurrentes no mezclan objetos: solo una puede crear el manifiesto. El cliente solo lista versiones con manifiesto válido. Esto no es una transacción S3; una identidad con permiso de lectura puede acceder a objetos incompletos si conoce sus claves.
12
+
13
+ Las claves de los archivos quedan restringidas al UUID y prefijo del manifiesto. En descargas se validan rutas y hashes antes de copiar al destino. No se verifica criptográficamente la identidad del publicador: quien pueda modificar tanto el manifiesto como los archivos puede alterar el contenido.
14
+
15
+ ## Límites de la versión inicial
16
+
17
+ - Python 3.11–3.14; API y CLI con una única dependencia directa: Boto3.
18
+ - Hasta 100000 archivos y directorios y 16 MiB por manifiesto.
19
+ - Nombres portables: se rechazan rutas absolutas, `..`, enlaces, nombres reservados de Windows y colisiones por mayúsculas o normalización Unicode.
20
+ - Se preservan bytes, rutas relativas y directorios vacíos. No se preservan permisos POSIX, atributos extendidos ni enlaces duros como tales.
21
+ - Se usa una copia temporal por archivo durante la subida, y una carpeta temporal con toda la descarga para verificarla. Debe haber espacio local suficiente.
22
+ - Las copias de cada archivo son estables; no constituyen una instantánea atómica de una carpeta que otro proceso esté modificando. Mantén el origen sin cambios.
23
+ - Las transferencias grandes usan multipart y reintentos acotados. La CLI muestra el resultado final; no incluye barra de progreso ni reanudación entre procesos.
24
+ - Una descarga verificada se incorpora archivo por archivo. Un fallo local durante esa incorporación puede dejar una carpeta parcialmente poblada.
25
+ - El listado pagina objetos S3 y valida manifiestos. Su coste crece con el contenido del prefijo; no hay catálogo central ni caché.
26
+ - No hay borrado, sincronización incremental, deduplicación, servidor HTTP ni edición de versiones publicadas.
27
+
28
+ La versión del paquete Python y la versión de cada dataset son independientes.
@@ -0,0 +1,55 @@
1
+ # Permisos AWS
2
+
3
+ La persona que usa el paquete necesita acceso a un bucket y prefijo asignados. Esta sección está dirigida a quien administra esos permisos.
4
+
5
+ ## Publicador limitado
6
+
7
+ Adjunta al rol del usuario una política de identidad equivalente a la siguiente, sustituyendo `mi-bucket` y `datasets/mi-equipo/`:
8
+
9
+ ```json
10
+ {
11
+ "Version": "2012-10-17",
12
+ "Statement": [
13
+ {
14
+ "Effect": "Allow",
15
+ "Action": "s3:ListBucket",
16
+ "Resource": "arn:aws:s3:::mi-bucket",
17
+ "Condition": {
18
+ "StringLike": {
19
+ "s3:prefix": ["datasets/mi-equipo/", "datasets/mi-equipo/*"]
20
+ }
21
+ }
22
+ },
23
+ {
24
+ "Effect": "Allow",
25
+ "Action": [
26
+ "s3:GetObject",
27
+ "s3:PutObject",
28
+ "s3:AbortMultipartUpload",
29
+ "s3:ListMultipartUploadParts"
30
+ ],
31
+ "Resource": "arn:aws:s3:::mi-bucket/datasets/mi-equipo/*"
32
+ }
33
+ ]
34
+ }
35
+ ```
36
+
37
+ Para un lector, conserva `s3:ListBucket` y únicamente `s3:GetObject` en la segunda declaración. No se necesita `s3:ListAllMyBuckets`, `s3:DeleteObject`, administración IAM ni acceso a otros buckets. El cliente no usa `HeadBucket` para diagnosticar un prefijo restringido.
38
+
39
+ ## Configuración de la cuenta
40
+
41
+ - Usa IAM Identity Center para personas y roles de ejecución para servicios. Cada usuario conserva su propia identidad.
42
+ - Mantén Block Public Access. Utiliza Object Ownership con ACL deshabilitadas; el cliente no envía ACL.
43
+ - Configura el cifrado predeterminado en el bucket. Con SSE-KMS, autoriza la clave además de S3: `kms:Decrypt` para lectura y también `kms:GenerateDataKey` para publicación multipart.
44
+ - Para otra cuenta AWS, configura AssumeRole o las políticas de identidad y bucket necesarias. No compartas claves del propietario.
45
+ - Otras políticas pueden ampliar o restringir el acceso. Un `Deny` explícito, SCP o límite de permisos puede prevalecer sobre esta concesión.
46
+
47
+ Retira las asignaciones al terminar el acceso y considera las sesiones temporales todavía vigentes. No es posible retirar mediante IAM las copias descargadas.
48
+
49
+ ## Versiones y mantenimiento
50
+
51
+ El manifiesto se crea con una escritura condicional y el cliente rechaza reemplazos. La política anterior permite `PutObject`: alguien que use otra herramienta podría modificar claves existentes. Para una exigencia de retención, diseña controles adicionales en AWS. El versionado de S3 permite recuperación, pero no bloquea escrituras.
52
+
53
+ No elimines automáticamente todo `uploads/`: contiene también datos publicados. Una tarea administrativa debe identificar cargas sin referencia en los manifiestos antes de eliminarlas. Puede configurarse por separado el aborto de multipart incompletos.
54
+
55
+ Referencias: [permisos S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-policy-actions.html), [credenciales Boto3](https://docs.aws.amazon.com/boto3/latest/guide/credentials.html), [escrituras condicionales](https://docs.aws.amazon.com/AmazonS3/latest/userguide/conditional-writes.html).
@@ -0,0 +1,161 @@
1
+ # Tutorial
2
+
3
+ Para usuarios con permisos limitados de lectura y publicación en un bucket y prefijo asignados.
4
+ No se requiere un rol administrador. Sustituye `mi-bucket`, `datasets/mi-equipo/`, región y perfil por tus valores.
5
+
6
+ ## 1. Instalar
7
+
8
+ En macOS o Linux:
9
+
10
+ ```bash
11
+ python3 -m venv ~/.venvs/gicc-datasets
12
+ source ~/.venvs/gicc-datasets/bin/activate
13
+ pip install gicc-datasets
14
+ gicc-datasets --help
15
+ ```
16
+
17
+ En Windows, crea el entorno con `py -m venv .venv` y actívalo con `.venv\Scripts\Activate.ps1` en PowerShell.
18
+ Activa el entorno en cada nueva terminal. Para actualizar el software, ejecuta `pip install --upgrade gicc-datasets`.
19
+
20
+ ## 2. Iniciar sesión en AWS
21
+
22
+ Si ya tienes un perfil AWS autorizado, úsalo directamente. Para IAM Identity Center necesitas AWS CLI v2 y los datos de acceso facilitados por tu organización:
23
+
24
+ ```bash
25
+ aws configure sso --profile gicc
26
+ aws sso login --profile gicc
27
+ ```
28
+
29
+ Selecciona el rol limitado para datasets. No copies claves de otra persona. La región de SSO puede diferir de la del bucket. Las credenciales temporales de un rol o las configuradas en `~/.aws` también funcionan mediante Boto3.
30
+
31
+ ## 3. Configurar el destino
32
+
33
+ ```bash
34
+ gicc-datasets configure --profile gicc --bucket mi-bucket \
35
+ --prefix datasets/mi-equipo/ --region us-east-1
36
+
37
+ gicc-datasets doctor
38
+ ```
39
+
40
+ Se guarda un archivo sin secretos en `~/.config/gicc-datasets/config.toml`, o bajo `XDG_CONFIG_HOME` cuando está definido. `doctor` comprueba el listado y muestra la identidad cuando utiliza una sesión propia. La escritura aparece como `not_checked`; se comprueba al subir.
41
+
42
+ Para otra ejecución, las opciones globales se colocan antes del subcomando:
43
+
44
+ ```bash
45
+ gicc-datasets --profile otro-perfil --bucket otro-bucket \
46
+ --prefix datasets/otro-equipo/ --region us-east-1 list
47
+ ```
48
+
49
+ La configuración explícita tiene prioridad sobre variables de entorno y valores guardados. Variables admitidas: `AWS_PROFILE`, `GICC_DATASETS_BUCKET`, `GICC_DATASETS_PREFIX`, `GICC_DATASETS_REGION`.
50
+ Sin perfil seleccionado, se utiliza la cadena estándar de Boto3. Cambiar el destino no amplía los permisos AWS.
51
+
52
+ ## 4. Subir una carpeta
53
+
54
+ Origen:
55
+
56
+ ```text
57
+ encuesta/
58
+ ├── README.md
59
+ ├── raw/hogares.csv
60
+ └── processed/resumen.parquet
61
+ ```
62
+
63
+ ```bash
64
+ gicc-datasets upload ./encuesta --dataset encuesta --version 1.0.0 --dry-run
65
+ gicc-datasets upload ./encuesta --dataset encuesta --version 1.0.0
66
+ ```
67
+
68
+ Se conservan las rutas relativas, sin añadir la carpeta exterior `encuesta`. Los directorios vacíos se registran. `--dry-run` muestra archivos, bytes y exclusiones; no llama a S3. En modo ZIP extraído sí usa almacenamiento temporal local.
69
+
70
+ Se excluyen por defecto `.git`, `.venv`, `.DS_Store`, `__MACOSX`, `.env` y `.aws`, en cualquier nivel. Puedes añadir patrones sobre la ruta relativa:
71
+
72
+ ```bash
73
+ gicc-datasets upload ./encuesta --dataset encuesta --version 1.1.0 \
74
+ --exclude '*.tmp' --exclude 'borradores/*'
75
+ ```
76
+
77
+ Las exclusiones no detectan todos los secretos: revisa el inventario. Mantén el origen estable durante la carga.
78
+
79
+ ## 5. Subir un ZIP
80
+
81
+ Conservarlo intacto:
82
+
83
+ ```bash
84
+ gicc-datasets upload ./encuesta.zip --dataset encuesta-zip --version 1.0.0
85
+ ```
86
+
87
+ Extraerlo y publicar sus archivos:
88
+
89
+ ```bash
90
+ gicc-datasets upload ./encuesta.zip --dataset encuesta-extraida --version 1.0.0 --extract-zip
91
+ ```
92
+
93
+ La segunda opción mantiene la estructura interna, incluida cualquier carpeta exterior del ZIP. Rechaza rutas inseguras, enlaces, colisiones y ZIP cifrados. Aplica exclusiones después de validar y extraer.
94
+
95
+ Límites predeterminados: 100000 entradas, 100 GiB descomprimidos y relación de compresión 1000. Puedes reducirlos o ajustarlos con `--zip-max-entries`, `--zip-max-bytes` y `--zip-max-ratio`. El límite general del manifiesto sigue siendo 100000 entradas y 16 MiB.
96
+
97
+ ## 6. Subir un archivo
98
+
99
+ ```bash
100
+ gicc-datasets upload ./indicadores.parquet --dataset indicadores --version 1.0.0
101
+ ```
102
+
103
+ El formato y contenido se conservan, sin conversión.
104
+
105
+ ## 7. Descargar y actualizar
106
+
107
+ ```bash
108
+ gicc-datasets list
109
+ gicc-datasets versions encuesta
110
+ gicc-datasets info encuesta --version 1.0.0
111
+ gicc-datasets download encuesta --version 1.0.0 --output ./descargas/encuesta-1.0.0
112
+ ```
113
+
114
+ Usa el mismo perfil limitado. Se verifican los archivos en una carpeta temporal antes de trasladarlos al destino. No se sobrescriben archivos por defecto; utiliza una carpeta nueva o `--overwrite` conscientemente. No se eliminan archivos locales adicionales.
115
+
116
+ Para actualizar el dataset, publica una versión nueva:
117
+
118
+ ```bash
119
+ gicc-datasets upload ./encuesta --dataset encuesta --version 2.0.0
120
+ ```
121
+
122
+ Cada versión es una copia completa. La versión anterior permanece accesible. Especificar la versión permite reproducir una descarga; no existe un alias `latest`.
123
+
124
+ ## 8. Python
125
+
126
+ ```python
127
+ from gicc_datasets import DatasetClient, VersionExistsError, ZipLimits
128
+
129
+ client = DatasetClient(profile="gicc", bucket="mi-bucket",
130
+ prefix="datasets/mi-equipo/", region="us-east-1")
131
+
132
+ for dataset in client.list_datasets():
133
+ print(dataset.id, dataset.versions)
134
+
135
+ try:
136
+ release = client.upload("./datos.zip", dataset="muestra", version="1.0.0",
137
+ extract_zip=True, zip_limits=ZipLimits(max_bytes=1024**3))
138
+ print(release.files, release.bytes)
139
+ except VersionExistsError:
140
+ print("La versión ya está publicada.")
141
+
142
+ manifest = client.info("muestra", "1.0.0")
143
+ client.download("muestra", version="1.0.0", output="./descargas/muestra")
144
+ ```
145
+
146
+ `upload(..., dry_run=True)` devuelve el plan sin utilizar AWS. `upload` y `download` devuelven `Release`. `info` devuelve el manifiesto como diccionario. `versions` devuelve una lista de cadenas ordenadas lexicográficamente.
147
+
148
+ ## Errores
149
+
150
+ | Código | Situación | Acción |
151
+ | --- | --- | --- |
152
+ | 2 | Configuración o argumentos | Revisa bucket, prefijo y opciones. |
153
+ | 3 | Identidad o acceso | Revisa el perfil, renueva SSO o consulta al responsable. |
154
+ | 4 | Objeto o bucket inexistente | Revisa dataset y versión. |
155
+ | 5 | Versión existente o concurrente | Publica una versión nueva. |
156
+ | 6 | Integridad, rutas o ZIP | Revisa el origen y el destino. |
157
+ | 7 | Transferencia o disco | Revisa conexión, permisos de transferencia y espacio. |
158
+ | 130 | Cancelación | Vuelve a iniciar la operación cuando corresponda. |
159
+
160
+ `--json` genera JSON para automatización; los errores se escriben en stderr. Un fallo de transferencia multipart puede informar código 7 incluso cuando su causa sea un permiso AWS.
161
+ Una carga fallida no publica un manifiesto completo, pero puede dejar objetos huérfanos. No se reanudan transferencias entre ejecuciones. La limpieza corresponde al responsable del bucket.
@@ -0,0 +1,52 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.27,<2"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "gicc-datasets"
7
+ version = "0.1.0"
8
+ description = "Versioned datasets in Amazon S3, using your existing AWS permissions."
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = "MIT"
12
+ authors = [{name = "pshiguihara"}]
13
+ keywords = ["datasets", "s3", "aws", "research"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Environment :: Console",
17
+ "Intended Audience :: Science/Research",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ "Programming Language :: Python :: 3.14",
23
+ "Operating System :: OS Independent",
24
+ ]
25
+ dependencies = ["boto3>=1.35.99,<2"]
26
+
27
+ [project.optional-dependencies]
28
+ dev = ["pytest>=8,<10", "moto[s3]>=5,<6", "ruff>=0.11", "build>=1.2", "twine>=6"]
29
+
30
+ [project.urls]
31
+ Homepage = "https://github.com/pshiguihara/gicc-datasets"
32
+ Documentation = "https://github.com/pshiguihara/gicc-datasets/blob/main/docs/tutorial.md"
33
+ Issues = "https://github.com/pshiguihara/gicc-datasets/issues"
34
+
35
+ [project.scripts]
36
+ gicc-datasets = "gicc_datasets.cli:main"
37
+
38
+ [tool.hatch.build.targets.wheel]
39
+ packages = ["src/gicc_datasets"]
40
+
41
+ [tool.hatch.build.targets.sdist]
42
+ include = ["/src", "/tests", "/docs", "/README.md", "/LICENSE", "/pyproject.toml"]
43
+
44
+ [tool.pytest.ini_options]
45
+ testpaths = ["tests"]
46
+
47
+ [tool.ruff]
48
+ line-length = 100
49
+ target-version = "py311"
50
+
51
+ [tool.ruff.lint]
52
+ select = ["E", "F", "I", "UP", "B"]
@@ -0,0 +1,30 @@
1
+ """Versioned datasets in Amazon S3."""
2
+
3
+ __version__ = "0.1.0"
4
+
5
+ from .client import DatasetClient, DatasetSummary, Release
6
+ from .errors import (
7
+ AccessDeniedError,
8
+ ConfigurationError,
9
+ DatasetError,
10
+ IntegrityError,
11
+ NotFoundError,
12
+ TransferError,
13
+ VersionExistsError,
14
+ )
15
+ from .sources import ZipLimits
16
+
17
+ __all__ = [
18
+ "DatasetClient",
19
+ "DatasetSummary",
20
+ "Release",
21
+ "ZipLimits",
22
+ "DatasetError",
23
+ "AccessDeniedError",
24
+ "ConfigurationError",
25
+ "IntegrityError",
26
+ "NotFoundError",
27
+ "TransferError",
28
+ "VersionExistsError",
29
+ "__version__",
30
+ ]
@@ -0,0 +1,3 @@
1
+ from .cli import main
2
+
3
+ raise SystemExit(main())