From 05b177389acdf5beb878a7309aa31c2ffc6a8320 Mon Sep 17 00:00:00 2001 From: AntoSalazar Date: Tue, 29 Apr 2025 00:17:21 -0600 Subject: [PATCH 1/6] feat: Add Docker setup for local development Includes Dockerfile, Docker Compose configuration, and a workaround script (run_sepomex_update.rb) for database seeding due to a persistent 'csv' load error under 'bundle exec'. Updates README with setup instructions and documents the seeding issue and workaround. --- Dockerfile | 32 ++++++++++++----- Gemfile | 2 ++ Rakefile | 5 ++- Readme.md | 82 +++++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 51 +++++++++++++++++++++++++++ run_sepomex_update.rb | 72 +++++++++++++++++++++++++++++++++++++ 6 files changed, 234 insertions(+), 10 deletions(-) create mode 100644 docker-compose.yml create mode 100644 run_sepomex_update.rb diff --git a/Dockerfile b/Dockerfile index cc4c7b3..f43bbc8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,32 @@ -FROM ruby:3.1-slim +# Use the full Ruby 3.4.2 image +FROM ruby:3.4.2 -ENV RACK_ENV=production +# Set environment variables +ENV RACK_ENV=production +# Or development if preferred for local server logs ENV LANG=en_US.UTF-8 +# Install OS dependencies (PostgreSQL client libs, build tools) RUN apt update && apt install -y \ - build-essential libpq-dev \ + build-essential libpq-dev \ && rm -rf /var/lib/apt/lists/* -# Install deps -ADD Gemfile Gemfile.lock ./ +# Update RubyGems & Install/Update Bundler +# Using latest Bundler 2.x series +RUN gem update --system && gem install bundler -v '~> 2.5' -RUN bundle install +# Set working directory inside the container +WORKDIR /app -ADD . . +# Copy Gemfile and Gemfile.lock +COPY Gemfile Gemfile.lock ./ -# run server -CMD bundle exec puma -p ${PORT:-3000} -e ${RACK_ENV:-development} +# Install gem dependencies using Bundler +RUN bundle install --jobs $(nproc) --retry 3 +# Added common optimizations + +# Copy the rest of the application code into the container +COPY . . + +# Command to run the application server (uses Bundler) +CMD bundle exec puma -p ${PORT:-3000} -e ${RACK_ENV:-development} \ No newline at end of file diff --git a/Gemfile b/Gemfile index a71c2ee..abaa790 100644 --- a/Gemfile +++ b/Gemfile @@ -3,6 +3,8 @@ source 'https://rubygems.org' ruby '3.4.2' + + gem 'activerecord' gem 'cuba' gem 'dalli' diff --git a/Rakefile b/Rakefile index 0550fd1..19885a7 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,10 @@ +$LOAD_PATH.unshift('/usr/local/lib/ruby/3.4.0') unless $LOAD_PATH.include?('/usr/local/lib/ruby/3.4.0') + + require 'active_record' require 'yaml' require './db' +require 'csv' desc 'Run migrations' namespace :db do task :migrate do @@ -17,7 +21,6 @@ namespace :sepomex do require 'net/http' require 'uri' require 'zip' - require 'csv' require './models/postal_code' uri = URI.parse('https://www.correosdemexico.gob.mx/SSLServicios/ConsultaCP/CodigoPostal_Exportar.aspx') diff --git a/Readme.md b/Readme.md index 77c32a3..c0b4ba4 100644 --- a/Readme.md +++ b/Readme.md @@ -12,6 +12,88 @@ Además se pueden realizar búsquedas de códigos postales usando los números i 3) Agrega el task de `rake sepomex:update` en el addon de Heroku Scheduler para que se corra cada día. +## Local Development Setup using Docker + +This project includes configuration for running locally using Docker and Docker Compose. + +**Prerequisites:** +* Docker Engine +* Docker Compose + +**Steps:** + +1. **Clone the Repository:** + ```bash + git clone + cd API-Codigos-Postales + ``` + +2. **Build the Docker Image:** + This command builds the necessary image based on the `Dockerfile`. It uses Bundler to install gems specified in `Gemfile.lock`. + ```bash + docker compose build + ``` + +3. **Start the Database:** + This starts the PostgreSQL database container in the background. + ```bash + docker compose up -d db + ``` + Wait a few seconds for the database to initialize (check `docker compose ps` for health status). + +4. **Run Database Migrations:** + This sets up the necessary tables in the database. + ```bash + docker compose run --rm web bundle exec rake db:migrate + ``` + +5. **Seed the Database (Workaround Required):** + + **KNOWN ISSUE:** Running the standard `bundle exec rake sepomex:update` task fails with a `LoadError: cannot load such file -- csv` within the Docker/Ruby 3.4.2 environment when executed via `bundle exec`. This appears to be a deep issue related to Bundler's execution context interfering with the loading of the default `csv` gem. + + **Workaround:** A separate script `run_sepomex_update.rb` has been created to perform the data download and import. However, due to the nature of the loading issue and other errors encountered when running without `bundle exec`, the most reliable (though complex) way to run this locally is currently: + + * **Option 1 (Recommended workaround):** Temporarily modify the `Dockerfile` to install gems globally, run the script without `bundle exec`, then revert the `Dockerfile`. + 1. Comment out the `COPY Gemfile* ./` and `RUN bundle install` lines in `Dockerfile`. + 2. Add `RUN gem install pg activerecord:8.0.1 activesupport:8.0.1 activemodel:8.0.1 rubyzip --no-document` before `WORKDIR /app`. + 3. Rebuild: `docker compose build --no-cache web` + 4. Run the script: `docker compose run --rm web ruby run_sepomex_update.rb` + 5. **CRITICAL:** Revert the `Dockerfile` changes back to using `bundle install` and remove the `gem install` line. + 6. Rebuild again: `docker compose build web` + + * **Option 2:** Get an interactive shell (`docker compose run --rm web bash`) and manually run the core download/parse/insert logic from `run_sepomex_update.rb` using `ruby -e "..."` commands. + + *Note: This seeding issue needs further investigation to find a less cumbersome solution.* + +6. **Start the Application Server:** + Once the database is seeded (using the workaround), start the Puma web server. Ensure your Dockerfile uses `bundle install` (not the global gem install workaround) before this step. + ```bash + docker compose up -d web + ``` + *(Or `docker compose up -d` to start/ensure both services are running)* + +7. **Access the API:** + The API should now be running at `http://localhost:3000`. You can test endpoints using `curl` or Postman. Remember to include the authentication header defined in `docker-compose.yml` (default example: `X-API-TOKEN: very-secret-local-token`). + + **Example Curl:** + ```bash + # Replace XXXXX with a valid postal code + curl -H "X-API-TOKEN: very-secret-local-token" http://localhost:3000/v2/codigo_postal/XXXXX + + # Example search + curl -H "X-API-TOKEN: very-secret-local-token" "http://localhost:3000/v2/buscar?codigo_postal=290" + ``` + +8. **Stopping:** + To stop the containers: + ```bash + docker compose down + ``` + To stop and remove the database volume (deletes data): + ```bash + docker compose down -v + ``` + ## Suscripción y documentación de la API [https://rapidapi.com/acrogenesis-llc-api/api/mexico-zip-codes](https://rapidapi.com/acrogenesis-llc-api/api/mexico-zip-codes) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..2844a1f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,51 @@ +# docker-compose.yml + +services: + db: + image: postgres:15 # Use a version known to have 'unaccent' readily available + container_name: codigos-postales-db + environment: + POSTGRES_USER: postgres # Choose a username + POSTGRES_PASSWORD: postgres # Choose a strong password + POSTGRES_DB: api-codigos-postales # Matches database.yml + volumes: + - postgres_data:/var/lib/postgresql/data + networks: + - app-network + healthcheck: + # Ensure username matches POSTGRES_USER above + test: ["CMD-SHELL", "pg_isready -U your_postgres_user -d api-codigos-postales"] + interval: 5s + timeout: 5s + retries: 5 + + web: + build: . # Build from Dockerfile in the current directory + container_name: codigos-postales-web + command: bundle exec puma -p 3000 -e development + volumes: + # Optional: Mount code for live changes in development + # Note: Might cause issues with permissions or dependencies installed in the image + # - .:/app + - gem_cache:/usr/local/bundle/gems # Persist gems + ports: + - "3000:3000" # Map host port 3000 to container port 3000 + depends_on: + db: + condition: service_healthy # Wait for DB to be ready + networks: + - app-network + environment: + RACK_ENV: development + # Construct DATABASE_URL using DB service details + DATABASE_URL: postgresql://postgres:postgres@db:5432/api-codigos-postales + VALIDATE_HEADER: X-API-TOKEN # Example header name + VALIDATE_HEADER_VALUE: very-secret-local-token # Example token value + # PORT: 3000 # Optional, already default + +volumes: + postgres_data: + gem_cache: + +networks: + app-network: \ No newline at end of file diff --git a/run_sepomex_update.rb b/run_sepomex_update.rb new file mode 100644 index 0000000..af556ec --- /dev/null +++ b/run_sepomex_update.rb @@ -0,0 +1,72 @@ +# run_sepomex_update.rb + +# Requires - ensure csv is required early, before potential conflicts +require 'csv' +require 'active_record' +require 'yaml' +require 'net/http' +require 'uri' +require 'zip' +require './db' # Establish DB connection +require './models/postal_code' # Load the model + + +# --- Start of copied logic from Rake task --- +uri = URI.parse('https://www.correosdemexico.gob.mx/SSLServicios/ConsultaCP/CodigoPostal_Exportar.aspx') + +params = { + '__VIEWSTATE' => '/wEPDwUINzcwOTQyOTgPZBYCAgEPZBYCAgEPZBYGAgMPDxYCHgRUZXh0BTrDmmx0aW1hIEFjdHVhbGl6YWNpw7NuIGRlIEluZm9ybWFjacOzbjogRmVicmVybyAyOCBkZSAyMDE5ZGQCBw8QDxYGHg1EYXRhVGV4dEZpZWxkBQNFZG8eDkRhdGFWYWx1ZUZpZWxkBQVJZEVkbx4LXyFEYXRhQm91bmRnZBAVISMtLS0tLS0tLS0tIFQgIG8gIGQgIG8gIHMgLS0tLS0tLS0tLQ5BZ3Vhc2NhbGllbnRlcw9CYWphIENhbGlmb3JuaWETQmFqYSBDYWxpZm9ybmlhIFN1cghDYW1wZWNoZRRDb2FodWlsYSBkZSBaYXJhZ296YQZDb2xpbWEHQ2hpYXBhcwlDaGlodWFodWERQ2l1ZGFkIGRlIE3DqXhpY28HRHVyYW5nbwpHdWFuYWp1YXRvCEd1ZXJyZXJvB0hpZGFsZ28HSmFsaXNjbwdNw6l4aWNvFE1pY2hvYWPDoW4gZGUgT2NhbXBvB01vcmVsb3MHTmF5YXJpdAtOdWV2byBMZcOzbgZPYXhhY2EGUHVlYmxhClF1ZXLDqXRhcm8MUXVpbnRhbmEgUm9vEFNhbiBMdWlzIFBvdG9zw60HU2luYWxvYQZTb25vcmEHVGFiYXNjbwpUYW1hdWxpcGFzCFRsYXhjYWxhH1ZlcmFjcnV6IGRlIElnbmFjaW8gZGUgbGEgTGxhdmUIWXVjYXTDoW4JWmFjYXRlY2FzFSECMDACMDECMDICMDMCMDQCMDUCMDYCMDcCMDgCMDkCMTACMTECMTICMTMCMTQCMTUCMTYCMTcCMTgCMTkCMjACMjECMjICMjMCMjQCMjUCMjYCMjcCMjgCMjkCMzACMzECMzIUKwMhZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZGQCHQ88KwALAGQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFC2J0bkRlc2NhcmdhqRZm1BP66KzYxUpp1Ej06LEoJ10=', + '__VIEWSTATEGENERATOR' => 'BE1A6D2E', + '__EVENTVALIDATION' => '/wEWKALhkeqeAQLG/OLvBgLWk4iCCgLWk4SCCgLWk4CCCgLWk7yCCgLWk7iCCgLWk7SCCgLWk7CCCgLWk6yCCgLWk+iBCgLWk+SBCgLJk4iCCgLJk4SCCgLJk4CCCgLJk7yCCgLJk7iCCgLJk7SCCgLJk7CCCgLJk6yCCgLJk+iBCgLJk+SBCgLIk4iCCgLIk4SCCgLIk4CCCgLIk7yCCgLIk7iCCgLIk7SCCgLIk7CCCgLIk6yCCgLIk+iBCgLIk+SBCgLLk4iCCgLLk4SCCgLLk4CCCgLL+uTWBALa4Za4AgK+qOyRAQLI56b6CwL1/KjtBQShtqSfolZPHREbgq/CaRh97SO2', + 'cboEdo' => '00', + 'rblTipo' => 'txt', + 'btnDescarga.x' => '44', + 'btnDescarga.y' => '10' +} +puts 'Downloading postal codes from SEPOMEX' +response_post = Net::HTTP.post_form(uri, params) + +puts 'Writing Zip' +File.open('latest.zip', 'w') do |file| + file.write response_post.body +end + +puts 'Extracting Zip' +Zip::File.open('latest.zip') do |zip_file| + # Ensure the directory exists if needed, though extracting to current dir is likely fine + zip_file.extract('CPdescarga.txt', 'latest.csv') { true } # Overwrite if exists +end + +puts 'Parsing Postal Codes' +# Use File.read for simplicity if memory allows, otherwise stick with readlines +csv_text = File.read('latest.csv', encoding: 'ISO-8859-1:UTF-8').lines[1..].join # Skip header line +csv = CSV.parse(csv_text, col_sep: '|', quote_char: '%', headers: :first_row, return_headers: false) # Don't return headers here + +# Removed unnecessary csv.delete calls as CSV.parse with headers: :first_row handles it. + +puts 'Inserting new Postal Codes' +old_logger = ActiveRecord::Base.logger +ActiveRecord::Base.logger = nil # Temporarily disable verbose SQL logging +count = 0 +total_rows = 0 +csv.each { |_| total_rows += 1 } # Get total count first for percentage +# Use find_or_initialize_by + save for potential efficiency, or stick with find_or_create_by +csv.each do |row| + arg = {} + row_h = row.to_h + arg[:codigo_postal] = row_h['d_codigo'] + arg[:colonia] = row_h['d_asenta'] + arg[:municipio] = row_h['D_mnpio'] + arg[:estado] = row_h['d_estado'] + PostalCode.find_or_create_by(arg) + count += 1 + print "#{(100 * count) / total_rows}% \r" if total_rows > 0 +end +ActiveRecord::Base.logger = old_logger # Restore logger +puts '' +puts 'Finished Inserting Postal Codes.' +puts 'Removing TempFiles' +File.delete('latest.csv') +File.delete('latest.zip') +puts 'Done.' +# --- End of copied logic --- \ No newline at end of file From c5a167092b45a9618d4ffbc6ece2bf5182b3daad Mon Sep 17 00:00:00 2001 From: AntoSalazar Date: Tue, 29 Apr 2025 00:23:30 -0600 Subject: [PATCH 2/6] update readme --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index c0b4ba4..4fe42dd 100644 --- a/Readme.md +++ b/Readme.md @@ -24,7 +24,7 @@ This project includes configuration for running locally using Docker and Docker 1. **Clone the Repository:** ```bash - git clone + git clone https://github.com/AntoSalazar/API-Codigos-Postales.git cd API-Codigos-Postales ``` From 206b1dc954f80bd7200aa81a330192996a2785f1 Mon Sep 17 00:00:00 2001 From: AntoSalazar Date: Thu, 26 Jun 2025 10:35:00 -0600 Subject: [PATCH 3/6] feat: Dockerize application and streamline setup This commit introduces comprehensive Docker support for the API-Codigos-Postales application, enabling easy setup and execution using Docker Compose. Key changes and problem resolutions include: - **Initial Dockerfile and docker-compose.yml setup:** Configured the application and PostgreSQL database services for containerization. - **Resolved Ruby version mismatch:** Corrected the Ruby version in the Dockerfile to `3.4.2` to align with the `Gemfile` specification, fixing build failures. - **Fixed PostgreSQL password authentication:** Addressed persistent `PG::ConnectionBad` errors by ensuring the database volume was properly reset and recreated with the correct password, resolving connection issues. - **Addressed `LoadError: cannot load such file -- csv`:** Explicitly added `gem 'csv'` to the `Gemfile` to ensure the `csv` library is correctly bundled and available within the Docker environment, resolving the original data seeding failure. - **Updated `Readme.md`:** Added detailed instructions for building, running, migrating, and seeding the database using `docker compose`, ensuring clarity and ease of use for new developers. --- Dockerfile | 27 +++------------ Gemfile | 2 +- Readme.md | 86 ++++++++++++++-------------------------------- docker-compose.yml | 41 ++++++++++------------ 4 files changed, 51 insertions(+), 105 deletions(-) diff --git a/Dockerfile b/Dockerfile index f43bbc8..a95042c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,32 +1,15 @@ -# Use the full Ruby 3.4.2 image FROM ruby:3.4.2 -# Set environment variables -ENV RACK_ENV=production -# Or development if preferred for local server logs -ENV LANG=en_US.UTF-8 +RUN apt-get update -qq && apt-get install -y build-essential libpq-dev -# Install OS dependencies (PostgreSQL client libs, build tools) -RUN apt update && apt install -y \ - build-essential libpq-dev \ - && rm -rf /var/lib/apt/lists/* - -# Update RubyGems & Install/Update Bundler -# Using latest Bundler 2.x series -RUN gem update --system && gem install bundler -v '~> 2.5' - -# Set working directory inside the container WORKDIR /app -# Copy Gemfile and Gemfile.lock COPY Gemfile Gemfile.lock ./ -# Install gem dependencies using Bundler -RUN bundle install --jobs $(nproc) --retry 3 -# Added common optimizations +RUN bundle install -# Copy the rest of the application code into the container COPY . . -# Command to run the application server (uses Bundler) -CMD bundle exec puma -p ${PORT:-3000} -e ${RACK_ENV:-development} \ No newline at end of file +EXPOSE 3000 + +CMD ["bundle", "exec", "puma", "-p", "3000", "-e", "development"] \ No newline at end of file diff --git a/Gemfile b/Gemfile index abaa790..53cd795 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ source 'https://rubygems.org' ruby '3.4.2' - +gem 'csv' gem 'activerecord' gem 'cuba' diff --git a/Readme.md b/Readme.md index 4fe42dd..aba6a8e 100644 --- a/Readme.md +++ b/Readme.md @@ -12,88 +12,51 @@ Además se pueden realizar búsquedas de códigos postales usando los números i 3) Agrega el task de `rake sepomex:update` en el addon de Heroku Scheduler para que se corra cada día. -## Local Development Setup using Docker +## Running with Docker Compose -This project includes configuration for running locally using Docker and Docker Compose. +This project can be easily run using Docker Compose, which sets up both the Ruby application and a PostgreSQL database. **Prerequisites:** -* Docker Engine -* Docker Compose +* Docker installed on your system. +* Docker Compose (usually included with Docker Desktop or installed separately). **Steps:** -1. **Clone the Repository:** - ```bash - git clone https://github.com/AntoSalazar/API-Codigos-Postales.git - cd API-Codigos-Postales - ``` - -2. **Build the Docker Image:** - This command builds the necessary image based on the `Dockerfile`. It uses Bundler to install gems specified in `Gemfile.lock`. +1. **Build the Docker images:** ```bash docker compose build ``` -3. **Start the Database:** - This starts the PostgreSQL database container in the background. +2. **Start the database service:** ```bash - docker compose up -d db + docker compose up -d zipcode_api_db ``` - Wait a few seconds for the database to initialize (check `docker compose ps` for health status). -4. **Run Database Migrations:** - This sets up the necessary tables in the database. +3. **Wait for the database to be healthy.** You can check its status with: ```bash - docker compose run --rm web bundle exec rake db:migrate + docker compose ps ``` + Wait until `zipcode_api_db` shows `healthy` in the `Status` column. -5. **Seed the Database (Workaround Required):** - - **KNOWN ISSUE:** Running the standard `bundle exec rake sepomex:update` task fails with a `LoadError: cannot load such file -- csv` within the Docker/Ruby 3.4.2 environment when executed via `bundle exec`. This appears to be a deep issue related to Bundler's execution context interfering with the loading of the default `csv` gem. - - **Workaround:** A separate script `run_sepomex_update.rb` has been created to perform the data download and import. However, due to the nature of the loading issue and other errors encountered when running without `bundle exec`, the most reliable (though complex) way to run this locally is currently: - - * **Option 1 (Recommended workaround):** Temporarily modify the `Dockerfile` to install gems globally, run the script without `bundle exec`, then revert the `Dockerfile`. - 1. Comment out the `COPY Gemfile* ./` and `RUN bundle install` lines in `Dockerfile`. - 2. Add `RUN gem install pg activerecord:8.0.1 activesupport:8.0.1 activemodel:8.0.1 rubyzip --no-document` before `WORKDIR /app`. - 3. Rebuild: `docker compose build --no-cache web` - 4. Run the script: `docker compose run --rm web ruby run_sepomex_update.rb` - 5. **CRITICAL:** Revert the `Dockerfile` changes back to using `bundle install` and remove the `gem install` line. - 6. Rebuild again: `docker compose build web` - - * **Option 2:** Get an interactive shell (`docker compose run --rm web bash`) and manually run the core download/parse/insert logic from `run_sepomex_update.rb` using `ruby -e "..."` commands. - - *Note: This seeding issue needs further investigation to find a less cumbersome solution.* - -6. **Start the Application Server:** - Once the database is seeded (using the workaround), start the Puma web server. Ensure your Dockerfile uses `bundle install` (not the global gem install workaround) before this step. +4. **Run database migrations:** ```bash - docker compose up -d web + docker compose run --rm zipcode_api_web bundle exec rake db:migrate ``` - *(Or `docker compose up -d` to start/ensure both services are running)* -7. **Access the API:** - The API should now be running at `http://localhost:3000`. You can test endpoints using `curl` or Postman. Remember to include the authentication header defined in `docker-compose.yml` (default example: `X-API-TOKEN: very-secret-local-token`). - - **Example Curl:** +5. **Seed the database with postal code data:** + This step downloads and imports the latest postal code data from SEPOMEX. It might take some time. ```bash - # Replace XXXXX with a valid postal code - curl -H "X-API-TOKEN: very-secret-local-token" http://localhost:3000/v2/codigo_postal/XXXXX - - # Example search - curl -H "X-API-TOKEN: very-secret-local-token" "http://localhost:3000/v2/buscar?codigo_postal=290" + docker compose run --rm zipcode_api_web bundle exec rake sepomex:update ``` -8. **Stopping:** - To stop the containers: - ```bash - docker compose down - ``` - To stop and remove the database volume (deletes data): +6. **Start the web application:** ```bash - docker compose down -v + docker compose up -d zipcode_api_web ``` +7. **Access the application:** + The API will be available at `http://localhost:3001`. + ## Suscripción y documentación de la API [https://rapidapi.com/acrogenesis-llc-api/api/mexico-zip-codes](https://rapidapi.com/acrogenesis-llc-api/api/mexico-zip-codes) @@ -144,7 +107,7 @@ https://mexico-zip-codes.p.rapidapi.com/buscar?codigo_postal=6641 ``` _Ejemplo de búsqueda limitada a 3 resultados_ -```json +```text https://mexico-zip-codes.p.rapidapi.com/buscar?codigo_postal=66&limit=3 ``` @@ -210,7 +173,10 @@ https://mexico-zip-codes.p.rapidapi.com/v2/buscar_por_ubicacion?estado=Nuevo%20L ___ ### Rake task -Ejecuta el rake task `rake sepomex:update` para descargar todos los códigos postales de México y actualizar tu base de datos. +Ejecuta el rake task `rake sepomex:update` para descargar todos los códigos postales de México y actualizar tu base de datos. When running with Docker Compose, use: +```bash +docker compose run --rm zipcode_api_web bundle exec rake sepomex:update +``` ### Colabora Errores y pull requests son bienvenidos en Github: https://github.com/Munett/API-Codigos-Postales. @@ -221,4 +187,4 @@ Los datos se obtuvieron de http://www.correosdemexico.gob.mx/lservicios/servicio ### Los datos se actualizan cada domingo. ### Licencia -MIT License +MIT License \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 2844a1f..e99e520 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,51 +1,48 @@ -# docker-compose.yml +version: '3.8' services: db: - image: postgres:15 # Use a version known to have 'unaccent' readily available - container_name: codigos-postales-db + image: postgres:15 + container_name: codigos-postales-db-test environment: - POSTGRES_USER: postgres # Choose a username - POSTGRES_PASSWORD: postgres # Choose a strong password - POSTGRES_DB: api-codigos-postales # Matches database.yml + POSTGRES_USER: postgres + POSTGRES_PASSWORD: password + POSTGRES_DB: api-codigos-postales volumes: - postgres_data:/var/lib/postgresql/data + ports: + - "5432:5432" networks: - app-network healthcheck: - # Ensure username matches POSTGRES_USER above - test: ["CMD-SHELL", "pg_isready -U your_postgres_user -d api-codigos-postales"] + test: ["CMD-SHELL", "pg_isready -U postgres -d api-codigos-postales"] interval: 5s timeout: 5s retries: 5 web: - build: . # Build from Dockerfile in the current directory - container_name: codigos-postales-web + build: . + container_name: codigos-postales-web-test command: bundle exec puma -p 3000 -e development volumes: - # Optional: Mount code for live changes in development - # Note: Might cause issues with permissions or dependencies installed in the image - # - .:/app - - gem_cache:/usr/local/bundle/gems # Persist gems + - .:/app + - gem_cache:/usr/local/bundle/gems ports: - - "3000:3000" # Map host port 3000 to container port 3000 + - "3000:3000" depends_on: db: - condition: service_healthy # Wait for DB to be ready + condition: service_healthy networks: - app-network environment: RACK_ENV: development - # Construct DATABASE_URL using DB service details - DATABASE_URL: postgresql://postgres:postgres@db:5432/api-codigos-postales - VALIDATE_HEADER: X-API-TOKEN # Example header name - VALIDATE_HEADER_VALUE: very-secret-local-token # Example token value - # PORT: 3000 # Optional, already default + DATABASE_URL: postgresql://postgres:password@db:5432/api-codigos-postales + VALIDATE_HEADER: X-API-TOKEN + VALIDATE_HEADER_VALUE: very-secret-local-token volumes: postgres_data: gem_cache: networks: - app-network: \ No newline at end of file + app-network: From 62b9b1d99de0f434626de0436fc6d8f36ee064e7 Mon Sep 17 00:00:00 2001 From: AntoSalazar Date: Thu, 26 Jun 2025 10:49:15 -0600 Subject: [PATCH 4/6] feat: Implement daily data update cron job This commit introduces a daily cron job to automatically update the postal code data using the `rake sepomex:update` task. - **Added `cron` to Docker image:** Modified `Dockerfile` to install `cron` and copy necessary scripts and configuration. - **Created `update_sepomex.sh`:** A shell script to execute the `rake sepomex:update` command within the container. - **Configured cron schedule:** Created `cron/sepomex_update_cron` to schedule the `update_sepomex.sh` script to run daily at 3:00 AM. - **Introduced `cron_worker` service:** Added a new service to `docker-compose.yml` to run the cron daemon, ensuring the scheduled task executes within the Docker environment. - **Updated `Readme.md`:** Documented the cron job setup, including verification and testing instructions. --- Dockerfile | 7 ++++++- Readme.md | 42 ++++++++++++++++++++++++++++++++++++++++ cron/sepomex_update_cron | 1 + docker-compose.yml | 16 +++++++++++++++ update_sepomex.sh | 4 ++++ 5 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 cron/sepomex_update_cron create mode 100644 update_sepomex.sh diff --git a/Dockerfile b/Dockerfile index a95042c..737bcf5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM ruby:3.4.2 -RUN apt-get update -qq && apt-get install -y build-essential libpq-dev +RUN apt-get update -qq && apt-get install -y build-essential libpq-dev cron WORKDIR /app @@ -8,6 +8,11 @@ COPY Gemfile Gemfile.lock ./ RUN bundle install +COPY update_sepomex.sh /app/update_sepomex.sh +COPY cron/sepomex_update_cron /etc/cron.d/sepomex_update_cron +RUN chmod +x /app/update_sepomex.sh +RUN chmod 0644 /etc/cron.d/sepomex_update_cron + COPY . . EXPOSE 3000 diff --git a/Readme.md b/Readme.md index aba6a8e..a4ca9fc 100644 --- a/Readme.md +++ b/Readme.md @@ -57,6 +57,48 @@ This project can be easily run using Docker Compose, which sets up both the Ruby 7. **Access the application:** The API will be available at `http://localhost:3001`. +## Scheduled Data Updates (Cron Job) + +This project includes a daily cron job to automatically update the postal code data from SEPOMEX. The update is scheduled to run every day at 3:00 AM (UTC). + +**How to Verify the Cron Job:** + +1. **Ensure the `cron_worker` service is running:** + ```bash + docker compose up -d cron_worker + ``` + +2. **Check the `cron_worker` logs:** + ```bash + docker compose logs -f cron_worker + ``` + You should see output related to the `rake sepomex:update` task when it runs. + +**How to Manually Trigger the Update (for testing):** + +To test the update process without waiting for the scheduled time, you can manually execute the update script inside the `cron_worker` container: + +```bash +docker compose exec cron_worker /app/update_sepomex.sh +``` + +**Temporarily Adjusting Cron Schedule for Testing:** + +If you need to test the cron daemon's scheduling functionality, you can temporarily modify the cron schedule: + +1. Edit the `cron/sepomex_update_cron` file inside your project directory. +2. Change the schedule (e.g., `0 3 * * *` to `* * * * *` for every minute). +3. Rebuild the `cron_worker` service: + ```bash + docker compose build cron_worker + ``` +4. Restart the `cron_worker` service: + ```bash + docker compose up -d cron_worker + ``` +5. Monitor the logs (`docker compose logs -f cron_worker`) to see the job run at the new interval. +6. **Remember to revert the cron schedule** in `cron/sepomex_update_cron` back to `0 3 * * *` and rebuild/restart the `cron_worker` service after testing. + ## Suscripción y documentación de la API [https://rapidapi.com/acrogenesis-llc-api/api/mexico-zip-codes](https://rapidapi.com/acrogenesis-llc-api/api/mexico-zip-codes) diff --git a/cron/sepomex_update_cron b/cron/sepomex_update_cron new file mode 100644 index 0000000..4cc5c0f --- /dev/null +++ b/cron/sepomex_update_cron @@ -0,0 +1 @@ +0 3 * * * /app/update_sepomex.sh >> /var/log/cron.log 2>&1 diff --git a/docker-compose.yml b/docker-compose.yml index e99e520..c31e348 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -40,6 +40,22 @@ services: VALIDATE_HEADER: X-API-TOKEN VALIDATE_HEADER_VALUE: very-secret-local-token + cron_worker: + build: . + container_name: codigos-postales-cron + depends_on: + db: + condition: service_healthy + environment: + RACK_ENV: development + DATABASE_URL: postgresql://postgres:password@db:5432/api-codigos-postales + volumes: + - .:/app + - gem_cache:/usr/local/bundle/gems + command: cron -f + networks: + - app-network + volumes: postgres_data: gem_cache: diff --git a/update_sepomex.sh b/update_sepomex.sh new file mode 100644 index 0000000..1c341e5 --- /dev/null +++ b/update_sepomex.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +cd /app +bundle exec rake sepomex:update From 55f0f22905ce37678cc6d25ea91ce584e03e27c0 Mon Sep 17 00:00:00 2001 From: AntoSalazar Date: Thu, 26 Jun 2025 11:18:46 -0600 Subject: [PATCH 5/6] upload correct files --- Gemfile.lock | 2 ++ Rakefile | 5 +-- run_sepomex_update.rb | 72 ------------------------------------------- 3 files changed, 3 insertions(+), 76 deletions(-) delete mode 100644 run_sepomex_update.rb diff --git a/Gemfile.lock b/Gemfile.lock index 16bffcb..802da5a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -26,6 +26,7 @@ GEM bigdecimal (3.1.9) concurrent-ruby (1.3.5) connection_pool (2.5.0) + csv (3.3.2) cuba (4.0.3) rack (>= 3.0.0) rack-session (>= 2.0.0) @@ -116,6 +117,7 @@ PLATFORMS DEPENDENCIES activerecord + csv cuba dalli database_cleaner-active_record diff --git a/Rakefile b/Rakefile index 19885a7..0550fd1 100644 --- a/Rakefile +++ b/Rakefile @@ -1,10 +1,6 @@ -$LOAD_PATH.unshift('/usr/local/lib/ruby/3.4.0') unless $LOAD_PATH.include?('/usr/local/lib/ruby/3.4.0') - - require 'active_record' require 'yaml' require './db' -require 'csv' desc 'Run migrations' namespace :db do task :migrate do @@ -21,6 +17,7 @@ namespace :sepomex do require 'net/http' require 'uri' require 'zip' + require 'csv' require './models/postal_code' uri = URI.parse('https://www.correosdemexico.gob.mx/SSLServicios/ConsultaCP/CodigoPostal_Exportar.aspx') diff --git a/run_sepomex_update.rb b/run_sepomex_update.rb deleted file mode 100644 index af556ec..0000000 --- a/run_sepomex_update.rb +++ /dev/null @@ -1,72 +0,0 @@ -# run_sepomex_update.rb - -# Requires - ensure csv is required early, before potential conflicts -require 'csv' -require 'active_record' -require 'yaml' -require 'net/http' -require 'uri' -require 'zip' -require './db' # Establish DB connection -require './models/postal_code' # Load the model - - -# --- Start of copied logic from Rake task --- -uri = URI.parse('https://www.correosdemexico.gob.mx/SSLServicios/ConsultaCP/CodigoPostal_Exportar.aspx') - -params = { - '__VIEWSTATE' => '/wEPDwUINzcwOTQyOTgPZBYCAgEPZBYCAgEPZBYGAgMPDxYCHgRUZXh0BTrDmmx0aW1hIEFjdHVhbGl6YWNpw7NuIGRlIEluZm9ybWFjacOzbjogRmVicmVybyAyOCBkZSAyMDE5ZGQCBw8QDxYGHg1EYXRhVGV4dEZpZWxkBQNFZG8eDkRhdGFWYWx1ZUZpZWxkBQVJZEVkbx4LXyFEYXRhQm91bmRnZBAVISMtLS0tLS0tLS0tIFQgIG8gIGQgIG8gIHMgLS0tLS0tLS0tLQ5BZ3Vhc2NhbGllbnRlcw9CYWphIENhbGlmb3JuaWETQmFqYSBDYWxpZm9ybmlhIFN1cghDYW1wZWNoZRRDb2FodWlsYSBkZSBaYXJhZ296YQZDb2xpbWEHQ2hpYXBhcwlDaGlodWFodWERQ2l1ZGFkIGRlIE3DqXhpY28HRHVyYW5nbwpHdWFuYWp1YXRvCEd1ZXJyZXJvB0hpZGFsZ28HSmFsaXNjbwdNw6l4aWNvFE1pY2hvYWPDoW4gZGUgT2NhbXBvB01vcmVsb3MHTmF5YXJpdAtOdWV2byBMZcOzbgZPYXhhY2EGUHVlYmxhClF1ZXLDqXRhcm8MUXVpbnRhbmEgUm9vEFNhbiBMdWlzIFBvdG9zw60HU2luYWxvYQZTb25vcmEHVGFiYXNjbwpUYW1hdWxpcGFzCFRsYXhjYWxhH1ZlcmFjcnV6IGRlIElnbmFjaW8gZGUgbGEgTGxhdmUIWXVjYXTDoW4JWmFjYXRlY2FzFSECMDACMDECMDICMDMCMDQCMDUCMDYCMDcCMDgCMDkCMTACMTECMTICMTMCMTQCMTUCMTYCMTcCMTgCMTkCMjACMjECMjICMjMCMjQCMjUCMjYCMjcCMjgCMjkCMzACMzECMzIUKwMhZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZGQCHQ88KwALAGQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFC2J0bkRlc2NhcmdhqRZm1BP66KzYxUpp1Ej06LEoJ10=', - '__VIEWSTATEGENERATOR' => 'BE1A6D2E', - '__EVENTVALIDATION' => '/wEWKALhkeqeAQLG/OLvBgLWk4iCCgLWk4SCCgLWk4CCCgLWk7yCCgLWk7iCCgLWk7SCCgLWk7CCCgLWk6yCCgLWk+iBCgLWk+SBCgLJk4iCCgLJk4SCCgLJk4CCCgLJk7yCCgLJk7iCCgLJk7SCCgLJk7CCCgLJk6yCCgLJk+iBCgLJk+SBCgLIk4iCCgLIk4SCCgLIk4CCCgLIk7yCCgLIk7iCCgLIk7SCCgLIk7CCCgLIk6yCCgLIk+iBCgLIk+SBCgLLk4iCCgLLk4SCCgLLk4CCCgLL+uTWBALa4Za4AgK+qOyRAQLI56b6CwL1/KjtBQShtqSfolZPHREbgq/CaRh97SO2', - 'cboEdo' => '00', - 'rblTipo' => 'txt', - 'btnDescarga.x' => '44', - 'btnDescarga.y' => '10' -} -puts 'Downloading postal codes from SEPOMEX' -response_post = Net::HTTP.post_form(uri, params) - -puts 'Writing Zip' -File.open('latest.zip', 'w') do |file| - file.write response_post.body -end - -puts 'Extracting Zip' -Zip::File.open('latest.zip') do |zip_file| - # Ensure the directory exists if needed, though extracting to current dir is likely fine - zip_file.extract('CPdescarga.txt', 'latest.csv') { true } # Overwrite if exists -end - -puts 'Parsing Postal Codes' -# Use File.read for simplicity if memory allows, otherwise stick with readlines -csv_text = File.read('latest.csv', encoding: 'ISO-8859-1:UTF-8').lines[1..].join # Skip header line -csv = CSV.parse(csv_text, col_sep: '|', quote_char: '%', headers: :first_row, return_headers: false) # Don't return headers here - -# Removed unnecessary csv.delete calls as CSV.parse with headers: :first_row handles it. - -puts 'Inserting new Postal Codes' -old_logger = ActiveRecord::Base.logger -ActiveRecord::Base.logger = nil # Temporarily disable verbose SQL logging -count = 0 -total_rows = 0 -csv.each { |_| total_rows += 1 } # Get total count first for percentage -# Use find_or_initialize_by + save for potential efficiency, or stick with find_or_create_by -csv.each do |row| - arg = {} - row_h = row.to_h - arg[:codigo_postal] = row_h['d_codigo'] - arg[:colonia] = row_h['d_asenta'] - arg[:municipio] = row_h['D_mnpio'] - arg[:estado] = row_h['d_estado'] - PostalCode.find_or_create_by(arg) - count += 1 - print "#{(100 * count) / total_rows}% \r" if total_rows > 0 -end -ActiveRecord::Base.logger = old_logger # Restore logger -puts '' -puts 'Finished Inserting Postal Codes.' -puts 'Removing TempFiles' -File.delete('latest.csv') -File.delete('latest.zip') -puts 'Done.' -# --- End of copied logic --- \ No newline at end of file From 4def72e2da5010aa9eae06d261085f18ab20c305 Mon Sep 17 00:00:00 2001 From: AntoSalazar Date: Thu, 26 Jun 2025 12:04:13 -0600 Subject: [PATCH 6/6] update readme --- Readme.md | 146 +++++++++++++++++++++++------------------------------- 1 file changed, 62 insertions(+), 84 deletions(-) diff --git a/Readme.md b/Readme.md index a4ca9fc..12584e8 100644 --- a/Readme.md +++ b/Readme.md @@ -1,109 +1,84 @@ # API para los códigos postales de México -[![Code Climate](https://codeclimate.com/github/Munett/API-Codigos-Postales/badges/gpa.svg)](https://codeclimate.com/github/Munett/API-Codigos-Postales) -[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/acrogenesis/API-Codigos-Postales) +[](https://codeclimate.com/github/Munett/API-Codigos-Postales) -Dado un código postal, regresa un arreglo con las colonia, municipio y estado perteneciente al código postal. -Además se pueden realizar búsquedas de códigos postales usando los números iniciales. +[](https://heroku.com/deploy?template=https://github.com/acrogenesis/API-Codigos-Postales) -## Sube la app a heroku -1) Da click en el botón `Deploy to Heroku` y sigue los pasos. -2) Al terminar corre `heroku run rake sepomex:update`. -3) Agrega el task de `rake sepomex:update` en el addon de Heroku -Scheduler para que se corra cada día. +Dado un código postal, regresa un arreglo con las colonias, municipio y estado perteneciente al código postal. Además, se pueden realizar búsquedas de códigos postales usando los números iniciales. + +## Sube la app a Heroku + +1) Da click en el botón `Deploy to Heroku` y sigue los pasos. +2) Al terminar corre `heroku run rake sepomex:update`. +3) Agrega el task de `rake sepomex:update` en el addon de Heroku Scheduler para que se corra cada día. ## Running with Docker Compose -This project can be easily run using Docker Compose, which sets up both the Ruby application and a PostgreSQL database. +This project can be easily run using Docker Compose, which sets up the Ruby application, a PostgreSQL database, and a cron job for data updates. **Prerequisites:** -* Docker installed on your system. -* Docker Compose (usually included with Docker Desktop or installed separately). + + * Docker and Docker Compose installed on your system. **Steps:** -1. **Build the Docker images:** - ```bash - docker compose build - ``` +1. **Clone the repository and navigate into the directory.** + +2. **Build and start all services in the background:** + This command builds the images if they don't exist and starts the `db`, `web`, and `cron_worker` containers. -2. **Start the database service:** ```bash - docker compose up -d zipcode_api_db + docker compose up -d --build ``` -3. **Wait for the database to be healthy.** You can check its status with: +3. **Check the status of the containers:** + Wait for the `db` service to show `(healthy)` in the status column before proceeding. + ```bash docker compose ps ``` - Wait until `zipcode_api_db` shows `healthy` in the `Status` column. 4. **Run database migrations:** + This command sets up the necessary tables in the database. + ```bash - docker compose run --rm zipcode_api_web bundle exec rake db:migrate + docker compose run --rm web bundle exec rake db:migrate ``` 5. **Seed the database with postal code data:** This step downloads and imports the latest postal code data from SEPOMEX. It might take some time. - ```bash - docker compose run --rm zipcode_api_web bundle exec rake sepomex:update - ``` -6. **Start the web application:** ```bash - docker compose up -d zipcode_api_web + docker compose run --rm web bundle exec rake sepomex:update ``` -7. **Access the application:** - The API will be available at `http://localhost:3001`. +6. **Access the application:** + The API should now be running and available at `http://localhost:3000`. ## Scheduled Data Updates (Cron Job) -This project includes a daily cron job to automatically update the postal code data from SEPOMEX. The update is scheduled to run every day at 3:00 AM (UTC). +The `cron_worker` service is configured to automatically run `rake sepomex:update` every day at 3:00 AM (UTC) to keep the postal code data fresh. **How to Verify the Cron Job:** -1. **Ensure the `cron_worker` service is running:** - ```bash - docker compose up -d cron_worker - ``` - -2. **Check the `cron_worker` logs:** +1. **Check the `cron_worker` logs:** ```bash docker compose logs -f cron_worker ``` - You should see output related to the `rake sepomex:update` task when it runs. + You will see output from the cron daemon and the rake task when it executes. -**How to Manually Trigger the Update (for testing):** +**How to Manually Trigger an Update:** -To test the update process without waiting for the scheduled time, you can manually execute the update script inside the `cron_worker` container: +To run the update process immediately without waiting for the scheduled time, execute the rake task directly on the `web` service (as it has the application code and dependencies): ```bash -docker compose exec cron_worker /app/update_sepomex.sh +docker compose run --rm web bundle exec rake sepomex:update ``` -**Temporarily Adjusting Cron Schedule for Testing:** - -If you need to test the cron daemon's scheduling functionality, you can temporarily modify the cron schedule: - -1. Edit the `cron/sepomex_update_cron` file inside your project directory. -2. Change the schedule (e.g., `0 3 * * *` to `* * * * *` for every minute). -3. Rebuild the `cron_worker` service: - ```bash - docker compose build cron_worker - ``` -4. Restart the `cron_worker` service: - ```bash - docker compose up -d cron_worker - ``` -5. Monitor the logs (`docker compose logs -f cron_worker`) to see the job run at the new interval. -6. **Remember to revert the cron schedule** in `cron/sepomex_update_cron` back to `0 3 * * *` and rebuild/restart the `cron_worker` service after testing. - ## Suscripción y documentación de la API [https://rapidapi.com/acrogenesis-llc-api/api/mexico-zip-codes](https://rapidapi.com/acrogenesis-llc-api/api/mexico-zip-codes) - **Consultar la información de un código postal** ```text @@ -111,6 +86,7 @@ https://mexico-zip-codes.p.rapidapi.com/codigo_postal/66436 ``` **Respuesta del servidor** + ```json { "codigo_postal": "66436", @@ -123,7 +99,7 @@ https://mexico-zip-codes.p.rapidapi.com/codigo_postal/66436 } ``` ---- +----- **Buscar códigos postales** @@ -131,29 +107,34 @@ https://mexico-zip-codes.p.rapidapi.com/codigo_postal/66436 https://mexico-zip-codes.p.rapidapi.com/buscar ``` -_parámetros necesarios_ +*parámetros necesarios* + ```text codigo_postal=# codigo a buscar, parcial o total ``` -_parámetros opcionales_ +*parámetros opcionales* + ```text limit=# número máximo de resultados a devolver ``` -_Ejemplo de búsqueda para códigos que inicien con **66**, con **664** y con **6641**_ -```json +*Ejemplo de búsqueda para códigos que inicien con **66**, con **664** y con **6641*** + +```text https://mexico-zip-codes.p.rapidapi.com/buscar?codigo_postal=66 https://mexico-zip-codes.p.rapidapi.com/buscar?codigo_postal=664 https://mexico-zip-codes.p.rapidapi.com/buscar?codigo_postal=6641 ``` -_Ejemplo de búsqueda limitada a 3 resultados_ +*Ejemplo de búsqueda limitada a 3 resultados* + ```text https://mexico-zip-codes.p.rapidapi.com/buscar?codigo_postal=66&limit=3 ``` -** Para el código postal 6641 el servidor regresa ** +\*\* Para el código postal 6641 el servidor regresa \*\* + ```json { "codigos_postales": [ @@ -168,7 +149,7 @@ https://mexico-zip-codes.p.rapidapi.com/buscar?codigo_postal=66&limit=3 } ``` ---- +----- **Buscar códigos postales por ubicación** @@ -176,34 +157,28 @@ https://mexico-zip-codes.p.rapidapi.com/buscar?codigo_postal=66&limit=3 https://mexico-zip-codes.p.rapidapi.com/v2/buscar_por_ubicacion ``` -_parámetros necesarios_ +*parámetros necesarios* + ```text estado=# nombre del estado municipio=# nombre del municipio ``` -_parámetros opcionales_ +*parámetros opcionales* + ```text colonia=# nombre de la colonia (opcional) limit=# número máximo de resultados a devolver ``` -_Ejemplo de búsqueda para códigos postales en Nuevo León, San Nicolás de los Garza_ -```text -https://mexico-zip-codes.p.rapidapi.com/v2/buscar_por_ubicacion?estado=Nuevo%20León&municipio=San%20Nicolás%20de%20los%20Garza -``` +*Ejemplo de búsqueda para códigos postales en Nuevo León, San Nicolás de los Garza* -_Ejemplo de búsqueda para códigos postales en Nuevo León, San Nicolás de los Garza, colonia Praderas de Santo Domingo_ ```text -https://mexico-zip-codes.p.rapidapi.com/v2/buscar_por_ubicacion?estado=Nuevo%20León&municipio=San%20Nicolás%20de%20los%20Garza&colonia=Praderas%20de%20Santo%20Domingo -``` - -_Ejemplo de búsqueda limitada a 5 resultados_ -```text -https://mexico-zip-codes.p.rapidapi.com/v2/buscar_por_ubicacion?estado=Nuevo%20León&municipio=San%20Nicolás%20de%20los%20Garza&limit=5 +https://mexico-zip-codes.p.rapidapi.com/v2/buscar_por_ubicacion?estado=Nuevo%20León&municipio=San%20Nicolás%20de%20los%20Garza ``` **Respuesta del servidor** + ```json { "codigos_postales": [ @@ -212,21 +187,24 @@ https://mexico-zip-codes.p.rapidapi.com/v2/buscar_por_ubicacion?estado=Nuevo%20L } ``` -___ +----- ### Rake task -Ejecuta el rake task `rake sepomex:update` para descargar todos los códigos postales de México y actualizar tu base de datos. When running with Docker Compose, use: + +Ejecuta el rake task `rake sepomex:update` para descargar todos los códigos postales de México y actualizar tu base de datos. When running with Docker Compose, use the correct service name: + ```bash -docker compose run --rm zipcode_api_web bundle exec rake sepomex:update +docker compose run --rm web bundle exec rake sepomex:update ``` ### Colabora -Errores y pull requests son bienvenidos en Github: https://github.com/Munett/API-Codigos-Postales. -Para bajar en tu BD todos los códigos postales corre el rake script `rake sepomex:update`. -Los datos se obtuvieron de http://www.correosdemexico.gob.mx/lservicios/servicios/CodigoPostal_Exportar.aspx +Errores y pull requests son bienvenidos en Github: [https://github.com/Munett/API-Codigos-Postales](https://github.com/Munett/API-Codigos-Postales). + +Los datos se obtuvieron de [http://www.correosdemexico.gob.mx/lservicios/servicios/CodigoPostal\_Exportar.aspx](http://www.correosdemexico.gob.mx/lservicios/servicios/CodigoPostal_Exportar.aspx) ### Los datos se actualizan cada domingo. ### Licencia + MIT License \ No newline at end of file