Python client for the Socrata Open Data API

Overview

PyPI version Build Status Code Coverage

sodapy

sodapy is a python client for the Socrata Open Data API.

Installation

You can install with pip install sodapy.

If you want to install from source, then clone this repository and run python setup.py install from the project root.

Requirements

At its core, this library depends heavily on the Requests package. All other requirements can be found in requirements.txt. sodapy is currently compatible with Python 3.5, 3.6, 3.7 and 3.8.

Documentation

The official Socrata Open Data API docs provide thorough documentation of the available methods, as well as other client libraries. A quick list of eligible domains to use with this API is available via the Socrata Discovery API or Socrata's Open Data Network.

This library supports writing directly to datasets with the Socrata Open Data API. For write operations that use data transformations in the Socrata Data Management Experience (the user interface for creating datasets), use the Socrata Data Management API. For more details on when to use SODA vs the Data Management API, see the Data Management API documentation. A Python SDK for the Socrata Data Management API can be found at socrata-py.

Examples

There are some jupyter notebooks in the examples directory with usage examples of sodapy in action.

Interface

Table of Contents

client

Import the library and set up a connection to get started.

>>> from sodapy import Socrata
>>> client = Socrata(
        "sandbox.demo.socrata.com",
        "FakeAppToken",
        username="[email protected]",
        password="mypassword",
        timeout=10
    )

username and password are only required for creating or modifying data. An application token isn't strictly required (can be None), but queries executed from a client without an application token will be subjected to strict throttling limits. You may want to increase the timeout seconds when making large requests. To create a bare-bones client:

>>> client = Socrata("sandbox.demo.socrata.com", None)

A client can also be created with a context manager to obviate the need for teardown:

>>> with Socrata("sandbox.demo.socrata.com", None) as client:
>>>    # do some stuff

The client, by default, makes requests over HTTPS. To modify this behavior, or to make requests through a proxy, take a look here.

datasets(limit=0, offset=0)

Retrieve datasets associated with a particular domain. The optional limit and offset keyword args can be used to retrieve a subset of the datasets. By default, all datasets are returned.

>>> client.datasets()
[{"resource" : {"name" : "Approved Building Permits", "id" : "msk6-43c6", "parent_fxf" : null, "description" : "Data of approved building/construction permits",...}, {resource : {...}}, ...]

get(dataset_identifier, content_type="json", **kwargs)

Retrieve data from the requested resources. Filter and query data by field name, id, or using SoQL keywords.

>>> client.get("nimj-3ivp", limit=2)
[{u'geolocation': {u'latitude': u'41.1085', u'needs_recoding': False, u'longitude': u'-117.6135'}, u'version': u'9', u'source': u'nn', u'region': u'Nevada', u'occurred_at': u'2012-09-14T22:38:01', u'number_of_stations': u'15', u'depth': u'7.60', u'magnitude': u'2.7', u'earthquake_id': u'00388610'}, {...}]

>>> client.get("nimj-3ivp", where="depth > 300", order="magnitude DESC", exclude_system_fields=False)
[{u'geolocation': {u'latitude': u'-15.563', u'needs_recoding': False, u'longitude': u'-175.6104'}, u'version': u'9', u':updated_at': 1348778988, u'number_of_stations': u'275', u'region': u'Tonga', u':created_meta': u'21484', u'occurred_at': u'2012-09-13T21:16:43', u':id': 132, u'source': u'us', u'depth': u'328.30', u'magnitude': u'4.8', u':meta': u'{\n}', u':updated_meta': u'21484', u'earthquake_id': u'c000cnb5', u':created_at': 1348778988}, {...}]

>>> client.get("nimj-3ivp/193", exclude_system_fields=False)
{u'geolocation': {u'latitude': u'21.6711', u'needs_recoding': False, u'longitude': u'142.9236'}, u'version': u'C', u':updated_at': 1348778988, u'number_of_stations': u'136', u'region': u'Mariana Islands region', u':created_meta': u'21484', u'occurred_at': u'2012-09-13T11:19:07', u':id': 193, u'source': u'us', u'depth': u'300.70', u'magnitude': u'4.4', u':meta': u'{\n}', u':updated_meta': u'21484', u':position': 193, u'earthquake_id': u'c000cmsq', u':created_at': 1348778988}

>>> client.get("nimj-3ivp", region="Kansas")
[{u'geolocation': {u'latitude': u'38.10', u'needs_recoding': False, u'longitude': u'-100.6135'}, u'version': u'9', u'source': u'nn', u'region': u'Kansas', u'occurred_at': u'2010-09-19T20:52:09', u'number_of_stations': u'15', u'depth': u'300.0', u'magnitude': u'1.9', u'earthquake_id': u'00189621'}, {...}]

get_all(dataset_identifier, content_type="json", **kwargs)

Read data from the requested resource, paginating over all results. Accepts the same arguments as get(). Returns a generator.

>>> client.get_all("nimj-3ivp")
<generator object Socrata.get_all at 0x7fa0dc8be7b0>

>>> for item in client.get_all("nimj-3ivp"):
...     print(item)
...
{'geolocation': {'latitude': '-15.563', 'needs_recoding': False, 'longitude': '-175.6104'}, 'version': '9', ':updated_at': 1348778988, 'number_of_stations': '275', 'region': 'Tonga', ':created_meta': '21484', 'occurred_at': '2012-09-13T21:16:43', ':id': 132, 'source': 'us', 'depth': '328.30', 'magnitude': '4.8', ':meta': '{\n}', ':updated_meta': '21484', 'earthquake_id': 'c000cnb5', ':created_at': 1348778988}
...

>>> import itertools
>>> items = client.get_all("nimj-3ivp")
>>> first_five = list(itertools.islice(items, 5))
>>> len(first_five)
5

get_metadata(dataset_identifier, content_type="json")

Retrieve the metadata associated with a particular dataset.

>>> client.get_metadata("nimj-3ivp")
{"newBackend": false, "licenseId": "CC0_10", "publicationDate": 1436655117, "viewLastModified": 1451289003, "owner": {"roleName": "administrator", "rights": [], "displayName": "Brett", "id": "cdqe-xcn5", "screenName": "Brett"}, "query": {}, "id": "songs", "createdAt": 1398014181, "category": "Public Safety", "publicationAppendEnabled": true, "publicationStage": "published", "rowsUpdatedBy": "cdqe-xcn5", "publicationGroup": 1552205, "displayType": "table", "state": "normal", "attributionLink": "http://foo.bar.com", "tableId": 3523378, "columns": [], "metadata": {"rdfSubject": "0", "renderTypeConfig": {"visible": {"table": true}}, "availableDisplayTypes": ["table", "fatrow", "page"], "attachments": ... }}

update_metadata(dataset_identifier, update_fields, content_type="json")

Update the metadata for a particular dataset. update_fields should be a dictionary containing only the metadata keys that you wish to overwrite.

Note: Invalid payloads to this method could corrupt the dataset or visualization. See this comment for more information.

>>> client.update_metadata("nimj-3ivp", {"attributionLink": "https://anothertest.com"})
{"newBackend": false, "licenseId": "CC0_10", "publicationDate": 1436655117, "viewLastModified": 1451289003, "owner": {"roleName": "administrator", "rights": [], "displayName": "Brett", "id": "cdqe-xcn5", "screenName": "Brett"}, "query": {}, "id": "songs", "createdAt": 1398014181, "category": "Public Safety", "publicationAppendEnabled": true, "publicationStage": "published", "rowsUpdatedBy": "cdqe-xcn5", "publicationGroup": 1552205, "displayType": "table", "state": "normal", "attributionLink": "https://anothertest.com", "tableId": 3523378, "columns": [], "metadata": {"rdfSubject": "0", "renderTypeConfig": {"visible": {"table": true}}, "availableDisplayTypes": ["table", "fatrow", "page"], "attachments": ... }}

download_attachments(dataset_identifier, content_type="json", download_dir="~/sodapy_downloads")

Download all attachments associated with a dataset. Return a list of paths to the downloaded files.

>>> client.download_attachments("nimj-3ivp", download_dir="~/Desktop")
    ['/Users/xmunoz/Desktop/nimj-3ivp/FireIncident_Codes.PDF', '/Users/xmunoz/Desktop/nimj-3ivp/AccidentReport.jpg']

create(name, **kwargs)

Create a new dataset. Optionally, specify keyword args such as:

  • description description of the dataset
  • columns list of fields
  • category dataset category (must exist in /admin/metadata)
  • tags list of tag strings
  • row_identifier field name of primary key
  • new_backend whether to create the dataset in the new backend

Example usage:

>>> columns = [{"fieldName": "delegation", "name": "Delegation", "dataTypeName": "text"}, {"fieldName": "members", "name": "Members", "dataTypeName": "number"}]
>>> tags = ["politics", "geography"]
>>> client.create("Delegates", description="List of delegates", columns=columns, row_identifier="delegation", tags=tags, category="Transparency")
{u'id': u'2frc-hyvj', u'name': u'Foo Bar', u'description': u'test dataset', u'publicationStage': u'unpublished', u'columns': [ { u'name': u'Foo', u'dataTypeName': u'text', u'fieldName': u'foo', ... }, { u'name': u'Bar', u'dataTypeName': u'number', u'fieldName': u'bar', ... } ], u'metadata': { u'rowIdentifier': 230641051 }, ... }

publish(dataset_identifier, content_type="json")

Publish a dataset after creating it, i.e. take it out of 'working copy' mode. The dataset id id returned from create will be used to publish.

>>> client.publish("2frc-hyvj")
{u'id': u'2frc-hyvj', u'name': u'Foo Bar', u'description': u'test dataset', u'publicationStage': u'unpublished', u'columns': [ { u'name': u'Foo', u'dataTypeName': u'text', u'fieldName': u'foo', ... }, { u'name': u'Bar', u'dataTypeName': u'number', u'fieldName': u'bar', ... } ], u'metadata': { u'rowIdentifier': 230641051 }, ... }

set_permission(dataset_identifier, permission="private", content_type="json")

Set the permissions of a dataset to public or private.

>>> client.set_permission("2frc-hyvj", "public")
<Response [200]>

upsert(dataset_identifier, payload, content_type="json")

Create a new row in an existing dataset.

>>> data = [{'Delegation': 'AJU', 'Name': 'Alaska', 'Key': 'AL', 'Entity': 'Juneau'}]
>>> client.upsert("eb9n-hr43", data)
{u'Errors': 0, u'Rows Deleted': 0, u'Rows Updated': 0, u'By SID': 0, u'Rows Created': 1, u'By RowIdentifier': 0}

Update/Delete rows in a dataset.

>>> data = [{'Delegation': 'sfa', ':id': 8, 'Name': 'bar', 'Key': 'doo', 'Entity': 'dsfsd'}, {':id': 7, ':deleted': True}]
>>> client.upsert("eb9n-hr43", data)
{u'Errors': 0, u'Rows Deleted': 1, u'Rows Updated': 1, u'By SID': 2, u'Rows Created': 0, u'By RowIdentifier': 0}

upsert's can even be performed with a csv file.

>>> data = open("upsert_test.csv")
>>> client.upsert("eb9n-hr43", data)
{u'Errors': 0, u'Rows Deleted': 0, u'Rows Updated': 1, u'By SID': 1, u'Rows Created': 0, u'By RowIdentifier': 0}

replace(dataset_identifier, payload, content_type="json")

Similar in usage to upsert, but overwrites existing data.

>>> data = open("replace_test.csv")
>>> client.replace("eb9n-hr43", data)
{u'Errors': 0, u'Rows Deleted': 0, u'Rows Updated': 0, u'By SID': 0, u'Rows Created': 12, u'By RowIdentifier': 0}

create_non_data_file(params, file_obj)

Creates a new file-based dataset with the name provided in the files tuple. A valid file input would be:

files = (
    {'file': ("gtfs2", open('myfile.zip', 'rb'))}
)
>>> with open(nondatafile_path, 'rb') as f:
>>>     files = (
>>>         {'file': ("nondatafile.zip", f)}
>>>     )
>>>     response = client.create_non_data_file(params, files)

replace_non_data_file(dataset_identifier, params, file_obj)

Same as create_non_data_file, but replaces a file that already exists in a file-based dataset.

Note: a table-based dataset cannot be replaced by a file-based dataset. Use create_non_data_file in order to replace.

>>>  with open(nondatafile_path, 'rb') as f:
>>>      files = (
>>>          {'file': ("nondatafile.zip", f)}
>>>      )
>>>      response = client.replace_non_data_file(DATASET_IDENTIFIER, {}, files)

delete(dataset_identifier, row_id=None, content_type="json")

Delete an individual row.

>>> client.delete("nimj-3ivp", row_id=2)
<Response [200]>

Delete the entire dataset.

>>> client.delete("nimj-3ivp")
<Response [200]>

close()

Close the session when you're finished.

>>> client.close()

Run tests

$ pytest

Contributing

See CONTRIBUTING.md.

Meta

This package uses semantic versioning.

Source and wheel distributions are available on PyPI. Here is how I create those releases.

python3 setup.py bdist_wheel
python3 setup.py sdist
twine upload dist/*
Comments
  • Query to return all dataset identifiers from an endpoint?

    Query to return all dataset identifiers from an endpoint?

    Hi,

    I'm not sure if I'm missing something, but can this library perform a query to return all dataset identifiers from a given endpoint, so that I can then loop through them and perform get requests?

    I could obviously just make a request to https://data.edmonton.ca/api/catalog/v1?domains=data.edmonton.ca and parse the JSON manually to get the resource ID from every top-level object, but it seems like there should be an easier way...

    opened by axfelix 16
  • Importing blob files

    Importing blob files

    I am attempting to replace a zip file in socrata. This file may be generated on a nightly basis. The Google Transit Feed System file format has a number of csv files of different schemas, so it doesn't make sense for a direct CSV upsert.

    Safe FME has provided a method for pushing blob files to Socrata. It seems to hit the not-so-documented api end point of POST https://data.texas.gov/api/imports2?method=blob&fileUploaderfile=['C:', 'myfile.zip'] with the usual header files.

    I was thinking about providing a PR that incorporates this functionality in sodapy. Do you think it would make sense to put a blob parameter in replace and upsert. If blob is true, then use the endpoint above to push the file?

    I was curious if there is a reason why api/imports2 is not used and if there are potentially other methods.

    opened by nathanhilbert 9
  • Exception: Unknown response format: application/json

    Exception: Unknown response format: application/json

    I deployed an application three months ago using sodapy. It was fully functional up until Monday, November 28. On my deployed instance, I get "502 Bad Gateway". Running locally, I get the following error:

    File "/Users/File/Path/Crime.py", line 12, in get_crimes
    crimes = client.get("cuks-n6tp",limit=3000)
    
    File "/usr/local/lib/python2.7/site-packages/sodapy/__init__.py", line 237, in get
    params=params)
    
    File "/usr/local/lib/python2.7/site-packages/sodapy/__init__.py", line 368, in _perform_request
    .format(content_type))
    
    Exception: Unknown response format: application/json
    

    I don't understand the exception. The data set is here and clearly json: https://data.sfgov.org/resource/cuks-n6tp.json

    Let me know if this is the wrong place to post this question.

    Thanks, Alex

    opened by alex-wap 8
  • New backend option

    New backend option

    I found out today from Socrata that ?nbe=true can be used to create the dataset in the new backend. They advised that this should be used for (a) geospatial datasets, and (b) huge tabular datasets (15-20 million rows). For everything else, the old backend should be used for now, since the new backend doesn't support everything just yet (ie. export formats).

    I also removed that whitespace on empty lines that I created in my last PR. My bad.

    Note that I imagine in a few months this won't be necessary as all dataset creation will automatically be in the new backend.

    opened by timwis 8
  • Create dataset

    Create dataset

    ~~Not ready to merge yet. This is a work in progress. Just opening the pull request to encourage discussion around the implementation.~~ (Update: Ready to merge)

    I'm still new to python and would love feedback and suggestions. I figure there's also room to discuss things like columns, and the fact that creating a dataset is actually 3 HTTP requests (create, set public, publish). Here's what I have so far.

    Edit: Another thing worth discussing is the fact that this uses the new API, so /resource/asdf-asdf.json is not the correct path (it's /api/views/asdf-asdf.json). I'd make the argument for abstracting the resource in the library and only looking for the 4x4 dataset ID. This way it would be very easy to switch from the old API to the new one, even for reading/GETs. I imagine in order to make this a non-breaking change, we'd have to allow the /resource/xxxx.json usage and just trim it off the string as I've done in this pull request.

    opened by timwis 8
  • get_all() has inconsistent pagination

    get_all() has inconsistent pagination

    After running:

    results = client.get_all("y8as-bmzj")
    with open("coc test.csv", "a", newline="", encoding="utf-8") as line_file:
        csv_writer = DictWriter(line_file, fieldnames=["id","sample_site","sample_date",
                                                       "parameter","numeric_result","result_qualifier",
                                                       "formatted_result","result_units","latitude_degrees","longitude_degrees","site_key"])
        for row in data:
            csv_writer.writerow(row)      
    

    I was receiving different final files each time. Sometimes these would include duplicate rows, other times I would have rows missing. I reran my code using pagination over the OData API instead with no issues. From my debugging the only thing I could figure was that the get_all() function wasn't returning the data correctly

    opened by patrickleclair-GORDONFN 6
  • UnicodeEncodeError on exception

    UnicodeEncodeError on exception

    While uploading some data to Socrata with sodapy 1.2.0 and the upsert method, an Exception was raised due to status response, but the code failed as it seems the text coming from the server including UTF-8 characters.

    Below is the traceback

      File "/Users/secastro/miniconda/lib/python2.7/site-packages/sodapy/__init__.py", line 221, in upsert
        return self._perform_update("post", resource, payload)
      File "/Users/secastro/miniconda/lib/python2.7/site-packages/sodapy/__init__.py", line 238, in _perform_update
        data=json.dumps(payload))
      File "/Users/secastro/miniconda/lib/python2.7/site-packages/sodapy/__init__.py", line 284, in _perform_request
        _raise_for_status(response)
      File "/Users/secastro/miniconda/lib/python2.7/site-packages/sodapy/__init__.py", line 332, in _raise_for_status
        http_error_msg += ".\n\t{0}".format(more_info)
    UnicodeEncodeError: 'ascii' codec can't encode character u'\ufffd' in position 90: ordinal not in range(128)
    

    I'm not uploading UTF-8 data, so I haven't tested specifically for that.

    opened by seb-at-nzrs 6
  • Issue with upsert/replace

    Issue with upsert/replace

    I keep getting the same error when using upsert or replace:

    Traceback (most recent call last):
      File "C:\Users\tristanya\AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\connectionpool.py", line 384, in _make_request
        six.raise_from(e, None)
      File "<string>", line 2, in raise_from
      File "C:\Users\tristanya\AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\connectionpool.py", line 380, in _make_request
        httplib_response = conn.getresponse()
      File "C:\Users\tristanya\AppData\Local\Continuum\anaconda3\lib\http\client.py", line 1321, in getresponse
        response.begin()
      File "C:\Users\tristanya\AppData\Local\Continuum\anaconda3\lib\http\client.py", line 296, in begin
        version, status, reason = self._read_status()
      File "C:\Users\tristanya\AppData\Local\Continuum\anaconda3\lib\http\client.py", line 257, in _read_status
        line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
      File "C:\Users\tristanya\AppData\Local\Continuum\anaconda3\lib\socket.py", line 589, in readinto
        return self._sock.recv_into(b)
      File "C:\Users\tristanya\AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\contrib\pyopenssl.py", line 307, in recv_into
        raise timeout('The read operation timed out')
    socket.timeout: The read operation timed out
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "C:\Users\tristanya\AppData\Local\Continuum\anaconda3\lib\site-packages\requests\adapters.py", line 449, in send
        timeout=timeout
      File "C:\Users\tristanya\AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\connectionpool.py", line 638, in urlopen
        _stacktrace=sys.exc_info()[2])
      File "C:\Users\tristanya\AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\util\retry.py", line 367, in increment
        raise six.reraise(type(error), error, _stacktrace)
      File "C:\Users\tristanya\AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\packages\six.py", line 686, in reraise
        raise value
      File "C:\Users\tristanya\AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\connectionpool.py", line 600, in urlopen
        chunked=chunked)
      File "C:\Users\tristanya\AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\connectionpool.py", line 386, in _make_request
        self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
      File "C:\Users\tristanya\AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\connectionpool.py", line 306, in _raise_timeout
        raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value)
    urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='mydata.iadb.org', port=443): Read timed out. (read timeout=10)
    

    I have tried using csv and json as the data format, neither work. Any idea what is going on?

    opened by tarmangue 5
  • Example basic queries

    Example basic queries

    • Added a Jupyter notebook going through two use cases, along with a .py version of the same.
    • Made a slight tweak to the init method to strip urls to the format that the code expects (which tripped me up for a while). I know that this is overstepping the original mandate, so feel free to remove.

    I tried running the tests but was unable to:

    (sodapy) [19:43:23] sodapy $ run_tests.py tests/
    Traceback (most recent call last):
      File "/usr/local/bin/run_tests.py", line 22, in <module>
        import cStringIO
    ModuleNotFoundError: No module named 'cStringIO'
    

    Attempts to pip install cStringIO and StringIO were unsuccessful - any pointers on how I can move forward on that?

    opened by matthewwritter 4
  • error when running examples

    error when running examples

    Hi there! I'm trying to run the examples provided in README, as

    Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 26 2016, 10:47:25)
    >>> from sodapy import Socrata
    >>> client = Socrata("sandbox.demo.socrata.com", None)
    >>> client.get("nimj-3ivp", limit=2)
    

    But it keeps on erroring

    >>> client.get("nimj-3ivp", limit=2)
    Traceback (most recent call last):
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/requests/packages/urllib3/connectionpool.py", line 594, in urlopen
        chunked=chunked)
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/requests/packages/urllib3/connectionpool.py", line 350, in _make_request
        self._validate_conn(conn)
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/requests/packages/urllib3/connectionpool.py", line 835, in _validate_conn
        conn.connect()
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/requests/packages/urllib3/connection.py", line 323, in connect
        ssl_context=context)
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/requests/packages/urllib3/util/ssl_.py", line 324, in ssl_wrap_socket
        return context.wrap_socket(sock, server_hostname=server_hostname)
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 377, in wrap_socket
        _context=self)
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 752, in __init__
        self.do_handshake()
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 988, in do_handshake
        self._sslobj.do_handshake()
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 633, in do_handshake
        self._sslobj.do_handshake()
    ConnectionResetError: [Errno 54] Connection reset by peer
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/requests/adapters.py", line 423, in send
        timeout=timeout
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/requests/packages/urllib3/connectionpool.py", line 643, in urlopen
        _stacktrace=sys.exc_info()[2])
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/requests/packages/urllib3/util/retry.py", line 334, in increment
        raise six.reraise(type(error), error, _stacktrace)
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/requests/packages/urllib3/packages/six.py", line 685, in reraise
        raise value.with_traceback(tb)
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/requests/packages/urllib3/connectionpool.py", line 594, in urlopen
        chunked=chunked)
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/requests/packages/urllib3/connectionpool.py", line 350, in _make_request
        self._validate_conn(conn)
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/requests/packages/urllib3/connectionpool.py", line 835, in _validate_conn
        conn.connect()
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/requests/packages/urllib3/connection.py", line 323, in connect
        ssl_context=context)
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/requests/packages/urllib3/util/ssl_.py", line 324, in ssl_wrap_socket
        return context.wrap_socket(sock, server_hostname=server_hostname)
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 377, in wrap_socket
        _context=self)
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 752, in __init__
        self.do_handshake()
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 988, in do_handshake
        self._sslobj.do_handshake()
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 633, in do_handshake
        self._sslobj.do_handshake()
    requests.packages.urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(54, 'Connection reset by peer'))
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/sodapy/__init__.py", line 237, in get
        params=params)
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/sodapy/__init__.py", line 341, in _perform_request
        response = getattr(self.session, request_type)(uri, **kwargs)
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/requests/sessions.py", line 501, in get
        return self.request('GET', url, **kwargs)
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/requests/sessions.py", line 488, in request
        resp = self.send(prep, **send_kwargs)
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/requests/sessions.py", line 609, in send
        r = adapter.send(request, **kwargs)
      File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/requests/adapters.py", line 473, in send
        raise ConnectionError(err, request=request)
    requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(54, 'Connection reset by peer'))
    

    Seems like a issue with Requests. I have searched around but haven't find anything helpful to resolve it online. Have you guys ran into it before?

    Thanks! Bowen

    opened by bowenli86 4
  • Can't access from behind proxy

    Can't access from behind proxy

    I'm trying to use python behind proxy and I get this error:

    HTTPSConnectionPool(host='hostname', port=443): Max retries exceeded with url: /api/views/hdsc-ubkz.json (Caused by NewConnectionError('<requests.packages.urllib3.connection.VerifiedHTTPSConnection object at 0x7fc509240110>: Failed to establish a new connection: [Errno 113] No route to host',))
    

    Is there a way to specify proxy settings with sodapy?

    opened by asarchami 4
Owner
Cristina
ACAB
Cristina
Python: Asynchronous client for the Open-Meteo API.

Python: Asynchronous client for the Open-Meteo API. Asynchronous client for the Open-Meteo API. About Open-Meteo offers free weather forecast APIs for

Franck Nijhof 11 Dec 21, 2022
wyscoutapi is an extremely basic API client for the Wyscout API (v2 & v3) for Python

wyscoutapi wyscoutapi is an extremely basic API client for the Wyscout API (v2 & v3). Usage Install with pip install wyscoutapi. To connect to the Wys

Ben Torvaney 11 Nov 22, 2022
Beyonic API Python official client library simplified examples using Flask, Django and Fast API.

Beyonic API Python official client library simplified examples using Flask, Django and Fast API.

Harun Mbaabu Mwenda 46 Sep 1, 2022
Python API Client for Twitter API v2

?? Python Client For Twitter API v2 ?? Why Twitter Stream ? Twitter-Stream.py a python API client for Twitter API v2 now supports FilteredStream, Samp

Twitivity 31 Nov 19, 2022
Dns-Client-Server - Dns Client Server For Python

Dns-client-server DNS Server: supporting all types of queries and replies. Shoul

Nishant Badgujar 1 Feb 15, 2022
Raphtory-client - The python client for the Raphtory project

Raphtory Client This is the python client for the Raphtory project Install via p

Raphtory 5 Apr 28, 2022
Drcom-pt-client - Drcom Pt version client with refresh timer

drcom-pt-client Drcom Pt version client with refresh timer Dr.com Pt版本客户端 可用于网页认

null 4 Nov 16, 2022
A Pythonic client for the official https://data.gov.gr API.

pydatagovgr An unofficial Pythonic client for the official data.gov.gr API. Aims to be an easy, intuitive and out-of-the-box way to: find data publish

Ilias Antonopoulos 40 Nov 10, 2022
Public API client for GETTR, a "non-bias [sic] social network," designed for data archival and analysis.

GoGettr GoGettr is an API client for GETTR, a "non-bias [sic] social network." (We will not reward their domain with a hyperlink.) GoGettr is built an

Stanford Internet Observatory 72 Dec 14, 2022
Maestral is an open-source Dropbox client written in Python.

Maestral - A light-weight and open-source Dropbox client for macOS and Linux

null 2.6k Jan 3, 2023
Official Python client for the MonkeyLearn API. Build and consume machine learning models for language processing from your Python apps.

MonkeyLearn API for Python Official Python client for the MonkeyLearn API. Build and run machine learning models for language processing from your Pyt

MonkeyLearn 157 Nov 22, 2022
🖥️ Python - P1 Monitor API Asynchronous Python Client

??️ Asynchronous Python client for the P1 Monitor

Klaas Schoute 9 Dec 12, 2022
Python API Client for Close

Close API A convenient Python wrapper for the Close API. API docs: http://developer.close.com Support: [email protected] Installation pip install clos

Close 56 Nov 30, 2022
Python client for CoinPayments API

pyCoinPayments - Python API client for CoinPayments Updates This library has now been converted to work with python3 This is an unofficial client for

James 27 Sep 21, 2022
DEPRECATED - Official Python Client for the Discogs API

⚠️ DEPRECATED This repository is no longer maintained. You can still use a REST client like Requests or other third-party Python library to access the

Discogs 483 Dec 31, 2022
The Foursquare API client for Python

foursquare Python client for the foursquare API. Philosophy: Map foursquare's endpoints one-to-one Clean, simple, Pythonic calls Only handle raw data,

Mike Lewis 400 Dec 19, 2022
Python Client for Instagram API

This project is not actively maintained. Proceed at your own risk! python-instagram A Python 2/3 client for the Instagram REST and Search APIs Install

Facebook Archive 2.9k Dec 30, 2022
A Python Client for News API

newsapi-python A Python client for the News API. License Provided under MIT License by Matt Lisivick. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRAN

Matt Lisivick 281 Dec 29, 2022
SmartFile API Client (Python).

A SmartFile Open Source project. Read more about how SmartFile uses and contributes to Open Source software. Summary This library includes two API cli

SmartFile 19 Jan 11, 2022