Code Monkey home page Code Monkey logo

scotty's Introduction

Simple service that stores users with their coordinates and searches for nearest one. Data is stored in PostgreSQL database. It's picked because it's very common and highly reliable database engine, also it has wonderful extension PostGIS to manage geospatial data.

Current version is a bit too anthropocentric, as it assumes that coordinates are passed as degrees of latitude and longitude, and distance is calculated in meters, according to WGS 84. So distances are calculated correctly only for Earth, but sorting should be more or less correct for any spheroidal planet. Kindly let me know if you need support of other planets.

There are also some difficulties with performance. Unfortunately there is no plain and simple way to optimise calculation of distance between two dots on surface, so search of the nearest user has linear difficulty. On the other hand, ordinary laptop with i7 CPU without any PostgreSQL fine-tuning handles 100k users for about 320 ms, and that looks acceptable.

How to run

Install all requirements

The application uses Flask as web server, JSONSchema to validate input and psycopg3 to connect to PostgreSQL. pytest is also can be useful to run tests.

python3 -m venv --system-site-packages ./venv
source ./venv/bin/activate
pip install -r requirements.in/test.txt

Run tests

Tests requre running PostgreSQL instance with enabled postgis extension and account permitted to create and drop tables.

$ pytest --conninfo postgresql://scotty:scotty@localhost:5432/scotty tests/*
============================= test session starts ==============================
platform linux -- Python 3.11.2, pytest-7.2.2, pluggy-1.0.0
rootdir: /home/valera/code/personal/scotty
collected 5 items

tests/models.py ..                                                        [ 40%]
tests/user_dao.py ...                                                     [100%]

============================== 5 passed in 0.23s ===============================

Start application

First create configuration file, you can use config.ini-example as an example.

cp config.ini-example config.ini

Create database and user to use PostgreSQL credentials from default config file. Create postgis extension.

create database scotty;
\connect scotty
create extension postgis;

create user scotty;
alter database scotty owner to scotty;
\passwd scotty

Then start application.

./scotty.py --config config.ini

Add some users

$ http POST localhost:5000/add_user "username=James Tiberius Kirk" lat:=2 long:=3
HTTP/1.1 200 OK
Connection: close
Content-Length: 59
Content-Type: application/json
Date: Mon, 27 Mar 2023 00:17:25 GMT
Server: Werkzeug/2.2.3 Python/3.11.2

{
    "username": "James Tiberius Kirk",
    "lat": 2,
    "long": 3
}

$ http POST localhost:5000/add_user "username=Leonard McCoy" lat:=3 long:=2
HTTP/1.1 200 OK
Connection: close
Content-Length: 53
Content-Type: application/json
Date: Mon, 27 Mar 2023 00:17:34 GMT
Server: Werkzeug/2.2.3 Python/3.11.2

{
    "username": "Leonard McCoy",
    "lat": 3,
    "long": 2
}

$ http POST localhost:5000/add_user username=Spock lat:=13 long:=25
HTTP/1.1 200 OK
Connection: close
Content-Length: 40
Content-Type: application/json
Date: Mon, 27 Mar 2023 00:19:05 GMT
Server: Werkzeug/2.2.3 Python/3.11.2

{
    "username": "Spock",
    "lat": 13,
    "long": 25
}

Get crew members sorted by distance

Only first 100 members will be returned.

$ http GET localhost:5000/get_users lat==4 long==5
HTTP/1.1 200 OK
Connection: close
Content-Length: 234
Content-Type: application/json
Date: Mon, 27 Mar 2023 00:19:38 GMT
Server: Werkzeug/2.2.3 Python/3.11.2

[
    {
        "distance": 313424.65220079,
        "username": "James Tiberius Kirk",
        "lat": 2.0,
        "long": 3.0
    },
    {
        "distance": 349845.80896481,
        "username": "Leonard McCoy",
        "lat": 3.0,
        "long": 2.0
    },
    {
        "distance": 2413163.60819159,
        "username": "Spock",
        "lat": 13.0,
        "long": 25.0
    }
]

Get the nearest crew member

$ http GET localhost:5000/get_users lat==4 long==5 count==1
HTTP/1.1 200 OK
Connection: close
Content-Length: 85
Content-Type: application/json
Date: Mon, 27 Mar 2023 00:20:04 GMT
Server: Werkzeug/2.2.3 Python/3.11.2

[
    {
        "distance": 313424.65220079,
        "username": "James Tiberius Kirk",
        "lat": 2.0,
        "long": 3.0
    }
]

Live long and prosper ๐Ÿ––

scotty's People

Contributors

valericus avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.