opendataframework 0.0.3__tar.gz → 0.0.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. {opendataframework-0.0.3 → opendataframework-0.0.4}/PKG-INFO +1 -1
  2. {opendataframework-0.0.3 → opendataframework-0.0.4}/pyproject.toml +1 -1
  3. {opendataframework-0.0.3 → opendataframework-0.0.4}/setup.py +3 -2
  4. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/__init__.py +1 -1
  5. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/__main__.py +161 -2
  6. opendataframework-0.0.4/src/opendataframework/api/inference/.env +7 -0
  7. opendataframework-0.0.4/src/opendataframework/api/inference/Dockerfile +16 -0
  8. opendataframework-0.0.4/src/opendataframework/api/inference/app/__init__.py +11 -0
  9. opendataframework-0.0.4/src/opendataframework/api/inference/app/config.py +14 -0
  10. opendataframework-0.0.4/src/opendataframework/api/inference/app/crud.py +14 -0
  11. opendataframework-0.0.4/src/opendataframework/api/inference/app/dependencies.py +19 -0
  12. opendataframework-0.0.4/src/opendataframework/api/inference/app/main.py +39 -0
  13. opendataframework-0.0.4/src/opendataframework/api/inference/app/models.py +20 -0
  14. opendataframework-0.0.4/src/opendataframework/api/inference/app/router.py +18 -0
  15. opendataframework-0.0.4/src/opendataframework/api/inference/docker-compose.yaml +16 -0
  16. opendataframework-0.0.4/src/opendataframework/api/inference/pyproject.toml +20 -0
  17. {opendataframework-0.0.3 → opendataframework-0.0.4}/LICENSE +0 -0
  18. {opendataframework-0.0.3 → opendataframework-0.0.4}/README.md +0 -0
  19. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/README.md +0 -0
  20. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/analytics/setup.sh +0 -0
  21. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/analytics/superset/.env +0 -0
  22. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/analytics/superset/Dockerfile +0 -0
  23. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/analytics/superset/database/postgres/create.sh +0 -0
  24. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/analytics/superset/database/postgres/setup.sh +0 -0
  25. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/analytics/superset/docker-compose.yaml +0 -0
  26. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/analytics/superset/setup.sh +0 -0
  27. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/api/api-postgres/.env +0 -0
  28. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/api/api-postgres/Dockerfile +0 -0
  29. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/api/api-postgres/app/__init__.py +0 -0
  30. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/api/api-postgres/app/config.py +0 -0
  31. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/api/api-postgres/app/crud.py +0 -0
  32. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/api/api-postgres/app/database.py +0 -0
  33. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/api/api-postgres/app/dependencies.py +0 -0
  34. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/api/api-postgres/app/main.py +0 -0
  35. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/api/api-postgres/app/models.py +0 -0
  36. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/api/api-postgres/app/router.py +0 -0
  37. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/api/api-postgres/docker-compose.yaml +0 -0
  38. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/api/api-postgres/poetry.lock +0 -0
  39. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/api/api-postgres/pyproject.toml +0 -0
  40. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/api/ingest.py +0 -0
  41. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/api/requirements.txt +0 -0
  42. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/api/setup.sh +0 -0
  43. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/devcontainers/R/.devcontainer/.Rprofile +0 -0
  44. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/devcontainers/R/.devcontainer/Dockerfile +0 -0
  45. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/devcontainers/R/.devcontainer/devcontainer.json +0 -0
  46. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/devcontainers/python/.devcontainer/Dockerfile +0 -0
  47. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/devcontainers/python/.devcontainer/devcontainer.json +0 -0
  48. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/docker-compose.yaml +0 -0
  49. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/docs/index.md +0 -0
  50. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/docs/mkdocs.yml +0 -0
  51. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/docs/requirements.txt +0 -0
  52. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/docs/stylesheets/extra.css +0 -0
  53. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/expectations.py +0 -0
  54. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/github/workflows/ci.yaml +0 -0
  55. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/hooks/.pre-commit-config.yaml +0 -0
  56. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/hooks/requirements.txt +0 -0
  57. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/layouts/research/.vscode/extensions.json +0 -0
  58. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/layouts/research/code/build/.gitkeep +0 -0
  59. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/layouts/research/code/check/.gitkeep +0 -0
  60. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/layouts/research/code/learn/.gitkeep +0 -0
  61. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/layouts/research/code/share/.gitkeep +0 -0
  62. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/layouts/research/data/derived/.gitkeep +0 -0
  63. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/layouts/research/data/raw/.gitkeep +0 -0
  64. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/layouts/research/libraries/.gitkeep +0 -0
  65. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/layouts/research/logs/.gitkeep +0 -0
  66. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/layouts/research/models/.gitkeep +0 -0
  67. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/layouts/research/output/figures/.gitkeep +0 -0
  68. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/layouts/research/output/tables/.gitkeep +0 -0
  69. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/layouts/research/paper/.gitkeep +0 -0
  70. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/requirements.txt +0 -0
  71. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/setup.sh +0 -0
  72. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/storage/postgres/.env +0 -0
  73. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/storage/postgres/Dockerfile +0 -0
  74. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/storage/postgres/docker-compose.yaml +0 -0
  75. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/storage/postgres/setup.sh +0 -0
  76. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/storage/setup.sh +0 -0
  77. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/tests/__init__.py +0 -0
  78. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/tests/requirements.txt +0 -0
  79. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/tests/test_example.py +0 -0
  80. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/utility/nginx/Dockerfile +0 -0
  81. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/utility/nginx/docker-compose.yaml +0 -0
  82. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/utility/nginx/nginx.conf +0 -0
  83. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/utility/nginx/static/images/logo.svg +0 -0
  84. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/utility/nginx/static/index.html +0 -0
  85. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/utility/setup.sh +0 -0
  86. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/utility/texlive/Dockerfile +0 -0
  87. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/utility/texlive/docker-compose.yaml +0 -0
  88. {opendataframework-0.0.3 → opendataframework-0.0.4}/src/opendataframework/utility/texlive/mnt/.gitkeep +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: opendataframework
3
- Version: 0.0.3
3
+ Version: 0.0.4
4
4
  Summary: Open Data Framework is an open source, full stack data framework.
5
5
  Home-page: https://github.com/opendataframework/opendataframework
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "opendataframework"
3
- version = "0.0.3"
3
+ version = "0.0.4"
4
4
  description = "Open Data Framework is an open source, full stack data framework."
5
5
  authors = [
6
6
  "mykytapavlov <mykytapavlov@users.noreply.github.com>",
@@ -8,6 +8,7 @@ packages = \
8
8
  ['opendataframework',
9
9
  'opendataframework.api',
10
10
  'opendataframework.api.api-postgres.app',
11
+ 'opendataframework.api.inference.app',
11
12
  'opendataframework.tests']
12
13
 
13
14
  package_data = \
@@ -42,7 +43,7 @@ package_data = \
42
43
  'utility/nginx/static/images/*',
43
44
  'utility/texlive/*',
44
45
  'utility/texlive/mnt/*'],
45
- 'opendataframework.api': ['api-postgres/*']}
46
+ 'opendataframework.api': ['api-postgres/*', 'inference/*']}
46
47
 
47
48
  install_requires = \
48
49
  ['typer>=0.12.3,<0.13.0']
@@ -52,7 +53,7 @@ entry_points = \
52
53
 
53
54
  setup_kwargs = {
54
55
  'name': 'opendataframework',
55
- 'version': '0.0.3',
56
+ 'version': '0.0.4',
56
57
  'description': 'Open Data Framework is an open source, full stack data framework.',
57
58
  'long_description': '# Open Data Framework\nOpen source, full stack data framework.\n',
58
59
  'author': 'mykytapavlov',
@@ -1,3 +1,3 @@
1
1
  """Open Data Framework package."""
2
2
 
3
- __version__ = "0.0.3"
3
+ __version__ = "0.0.4"
@@ -100,6 +100,7 @@ class Component:
100
100
 
101
101
  # API
102
102
  API_POSTGRES: str = "api-postgres"
103
+ INFERENCE: str = "inference"
103
104
 
104
105
  # DEVCONTAINERS
105
106
  PYTHON: str = "python"
@@ -123,7 +124,7 @@ FILE_FORMATS = {
123
124
  COMPONENTS = {
124
125
  Layer.ANALYTICS: [Component.SUPERSET],
125
126
  Layer.DEVCONTAINERS: [Component.PYTHON, Component.R],
126
- Layer.API: [Component.API_POSTGRES],
127
+ Layer.API: [Component.API_POSTGRES, Component.INFERENCE],
127
128
  Layer.STORAGE: [Component.POSTGRES],
128
129
  Layer.UTILITY: [Component.NGINX, Component.TEXLIVE],
129
130
  }
@@ -154,6 +155,7 @@ PORTS = {
154
155
  Component.SUPERSET: "8088",
155
156
  # API
156
157
  Component.API_POSTGRES: "8000",
158
+ Component.INFERENCE: "8000",
157
159
  # STORAGE
158
160
  Component.POSTGRES: "5432",
159
161
  # UTILITY
@@ -431,16 +433,20 @@ class Entity:
431
433
  class Project:
432
434
  """Project."""
433
435
 
434
- def __init__(self, name: str, path: str = "", data: str = ""):
436
+ def __init__(self, name: str, path: str = "", data: str = "", models: str = ""):
435
437
  """Create project instance."""
436
438
  self._name = None
437
439
  self._path = None
438
440
  self._profile = Profile.CUSTOM
439
441
  self._layout = Layout.CUSTOM
442
+ self._models = None
443
+
440
444
  if data:
441
445
  self._data = os.path.join(os.getcwd(), data)
442
446
  else:
443
447
  self._data = os.path.join(os.getcwd(), "data")
448
+ if models:
449
+ self._models = os.path.join(os.getcwd(), models)
444
450
 
445
451
  self._settings = {
446
452
  "opendataframework": __version__,
@@ -505,6 +511,34 @@ class Project:
505
511
 
506
512
  self._path = path
507
513
 
514
+ if not self._models:
515
+ models = os.path.join(os.getcwd(), "models")
516
+ if not os.path.exists(models):
517
+ return
518
+ self._models = models
519
+
520
+ models_path = os.path.join(path, "models")
521
+ if not os.path.exists(models_path):
522
+ os.mkdir(models_path)
523
+ rprint(f"{models_path}[green] created[/green]")
524
+
525
+ for folder in os.listdir(self._models):
526
+ source_path = os.path.join(self._models, folder)
527
+ if os.path.isdir(source_path):
528
+ dest_path = os.path.join(models_path, folder)
529
+ if not os.path.exists(dest_path):
530
+ os.mkdir(dest_path)
531
+
532
+ for file_name in os.listdir(source_path):
533
+ supported = [
534
+ file_name.endswith(".pkl"),
535
+ file_name.strip().lower() == "requirements.txt",
536
+ ]
537
+ if not any(supported):
538
+ continue
539
+ self.copy(source_path, dest_path, file_name)
540
+ rprint(f"{file_name}[green] copied to [/green]{dest_path}")
541
+
508
542
  @property
509
543
  def settings(self) -> dict:
510
544
  """Get project settings."""
@@ -1340,9 +1374,134 @@ class API:
1340
1374
 
1341
1375
  rprint(f"{to_path}[green] created[/green]")
1342
1376
 
1377
+ def inference(self):
1378
+ """Configure API `INFERENCE` component."""
1379
+ from_path = os.path.join(SRC_PATH, Layer.API, Component.INFERENCE)
1380
+ if not os.path.exists(from_path):
1381
+ raise ValueError(f"{from_path} does not exist")
1382
+
1383
+ entities = self.project.settings.get("entities", {})
1384
+
1385
+ for plural_name, settings in entities.items():
1386
+ components = settings["layers"].get(Layer.API, {})
1387
+ if Component.INFERENCE not in components:
1388
+ continue
1389
+
1390
+ to_path = os.path.join(
1391
+ self.project.path,
1392
+ PLATFORM_FOLDER,
1393
+ Layer.API,
1394
+ Component.INFERENCE,
1395
+ plural_name,
1396
+ )
1397
+ if os.path.exists(to_path):
1398
+ raise ValueError(f"{to_path} already exists")
1399
+
1400
+ shutil.copytree(
1401
+ from_path,
1402
+ to_path,
1403
+ ignore=shutil.ignore_patterns(
1404
+ *IGNORE_PATTERNS,
1405
+ ),
1406
+ )
1407
+
1408
+ model_path = os.path.join(self.project.path, "models", plural_name)
1409
+ if not os.path.exists(os.path.join(model_path, "model.pkl")):
1410
+ raise ValueError(f"{model_path} does not exist")
1411
+
1412
+ Project.copy(model_path, os.path.join(to_path, "app"), "model.pkl")
1413
+
1414
+ if os.path.exists(os.path.join(model_path, "requirements.txt")):
1415
+ with open(os.path.join(model_path, "requirements.txt"), "r") as file:
1416
+ filedata = file.read()
1417
+ new_filedata = []
1418
+ for line in filedata.split("\n"):
1419
+ if not line:
1420
+ continue
1421
+ packet, version = line.split("==")
1422
+ new_line = f'{packet} = "{version}"'
1423
+ new_filedata.append(new_line)
1424
+ filedata = "\n".join(new_filedata)
1425
+
1426
+ Project.replace(
1427
+ os.path.join(to_path, "pyproject.toml"),
1428
+ "# dependencies",
1429
+ filedata,
1430
+ )
1431
+
1432
+ hostname = self.project.settings["project"].replace("_", "-")
1433
+
1434
+ Project.replace(
1435
+ os.path.join(to_path, "docker-compose.yaml"),
1436
+ f"hostname: {PROJECT_NAME}-{Component.INFERENCE}",
1437
+ f"hostname: {hostname}-{Component.INFERENCE}",
1438
+ )
1439
+
1440
+ Project.replace(
1441
+ os.path.join(to_path, "docker-compose.yaml"),
1442
+ f"{PROJECT_NAME}",
1443
+ self.project.settings["project"],
1444
+ )
1445
+
1446
+ Project.replace(
1447
+ os.path.join(to_path, "docker-compose.yaml"), "entity", plural_name
1448
+ )
1449
+
1450
+ port = components[Component.INFERENCE]["port"]
1451
+ Project.replace(
1452
+ os.path.join(to_path, "docker-compose.yaml"),
1453
+ f"{PORTS[Component.INFERENCE]}:",
1454
+ f"{port}:",
1455
+ )
1456
+
1457
+ # model
1458
+ model_path = os.path.join(to_path, "app", "models.py")
1459
+ new_text = "# fields"
1460
+
1461
+ for field_name, field_type in settings["fields"].items():
1462
+ if field_name in Field.RESERVED_FIELDS:
1463
+ raise ValueError(
1464
+ f"Field names `{self.RESERVED_FIELDS}` are reserved"
1465
+ )
1466
+ if "datetime" in field_type:
1467
+ # TODO: format validator
1468
+ field_type = "datetime"
1469
+
1470
+ new_text += f"\n {field_name}: {field_type}"
1471
+
1472
+ Project.replace(model_path, "# extra fields", new_text)
1473
+ Project.replace(model_path, "entities", plural_name)
1474
+ Project.replace(model_path, "Entity", settings["name"].capitalize())
1475
+
1476
+ # crud
1477
+ crud_path = os.path.join(to_path, "app", "crud.py")
1478
+ Project.replace(crud_path, "entity", settings["name"])
1479
+ Project.replace(crud_path, "entities", plural_name)
1480
+ Project.replace(crud_path, "Entity", settings["name"].capitalize())
1481
+
1482
+ # router
1483
+ router_path = os.path.join(to_path, "app", "router.py")
1484
+ Project.replace(router_path, "entity", settings["name"])
1485
+ Project.replace(router_path, "entities", plural_name)
1486
+ Project.replace(router_path, "Entity", settings["name"].capitalize())
1487
+
1488
+ # env
1489
+ env_path = os.path.join(to_path, ".env")
1490
+ Project.replace(
1491
+ env_path, f"{PROJECT_NAME}", self.project.settings["project"]
1492
+ )
1493
+ Project.replace(env_path, "description", settings["description"])
1494
+
1495
+ # main
1496
+ main_path = os.path.join(to_path, "app", "main.py")
1497
+ Project.replace(main_path, "entity", settings["name"])
1498
+
1499
+ rprint(f"{to_path}[green] created[/green]")
1500
+
1343
1501
  def __call__(self):
1344
1502
  """Call layer."""
1345
1503
  self.api_postgres()
1504
+ self.inference()
1346
1505
 
1347
1506
 
1348
1507
  class Devcontainers:
@@ -0,0 +1,7 @@
1
+ API_V1_PREFIX="/api/v1"
2
+
3
+ DEBUG=True
4
+ DESCRIPTION="description"
5
+
6
+ PROJECT_NAME="project_name"
7
+ VERSION="0.1.0"
@@ -0,0 +1,16 @@
1
+ FROM python:3.11.2
2
+ WORKDIR /api
3
+
4
+ COPY .env pyproject.toml ./
5
+
6
+
7
+ ARG poetry_version=1.3.2
8
+ RUN pip install poetry==${poetry_version}
9
+ RUN poetry config virtualenvs.create false
10
+ RUN poetry install
11
+
12
+ COPY app/ app/
13
+
14
+ EXPOSE 8000
15
+
16
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
@@ -0,0 +1,11 @@
1
+ """App package."""
2
+
3
+ from os import getenv
4
+
5
+ from dotenv import load_dotenv
6
+
7
+ from app.config import Settings
8
+
9
+ load_dotenv(getenv("ENV_FILE"))
10
+
11
+ settings = Settings()
@@ -0,0 +1,14 @@
1
+ """Config module."""
2
+
3
+ from pydantic import BaseSettings
4
+
5
+
6
+ class Settings(BaseSettings):
7
+ """Settings."""
8
+
9
+ # Base
10
+ api_v1_prefix: str
11
+ debug: bool
12
+ project_name: str
13
+ version: str
14
+ description: str
@@ -0,0 +1,14 @@
1
+ """CRUD module."""
2
+
3
+ from typing import Any
4
+
5
+ import pandas as pd
6
+
7
+ from app.models import Entity
8
+
9
+
10
+ def predict(entity: Entity, inference: Any) -> float:
11
+ """Predict."""
12
+ data = pd.DataFrame(entity.dict(), index=[0])
13
+ predictions = inference.predict(data)
14
+ return predictions[0]
@@ -0,0 +1,19 @@
1
+ """Dependencies module."""
2
+
3
+ import os
4
+ import pickle
5
+ from pathlib import Path
6
+
7
+ MODEL_PATH = os.path.join(Path(__file__).parent, "model.pkl")
8
+ INFERENCE_MODEL = None
9
+
10
+
11
+ def get_inference():
12
+ """Get inference model."""
13
+ global INFERENCE_MODEL
14
+
15
+ if INFERENCE_MODEL is None:
16
+ with open(MODEL_PATH, "rb") as file:
17
+ INFERENCE_MODEL = pickle.load(file) # nosec
18
+
19
+ yield INFERENCE_MODEL
@@ -0,0 +1,39 @@
1
+ """Main module."""
2
+
3
+ from fastapi import FastAPI
4
+ from fastapi.middleware.cors import CORSMiddleware
5
+
6
+ from app import settings
7
+ from app.models import HealthCheck
8
+ from app.router import inference_router
9
+
10
+ app = FastAPI(
11
+ title=settings.project_name,
12
+ version=settings.version,
13
+ openapi_url=f"{settings.api_v1_prefix}/openapi.json",
14
+ debug=settings.debug,
15
+ )
16
+
17
+
18
+ origins = ["http://localhost:8080"]
19
+
20
+ app.add_middleware(
21
+ CORSMiddleware,
22
+ allow_origins=origins,
23
+ allow_credentials=True,
24
+ allow_methods=["*"],
25
+ allow_headers=["*"],
26
+ )
27
+
28
+
29
+ @app.get("/", response_model=HealthCheck, tags=["status"])
30
+ async def health_check():
31
+ """Health check."""
32
+ return {
33
+ "name": settings.project_name,
34
+ "version": settings.version,
35
+ "description": settings.description,
36
+ }
37
+
38
+
39
+ app.include_router(inference_router, prefix=settings.api_v1_prefix)
@@ -0,0 +1,20 @@
1
+ """Models module."""
2
+
3
+ from pydantic import BaseModel
4
+ from sqlmodel import SQLModel
5
+
6
+
7
+ class HealthCheck(BaseModel):
8
+ """Health check model."""
9
+
10
+ name: str
11
+ version: str
12
+ description: str
13
+
14
+
15
+ class Entity(SQLModel):
16
+ """Entity model."""
17
+
18
+ __tablename__ = "entities"
19
+
20
+ # extra fields
@@ -0,0 +1,18 @@
1
+ """Router module."""
2
+
3
+ from typing import Any
4
+
5
+ from fastapi import APIRouter, Depends, status
6
+
7
+ from app.crud import predict
8
+ from app.dependencies import get_inference
9
+ from app.models import Entity
10
+
11
+ inference_router = APIRouter(prefix="/inference", tags=["inference"])
12
+
13
+
14
+ @inference_router.post("/", status_code=status.HTTP_200_OK)
15
+ def get_prediction(entity: Entity, inference: Any = Depends(get_inference)) -> float:
16
+ """Create prediction."""
17
+ prediction = predict(entity, inference)
18
+ return prediction
@@ -0,0 +1,16 @@
1
+ version: "3.9"
2
+ services:
3
+ project_name_entity:
4
+ profiles: ["api"]
5
+ image: project_name:entity
6
+ container_name: project_name_entity
7
+ hostname: project_name-entity
8
+ build:
9
+ context: ./api/inference/entity
10
+ args:
11
+ poetry_version: "1.3.2"
12
+ ports:
13
+ - 8000:8000
14
+ networks:
15
+ - project_name_default
16
+ restart: always
@@ -0,0 +1,20 @@
1
+ [tool.poetry]
2
+ name = "api"
3
+ version = "0.1.0"
4
+ description = ""
5
+ authors = [""]
6
+ license = "MIT"
7
+ readme = "README.md"
8
+
9
+ [tool.poetry.dependencies]
10
+ python = "^3.11"
11
+ fastapi = "^0.92.0"
12
+ sqlmodel = "^0.0.8"
13
+ python-dotenv = "^0.21.1"
14
+ uvicorn = "^0.20.0"
15
+ pandas = "^2.2.3"
16
+ # dependencies
17
+
18
+ [build-system]
19
+ requires = ["poetry-core"]
20
+ build-backend = "poetry.core.masonry.api"