upstream-sdk-python 0.0.3__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.
- upstream_sdk_python-0.0.3/.gitignore +2 -0
- upstream_sdk_python-0.0.3/PKG-INFO +51 -0
- upstream_sdk_python-0.0.3/README.md +28 -0
- upstream_sdk_python-0.0.3/pyproject.toml +34 -0
- upstream_sdk_python-0.0.3/upstream_sdk/__init__.py +4 -0
- upstream_sdk_python-0.0.3/upstream_sdk/client.py +47 -0
- upstream_sdk_python-0.0.3/upstream_sdk/types.py +35 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: upstream-sdk-python
|
|
3
|
+
Version: 0.0.3
|
|
4
|
+
Summary: Simple and open logging for your projects
|
|
5
|
+
Project-URL: Homepage, https://up.linus.my
|
|
6
|
+
Project-URL: Documentation, https://docs.linus.my/upstream
|
|
7
|
+
Project-URL: Repository, https://github.com/linusdotmy/upstream
|
|
8
|
+
License: CC BY-NC 4.0
|
|
9
|
+
Keywords: events,logging,logs,sdk,upstream
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Requires-Python: >=3.8
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# upstream-sdk
|
|
25
|
+
|
|
26
|
+
Simple and open logging for your projects.
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install upstream-sdk
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from upstream_sdk import Upstream, EventProps
|
|
38
|
+
|
|
39
|
+
up = Upstream("YOUR_API_KEY")
|
|
40
|
+
|
|
41
|
+
up.events.ingest(EventProps(
|
|
42
|
+
title="Project Deployed",
|
|
43
|
+
icon="😁",
|
|
44
|
+
))
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
That's just scratching the surface. You can log complex events with JSON, timeline events, descriptions, fields, and even add action buttons.
|
|
48
|
+
|
|
49
|
+
## License
|
|
50
|
+
|
|
51
|
+
MIT
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# upstream-sdk
|
|
2
|
+
|
|
3
|
+
Simple and open logging for your projects.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install upstream-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from upstream_sdk import Upstream, EventProps
|
|
15
|
+
|
|
16
|
+
up = Upstream("YOUR_API_KEY")
|
|
17
|
+
|
|
18
|
+
up.events.ingest(EventProps(
|
|
19
|
+
title="Project Deployed",
|
|
20
|
+
icon="😁",
|
|
21
|
+
))
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
That's just scratching the surface. You can log complex events with JSON, timeline events, descriptions, fields, and even add action buttons.
|
|
25
|
+
|
|
26
|
+
## License
|
|
27
|
+
|
|
28
|
+
MIT
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "upstream-sdk-python"
|
|
7
|
+
version = "0.0.3"
|
|
8
|
+
description = "Simple and open logging for your projects"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "CC BY-NC 4.0"}
|
|
11
|
+
requires-python = ">=3.8"
|
|
12
|
+
keywords = ["upstream", "logging", "sdk", "events", "logs"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 4 - Beta",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.8",
|
|
19
|
+
"Programming Language :: Python :: 3.9",
|
|
20
|
+
"Programming Language :: Python :: 3.10",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
24
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.urls]
|
|
28
|
+
Homepage = "https://up.linus.my"
|
|
29
|
+
Documentation = "https://docs.linus.my/upstream"
|
|
30
|
+
Repository = "https://github.com/linusdotmy/upstream"
|
|
31
|
+
|
|
32
|
+
[tool.hatch.build.targets.wheel]
|
|
33
|
+
packages = ["upstream_sdk"]
|
|
34
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import urllib.request
|
|
3
|
+
from dataclasses import asdict
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
from .types import EventProps
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class _EventsAPI:
|
|
10
|
+
def __init__(self, api_key: str, host: str):
|
|
11
|
+
self._api_key = api_key
|
|
12
|
+
self._host = host.rstrip("/")
|
|
13
|
+
|
|
14
|
+
def ingest(self, payload: EventProps) -> dict:
|
|
15
|
+
url = f"{self._host}/api/events/ingest"
|
|
16
|
+
data = asdict(payload)
|
|
17
|
+
|
|
18
|
+
# Convert snake_case to camelCase for API compatibility
|
|
19
|
+
if "created_at" in data:
|
|
20
|
+
data["createdAt"] = data.pop("created_at")
|
|
21
|
+
|
|
22
|
+
# Remove None values to keep payload clean
|
|
23
|
+
data = {k: v for k, v in data.items() if v is not None}
|
|
24
|
+
|
|
25
|
+
req = urllib.request.Request(
|
|
26
|
+
url,
|
|
27
|
+
data=json.dumps(data, default=str).encode("utf-8"),
|
|
28
|
+
headers={
|
|
29
|
+
"Content-Type": "application/json",
|
|
30
|
+
"x-api-key": self._api_key,
|
|
31
|
+
},
|
|
32
|
+
method="POST",
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
with urllib.request.urlopen(req) as response:
|
|
37
|
+
return json.loads(response.read().decode("utf-8"))
|
|
38
|
+
except urllib.error.HTTPError as e:
|
|
39
|
+
body = e.read().decode("utf-8")
|
|
40
|
+
raise Exception(f"Upstream API error ({e.code}): {body}") from e
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class Upstream:
|
|
44
|
+
def __init__(self, api_key: str, host: Optional[str] = None):
|
|
45
|
+
self._api_key = api_key
|
|
46
|
+
self._host = host or "https://up.linus.my"
|
|
47
|
+
self.events = _EventsAPI(self._api_key, self._host)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Any, List, Literal, Optional
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@dataclass
|
|
6
|
+
class Field:
|
|
7
|
+
name: str
|
|
8
|
+
value: str
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class TimelineEvent:
|
|
13
|
+
icon: str
|
|
14
|
+
time: str
|
|
15
|
+
content: str
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class Action:
|
|
20
|
+
title: str
|
|
21
|
+
type: Literal["default", "secondary", "ghost"]
|
|
22
|
+
url: str
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass
|
|
26
|
+
class EventProps:
|
|
27
|
+
title: str
|
|
28
|
+
icon: str
|
|
29
|
+
created_at: Optional[str] = None
|
|
30
|
+
content: Optional[str] = None
|
|
31
|
+
category: Optional[str] = None
|
|
32
|
+
fields: Optional[List[Field]] = None
|
|
33
|
+
events: Optional[List[TimelineEvent]] = None
|
|
34
|
+
data: Optional[Any] = None
|
|
35
|
+
actions: Optional[List[Action]] = None
|