Initial commit

This commit is contained in:
2024-07-08 19:44:51 +01:00
commit 7dd401c232
9 changed files with 1860 additions and 0 deletions

161
.gitignore vendored Normal file
View File

@@ -0,0 +1,161 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
.ruff_cache

11
Makefile Normal file
View File

@@ -0,0 +1,11 @@
.venv:
python3 -m pip install poetry
python3 -m poetry install --with test,github
.PHONY: tests
tests: .venv
python3 -m poetry run pytest
lint: .venv
python3 -m poetry run ruff check --output-format=github --select=E9,F63,F7,F82 --target-version=py37 .
python3 -m poetry run ruff check --output-format=github --target-version=py37 .

5
README.md Normal file
View File

@@ -0,0 +1,5 @@
# pydantic-spaceapi
A collection of [Pydantic](https://docs.pydantic.dev) models representing the common formats of the [SpaceAPI spec](https://spaceapi.io).
Originally developed as part of [Leigh Hackspace's Hackspace-API](https://github.com/leigh-hackspace/hackspace-api), but forked off into a separate repository for further development.

1297
poetry.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

View File

@@ -0,0 +1,125 @@
"""
SpaceAPI v13
https://github.com/SpaceApi/schema
"""
from typing import List, Optional
from pydantic import BaseModel, HttpUrl
from pydantic_extra_types.coordinate import Latitude, Longitude
from .sensors import (
SpaceAPIv13BarometerSensorModel,
SpaceAPIv13BaseSensorModel,
SpaceAPIv13BeverageSupplySensorModel,
SpaceAPIv13HumiditySensorModel,
SpaceAPIv13TemperatureSensorModel,
SpaceAPIv13NetworkConnectionSensorModel,
SpaceAPIv13PeoplePresentSensorModel,
SpaceAPIv13PowerConsumptionSensorModel,
SpaceAPIv13TotalMemberCountSensorModel,
SpaceAPIv13WindSensorModel,
SpaceAPIv13AccountBalanceSensorModel,
SpaceAPIv13RadiationSensorModel,
)
class SpaceAPIv13LocationModel(BaseModel):
address: Optional[str] = None
lat: Latitude
lon: Longitude
timezone: Optional[str] = None
class SpaceAPIv13SpacefedModel(BaseModel):
spacenet: bool = False
spacesaml: bool = False
spacephone: bool = False
class SpaceAPIv13KeymastersModel(BaseModel):
name: Optional[str] = None
irc_nick: Optional[str] = None
phone: Optional[str] = None
email: Optional[str] = None
twitter: Optional[str] = None
class SpaceAPIv13ContactModel(BaseModel):
phone: Optional[str] = None
sip: Optional[str] = None
keymasters: Optional[List[SpaceAPIv13KeymastersModel]] = None
irc: Optional[str] = None
twitter: Optional[str] = None
identica: Optional[str] = None
foursquare: Optional[str] = None
email: Optional[str] = None
ml: Optional[str] = None
jabber: Optional[str] = None
issue_mail: Optional[str] = None
gopher: Optional[str] = None
class SpaceAPIv13StateIconModel(BaseModel):
open: HttpUrl
closed: HttpUrl
class SpaceAPIv13StateModel(BaseModel):
open: bool = False
lastchange: Optional[int] = None
trigger_persion: Optional[str] = None
message: Optional[str] = None
icon: Optional[SpaceAPIv13StateIconModel] = None
class SpaceAPIv13EventModel(BaseModel):
name: str
type: str
timestamp: int
extra: str
class SpaceAPIv13SensorsModel(BaseModel):
temperature: Optional[List[SpaceAPIv13TemperatureSensorModel]] = None
door_locked: Optional[List[SpaceAPIv13BaseSensorModel]] = None
barometer: Optional[List[SpaceAPIv13BarometerSensorModel]] = None
radiation: Optional[List[SpaceAPIv13RadiationSensorModel]] = None
humidity: Optional[List[SpaceAPIv13HumiditySensorModel]] = None
beverage_supply: Optional[List[SpaceAPIv13BeverageSupplySensorModel]] = None
power_consumption: Optional[List[SpaceAPIv13PowerConsumptionSensorModel]] = None
wind: Optional[List[SpaceAPIv13WindSensorModel]] = None
network_connections: Optional[List[SpaceAPIv13NetworkConnectionSensorModel]] = None
account_balance: Optional[List[SpaceAPIv13AccountBalanceSensorModel]] = None
total_member_count: Optional[List[SpaceAPIv13TotalMemberCountSensorModel]] = None
people_now_present: Optional[List[SpaceAPIv13PeoplePresentSensorModel]] = None
class SpaceAPIv13FeedModel(BaseModel):
type: Optional[str] = None
url: HttpUrl
class SpaceAPIv13FeedsModel(BaseModel):
blog: Optional[SpaceAPIv13FeedModel] = None
wiki: Optional[SpaceAPIv13FeedModel] = None
calendar: Optional[SpaceAPIv13FeedModel] = None
flickr: Optional[SpaceAPIv13FeedModel] = None
class SpaceAPIv13Model(BaseModel):
api: str = "0.13"
space: str
logo: HttpUrl
url: HttpUrl
location: SpaceAPIv13LocationModel
spacefed: Optional[SpaceAPIv13SpacefedModel] = None
cam: Optional[List[HttpUrl]] = None
state: Optional[SpaceAPIv13StateModel] = None
events: Optional[List[SpaceAPIv13EventModel]] = None
contact: SpaceAPIv13ContactModel
issue_report_channels: Optional[List[str]] = None
sensors: Optional[SpaceAPIv13SensorsModel] = None
feeds: Optional[SpaceAPIv13FeedsModel] = None
projects: Optional[List[str]] = None

View File

@@ -0,0 +1,153 @@
from typing import Optional, List
from enum import Enum
from pydantic import BaseModel
from pydantic_extra_types.mac_address import MacAddress
class SpaceAPIv13BaseSensorModel(BaseModel):
value: float
location: Optional[str] = None
name: Optional[str] = None
description: Optional[str] = None
class TemperatureUnitEnum(str, Enum):
celsius = "°C"
fahrenheit = "°F"
kelvin = "K"
delisle = "°De"
newton = "°N"
rankine = "°R"
reaumur = "°Ré"
romer = "°Rø"
class SpaceAPIv13TemperatureSensorModel(SpaceAPIv13BaseSensorModel):
unit: TemperatureUnitEnum
location: str
class PressureUnitEnum(str, Enum):
hectopascal = "hPa"
class SpaceAPIv13BarometerSensorModel(SpaceAPIv13BaseSensorModel):
unit: PressureUnitEnum
location: str
class RadiationUnitEnum(str, Enum):
cpm = "cpm"
rh = "r/h"
usvh = "µSv/h"
msva = "mSv/a"
usva = "µSv/a"
class SpaceAPIv13RadiationTypeSensorModel(SpaceAPIv13BaseSensorModel):
unit: RadiationUnitEnum
dead_time: Optional[float] = None
conversion_factor: Optional[float] = None
class SpaceAPIv13RadiationSensorModel(SpaceAPIv13BaseSensorModel):
alpha: Optional[List[SpaceAPIv13RadiationTypeSensorModel]] = None
beta: Optional[List[SpaceAPIv13RadiationTypeSensorModel]] = None
gamma: Optional[List[SpaceAPIv13RadiationTypeSensorModel]] = None
beta_gamma: Optional[List[SpaceAPIv13RadiationTypeSensorModel]] = None
class HumidityUnitEnum(str, Enum):
relative_humidity = "%"
class SpaceAPIv13HumiditySensorModel(SpaceAPIv13BaseSensorModel):
unit: HumidityUnitEnum
location: str
class BeverageUnitEnum(str, Enum):
bottle = "btl"
crate = "crt"
class SpaceAPIv13BeverageSupplySensorModel(SpaceAPIv13BaseSensorModel):
unit: BeverageUnitEnum
class PowerConsumptionUnitEnum(str, Enum):
millawatt = "mW"
watt = "W"
voltage_amps = "VA"
class SpaceAPIv13PowerConsumptionSensorModel(SpaceAPIv13BaseSensorModel):
unit: PowerConsumptionUnitEnum
class WindSpeedUnitEnum(str, Enum):
meters_second = "m/s"
kilometers_hour = "km/h"
knots = "kn"
class SpaceAPIv13WindSpeedSensorPropertyModel(BaseModel):
value: float
unit: WindSpeedUnitEnum
class WindDirectionUnitEnum(str, Enum):
degrees = "°"
class SpaceAPIv13WindDirectionPropertyModel(BaseModel):
value: float
unit: WindDirectionUnitEnum
class WindElevationUnitEnum(str, Enum):
meters = "m"
class SpaceAPIv13WindElevationPropertyModel(BaseModel):
value: float
unit: WindElevationUnitEnum
class SpaceAPIv13WindSensorPropertiesModel(BaseModel):
speed: SpaceAPIv13WindSpeedSensorPropertyModel
gust: SpaceAPIv13WindSpeedSensorPropertyModel
direction: SpaceAPIv13WindDirectionPropertyModel
elevation: SpaceAPIv13WindElevationPropertyModel
class SpaceAPIv13WindSensorModel(SpaceAPIv13BaseSensorModel):
properties: SpaceAPIv13WindSensorPropertiesModel
class NetworkConnectionTypeEnum(str, Enum):
wifi = "wifi"
cable = "cable"
spacenet = "spacenet"
class SpaceAPIv13MachineModel(BaseModel):
name: Optional[str] = None
mac: MacAddress
class SpaceAPIv13NetworkConnectionSensorModel(SpaceAPIv13BaseSensorModel):
type: NetworkConnectionTypeEnum
machines: Optional[List[SpaceAPIv13MachineModel]] = None
class SpaceAPIv13AccountBalanceSensorModel(SpaceAPIv13BaseSensorModel):
unit: str
class SpaceAPIv13TotalMemberCountSensorModel(SpaceAPIv13BaseSensorModel):
pass
class SpaceAPIv13PeoplePresentSensorModel(SpaceAPIv13BaseSensorModel):
names: Optional[List[str]] = None

86
pydantic_spaceapi/v14.py Normal file
View File

@@ -0,0 +1,86 @@
"""
SpaceAPI v14
https://github.com/SpaceApi/schema
Most models are inherited from v13, updated models have values overridden
"""
from typing import List, Optional
from enum import Enum
from pydantic import BaseModel, HttpUrl
from .v13 import (
SpaceAPIv13LocationModel,
SpaceAPIv13ContactModel,
SpaceAPIv13KeymastersModel,
SpaceAPIv13Model,
SpaceAPIv13BaseSensorModel,
SpaceAPIv13SensorsModel,
)
class SpaceAPIv14LocationModel(SpaceAPIv13LocationModel):
timezone: Optional[str] = None
class SpaceAPIv14KeymastersModel(SpaceAPIv13KeymastersModel):
xmpp: Optional[str] = None
matrix: Optional[str] = None
mastodon: Optional[str] = None
mumble: Optional[str] = None
class SpaceAPIv14ContactModel(SpaceAPIv13ContactModel):
keymasters: Optional[List[SpaceAPIv14KeymastersModel]] = None
xmpp: Optional[str] = None
matrix: Optional[str] = None
mastodon: Optional[str] = None
mumble: Optional[str] = None
class SpaceAPIv14LinkModel(BaseModel):
name: str
description: Optional[str] = None
url: HttpUrl
class SpaceAPIv14NetworkTrafficSensorModel(SpaceAPIv13BaseSensorModel):
properties: dict
class SpaceAPIv14SensorsModel(SpaceAPIv13SensorsModel):
network_traffic: Optional[List[SpaceAPIv14NetworkTrafficSensorModel]] = None
class BillingIntervalEnum(str, Enum):
yearly = "yearly"
monthly = "monthly"
weekly = "weekly"
daily = "daily"
hourly = "hourly"
other = "other"
class SpaceAPIv14MembershipPlanModel(BaseModel):
name: str
value: int
currency: str
billing_interval: BillingIntervalEnum
description: Optional[str] = None
class SpaceAPIv14SpacefedModel(BaseModel):
spacenet: bool = False
spacesaml: bool = False
class SpaceAPIv14Model(SpaceAPIv13Model):
api_compatibility: List[str] = ["14"]
location: SpaceAPIv14LocationModel
spacefed: Optional[SpaceAPIv14SpacefedModel] = None
contact: SpaceAPIv14ContactModel
sensors: SpaceAPIv14SensorsModel
links: Optional[List[SpaceAPIv14LinkModel]] = None
membership_plans: Optional[List[SpaceAPIv14MembershipPlanModel]] = None

22
pyproject.toml Normal file
View File

@@ -0,0 +1,22 @@
[tool.poetry]
name = "pydantic-spaceapi"
version = "1.3.2"
description = ""
authors = ["Andrew Williams <andy@tensixtyone.com>"]
license = "MIT"
readme = "README.md"
repository = "https://github.com/nikdoof/pydantic-spaceapi/"
packages = [{include = "pydantic_spaceapi"}]
[tool.poetry.dependencies]
python = "^3.10"
poetry = "^1.7.1"
pydantic-extra-types = "^2.8.2"
ruff = "^0.5.1"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.ruff]
ignore = ["E501"]