Name | sqapi JSON |
Version |
0.59
JSON |
| download |
home_page | https://bitbucket.org/ariell/pysq |
Summary | A python package that simplifies interactions with the SQUIDLE+ API. It can be used to integrate automated labelling from machine learning algorithms and plenty other cool things. |
upload_time | 2025-08-28 13:37:19 |
maintainer | None |
docs_url | None |
author | Greybits Engineering |
requires_python | None |
license | MIT |
keywords |
squidle+
api
sq
machine learning
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# SQAPI
`sqapi` is a python package that simplifies interactions with the
[SQUIDLE+ API](https://squidle.org/api/help?template=api_help_page.html).
It can be used for everything from creating simple queries through to integrating automated
labelling from machine learning algorithms and plenty other cool things.
### Installation
To install the `sqapi` module, you can use `pip`
```shell
pip install sqapi
```
### What is this?
The `sqapi` module helps to build the `HTTP` requests that are sent to the [SQUIDLE+](squidle.org) `API`. These are
`GET`, `POST`, `PATCH` or `DELETE` requests. Setting `verbosity=2` on the `sqapi` module will print the `HTTP`
requests that are being made.
`sqapi` takes care of authentication, and simplifies the creation of API queries.
For example:
```python
from sqapi.api import SQAPI
api = SQAPI(host=<HOST>, api_key=<API_KEY>, verbosity=2) # instantiate the sqapi module
r=api.get(<ENDPOINT>) # define a get request using a specific endpoint
r.filter(<NAME>,<OPERATORE>,<VALUE>) # define a filter to compare a property with a value using an operator
data = r.execute().json() # perform the request & return result as JSON dict (don't set template)
```
For more information about structuring queries, check out the [Making API queries](https://squidle.org/api/help?template=api_help_page.html#api_query)
section of the SQ+ API documentation page.
Instantiating `sqapi` without an API key argument will prompt for a user login, i.e.:
```python
sqapi = SQAPI(host=<HOST>, verbosity=2) # instantiate the sqapi module
```
You can also use it to apply built-in templates to the data that comes out of the API:
```python
r.template(<TEMPLATE>) # format the output of the request using an inbuilt HTML template
html = r.execute().text # perform the request & return result as text (eg: for html)
```
> **IMPORTANT:** in order to proceed, you will need a user account on [SQUIDLE+](https://squidle.org). You will also
> need to activate your API key.
## Examples
### Creating queries
This is by no means an extensive list of possible API queries. The API is extensive and the models are documented
[here](https://squidle.org/api/help?template=api_help_page.html) and the creation of queries is documented
[here](https://squidle.org/api/help?template=api_help_page.html#api_query). `SQAPI` enables a convenient mechanism
for creating these queries inside of Python. For example, a basic API query to list all the annotations that have valid
labels starting with 'ecklonia' within a spatially constrained bounding box would be:
```json
{
"filters": [
{
"name": "label",
"op": "has",
"val": {
"name": "name",
"op": "ilike",
"val": "ecklonia%"
}
},
{
"name": "point",
"op": "has",
"val": {
"name": "media",
"op": "has",
"val": {
"name": "poses",
"op": "any",
"val": {
"name": "geom",
"op": "geo_in_bbox",
"val": [
{
"lat": -32.020013585799155,
"lon": 115.49980113118502
},
{
"lat": -32.01995006531625,
"lon": 115.49987604949759
}
]
}
}
}
}
]
}
```
The result of that query can be accessed dynamically through
[here as pretty JSON](https://squidle.org/api/annotation?template=json.html&q={"filters":[{"name":"point","op":"has","val":{"name":"has_xy","op":"eq","val":true}},{"name":"point","op":"has","val":{"name":"media","op":"has","val":{"name":"poses","op":"any","val":{"name":"geom","op":"geo_in_bbox","val":[{"lat":-32.020013585799155,"lon":115.49980113118502},{"lat":-32.01995006531625,"lon":115.49987604949759}]}}}}]}) or
[here as raw JSON](https://squidle.org/api/annotation?q={"filters":[{"name":"point","op":"has","val":{"name":"has_xy","op":"eq","val":true}},{"name":"point","op":"has","val":{"name":"media","op":"has","val":{"name":"poses","op":"any","val":{"name":"geom","op":"geo_in_bbox","val":[{"lat":-32.020013585799155,"lon":115.49980113118502},{"lat":-32.01995006531625,"lon":115.49987604949759}]}}}}]}) or
[here with a template](https://squidle.org/iframe/api/annotation?template=models/annotation/list_thumbnails.html&q={"filters":[{"name":"point","op":"has","val":{"name":"has_xy","op":"eq","val":true}},{"name":"point","op":"has","val":{"name":"media","op":"has","val":{"name":"poses","op":"any","val":{"name":"geom","op":"geo_in_bbox","val":[{"lat":-32.020013585799155,"lon":115.49980113118502},{"lat":-32.01995006531625,"lon":115.49987604949759}]}}}}]}&include_link=true).
Note with a logged in browser session, that link will extract cropped thumbnails around each annotation, but without logging in,
you'll just see a thumbnail the whole image associated with that annotation.
The Python code required to build that query could be something like:
```python
from sqapi.api import SQAPI, query_filter as qf
api = SQAPI(host="https://squidle.org", ) # optionally pass in api_key to avoid log in prompt
r = api.get("/api/annotation")
r.filter("label", "has", qf("name","ilike","ecklonia%")) # filter for label name, % here is a wildcard matching anything
bbox = [{"lat": -32.020013585799155,"lon": 115.49980113118502},{"lat": -32.01995006531625,"lon": 115.49987604949759}]
r.filter("point", "has", qf("media", "has", qf("poses", "any", qf("geom", "geo_in_bbox", bbox)))) # filter within bounding box
```
### Exporting a dataset
Coming soon...
### Uploading a Media Item
```python
from sqapi.api import SQAPI
import json
api = SQAPI(host="http://localhost:5000", )
data = {
"key": "20101010101010100_CAMID",
"deployment_id": 15640,
"timestamp_start": "2010-10-10T10:10:10.100",
"pose": {
"lat": -43.2,
"lon": 150.5,
"dep": 10.4,
"alt": 2.0,
"data": { # optional data to attach to pose (key-value pair, where val is float)
"test": 123,
"field": 321
}
},
"data": {} # optional data to attach to frame (JSON)
}
r=api.upload_file("/api/media/save", file_path="path/to/image.jpg", data=dict(json=json.dumps(data))).execute()
print(r.json())
```
### Adding an Annotation to a Media Object
This involves a few operations, which are typically done in separate steps:
1. Add the `media` object to the `media_collection`
2. Add the annotation `point` with an empty `annotation` to the `annotation_set`
3. Set the `label_id` of the `annotation` to associate the `label`
If you're building up an annotation set directly from a list of media, that can be a bit cumbersome
and here is a shortcut, which allows you to do all of this in a single API call:
```python
from sqapi.api import SQAPI
api = SQAPI(host="http://localhost:5000", )
MEDIA_ID=8230624
ANNOTATION_SET_ID=12488
LABEL_ID=13308
IMG_WIDTH=640
IMG_HEIGHT=480
payload = {
"annotation_set_id":ANNOTATION_SET_ID,
"set_media": {"id": MEDIA_ID},
"annotation_label": {"id":LABEL_ID,"comment":"something","likelihood":1.0,"needs_review":True},
"pixels": {"polygon":[[50, 50],[250, 50],[250, 250],[50, 250],[50, 50]],"width":IMG_WIDTH,"height":IMG_HEIGHT},
# "x":0.5, "y":0.5, "polygon":[[p1x, p1y],...],
"is_targeted":True
}
r = api.post('/api/point', json_data=payload).execute()
print(r.json())
```
### Machine learning integration
The [sqbot](https://bitbucket.org/ariell/sqbot/) repository, which is based on this module (`sqapi`) has has tools and
templates for deploying ML allgorithms in Squidle+.
Raw data
{
"_id": null,
"home_page": "https://bitbucket.org/ariell/pysq",
"name": "sqapi",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "SQUIDLE+, API, SQ, Machine Learning",
"author": "Greybits Engineering",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/4b/73/830611c95eb25387de14a6d9f1b9e65f5c0d4eabf31589d6f8e879d1cbd2/sqapi-0.59.tar.gz",
"platform": null,
"description": "# SQAPI\n\n`sqapi` is a python package that simplifies interactions with the \n[SQUIDLE+ API](https://squidle.org/api/help?template=api_help_page.html).\nIt can be used for everything from creating simple queries through to integrating automated \nlabelling from machine learning algorithms and plenty other cool things.\n\n### Installation\nTo install the `sqapi` module, you can use `pip`\n```shell\npip install sqapi \n```\n\n### What is this?\nThe `sqapi` module helps to build the `HTTP` requests that are sent to the [SQUIDLE+](squidle.org) `API`. These are \n`GET`, `POST`, `PATCH` or `DELETE` requests. Setting `verbosity=2` on the `sqapi` module will print the `HTTP` \nrequests that are being made.\n\n`sqapi` takes care of authentication, and simplifies the creation of API queries. \nFor example:\n\n```python\nfrom sqapi.api import SQAPI\n\napi = SQAPI(host=<HOST>, api_key=<API_KEY>, verbosity=2) # instantiate the sqapi module\nr=api.get(<ENDPOINT>) # define a get request using a specific endpoint\nr.filter(<NAME>,<OPERATORE>,<VALUE>) # define a filter to compare a property with a value using an operator\ndata = r.execute().json() # perform the request & return result as JSON dict (don't set template)\n```\n\nFor more information about structuring queries, check out the [Making API queries](https://squidle.org/api/help?template=api_help_page.html#api_query)\nsection of the SQ+ API documentation page.\n\nInstantiating `sqapi` without an API key argument will prompt for a user login, i.e.:\n```python\nsqapi = SQAPI(host=<HOST>, verbosity=2) # instantiate the sqapi module\n```\n\nYou can also use it to apply built-in templates to the data that comes out of the API:\n```python\nr.template(<TEMPLATE>) # format the output of the request using an inbuilt HTML template\nhtml = r.execute().text # perform the request & return result as text (eg: for html)\n```\n\n> **IMPORTANT:** in order to proceed, you will need a user account on [SQUIDLE+](https://squidle.org). You will also \n> need to activate your API key.\n\n## Examples\n### Creating queries\nThis is by no means an extensive list of possible API queries. The API is extensive and the models are documented\n[here](https://squidle.org/api/help?template=api_help_page.html) and the creation of queries is documented \n[here](https://squidle.org/api/help?template=api_help_page.html#api_query). `SQAPI` enables a convenient mechanism \nfor creating these queries inside of Python. For example, a basic API query to list all the annotations that have valid \nlabels starting with 'ecklonia' within a spatially constrained bounding box would be:\n```json\n{\n \"filters\": [\n {\n \"name\": \"label\",\n \"op\": \"has\",\n \"val\": {\n \"name\": \"name\",\n \"op\": \"ilike\",\n \"val\": \"ecklonia%\"\n }\n },\n {\n \"name\": \"point\",\n \"op\": \"has\",\n \"val\": {\n \"name\": \"media\",\n \"op\": \"has\",\n \"val\": {\n \"name\": \"poses\",\n \"op\": \"any\",\n \"val\": {\n \"name\": \"geom\",\n \"op\": \"geo_in_bbox\",\n \"val\": [\n {\n \"lat\": -32.020013585799155,\n \"lon\": 115.49980113118502\n },\n {\n \"lat\": -32.01995006531625,\n \"lon\": 115.49987604949759\n }\n ]\n }\n }\n }\n }\n ]\n}\n```\nThe result of that query can be accessed dynamically through \n[here as pretty JSON](https://squidle.org/api/annotation?template=json.html&q={\"filters\":[{\"name\":\"point\",\"op\":\"has\",\"val\":{\"name\":\"has_xy\",\"op\":\"eq\",\"val\":true}},{\"name\":\"point\",\"op\":\"has\",\"val\":{\"name\":\"media\",\"op\":\"has\",\"val\":{\"name\":\"poses\",\"op\":\"any\",\"val\":{\"name\":\"geom\",\"op\":\"geo_in_bbox\",\"val\":[{\"lat\":-32.020013585799155,\"lon\":115.49980113118502},{\"lat\":-32.01995006531625,\"lon\":115.49987604949759}]}}}}]}) or\n[here as raw JSON](https://squidle.org/api/annotation?q={\"filters\":[{\"name\":\"point\",\"op\":\"has\",\"val\":{\"name\":\"has_xy\",\"op\":\"eq\",\"val\":true}},{\"name\":\"point\",\"op\":\"has\",\"val\":{\"name\":\"media\",\"op\":\"has\",\"val\":{\"name\":\"poses\",\"op\":\"any\",\"val\":{\"name\":\"geom\",\"op\":\"geo_in_bbox\",\"val\":[{\"lat\":-32.020013585799155,\"lon\":115.49980113118502},{\"lat\":-32.01995006531625,\"lon\":115.49987604949759}]}}}}]}) or \n[here with a template](https://squidle.org/iframe/api/annotation?template=models/annotation/list_thumbnails.html&q={\"filters\":[{\"name\":\"point\",\"op\":\"has\",\"val\":{\"name\":\"has_xy\",\"op\":\"eq\",\"val\":true}},{\"name\":\"point\",\"op\":\"has\",\"val\":{\"name\":\"media\",\"op\":\"has\",\"val\":{\"name\":\"poses\",\"op\":\"any\",\"val\":{\"name\":\"geom\",\"op\":\"geo_in_bbox\",\"val\":[{\"lat\":-32.020013585799155,\"lon\":115.49980113118502},{\"lat\":-32.01995006531625,\"lon\":115.49987604949759}]}}}}]}&include_link=true).\nNote with a logged in browser session, that link will extract cropped thumbnails around each annotation, but without logging in,\nyou'll just see a thumbnail the whole image associated with that annotation.\nThe Python code required to build that query could be something like:\n```python\nfrom sqapi.api import SQAPI, query_filter as qf\napi = SQAPI(host=\"https://squidle.org\", ) # optionally pass in api_key to avoid log in prompt\nr = api.get(\"/api/annotation\")\nr.filter(\"label\", \"has\", qf(\"name\",\"ilike\",\"ecklonia%\")) # filter for label name, % here is a wildcard matching anything\nbbox = [{\"lat\": -32.020013585799155,\"lon\": 115.49980113118502},{\"lat\": -32.01995006531625,\"lon\": 115.49987604949759}]\nr.filter(\"point\", \"has\", qf(\"media\", \"has\", qf(\"poses\", \"any\", qf(\"geom\", \"geo_in_bbox\", bbox)))) # filter within bounding box\n```\n\n### Exporting a dataset\nComing soon...\n\n### Uploading a Media Item\n```python\nfrom sqapi.api import SQAPI\nimport json\napi = SQAPI(host=\"http://localhost:5000\", )\ndata = {\n \"key\": \"20101010101010100_CAMID\",\n \"deployment_id\": 15640,\n \"timestamp_start\": \"2010-10-10T10:10:10.100\",\n \"pose\": {\n \"lat\": -43.2,\n \"lon\": 150.5,\n \"dep\": 10.4,\n \"alt\": 2.0,\n \"data\": { # optional data to attach to pose (key-value pair, where val is float)\n \"test\": 123,\n \"field\": 321\n }\n },\n \"data\": {} # optional data to attach to frame (JSON)\n}\n\nr=api.upload_file(\"/api/media/save\", file_path=\"path/to/image.jpg\", data=dict(json=json.dumps(data))).execute()\nprint(r.json())\n```\n\n### Adding an Annotation to a Media Object\nThis involves a few operations, which are typically done in separate steps:\n\n1. Add the `media` object to the `media_collection` \n2. Add the annotation `point` with an empty `annotation` to the `annotation_set`\n3. Set the `label_id` of the `annotation` to associate the `label`\n\nIf you're building up an annotation set directly from a list of media, that can be a bit cumbersome\nand here is a shortcut, which allows you to do all of this in a single API call:\n```python\nfrom sqapi.api import SQAPI\napi = SQAPI(host=\"http://localhost:5000\", )\n\nMEDIA_ID=8230624\nANNOTATION_SET_ID=12488\nLABEL_ID=13308\nIMG_WIDTH=640\nIMG_HEIGHT=480\n\npayload = {\n \"annotation_set_id\":ANNOTATION_SET_ID,\n \"set_media\": {\"id\": MEDIA_ID},\n \"annotation_label\": {\"id\":LABEL_ID,\"comment\":\"something\",\"likelihood\":1.0,\"needs_review\":True},\n \"pixels\": {\"polygon\":[[50, 50],[250, 50],[250, 250],[50, 250],[50, 50]],\"width\":IMG_WIDTH,\"height\":IMG_HEIGHT},\n # \"x\":0.5, \"y\":0.5, \"polygon\":[[p1x, p1y],...],\n \"is_targeted\":True\n}\nr = api.post('/api/point', json_data=payload).execute()\nprint(r.json())\n```\n\n\n\n### Machine learning integration\nThe [sqbot](https://bitbucket.org/ariell/sqbot/) repository, which is based on this module (`sqapi`) has has tools and \ntemplates for deploying ML allgorithms in Squidle+.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A python package that simplifies interactions with the SQUIDLE+ API. It can be used to integrate automated labelling from machine learning algorithms and plenty other cool things.",
"version": "0.59",
"project_urls": {
"Homepage": "https://bitbucket.org/ariell/pysq"
},
"split_keywords": [
"squidle+",
" api",
" sq",
" machine learning"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "4b73830611c95eb25387de14a6d9f1b9e65f5c0d4eabf31589d6f8e879d1cbd2",
"md5": "5f9e1992e49bed2e9607a02810dcab46",
"sha256": "50df6f31ed74ef80e399a89c89841f8684e14b2e775a9ce129c3fcee72f00ba1"
},
"downloads": -1,
"filename": "sqapi-0.59.tar.gz",
"has_sig": false,
"md5_digest": "5f9e1992e49bed2e9607a02810dcab46",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 18026,
"upload_time": "2025-08-28T13:37:19",
"upload_time_iso_8601": "2025-08-28T13:37:19.350841Z",
"url": "https://files.pythonhosted.org/packages/4b/73/830611c95eb25387de14a6d9f1b9e65f5c0d4eabf31589d6f8e879d1cbd2/sqapi-0.59.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-28 13:37:19",
"github": false,
"gitlab": false,
"bitbucket": true,
"codeberg": false,
"bitbucket_user": "ariell",
"bitbucket_project": "pysq",
"lcname": "sqapi"
}