@@ -29,14 +29,13 @@ Development Installation
2929
30302. Create and activate a virtual environment:
3131 ` ` ` bash
32- python -m . venv venv
33- source . venv/bin/activate # On Windows: venv\Scripts\activate
32+ python -m venv venv
33+ source venv/bin/activate # On Windows: venv\Scripts\activate
3434 ` ` `
3535
36363. Install development dependencies:
3737 ` ` ` bash
38- pip install .
39- pip install .[dev]
38+ pip install -e .
4039 pip install -r requirements-dev.txt
4140 ` ` `
4241
@@ -52,27 +51,28 @@ from geocodio import GeocodioClient
5251client = GeocodioClient(" YOUR_API_KEY" )
5352
5453# Single forward geocode
55- response = client.geocode(" 123 Anywhere St, Chicago, IL " )
56- print(response)
54+ response = client.geocode(" 1600 Pennsylvania Ave, Washington, DC " )
55+ print(response.results[0].formatted_address )
5756
5857# Batch forward geocode
5958addresses = [
60- " 123 Anywhere St, Chicago, IL " ,
61- " 456 Oak St, Los Angeles , CA"
59+ " 1600 Pennsylvania Ave, Washington, DC " ,
60+ " 1 Infinite Loop, Cupertino , CA"
6261]
6362batch_response = client.geocode(addresses)
64- print(batch_response)
63+ for result in batch_response.results:
64+ print(result.formatted_address)
6565
6666# Single reverse geocode
6767rev = client.reverse(" 38.9002898,-76.9990361" )
68- print(rev)
68+ print(rev.results[0].formatted_address )
6969
7070# Append additional fields
7171data = client.geocode(
72- " 123 Anywhere St, Chicago, IL " ,
72+ " 1600 Pennsylvania Ave, Washington, DC " ,
7373 fields=[" cd" , " timezone" ]
7474)
75- print(data)
75+ print(data.results[0].fields.timezone.name if data.results[0].fields.timezone else " No timezone data " )
7676` ` `
7777
7878# ## List API
@@ -85,68 +85,50 @@ from geocodio import GeocodioClient
8585# Initialize the client with your API key
8686client = GeocodioClient(" YOUR_API_KEY" )
8787
88- # Create a new list
89- new_list = client.create_list(
90- name=" My Addresses" ,
91- description=" A list of addresses to geocode" ,
92- items=[
93- " 1600 Pennsylvania Ave, Washington, DC" ,
94- " 1 Infinite Loop, Cupertino, CA"
95- ]
96- )
97- print(new_list)
98-
9988# Get all lists
10089lists = client.get_lists ()
101- print(lists)
90+ print(f " Found {len( lists.data)} lists " )
10291
103- # Get a specific list
104- list_id = new_list.list.id
105- list_details = client.get_list(list_id)
106- print(list_details)
107-
108- # Update a list
109- updated_list = client.update_list(
110- list_id=list_id,
111- name=" Updated List Name" ,
112- description=" Updated description"
113- )
114- print(updated_list)
115-
116- # Add items to a list
117- added_items = client.add_items_to_list(
118- list_id=list_id,
119- items=[
120- " 123 Anywhere St, Chicago, IL" ,
121- " 456 Oak St, Los Angeles, CA"
122- ]
123- )
124- print(added_items)
92+ # Create a new list from a file
93+ with open(" addresses.csv" , " rb" ) as f:
94+ new_list = client.create_list(
95+ file=f,
96+ filename=" addresses.csv" ,
97+ direction=" forward"
98+ )
99+ print(f" Created list: {new_list.id}" )
125100
126- # Geocode all items in a list
127- geocoded_list = client.geocode_list(
128- list_id=list_id,
129- fields=[" timezone" , " cd" ]
130- )
131- print(geocoded_list)
101+ # Get a specific list
102+ list_details = client.get_list(new_list.id)
103+ print(f" List status: {list_details.status}" )
132104
133- # Remove items from a list
134- item_ids = [item.id for item in added_items.items]
135- client.remove_items_from_list(
136- list_id=list_id,
137- item_ids=item_ids
138- )
105+ # Download a completed list
106+ if list_details.status and list_details.status.get(" state" ) == " COMPLETED" :
107+ file_content = client.download(new_list.id, " downloaded_results.csv" )
108+ print(" List downloaded successfully" )
139109
140110# Delete a list
141- client.delete_list(list_id )
111+ client.delete_list(new_list.id )
142112` ` `
143113
144114Error Handling
145115--------------
146116
147- - ` GeocodioAuthError` is raised for authentication failures (HTTP 403).
148- - ` GeocodioDataError` is raised for invalid requests (HTTP 422).
149- - ` GeocodioServerError` is raised for server-side errors (HTTP 5xx).
117+ ` ` ` python
118+ from geocodio import GeocodioClient, AuthenticationError, InvalidRequestError
119+
120+ try:
121+ client = GeocodioClient(" INVALID_API_KEY" )
122+ response = client.geocode(" 1600 Pennsylvania Ave, Washington, DC" )
123+ except AuthenticationError as e:
124+ print(f" Authentication failed: {e}" )
125+
126+ try:
127+ client = GeocodioClient(" YOUR_API_KEY" )
128+ response = client.geocode(" " ) # Empty address
129+ except InvalidRequestError as e:
130+ print(f" Invalid request: {e}" )
131+ ` ` `
150132
151133Documentation
152134-------------
@@ -164,3 +146,30 @@ License
164146-------
165147
166148This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
149+
150+ CI & Publishing
151+ ---------------
152+
153+ - CI runs unit tests and linting on every push. E2E tests run if ` GEOCODIO_API_KEY` is set as a secret.
154+ - PyPI publishing workflow supports both TestPyPI and PyPI. See ` .github/workflows/publish.yml` .
155+ - Use ` test_pypi_release.py` for local packaging and dry-run upload.
156+
157+ # ## Testing GitHub Actions Workflows
158+
159+ The project includes tests for GitHub Actions workflows using ` act` for local development:
160+
161+ ` ` ` bash
162+ # Test all workflows (requires act and Docker)
163+ pytest tests/test_workflows.py
164+
165+ # Test specific workflow
166+ pytest tests/test_workflows.py::test_ci_workflow
167+ pytest tests/test_workflows.py::test_publish_workflow
168+ ` ` `
169+
170+ ** Prerequisites:**
171+ - Install [act](https://github.com/nektos/act) for local GitHub Actions testing
172+ - Docker must be running
173+ - For publish workflow tests: Set ` TEST_PYPI_API_TOKEN` environment variable
174+
175+ ** Note:** Workflow tests are automatically skipped in CI environments.
0 commit comments